caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* arm backend
@ 2009-04-30 12:14 Joel Reymont
  2009-04-30 13:28 ` Sylvain Le Gall
  2009-05-05  9:43 ` [Caml-list] arm backend Xavier Leroy
  0 siblings, 2 replies; 15+ messages in thread
From: Joel Reymont @ 2009-04-30 12:14 UTC (permalink / raw)
  To: O'Caml Mailing List

Is the ARM backend (ocamlopt) usable and actively maintained?

	Thanks, Joel

---
Mac hacker with a performance bent
http://linkedin.com/in/joelreymont




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: arm backend
  2009-04-30 12:14 arm backend Joel Reymont
@ 2009-04-30 13:28 ` Sylvain Le Gall
  2009-04-30 18:03   ` [Caml-list] " Stéphane Glondu
  2009-05-05  9:43 ` [Caml-list] arm backend Xavier Leroy
  1 sibling, 1 reply; 15+ messages in thread
From: Sylvain Le Gall @ 2009-04-30 13:28 UTC (permalink / raw)
  To: caml-list

Hello,

On 30-04-2009, Joel Reymont <joelr1@gmail.com> wrote:
> Is the ARM backend (ocamlopt) usable and actively maintained?
>

Xavier talked a little about it on 2009 OCaml Meeting. It seems that he
is interested in maintaining it but there is problem with floating point
computation (depending on some modes you can have hard/soft/semi-soft...
floating point computation). I don't know the status and Xavier Leroy
will explain you better the issue. 

AFAIK, he is interested in making ocamlopt backend work on NSLU2...

Regards
Sylvain Le Gall


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Caml-list] Re: arm backend
  2009-04-30 13:28 ` Sylvain Le Gall
@ 2009-04-30 18:03   ` Stéphane Glondu
  2009-04-30 19:19     ` Nathaniel Gray
  0 siblings, 1 reply; 15+ messages in thread
From: Stéphane Glondu @ 2009-04-30 18:03 UTC (permalink / raw)
  To: Sylvain Le Gall; +Cc: caml-list

Sylvain Le Gall a écrit :
> Xavier talked a little about it on 2009 OCaml Meeting. It seems that he
> is interested in maintaining it but there is problem with floating point
> computation (depending on some modes you can have hard/soft/semi-soft...
> floating point computation). I don't know the status and Xavier Leroy
> will explain you better the issue. 

http://caml.inria.fr/mantis/view.php?id=3746


Cheers,

-- 
Stéphane



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Caml-list] Re: arm backend
  2009-04-30 18:03   ` [Caml-list] " Stéphane Glondu
@ 2009-04-30 19:19     ` Nathaniel Gray
  2009-05-01 12:02       ` Mattias Engdegård
  2009-05-01 22:12       ` Jeffrey Scofield
  0 siblings, 2 replies; 15+ messages in thread
From: Nathaniel Gray @ 2009-04-30 19:19 UTC (permalink / raw)
  To: caml-list

On Thu, Apr 30, 2009 at 11:03 AM, Stéphane Glondu <steph@glondu.net> wrote:
>
> http://caml.inria.fr/mantis/view.php?id=3746

Speaking of which, has anybody built an ocaml cross compiler for the
iphone that can work with native cocoa touch apps built with the
official SDK?  It's probably too late for my current project but in
the future I'd love to use ocaml for my iPhone projects.  I tried
following the instructions here[1] with some necessary
modifications[2] to get the assembler to work but my test app crashed
as soon as it entered ocaml code.  I don't know enough about the ARM
platform to say why.

Cheers,
-n8

[1] http://web.yl.is.s.u-tokyo.ac.jp/~tosh/ocaml-on-iphone/
[2] I had to change all '.global' to '.globl' in arm.s and
arm/emit.mlp.  I have no idea what that signifies.

-- 
Nathan Gray
http://www.n8gray.org/


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Caml-list] Re: arm backend
  2009-04-30 19:19     ` Nathaniel Gray
@ 2009-05-01 12:02       ` Mattias Engdegård
  2009-05-01 18:27         ` Nathaniel Gray
  2009-05-01 22:12       ` Jeffrey Scofield
  1 sibling, 1 reply; 15+ messages in thread
From: Mattias Engdegård @ 2009-05-01 12:02 UTC (permalink / raw)
  To: n8gray; +Cc: caml-list

>[2] I had to change all '.global' to '.globl' in arm.s and
>arm/emit.mlp.  I have no idea what that signifies.

Only that Apple's assembler only understands .globl. Gas (the assembler
in GNU binutils) should accept both .global and .globl, so it is probably
safe to use the latter only. There is no difference in semantics.

Another pseudo-op that sometimes causes problems is .align whose exact
behaviour with respect to its argument varies between platforms.
Both gas and Apple's as accept .p2align, so this is usually a safer
choice.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Caml-list] Re: arm backend
  2009-05-01 12:02       ` Mattias Engdegård
@ 2009-05-01 18:27         ` Nathaniel Gray
  2009-05-01 19:24           ` Mattias Engdegård
  0 siblings, 1 reply; 15+ messages in thread
From: Nathaniel Gray @ 2009-05-01 18:27 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: caml-list

On Fri, May 1, 2009 at 5:02 AM, Mattias Engdegård <mattias@virtutech.se> wrote:
>>[2] I had to change all '.global' to '.globl' in arm.s and
>>arm/emit.mlp.  I have no idea what that signifies.
>
> Only that Apple's assembler only understands .globl. Gas (the assembler
> in GNU binutils) should accept both .global and .globl, so it is probably
> safe to use the latter only. There is no difference in semantics.

Ah, mystery solved.  Thanks!

> Another pseudo-op that sometimes causes problems is .align whose exact
> behaviour with respect to its argument varies between platforms.
> Both gas and Apple's as accept .p2align, so this is usually a safer
> choice.

It's all very confusing to me because I thought Apple's assembler
*was* gas.  In the man page for as it's described as "Mac OS X Mach-O
GNU-based assemblers".  The -v flag for the iPhone version of as
gives:

"Apple Computer, Inc. version cctools-667.10.0~186, GNU assembler version 1.38"

Very odd that they decided to take out support for .global in their version...

Cheers,
-n8

-- 
Nathan Gray
http://www.n8gray.org/


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Caml-list] Re: arm backend
  2009-05-01 18:27         ` Nathaniel Gray
@ 2009-05-01 19:24           ` Mattias Engdegård
  0 siblings, 0 replies; 15+ messages in thread
From: Mattias Engdegård @ 2009-05-01 19:24 UTC (permalink / raw)
  To: n8gray; +Cc: caml-list

>It's all very confusing to me because I thought Apple's assembler
>*was* gas.

Sort of - if I understand it correctly, it is set of separately
maintained patches (for Mach-O) to an old version of gas. It is most
conveniently thought of as a different assembler. Not that it matters,
as the syntax and pseudo-ops supported by gas itself vary between
platforms, as the aim is to behave as the native assembler.

If you care, you could look at the cctools sources - they are publically
available.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: arm backend
  2009-04-30 19:19     ` Nathaniel Gray
  2009-05-01 12:02       ` Mattias Engdegård
@ 2009-05-01 22:12       ` Jeffrey Scofield
  2009-05-02  0:07         ` [Caml-list] " Nathaniel Gray
  1 sibling, 1 reply; 15+ messages in thread
From: Jeffrey Scofield @ 2009-05-01 22:12 UTC (permalink / raw)
  To: caml-list

Nathaniel Gray <n8gray@gmail.com> writes:

> Speaking of which, has anybody built an ocaml cross compiler for the
> iphone that can work with native cocoa touch apps built with the
> official SDK?  It's probably too late for my current project but in
> the future I'd love to use ocaml for my iPhone projects.  I tried
> following the instructions here[1] with some necessary
> modifications[2] to get the assembler to work but my test app crashed
> as soon as it entered ocaml code.  I don't know enough about the ARM
> platform to say why.

Yes, we have OCaml 3.10.2 cross compiling for iPhone OS 2.2.

We started from the instructions you mention:

> [1] http://web.yl.is.s.u-tokyo.ac.jp/~tosh/ocaml-on-iphone/

We made the same change to the .global pseudo-ops:

> [2] I had to change all '.global' to '.globl' in arm.s and
> arm/emit.mlp.  I have no idea what that signifies.

(These are just variant spellings of the same pseudo-op
for declaring a global symbol.  For whatever reason, the
Apple assembler seems to insist on .globl.  Other
incarnations of gas seem to allow either spelling.)

There are at least two more problems, however.  Presumably
this is due to differences between the iPhone ABI and the one that
the ARM port (the old one I guess you could say) is targeted for.

1.  arm.S uses r10 as a scratch register, but it is not a scratch
    register on iPhone.  It has to be saved/restored when passing
    between OCaml and the native iPhone code (I think of it as
    ObjC code).  Note, by the way, that gdb shows r10 by the
   alternate name of sl.  This is confusing at first.

2. arm.S assumes r9 can be used as a general purpose register,
    but it is used on the iPhone to hold a global thread context.
   Again, it has to be saved/restored (or at least that's what we
   decided to do).

We saw crashes caused by both of these problems.

I'm appending a new version of arm.S that works for us with
one OCaml thread.  (Multiple threads will almost certainly
require more careful handling of r9.)  It has the patches
from Toshiyuki Maeda mentioned above and a few of our
own to fix these two problems.

We have an application that has been working well for
a couple months, so there's some evidence that these
changes are sufficient.

We also made a small fix to the ARM code generator
(beyond the patches from Toshiyuki Maeda).  In essence,
it fixes up the handling of unboxed floating return
values of external functions.  Things mostly work without
this change; I'll save a description for a later post (if
anybody is interested).

Regards,

Jeff Scofield
Seattle

---------- 8< ---- cut here for arm.S ----- >8 -----
/***********************************************************************/
/*                                                                     */
/*                           Objective Caml                            */
/*                                                                     */
/*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         */
/*                                                                     */
/*  Copyright 1998 Institut National de Recherche en Informatique et   */
/*  en Automatique.  All rights reserved.  This file is distributed    */
/*  under the terms of the GNU Library General Public License, with    */
/*  the special exception on linking described in file ../LICENSE.     */
/*                                                                     */
/***********************************************************************/

/* $Id: arm.S,v 1.15.18.1 2008/02/20 12:25:17 xleroy Exp $ */

/* Linux/BSD with ELF binaries and Solaris do not prefix identifiers with _.
   Linux/BSD with a.out binaries and NextStep do.
   Copied from asmrun/i386.S */

#if defined(SYS_solaris)
#define CONCAT(a,b) a/**/b
#else
#define CONCAT(a,b) a##b
#endif

#if defined(SYS_linux_elf) || defined(SYS_bsd_elf) \
 || defined(SYS_solaris) || defined(SYS_beos) || defined(SYS_gnu)
#define G(x) x
#define LBL(x) CONCAT(.L,x)
#else
#define G(x) CONCAT(_,x)
#define LBL(x) CONCAT(L,x)
#endif

#if defined(SYS_macosx)
#define global globl
#endif

/* Asm part of the runtime system, ARM processor */

#define trap_ptr        r11
#define alloc_ptr       r8
#define alloc_limit     r9
#define sp              r13
#define lr              r14
#define pc              r15

        .text

/* Allocation functions and GC interface */

        .global G(caml_call_gc)
G(caml_call_gc):
    /* Record return address */
    /* We can use r10 as a temp reg since it's not live here */
        ldr     r10, LBL(caml_last_return_address)
        str     lr, [r10, #0]
    /* Branch to shared GC code */
        bl      LBL(invoke_gc)
    /* Restart allocation sequence (4 instructions before) */
        sub     lr, lr, #16
        mov     pc, lr

        .global G(caml_alloc1)
G(caml_alloc1):
        ldr     r10, [alloc_limit, #0]
        sub     alloc_ptr, alloc_ptr, #8
        cmp     alloc_ptr, r10
        movcs   pc, lr                /* Return if alloc_ptr >= alloc_limit */
    /* Record return address */
        ldr     r10, LBL(caml_last_return_address)
        str     lr, [r10, #0]
    /* Invoke GC */
        bl      LBL(invoke_gc)
    /* Try again */
        b       G(caml_alloc1)

        .global G(caml_alloc2)
G(caml_alloc2):
        ldr     r10, [alloc_limit, #0]
        sub     alloc_ptr, alloc_ptr, #12
        cmp     alloc_ptr, r10
        movcs   pc, lr                /* Return if alloc_ptr >= alloc_limit */
    /* Record return address */
        ldr     r10, LBL(caml_last_return_address)
        str     lr, [r10, #0]
    /* Invoke GC */
        bl      LBL(invoke_gc)
    /* Try again */
        b       G(caml_alloc2)

        .global G(caml_alloc3)
G(caml_alloc3):
        ldr     r10, [alloc_limit, #0]
        sub     alloc_ptr, alloc_ptr, #16
        cmp     alloc_ptr, r10
        movcs   pc, lr                /* Return if alloc_ptr >= alloc_limit */
    /* Record return address */
        ldr     r10, LBL(caml_last_return_address)
        str     lr, [r10, #0]
    /* Invoke GC */
        bl      LBL(invoke_gc)
    /* Try again */
        b       G(caml_alloc3)

        .global G(caml_allocN)
G(caml_allocN):
        str     r12, [sp, #-4]!
        ldr     r12, [alloc_limit, #0]
        sub     alloc_ptr, alloc_ptr, r10
        cmp     alloc_ptr, r12
        ldr     r12, [sp], #4
        movcs   pc, lr                /* Return if alloc_ptr >= alloc_limit */
    /* Record return address and desired size */
        ldr     alloc_limit, LBL(caml_last_return_address)
        str     lr, [alloc_limit, #0]
        ldr     alloc_limit, LBL(Lcaml_requested_size)
        str     r10, [alloc_limit, #0]
    /* Invoke GC */
        bl      LBL(invoke_gc)
    /* Try again */
        ldr     r10, LBL(Lcaml_requested_size)
        ldr     r10, [r10, #0]
        b       G(caml_allocN)

/* Shared code to invoke the GC */
LBL(invoke_gc):
    /* Record lowest stack address */
        ldr     r10, LBL(caml_bottom_of_stack)
        str     sp, [r10, #0]
    /* Save integer registers and return address on stack */
        stmfd   sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r10,r12,lr}
    /* Store pointer to saved integer registers in caml_gc_regs */
        ldr     r10, LBL(caml_gc_regs)
        str     sp, [r10, #0]
    /* Save non-callee-save float registers */
        sub     sp, sp, #64
        fstd    d0, [sp, #56]
        fstd    d1, [sp, #48]
        fstd    d2, [sp, #40]
        fstd    d3, [sp, #32]
        fstd    d4, [sp, #24]
        fstd    d5, [sp, #16]
        fstd    d6, [sp, #8]
        fstd    d7, [sp, #0]
    /* Save current allocation pointer for debugging purposes */
        ldr     r10, LBL(caml_young_ptr)
        str     alloc_ptr, [r10, #0]
    /* Save trap pointer in case an exception is raised during GC */
        ldr     r10, LBL(caml_exception_pointer)
        str     trap_ptr, [r10, #0]
    /* Restore r9 for iPhoneOS */
        ldr     r9, LBL(Lcaml_touch_threadctx) /* iPhone */
        ldr     r9, [r9, #0]                   /* iPhone */
    /* Call the garbage collector */
        bl      G(caml_garbage_collection)
    /* Restore the registers from the stack */
        fldd    d7, [sp, #0]
        fldd    d6, [sp, #8]
        fldd    d5, [sp, #16]
        fldd    d4, [sp, #24]
        fldd    d3, [sp, #32]
        fldd    d2, [sp, #40]
        fldd    d1, [sp, #48]
        fldd    d0, [sp, #56]
        add     sp, sp, #64
        ldmfd   sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r10,r12}
    /* Reload return address */
        ldr     r10, LBL(caml_last_return_address)
        ldr     lr, [r10, #0]
    /* Say that we are back into Caml code */
        mov     alloc_ptr, #0
        str     alloc_ptr, [r10, #0]
    /* Reload new allocation pointer and allocation limit */
        ldr     r10, LBL(caml_young_ptr)
        ldr     alloc_ptr, [r10, #0]
        ldr     alloc_limit, LBL(caml_young_limit)
    /* Return to caller */
        ldmfd   sp!, {pc}

/* Call a C function from Caml */
/* Function to call is in r10 */

        .global G(caml_c_call)
G(caml_c_call):
    /* Preserve return address in callee-save register r4 */
        mov     r4, lr
    /* Record lowest stack address and return address */
        ldr     r5, LBL(caml_last_return_address)
        ldr     r6, LBL(caml_bottom_of_stack)
        str     lr, [r5, #0]
        str     sp, [r6, #0]
    /* Make the exception handler and alloc ptr available to the C code */
        ldr     r6, LBL(caml_young_ptr)
        ldr     r7, LBL(caml_exception_pointer)
        str     alloc_ptr, [r6, #0]
        str     trap_ptr, [r7, #0]
        ldr     r9, LBL(Lcaml_touch_threadctx) /* iPhone */
        ldr     r9, [r9, #0]                   /* iPhone */
    /* Call the function */
        mov     lr, pc
        mov     pc, r10
    /* Reload alloc ptr */
        ldr     alloc_ptr, [r6, #0]    /* r6 still points to caml_young_ptr */
    /* Say that we are back into Caml code */
        mov     r6, #0
        str     r6, [r5, #0] /* r5 still points to caml_last_return_address */
    /* Return */
        mov     pc, r4

/* Start the Caml program */

        .global G(caml_start_program)
G(caml_start_program):
        stmfd   sp!, {r10}
        ldr     r10, LBL(Lcaml_touch_threadctx) /* iPhone */
        str     r9, [r10, #0]                   /* iPhone */
        ldr     r10, LBL(caml_program)

/* Code shared with caml_callback* */
/* Address of Caml code to call is in r10 */
/* Arguments to the Caml code are in r0...r3 */

LBL(jump_to_caml):
    /* Save return address and callee-save registers */
        stmfd   sp!, {r4,r5,r6,r7,r8,r9,r11,lr}
        sub     sp, sp, #64
        fstd    d15, [sp, #56]
        fstd    d14, [sp, #48]
        fstd    d13, [sp, #40]
        fstd    d12, [sp, #32]
        fstd    d11, [sp, #24]
        fstd    d10, [sp, #16]
        fstd    d9, [sp, #8]
        fstd    d8, [sp, #0]
    /* Setup a callback link on the stack */
        sub     sp, sp, #(4*3)
        ldr     r4, LBL(caml_bottom_of_stack)
        ldr     r4, [r4, #0]
        str     r4, [sp, #0]
        ldr     r4, LBL(caml_last_return_address)
        ldr     r4, [r4, #0]
        str     r4, [sp, #4]
        ldr     r4, LBL(caml_gc_regs)
        ldr     r4, [r4, #0]
        str     r4, [sp, #8]
    /* Setup a trap frame to catch exceptions escaping the Caml code */
        sub     sp, sp, #(4*2)
        ldr     r4, LBL(caml_exception_pointer)
        ldr     r4, [r4, #0]
        str     r4, [sp, #0]
        ldr     r4, LBL(Ltrap_handler)
        str     r4, [sp, #4]
        mov     trap_ptr, sp
    /* Reload allocation pointers */
        ldr     r4, LBL(caml_young_ptr)
        ldr     alloc_ptr, [r4, #0]
        ldr     alloc_limit, LBL(caml_young_limit)
    /* We are back into Caml code */
        ldr     r4, LBL(caml_last_return_address)
        mov     r5, #0
        str     r5, [r4, #0]
    /* Call the Caml code */
        mov     lr, pc
        mov     pc, r10
LBL(caml_retaddr):
    /* Pop the trap frame, restoring caml_exception_pointer */
        ldr     r4, LBL(caml_exception_pointer)
        ldr     r5, [sp, #0]
        str     r5, [r4, #0]
        add     sp, sp, #(2 * 4)
    /* Pop the callback link, restoring the global variables */
LBL(return_result):
        ldr     r4, LBL(caml_bottom_of_stack)
        ldr     r5, [sp, #0]
        str     r5, [r4, #0]
        ldr     r4, LBL(caml_last_return_address)
        ldr     r5, [sp, #4]
        str     r5, [r4, #0]
        ldr     r4, LBL(caml_gc_regs)
        ldr     r5, [sp, #8]
        str     r5, [r4, #0]
        add     sp, sp, #(4*3)
    /* Update allocation pointer */
        ldr     r4, LBL(caml_young_ptr)
        str     alloc_ptr, [r4, #0]
    /* Reload callee-save registers and return */
        fldd    d8, [sp, #0]
        fldd    d9, [sp, #8]
        fldd    d10, [sp, #16]
        fldd    d11, [sp, #24]
        fldd    d12, [sp, #32]
        fldd    d13, [sp, #40]
        fldd    d14, [sp, #48]
        fldd    d15, [sp, #56]
        add     sp, sp, #64
        ldmfd   sp!, {r4,r5,r6,r7,r8,r9,r11,lr}
        ldmfd   sp!, {r10}
        mov     pc, lr

    /* The trap handler */
LBL(trap_handler):
    /* Save exception pointer */
        ldr     r4, LBL(caml_exception_pointer)
        str     trap_ptr, [r4, #0]
    /* Encode exception bucket as an exception result */
        orr     r0, r0, #2
    /* Return it */
        b       LBL(return_result)

/* Raise an exception from C */

        .global G(caml_raise_exception)
G(caml_raise_exception):
    /* Reload Caml allocation pointers */
        ldr     r1, LBL(caml_young_ptr)
        ldr     alloc_ptr, [r1, #0]
        ldr     alloc_limit, LBL(caml_young_limit)
    /* Say we're back into Caml */
        ldr     r1, LBL(caml_last_return_address)
        mov     r2, #0
        str     r2, [r1, #0]
    /* Cut stack at current trap handler */
        ldr     r1, LBL(caml_exception_pointer)
        ldr     sp, [r1, #0]
    /* Pop previous handler and addr of trap, and jump to it */
        ldmfd   sp!, {trap_ptr, pc}

/* Callback from C to Caml */

        .global G(caml_callback_exn)
G(caml_callback_exn):
    /* Initial shuffling of arguments (r0 = closure, r1 = first arg) */
        stmfd   sp!, {r10}
        mov     r10, r0
        mov     r0, r1            /* r0 = first arg */
        mov     r1, r10           /* r1 = closure environment */
        ldr     r10, [r10, #0]    /* code pointer */
        b       LBL(jump_to_caml)

        .global G(caml_callback2_exn)
G(caml_callback2_exn):
    /* Initial shuffling of arguments (r0 = closure, r1 = arg1, r2 = arg2) */
        stmfd   sp!, {r10}
        mov     r10, r0
        mov     r0, r1           /* r0 = first arg */
        mov     r1, r2           /* r1 = second arg */
        mov     r2, r10          /* r2 = closure environment */
        ldr     r10, LBL(caml_apply2)
        b       LBL(jump_to_caml)

        .global G(caml_callback3_exn)
G(caml_callback3_exn):
    /* Initial shuffling of arguments */
    /* (r0 = closure, r1 = arg1, r2 = arg2, r3 = arg3) */
        stmfd   sp!, {r10}
        mov     r10, r0
        mov     r0, r1          /* r0 = first arg */
        mov     r1, r2          /* r1 = second arg */
        mov     r2, r3          /* r2 = third arg */
        mov     r3, r10         /* r3 = closure environment */
        ldr     r10, LBL(caml_apply3)
        b       LBL(jump_to_caml)

        .global G(caml_ml_array_bound_error)
G(caml_ml_array_bound_error):
    /* Load address of [caml_array_bound_error] in r10 */
        ldr     r10, LBL(caml_array_bound_error)
    /* Call that function */
        b       G(caml_c_call)

/* Global references */

LBL(caml_last_return_address):     .long G(caml_last_return_address)
LBL(caml_bottom_of_stack):         .long G(caml_bottom_of_stack)
LBL(caml_gc_regs):                 .long G(caml_gc_regs)
LBL(caml_young_ptr):               .long G(caml_young_ptr)
LBL(caml_young_limit):             .long G(caml_young_limit)
LBL(caml_exception_pointer):       .long G(caml_exception_pointer)
LBL(caml_program):                 .long G(caml_program)
LBL(Ltrap_handler):                .long LBL(trap_handler)
LBL(caml_apply2):                  .long G(caml_apply2)
LBL(caml_apply3):                  .long G(caml_apply3)
LBL(Lcaml_requested_size):         .long LBL(caml_requested_size)
LBL(caml_array_bound_error):       .long G(caml_array_bound_error)
LBL(Lcaml_touch_threadctx):        .long LBL(caml_touch_threadctx)

.data
LBL(caml_requested_size):          .long 0
LBL(caml_touch_threadctx):         .long 0

/* GC roots for callback */

        .data

        .global G(caml_system__frametable)
G(caml_system__frametable):
        .long   1               /* one descriptor */
        .long   LBL(caml_retaddr)  /* return address into callback */
        .short  -1              /* negative frame size => use callback link */
        .short  0               /* no roots */
        .align  2

#if defined(SYS_macosx)
        .text
        .global G(__stub__modsi3)
G(__stub__modsi3):
        b       LBL(__stub__modsi3)
        .global G(__stub__divsi3)
G(__stub__divsi3):
        b       LBL(__stub__divsi3)

        .section __TEXT,__picsymbolstub4,symbol_stubs,none,16
        .align 2
LBL(__stub__modsi3):
        .indirect_symbol G(__modsi3)
        ldr     ip, LBL(__stub__modsi3$slp)
LBL(__stub__modsi3$scv):
        add     ip, pc, ip
        ldr     pc, [ip, #0]
LBL(__stub__modsi3$slp):
        .long   LBL(__stub__modsi3$lazy_ptr) - (LBL(__stub__modsi3$scv) + 8)
        .lazy_symbol_pointer
LBL(__stub__modsi3$lazy_ptr):
        .indirect_symbol G(__modsi3)
        .long   dyld_stub_binding_helper

        .section __TEXT,__picsymbolstub4,symbol_stubs,none,16
        .align 2
LBL(__stub__divsi3):
        .indirect_symbol G(__divsi3)
        ldr     ip, LBL(__stub__divsi3$slp)
LBL(__stub__divsi3$scv):
        add     ip, pc, ip
        ldr     pc, [ip, #0]
LBL(__stub__divsi3$slp):
        .long   LBL(__stub__divsi3$lazy_ptr) - (LBL(__stub__divsi3$scv) + 8)
        .lazy_symbol_pointer
LBL(__stub__divsi3$lazy_ptr):
        .indirect_symbol G(__divsi3)
        .long   dyld_stub_binding_helper

        .subsections_via_symbols
#endif


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Caml-list] Re: arm backend
  2009-05-01 22:12       ` Jeffrey Scofield
@ 2009-05-02  0:07         ` Nathaniel Gray
  2009-05-02 23:15           ` OCaml on iPhone (was: arm backend) Jeffrey Scofield
  0 siblings, 1 reply; 15+ messages in thread
From: Nathaniel Gray @ 2009-05-02  0:07 UTC (permalink / raw)
  To: Jeffrey Scofield; +Cc: caml-list

On Fri, May 1, 2009 at 3:12 PM, Jeffrey Scofield <dynasticon@mac.com> wrote:
> Nathaniel Gray <n8gray@gmail.com> writes:
>
>> Speaking of which, has anybody built an ocaml cross compiler for the
>> iphone that can work with native cocoa touch apps built with the
>> official SDK?  It's probably too late for my current project but in
>> the future I'd love to use ocaml for my iPhone projects.  I tried
>> following the instructions here[1] with some necessary
>> modifications[2] to get the assembler to work but my test app crashed
>> as soon as it entered ocaml code.  I don't know enough about the ARM
>> platform to say why.
>
> Yes, we have OCaml 3.10.2 cross compiling for iPhone OS 2.2.

Great!

> There are at least two more problems, however.  Presumably
> this is due to differences between the iPhone ABI and the one that
> the ARM port (the old one I guess you could say) is targeted for.
>
> 1.  arm.S uses r10 as a scratch register, but it is not a scratch
>    register on iPhone.  It has to be saved/restored when passing
>    between OCaml and the native iPhone code (I think of it as
>    ObjC code).  Note, by the way, that gdb shows r10 by the
>   alternate name of sl.  This is confusing at first.
>
> 2. arm.S assumes r9 can be used as a general purpose register,
>    but it is used on the iPhone to hold a global thread context.
>   Again, it has to be saved/restored (or at least that's what we
>   decided to do).
>
> We saw crashes caused by both of these problems.

Ok, I'm glad I left this to people who are familiar with ARM assembly
programming.  :-)

> I'm appending a new version of arm.S that works for us with
> one OCaml thread.  (Multiple threads will almost certainly
> require more careful handling of r9.)  It has the patches
> from Toshiyuki Maeda mentioned above and a few of our
> own to fix these two problems.

Awesome, but now I'm confused because the arm.S you included has lots
of .global pseudo-ops.  Do you not compile it with Apple's as?

> We have an application that has been working well for
> a couple months, so there's some evidence that these
> changes are sufficient.

What's your app?  How are you managing the interface between Cocoa and OCaml?

> We also made a small fix to the ARM code generator
> (beyond the patches from Toshiyuki Maeda).  In essence,
> it fixes up the handling of unboxed floating return
> values of external functions.  Things mostly work without
> this change; I'll save a description for a later post (if
> anybody is interested).

I am very interested in any and all information needed to get a
correct OCaml port suitable for use in App Store applications.  Please
share!

BTW, I've added an issue in mantis[1] now that I know this is more
than a configuration problem.

Thanks,
-n8

[1] http://caml.inria.fr/mantis/view.php?id=4782

-- 
Nathan Gray
http://www.n8gray.org/


^ permalink raw reply	[flat|nested] 15+ messages in thread

* OCaml on iPhone (was: arm backend)
  2009-05-02  0:07         ` [Caml-list] " Nathaniel Gray
@ 2009-05-02 23:15           ` Jeffrey Scofield
  2009-05-03 12:34             ` [Caml-list] " Robert Muller
  0 siblings, 1 reply; 15+ messages in thread
From: Jeffrey Scofield @ 2009-05-02 23:15 UTC (permalink / raw)
  To: caml-list

Nathaniel Gray <n8gray@gmail.com> writes:

> Ok, I'm glad I left this to people who are familiar with ARM
> assembly programming.  :-)

We've done a lot of assembly programming, but none of us is an
ARM expert.  We looked at ARM documents and the assembly (.s)
files generated by ocamlopt and gcc, and spent some long sessions
with gdb.

> Awesome, but now I'm confused because the arm.S you included
> has lots of .global pseudo-ops.  Do you not compile it with
> Apple's as?

At around line 36, you'll see:

  #define global globl

As I said in private mail, you could call this a hack, but it's a
way to avoid making lots of small changes everywhere in the file.

> What's your app?

We're working on a collection of card games for casual play.

> How are you managing the interface between Cocoa and OCaml?

This is a big topic.  The summary is that we model Cocoa objects
as OCaml objects.  We have a layer that wraps OCaml objects in
smallish ObjC objects for use on the ObjC side, and wraps ObjC
objects in smallish OCaml objects for use on the OCaml side.  The
layer then translates between these representations as required
for calls into iPhoneOS and Cocoa Touch from OCaml (asking for
iPhone OS services) and into OCaml from iPhoneOS (for event
handling).

> > We also made a small fix to the ARM code generator
>
> I am very interested in any and all information needed to get a
> correct OCaml port suitable for use in App Store applications.
> Please share!

OK, I'll gather up our patch and send it to the list.  I want to
separate out our changes from those of Toshiyuki Maeda [1].

As I said, our patch fixes calls to external C float functions
such as floor(), sin(), and so on.  There is special handling in
ocamlopt to allow them to be unboxed, but the ABI of the existing
ARM code generator doesn't match the iPhone ABI.

Regards,

Jeff Scofield
Seattle

[1] http://web.yl.is.s.u-tokyo.ac.jp/~tosh/ocaml-on-iphone/


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Caml-list] OCaml on iPhone (was: arm backend)
  2009-05-02 23:15           ` OCaml on iPhone (was: arm backend) Jeffrey Scofield
@ 2009-05-03 12:34             ` Robert Muller
  2009-05-05  4:59               ` OCaml on iPhone Jeffrey Scofield
  0 siblings, 1 reply; 15+ messages in thread
From: Robert Muller @ 2009-05-03 12:34 UTC (permalink / raw)
  To: Jeffrey Scofield; +Cc: caml-list

This sounds great.  I will be teaching an iphone programming course  
next year and I would
very much like to use the course as an opportunity to introduce  
students to caml. I know that
there are others gearing up for iphone programming courses who aren't  
thrilled with the idea
of teaching Objective C.

If you were to post your resources on a web site it might lower the  
barrier to entry for more
people to use ocaml + your wrappers rather than Objective C.

Bob Muller


On May 2, 2009, at 7:15 PM, Jeffrey Scofield wrote:

> Nathaniel Gray <n8gray@gmail.com> writes:
>
>> Ok, I'm glad I left this to people who are familiar with ARM
>> assembly programming.  :-)
>
> We've done a lot of assembly programming, but none of us is an
> ARM expert.  We looked at ARM documents and the assembly (.s)
> files generated by ocamlopt and gcc, and spent some long sessions
> with gdb.
>
>> Awesome, but now I'm confused because the arm.S you included
>> has lots of .global pseudo-ops.  Do you not compile it with
>> Apple's as?
>
> At around line 36, you'll see:
>
>  #define global globl
>
> As I said in private mail, you could call this a hack, but it's a
> way to avoid making lots of small changes everywhere in the file.
>
>> What's your app?
>
> We're working on a collection of card games for casual play.
>
>> How are you managing the interface between Cocoa and OCaml?
>
> This is a big topic.  The summary is that we model Cocoa objects
> as OCaml objects.  We have a layer that wraps OCaml objects in
> smallish ObjC objects for use on the ObjC side, and wraps ObjC
> objects in smallish OCaml objects for use on the OCaml side.  The
> layer then translates between these representations as required
> for calls into iPhoneOS and Cocoa Touch from OCaml (asking for
> iPhone OS services) and into OCaml from iPhoneOS (for event
> handling).
>
>>> We also made a small fix to the ARM code generator
>>
>> I am very interested in any and all information needed to get a
>> correct OCaml port suitable for use in App Store applications.
>> Please share!
>
> OK, I'll gather up our patch and send it to the list.  I want to
> separate out our changes from those of Toshiyuki Maeda [1].
>
> As I said, our patch fixes calls to external C float functions
> such as floor(), sin(), and so on.  There is special handling in
> ocamlopt to allow them to be unboxed, but the ABI of the existing
> ARM code generator doesn't match the iPhone ABI.
>
> Regards,
>
> Jeff Scofield
> Seattle
>
> [1] http://web.yl.is.s.u-tokyo.ac.jp/~tosh/ocaml-on-iphone/
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: OCaml on iPhone
  2009-05-03 12:34             ` [Caml-list] " Robert Muller
@ 2009-05-05  4:59               ` Jeffrey Scofield
  0 siblings, 0 replies; 15+ messages in thread
From: Jeffrey Scofield @ 2009-05-05  4:59 UTC (permalink / raw)
  To: caml-list

Robert Muller <muller@cs.bc.edu> writes:

> This sounds great.  I will be teaching an iphone programming
> course next year and I would very much like to use the course
> as an opportunity to introduce students to caml.  I know that
> there are others gearing up for iphone programming courses who
> aren't thrilled with the idea of teaching Objective C.

Right now we're mostly focused on getting iPhone applications
completed and accepted by Apple.  We've built the interface layer
by hand, a little bit at a time as required.   So there are
wrappers only for the parts of Cocoa Touch we use, and there are
a few rough edges.  It wouldn't make a good teaching environment
in its current form.

The cross-compiler does work though, and it builds working
applications.  I'll be sending the rest of our patches shortly.
Creating wrappers for all of Cocoa Touch would be a very big job
but it might be possible to implement a small subset for
students.

> If you were to post your resources on a web site it might lower
> the barrier to entry for more people to use ocaml + your
> wrappers rather than Objective C.

Right now the best we can do is probably to offer advice on some
things that did and didn't work for us.  As we make progress
perhaps we'll be in a position to do more.

Regards,

Jeff Scofield
Seattle


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Caml-list] arm backend
  2009-04-30 12:14 arm backend Joel Reymont
  2009-04-30 13:28 ` Sylvain Le Gall
@ 2009-05-05  9:43 ` Xavier Leroy
  2009-05-05 18:21   ` Nathaniel Gray
  2009-05-06  3:56   ` Jeffrey Scofield
  1 sibling, 2 replies; 15+ messages in thread
From: Xavier Leroy @ 2009-05-05  9:43 UTC (permalink / raw)
  To: Joel Reymont; +Cc: O'Caml Mailing List

Joel Reymont wrote:

> Is the ARM backend (ocamlopt) usable and actively maintained?

In brief: yes modulo ABI issues; yes.

In more details:

In OCaml 3.11 and earlier, the ARM port uses an old ABI (software
conventions on using registers, etc).  This ABI corresponds to the
"arm" port of Debian; I don't know about other Linux distros.
OCaml/ARM works like a charm on platforms supported by Debian/arm.
I use it on a Linksys NSLU2.

However, most embedded Linux/ARM platforms use a more recent,
incompatible ABI called EABI.  In Debian Lenny, it's available under
the name "armel".

I recently revised the OCaml/ARM port to adapt it to EABI and to
software floating-point emulation.  You can find it in the CVS trunk,
and testing and feedback is most welcome.  It works fine under Debian
Lenny "armel".

Floating-point performance is better than with the old port, because
the latter used floating-point instructions that are no longer
available on contemporary ARM processors and therefore had to be
trapped and emulated by the kernel.  In contrast, with soft
floating-point, emulation is performed in user land by C library
functions, which can also take advantage of vector float
instructions if the processor supports them.

Concerning the iPhone, it is not supported out of the box by 3.11 nor
by the CVS trunk code.  For 3.11, several patches have been mentioned
on this list; it would be great if someone with iPhone development
experience could combine them and publish a unified patch.

For the CVS trunk code, it seems we are getting close: as far as I
could see, MacOSX/ARM uses EABI plus Apple's "signature" approach to
dynamic linking.  However, I haven't yet succeeded in running Apple's
iPhone SDK compilers from the command-line.  (It looks like one of
those Microsoft SDK's that assume everyone is developing from the
vendor-supplied IDE...)  Again, I welcome feedback and patches from
iPhone development experts.

- Xavier Leroy


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Caml-list] arm backend
  2009-05-05  9:43 ` [Caml-list] arm backend Xavier Leroy
@ 2009-05-05 18:21   ` Nathaniel Gray
  2009-05-06  3:56   ` Jeffrey Scofield
  1 sibling, 0 replies; 15+ messages in thread
From: Nathaniel Gray @ 2009-05-05 18:21 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: Joel Reymont, O'Caml Mailing List

[-- Attachment #1: Type: text/plain, Size: 1395 bytes --]

On Tue, May 5, 2009 at 2:43 AM, Xavier Leroy <Xavier.Leroy@inria.fr> wrote:
>
> Concerning the iPhone, it is not supported out of the box by 3.11 nor
> by the CVS trunk code.  For 3.11, several patches have been mentioned
> on this list; it would be great if someone with iPhone development
> experience could combine them and publish a unified patch.

Feel free to attach any such patch to the bug in mantis:
  http://caml.inria.fr/mantis/view.php?id=4782

> For the CVS trunk code, it seems we are getting close: as far as I
> could see, MacOSX/ARM uses EABI plus Apple's "signature" approach to
> dynamic linking.  However, I haven't yet succeeded in running Apple's
> iPhone SDK compilers from the command-line.  (It looks like one of
> those Microsoft SDK's that assume everyone is developing from the
> vendor-supplied IDE...)  Again, I welcome feedback and patches from
> iPhone development experts.

I'm attaching (here and at the bug) a script I use to configure and
build an e-mail library for both the iPhone simulator (x86) and the
iPhone itself (arm).  There's some extraneous junk in there but you
should get the idea.  The important flags are '-arch armv6' and
'-isysroot /path/to/sdk'.  It might also be worth mentioning that
Apple prohibits the use of dynamic libraries in iPhone apps (for now
at least) and most iPhone projects are built in Thumb mode by default.

Cheers,
-n8

[-- Attachment #2: configure-libetpan --]
[-- Type: application/octet-stream, Size: 1479 bytes --]

#!/bin/zsh
# We do have iconv and libz built in on iPhone
# We have expat on the simulator but not the phone.  That's ok, we don't need it

# NOTE: be sure to verify the tool versions below!

# Where to install
PREFIX=$HOME/src/MyProject/usr
GCCVERSION=4.0.1
SDKVERSION=2.2.1
DARWINVERSION=9

case $1 in
    arm)
        PLAT=/Developer/Platforms/iPhone.platform
        SDK=$PLAT/Developer/SDKs/iPhoneOS$SDKVERSION.sdk
        export CFLAGS="-arch armv6"
        export LDFLAGS="-arch armv6"
        CONFIGOPTS=(--build=`config.guess` --host=arm-apple-darwin9)
        GCCPREFIX=arm
        ;;
        
    i386)
        PLAT=/Developer/Platforms/iPhoneSimulator.platform
        SDK=$PLAT/Developer/SDKs/iPhoneSimulator$SDKVERSION.sdk
        export CFLAGS=
        export LDFLAGS=
        CONFIGOPTS=
        GCCPREFIX=i686
        ;;
    *)
        echo "Usage: $0 (arm|i386)"
        echo " and make sure to verify the SDK version & gcc version are correct"
        exit 1
        ;;
esac

export CFLAGS="$CFLAGS -isysroot $SDK"
BIN=$PLAT/Developer/usr/bin
export CPP=$BIN/cpp
export CXXCPP=$BIN/cpp
export CC=$BIN/$GCCPREFIX-apple-darwin$DARWINVERSION-gcc-$GCCVERSION
export CXX=$BIN/$GCCPREFIX-apple-darwin$DARWINVERSION-g++-$GCCVERSION
export LD=$BIN/ld
export AS=$BIN/as

cd libetpan-0.57
PATH=$BIN:$PATH ./configure --prefix=$PREFIX --disable-shared --enable-static --disable-db --without-sasl --without-gnutls --with-openssl=$PREFIX $CONFIGOPTS

PATH=$BIN:$PATH make


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: arm backend
  2009-05-05  9:43 ` [Caml-list] arm backend Xavier Leroy
  2009-05-05 18:21   ` Nathaniel Gray
@ 2009-05-06  3:56   ` Jeffrey Scofield
  1 sibling, 0 replies; 15+ messages in thread
From: Jeffrey Scofield @ 2009-05-06  3:56 UTC (permalink / raw)
  To: caml-list

Xavier Leroy <Xavier.Leroy@inria.fr> writes:

> Concerning the iPhone, it is not supported out of the box by
> 3.11 nor by the CVS trunk code.  For 3.11, several patches have
> been mentioned on this list; it would be great if someone with
> iPhone development experience could combine them and publish a
> unified patch.

I'm happy to provide a unified patch containing everything
we use to cross-compile OCaml for iPhone.  Note that our
patches are against OCaml 3.10.2.  This is simpler for us because
we started with patches by Toshiyuki Maeda that are for 3.10.2.
I would imagine that the changes for 3.11 are minimal, but we
haven't tried it yet.  When we move to 3.11, I'd be happy to
provide new patches (if nobody else does so earlier).

> For the CVS trunk code, it seems we are getting close: as far
> as I could see, MacOSX/ARM uses EABI plus Apple's "signature"
> approach to dynamic linking.  However, I haven't yet succeeded
> in running Apple's iPhone SDK compilers from the command-line.
> (It looks like one of those Microsoft SDK's that assume
> everyone is developing from the vendor-supplied IDE...)  Again,
> welcome feedback and patches from iPhone development experts.

Yes, Apple assumes all developers use their IDE, Xcode.  You can
extract working command lines from the Xcode build log,
painfully.

Here's a little script that shows how we run the cross-compiling
version of gcc.  Although Nathaniel Gray has already posted his,
it might be helpful to have two independent sets.

This is for compiling to the iPhoneOS 2.2 environment.
Differences for other environments are straightforward.

    #!/bin/sh
    PLATFORM=/Developer/Platforms/iPhoneOS.platform
    SDK=/Developer/SDKs/iPhoneOS2.2.sdk
    CC="$PLATFORM/Developer/usr/bin/gcc -arch armv6 -isysroot $PLATFORM/$SDK"
    $CC "$@"

Regards,

Jeff Scofield
Seattle


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2009-05-06  3:56 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-30 12:14 arm backend Joel Reymont
2009-04-30 13:28 ` Sylvain Le Gall
2009-04-30 18:03   ` [Caml-list] " Stéphane Glondu
2009-04-30 19:19     ` Nathaniel Gray
2009-05-01 12:02       ` Mattias Engdegård
2009-05-01 18:27         ` Nathaniel Gray
2009-05-01 19:24           ` Mattias Engdegård
2009-05-01 22:12       ` Jeffrey Scofield
2009-05-02  0:07         ` [Caml-list] " Nathaniel Gray
2009-05-02 23:15           ` OCaml on iPhone (was: arm backend) Jeffrey Scofield
2009-05-03 12:34             ` [Caml-list] " Robert Muller
2009-05-05  4:59               ` OCaml on iPhone Jeffrey Scofield
2009-05-05  9:43 ` [Caml-list] arm backend Xavier Leroy
2009-05-05 18:21   ` Nathaniel Gray
2009-05-06  3:56   ` Jeffrey Scofield

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).