Index: configure =================================================================== --- configure (.../vendor/ocaml/4.01.0) (revision 112) +++ configure (.../trunk/ocamlxarm/4.0) (revision 112) @@ -278,7 +278,14 @@ bytecccompopts="-fno-defer-pop $gcc_warnings -DSHRINKED_GNUC" mathlib="";; *,*-*-darwin*) - bytecccompopts="-fno-defer-pop $gcc_warnings" + # On recent version of OSX, gcc is a symlink to clang + if $bytecc --version | grep -q clang; then + # -fno-defer-pop is not supported by clang, and make recent + # versions of clang to fail + bytecccompopts="$gcc_warnings" + else + bytecccompopts="-fno-defer-pop $gcc_warnings" + fi mathlib="" mkexe="$mkexe -Wl,-no_compact_unwind" # Tell gcc that we can use 32-bit code addresses for threaded code Index: VERSION =================================================================== --- VERSION (.../vendor/ocaml/4.01.0) (revision 112) +++ VERSION (.../trunk/ocamlxarm/4.0) (revision 112) @@ -1,4 +1,4 @@ -4.01.0 +4.01.0+xarm-4.0.2-v7 # The version string is the first line of this file. # It must be in the format described in stdlib/sys.mli Index: asmcomp/arm/arch.ml =================================================================== --- asmcomp/arm/arch.ml (.../vendor/ocaml/4.01.0) (revision 112) +++ asmcomp/arm/arch.ml (.../trunk/ocamlxarm/4.0) (revision 112) @@ -23,6 +23,7 @@ match Config.system with "linux_eabi" -> EABI | "linux_eabihf" -> EABI_HF + | "macosx" -> EABI_HF | _ -> assert false let string_of_arch = function @@ -52,7 +53,11 @@ | EABI, "armv7" -> ARMv7, Soft, false | EABI, _ -> ARMv4, Soft, false | EABI_HF, "armv6" -> ARMv6, VFPv2, false - | EABI_HF, _ -> ARMv7, VFPv3_D16, true + | EABI_HF, _ -> + if Config.system = "macosx" then + ARMv7, VFPv3, true + else + ARMv7, VFPv3_D16, true end in (ref def_arch, ref def_fpu, ref def_thumb) Index: asmcomp/arm/emit.mlp =================================================================== --- asmcomp/arm/emit.mlp (.../vendor/ocaml/4.01.0) (revision 112) +++ asmcomp/arm/emit.mlp (.../trunk/ocamlxarm/4.0) (revision 112) @@ -29,23 +29,40 @@ (* Output a label *) let emit_label lbl = - emit_string ".L"; emit_int lbl + let prefix = if Config.system = "macosx" then "L" else ".L" in + emit_string prefix; emit_int lbl let emit_data_label lbl = - emit_string ".Ld"; emit_int lbl + let prefix = if Config.system = "macosx" then "Ld" else ".Ld" in + emit_string prefix; emit_int lbl (* Symbols *) +let symbol_prefix = + match Config.system with + "linux_eabi" | "linux_eabihf" -> "" + | _ -> "_" + let emit_symbol s = - Emitaux.emit_symbol '$' s + emit_string symbol_prefix; Emitaux.emit_symbol '$' s let emit_call s = - if !Clflags.dlcode || !pic_code + let plt = + match Config.system with + "macosx" -> false + | _ -> !Clflags.dlcode || !pic_code + in + if plt then `bl {emit_symbol s}(PLT)` else `bl {emit_symbol s}` let emit_jump s = - if !Clflags.dlcode || !pic_code + let plt = + match Config.system with + "linux_eabi" | "linux_eabihf" -> !Clflags.dlcode || !pic_code + | _ -> false + in + if plt then `b {emit_symbol s}(PLT)` else `b {emit_symbol s}` @@ -55,6 +72,10 @@ {loc = Reg r} -> emit_string (register_name r) | _ -> fatal_error "Emit_arm.emit_reg" +let emit_next_reg = function + {loc = Reg r} -> emit_string (register_name (r + 1)) + | _ -> fatal_error "Emit_arm.emit_next_reg" + (* Layout of the stack frame *) let stack_offset = ref 0 @@ -368,7 +389,13 @@ let src = i.arg.(0) and dst = i.res.(0) in if src.loc = dst.loc then 0 else begin begin match (src, dst) with - {loc = Reg _; typ = Float}, {loc = Reg _} -> + {loc = Reg _; typ = Float}, {loc = Reg _; typ = Int|Addr} + when Config.system = "macosx" -> + ` vmov {emit_reg dst}, {emit_next_reg dst}, {emit_reg src}\n` + | {loc = Reg _; typ = Int|Addr}, {loc = Reg _; typ = Float} + when Config.system = "macosx" -> + ` vmov {emit_reg dst}, {emit_reg src}, {emit_next_reg src}\n` + | {loc = Reg _; typ = Float}, {loc = Reg _} -> ` fcpyd {emit_reg dst}, {emit_reg src}\n` | {loc = Reg _}, {loc = Reg _} -> ` mov {emit_reg dst}, {emit_reg src}\n` @@ -761,8 +788,25 @@ (* The Thumb-2 TBH instruction supports only forward branches, so we need to generate appropriate trampolines for all labels that appear before this switch instruction (PR#5623) *) + (* Apple's assembler mishandles (or disagrees about) the + * following: + * + * .short (Lnnn-.)/2+0 + * .short (Lmmm-.)/2+1 + * ... + * I'm replacing it with the following, which should work for + * Apple and Linux (I hope): + * + * Lbbb: + * .short (Lnnn-Lbbb)/2 + * .short (Lmmm-Lbbb)/2 + * ... + * + * JAS Tue Jul 24 08:33:49 PDT 2012 *) let tramtbl = Array.copy jumptbl in + let base = new_label() in ` tbh [pc, {emit_reg i.arg.(0)}, lsl #1]\n`; + `{emit_label base}:\n`; for j = 0 to Array.length tramtbl - 1 do let rec label i = match i.desc with @@ -770,7 +814,7 @@ | Llabel lbl when lbl = tramtbl.(j) -> lbl | _ -> label i.next in tramtbl.(j) <- label i.next; - ` .short ({emit_label tramtbl.(j)}-.)/2+{emit_int j}\n` + ` .short ({emit_label tramtbl.(j)}-{emit_label base})/2\n` done; (* Generate the necessary trampolines *) for j = 0 to Array.length tramtbl - 1 do @@ -860,11 +904,17 @@ ` .text\n`; ` .align 2\n`; ` .globl {emit_symbol fundecl.fun_name}\n`; - if !arch > ARMv6 && !thumb then - ` .thumb\n` - else + if !arch > ARMv6 && !thumb then begin + ` .thumb\n`; + if Config.system = "macosx" then + ` .thumb_func {emit_symbol fundecl.fun_name}\n` + else + ` .type {emit_symbol fundecl.fun_name}, %function\n`; + end else begin ` .arm\n`; - ` .type {emit_symbol fundecl.fun_name}, %function\n`; + if Config.system <> "macosx" then + ` .type {emit_symbol fundecl.fun_name}, %function\n`; + end; `{emit_symbol fundecl.fun_name}:\n`; emit_debug_info fundecl.fun_dbg; cfi_startproc(); @@ -881,8 +931,10 @@ List.iter emit_call_gc !call_gc_sites; List.iter emit_call_bound_error !bound_error_sites; cfi_endproc(); - ` .type {emit_symbol fundecl.fun_name}, %function\n`; - ` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n` + if Config.system <> "macosx" then begin + ` .type {emit_symbol fundecl.fun_name}, %function\n`; + ` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n` + end (* Emission of data *) @@ -911,20 +963,29 @@ let begin_assembly() = reset_debug_info(); ` .syntax unified\n`; - begin match !arch with - | ARMv4 -> ` .arch armv4t\n` - | ARMv5 -> ` .arch armv5t\n` - | ARMv5TE -> ` .arch armv5te\n` - | ARMv6 -> ` .arch armv6\n` - | ARMv6T2 -> ` .arch armv6t2\n` - | ARMv7 -> ` .arch armv7-a\n` - end; - begin match !fpu with - Soft -> ` .fpu softvfp\n` - | VFPv2 -> ` .fpu vfpv2\n` - | VFPv3_D16 -> ` .fpu vfpv3-d16\n` - | VFPv3 -> ` .fpu vfpv3\n` - end; + let arch_pseud_str = + match Config.system, !arch with + | "macosx", ARMv4 -> ".machine armv4t" + | "macosx", ARMv5 -> ".machine armv5" + | "macosx", ARMv5TE -> ".machine armv5" + | "macosx", ARMv6 -> ".machine armv6" + | "macosx", ARMv6T2 -> ".machine armv6" + | "macosx", ARMv7 -> ".machine armv7" + | _, ARMv4 -> ".arch armv4t" + | _, ARMv5 -> ".arch armv5t" + | _, ARMv5TE -> ".arch armv5te" + | _, ARMv6 -> ".arch armv6" + | _, ARMv6T2 -> ".arch armv6t2" + | _, ARMv7 -> ".arch armv7-a" + in + ` {emit_string arch_pseud_str}\n`; + if Config.system <> "macosx" then + begin match !fpu with + Soft -> ` .fpu softvfp\n` + | VFPv2 -> ` .fpu vfpv2\n` + | VFPv3_D16 -> ` .fpu vfpv3-d16\n` + | VFPv3 -> ` .fpu vfpv3\n` + end; `trap_ptr .req r8\n`; `alloc_ptr .req r10\n`; `alloc_limit .req r11\n`; @@ -935,12 +996,18 @@ let lbl_begin = Compilenv.make_symbol (Some "code_begin") in ` .text\n`; ` .globl {emit_symbol lbl_begin}\n`; + if Config.system = "macosx" && !thumb then + ` .thumb_func {emit_symbol lbl_begin}\n` + else (); `{emit_symbol lbl_begin}:\n` let end_assembly () = let lbl_end = Compilenv.make_symbol (Some "code_end") in ` .text\n`; ` .globl {emit_symbol lbl_end}\n`; + if Config.system = "macosx" && !thumb then + ` .thumb_func {emit_symbol lbl_end}\n` + else (); `{emit_symbol lbl_end}:\n`; let lbl_end = Compilenv.make_symbol (Some "data_end") in ` .data\n`; @@ -950,20 +1017,39 @@ let lbl = Compilenv.make_symbol (Some "frametable") in ` .globl {emit_symbol lbl}\n`; `{emit_symbol lbl}:\n`; + let efa_label lbl = begin + if Config.system = "macosx" then begin + if !thumb then + ` .thumb_func {emit_label lbl}\n` + end else begin + ` .type {emit_label lbl}, %function\n` + end; + ` .word {emit_label lbl}\n`; + end in + let efa_label_rel = + if Config.system = "macosx" then + let sylab1 = new_label () in + let sylab2 = ref 99 in + (fun lbl ofs -> + incr sylab2; + `Lofs_{emit_int sylab1}_{emit_int !sylab2} = {emit_label lbl} - . + {emit_int32 ofs}\n`; + ` .word Lofs_{emit_int sylab1}_{emit_int !sylab2}\n`) + else + (fun lbl ofs -> ` .word {emit_label lbl} - . + {emit_int32 ofs}\n`) + in emit_frames - { efa_label = (fun lbl -> - ` .type {emit_label lbl}, %function\n`; - ` .word {emit_label lbl}\n`); + { efa_label; efa_16 = (fun n -> ` .short {emit_int n}\n`); efa_32 = (fun n -> ` .long {emit_int32 n}\n`); efa_word = (fun n -> ` .word {emit_int n}\n`); efa_align = (fun n -> ` .align {emit_int(Misc.log2 n)}\n`); - efa_label_rel = (fun lbl ofs -> - ` .word {emit_label lbl} - . + {emit_int32 ofs}\n`); + efa_label_rel; efa_def_label = (fun lbl -> `{emit_label lbl}:\n`); efa_string = (fun s -> emit_string_directive " .asciz " s) }; - ` .type {emit_symbol lbl}, %object\n`; - ` .size {emit_symbol lbl}, .-{emit_symbol lbl}\n`; + if Config.system <> "macosx" then begin + ` .type {emit_symbol lbl}, %object\n`; + ` .size {emit_symbol lbl}, .-{emit_symbol lbl}\n`; + end; begin match Config.system with "linux_eabihf" | "linux_eabi" -> (* Mark stack as non-executable *) Index: asmcomp/arm/proc.ml =================================================================== --- asmcomp/arm/proc.ml (.../vendor/ocaml/4.01.0) (revision 112) +++ asmcomp/arm/proc.ml (.../trunk/ocamlxarm/4.0) (revision 112) @@ -136,6 +136,40 @@ done; (loc, Misc.align !ofs 8) (* keep stack 8-aligned *) +let calling_conventions_fipair first_int last_int make_stack arg = + (* The same as calling_conventions, except that floats are passed in + * pairs of int registers. These are the conventions of iOS. To avoid + * making too many changes, a float value is represented as a single + * register (the smaller one). Functions in emit.mlp can tell what to + * do by observing the type. + *) + let loc = Array.create (Array.length arg) Reg.dummy in + let int = ref first_int in + let ofs = ref 0 in + for i = 0 to Array.length arg - 1 do + match arg.(i).typ with + Int | Addr as ty -> + if !int <= last_int then begin + loc.(i) <- phys_reg !int; + incr int + end else begin + loc.(i) <- stack_slot (make_stack !ofs) ty; + ofs := !ofs + size_int + end + | Float -> + assert (abi = EABI_HF); + assert (!fpu >= VFPv3_D16); + if !int <= last_int - 1 then begin + loc.(i) <- phys_reg !int; + int := !int + 2 + end else begin + ofs := Misc.align !ofs size_float; + loc.(i) <- stack_slot (make_stack !ofs) Float; + ofs := !ofs + size_float + end + done; + (loc, Misc.align !ofs 8) (* keep stack 8-aligned *) + let incoming ofs = Incoming ofs let outgoing ofs = Outgoing ofs let not_supported ofs = fatal_error "Proc.loc_results: cannot call" @@ -153,16 +187,37 @@ let loc_results res = let (loc, _) = calling_conventions 0 7 100 115 not_supported res in loc -(* C calling convention: +(* C calling convention for Linux: first integer args in r0...r3 first float args in d0...d7 (EABI+VFP) remaining args on stack. - Return values in r0...r1 or d0. *) + Return values in r0...r1 or d0. + C calling convention for iOS: + first integer args in r0...r3 + first float args in pairs of regs r0/r1, r1/r2, or r2/r3 + remaining args on stack. + Return values in r0 or r0/r1 for floats. *) + let loc_external_arguments arg = - calling_conventions 0 3 100 107 outgoing arg + if Config.system = "macosx" then + calling_conventions_fipair 0 3 outgoing arg + else + calling_conventions 0 3 100 107 outgoing arg + let loc_external_results res = - let (loc, _) = calling_conventions 0 1 100 100 not_supported res in loc + if Config.system = "macosx" then + let (loc, _) = calling_conventions_fipair 0 1 not_supported res in + if Array.length res < 1 || res.(0).typ <> Float then loc + else + (* If the result is Float, mark as a register pair by changing the + * register name. Code in selection.ml knows to look for this. + * This is hacky but lots of the code seems to depend on the + * result being a single register. + *) + [| { loc.(0) with name = loc.(0).name ^ "+" } |] + else + let (loc, _) = calling_conventions 0 1 100 100 not_supported res in loc let loc_exn_bucket = phys_reg 0 Index: asmcomp/arm/selection.ml =================================================================== --- asmcomp/arm/selection.ml (.../vendor/ocaml/4.01.0) (revision 112) +++ asmcomp/arm/selection.ml (.../trunk/ocamlxarm/4.0) (revision 112) @@ -172,13 +172,19 @@ when n = 1 lsl Misc.log2 n -> (Iintop_imm(Idiv, n), [arg]) | (Cdivi, args) -> - (Iextcall("__aeabi_idiv", false), args) + if Config.system = "macosx" then + (Iextcall("__divsi3", false), args) + else + (Iextcall("__aeabi_idiv", false), args) | (Cmodi, [arg; Cconst_int n]) when n > 1 && n = 1 lsl Misc.log2 n -> (Iintop_imm(Imod, n), [arg]) | (Cmodi, args) -> - (* See above for fix up of return register *) - (Iextcall("__aeabi_idivmod", false), args) + if Config.system = "macosx" then + (Iextcall("__modsi3", false), args) + else + (* See above for fix up of return register *) + (Iextcall("__aeabi_idivmod", false), args) (* Recognize 16-bit bswap instruction (ARMv6T2 because we need movt) *) | (Cextcall("caml_bswap16_direct", _, _, _), args) when !arch >= ARMv6T2 -> (Ispecific(Ibswap 16), args) @@ -271,6 +277,58 @@ with Use_default -> super#insert_op_debug op dbg rs rd +(* Here we handle floating returns in iOS, which are in r0/r1 as a pair. + * Proc.loc_external_results can return a fake register that represents + * the pair. We detect it and replace it with two separate registers, + * which allows the liveness analysis to notice that both are in use. + *) +method private loc_external_res_ispair = function + { Reg.loc = Reg.Reg _; Reg.name = name } -> + let l = String.length name in l > 0 && name.[l - 1] = '+' + | _ -> false + + +method insert_debug desc dbg arg res = + (* Here, res.(0) might be a register pair. + *) + let res' = + if Array.length res > 0 && self#loc_external_res_ispair res.(0) then + match res.(0) with + { Reg.loc = Reg.Reg n } -> [| Proc.phys_reg n; Proc.phys_reg (n + 1) |] + | _ -> res + else res in + super#insert_debug desc dbg arg res' + +method insert_move_args arg loc stacksize = + (* Here we have a register pair as the target if the source is Float + * and the target is a physical register. + *) + if stacksize <> 0 then self#insert (Iop(Istackoffset stacksize)) [||] [||]; + for i = 0 to Array.length arg - 1 do + match arg.(i).Reg.typ, loc.(i).Reg.loc with + (Float, Reg.Reg n) -> + let rpair = [| Proc.phys_reg n; Proc.phys_reg (n + 1) |] in + self#insert (Iop Imove) [|arg.(i)|] rpair + | _ -> + self#insert_move arg.(i) loc.(i) + done + +method insert_move_results loc res stacksize = + (* Here, loc.(0) might be a register pair. + *) + if stacksize <> 0 then + self#insert (Iop(Istackoffset(-stacksize))) [||] [||]; + for i = 0 to Array.length loc - 1 do + if self#loc_external_res_ispair loc.(i) then + match loc.(i) with + { Reg.loc = Reg.Reg n } -> + let rpair = [| Proc.phys_reg n; Proc.phys_reg (n + 1) |] in + self#insert (Iop Imove) rpair [|res.(i)|] + | _ -> self#insert_move loc.(i) res.(i) + else + self#insert_move loc.(i) res.(i) + done + end let fundecl f = (new selector)#emit_fundecl f Index: asmcomp/interf.ml =================================================================== --- asmcomp/interf.ml (.../vendor/ocaml/4.01.0) (revision 112) +++ asmcomp/interf.ml (.../trunk/ocamlxarm/4.0) (revision 112) @@ -121,6 +121,7 @@ if weight > 0 then begin let i = r1.stamp and j = r2.stamp in if i <> j + && Proc.register_class r1 = Proc.register_class r2 && r1.loc = Unknown && (let p = if i < j then (i, j) else (j, i) in not (IntPairSet.mem p !mat)) Index: tools/make-package-macosx =================================================================== --- tools/make-package-macosx (.../vendor/ocaml/4.01.0) (revision 112) +++ tools/make-package-macosx (.../trunk/ocamlxarm/4.0) (revision 112) @@ -28,9 +28,9 @@ IFPkgDescriptionDeleteWarning IFPkgDescriptionDescription - The OCaml compiler and tools + The OCaml compiler and tools for iOS IFPkgDescriptionTitle - OCaml + OCaml for iOS IFPkgDescriptionVersion ${VERSION} @@ -44,11 +44,11 @@ CFBundleGetInfoString - OCaml ${VERSION} + OCaml ${VERSION} for iOS CFBundleIdentifier - fr.inria.ocaml + com.psellos.ocamlxarm CFBundleName - OCaml + OCaml for iOS CFBundleShortVersionString ${VERSION} IFMajorVersion @@ -60,7 +60,7 @@ IFPkgFlagAuthorizationAction AdminAuthorization IFPkgFlagDefaultLocation - /usr/local + /usr/local/ocamlxarm IFPkgFlagInstallFat IFPkgFlagIsRequired @@ -83,15 +83,16 @@ # stop here -> | cat >resources/ReadMe.txt <&2; exit 1 + fi + ARCH=$2 + shift 2 + ;; + -*) echo "$USAGE" >&2; exit 1 ;; + *) break ;; + esac + done + if [ $# -lt 1 ]; then + echo "$USAGE" >&2; exit 1 + fi + case $1 in + all|phase1|config1) + ;; + *) + if grep -qs -e MODEL=armv6 config/Makefile; then + OARCH=6 + else + OARCH=7 + fi + if [ "$ARCH" != '' -a "$ARCH" != $OARCH ]; then + echo "$I: warning: ignoring -v$ARCH, architecture is -v$OARCH" >&2 + fi + ARCH=$OARCH + ;; + esac + case $ARCH in + *?) ;; + *) ARCH=7 ;; + esac + echo $ARCH $1 +} + +# Small steps +config1 () { + # Configure for building bytecode interpreter to run on Intel OS X. + # But specify ARM architecture for assembly and partial link. + ARMARCH=v$1 + echo "xarm-build: ----- configure phase 1, arm$ARMARCH -----" + ./configure \ + -bindir $XARMTARGET/$ARMARCH/bin \ + -libdir $XARMTARGET/$ARMARCH/lib/ocaml \ + -mandir $XARMTARGET/$ARMARCH/man/man1 \ + -no-curses \ + -no-tk \ + -no-graph \ + -host i386-apple-darwin11.3.0 \ + -cc "clang -arch $OSXARCH" \ + -as "$TOOLDIR/clang -arch arm$ARMARCH -no-integrated-as -c" \ + -aspp "$TOOLDIR/clang -arch arm$ARMARCH -no-integrated-as -c" + # Post-modify config/Makefile to select the ARM back end for + # ocamlopt (to generate ARM assembly code). + $SED -i .bak \ + -e '1i\ +# modified by xarm-build for OCamlXARM' \ + -e 's/^ARCH[ ]*=.*/ARCH=arm/' \ + -e "s/^MODEL[ ]*=.*/MODEL=arm$ARMARCH/" \ + -e "s#^PARTIALLD[ ]*=.*#PARTIALLD=$TOOLDIR/ld -r#" \ + config/Makefile + # Post-modify utils/config.ml to tell ocamlopt to create ARM + # binaries for itself. Also tell ocamlc and ocamlopt to use ARM + # architecture when compiling C files. + make utils/config.ml + $SED -i .bak \ + -e 's#let[ ][ ]*mkexe[ ]*=.*#let mkexe ="'"$TOOLDIR/clang -arch arm$ARMARCH -isysroot $PLT$SDK"'"#' \ + -e 's#let[ ][ ]*bytecomp_c_compiler[ ]*=.*#let bytecomp_c_compiler ="'"$TOOLDIR/clang -arch arm$ARMARCH -isysroot $PLT$SDK"'"#' \ + -e 's#let[ ][ ]*native_c_compiler[ ]*=.*#let native_c_compiler ="'"$TOOLDIR/clang -arch arm$ARMARCH -isysroot $PLT$SDK"'"#' \ + utils/config.ml +} + +build1 () { + # Don't assemble asmrun/arm.S for Phase 1 build. Modify Makefile + # temporarily to disable. Be really sure to put back for Phase 2. + ARMARCH=v$1 + echo "xarm-build: ----- build phase 1, arm$ARMARCH -----" + trap 'mv -f asmrun/Makefile.aside asmrun/Makefile' EXIT + grep -q '^[ ]*ASMOBJS[ ]*=' asmrun/Makefile && \ + mv -f asmrun/Makefile asmrun/Makefile.aside + $SED -e '/^[ ]*ASMOBJS[ ]*=/s/^/#/' \ + asmrun/Makefile.aside > asmrun/Makefile + make world && make opt + mv -f asmrun/Makefile.aside asmrun/Makefile + trap - EXIT + # Save the Phase 1 shared (dynamically loadable) libraries and + # restore them after Phase 2. They're required by some OCaml + # utilities, such as camlp4. + # + # The shared libraries are useful only with the bytecode + # interpreter, which we don't support under iOS. This lets us (just + # barely) fit OCamlXARM into the form of a usual OCaml release. + find . -name '*.so' -exec mv {} {}phase1 \; +} + +config2 () { + # Clean out OS X runtime + ARMARCH=v$1 + echo "xarm-build: ----- configure phase 2, arm$ARMARCH -----" + cd asmrun; make clean; cd .. + cd stdlib; make clean; cd .. + cd otherlibs/bigarray; make clean; cd ../.. + cd otherlibs/dynlink; make clean; cd ../.. + cd otherlibs/num; make clean; cd ../.. + cd otherlibs/str; make clean; cd ../.. + cd otherlibs/systhreads; make clean; cd ../.. + cd otherlibs/threads; make clean; cd ../.. + cd otherlibs/unix; make clean; cd ../.. + # Reconfigure for iOS environment, using iOS Simulator to test the + # ABI. + ./configure \ + -bindir $XARMTARGET/$ARMARCH/bin \ + -libdir $XARMTARGET/$ARMARCH/lib/ocaml \ + -mandir $XARMTARGET/$ARMARCH/man/man1 \ + -no-curses \ + -no-tk \ + -no-graph \ + -host arm-apple-darwin10.0.0d3 \ + -cc "gcc -arch i386 -isysroot $SIMPLT$SIMSDK" \ + -as "gcc -arch i386 -c" \ + -aspp "gcc -arch i386 -c" \ + -lib "-Wl,-syslibroot,$SIMPLT$SIMSDK" + # Post-modify config/Makefile to specify the real cross-compiling + # toolchain. + $SED -i .bak \ + -e '1i\ +# modified by xarm-build for OCamlXARM' \ + -e "s|^BYTECC[ ]*=.*|BYTECC=$TOOLDIR/cc -arch arm$ARMARCH -isysroot $PLT$SDK|" \ + -e "s|^BYTECCLIBS[ ]*=.*|BYTECCLIBS=-Wl,-syslibroot,$PLT$SDK|" \ + -e 's/^ARCH[ ]*=.*/ARCH=arm/' \ + -e 's/^BNG_ARCH[ ]*=.*/BNG_ARCH=arm/' \ + -e "s/^MODEL[ ]*=.*/MODEL=arm$ARMARCH/" \ + -e 's/^SYSTEM[ ]*=.*/SYSTEM=macosx/' \ + -e "s|^NATIVECC[ ]*=.*|NATIVECC=$TOOLDIR/cc -arch arm$ARMARCH -isysroot $PLT$SDK|" \ + -e "s|^NATIVECCLIBS[ ]*=.*|NATIVECCLIBS=-Wl,-syslibroot,$PLT$SDK|" \ + -e "s|^ASM[ ]*=.*|ASM=$TOOLDIR/cc -arch arm$ARMARCH -no-integrated-as -c|" \ + -e "s|^ASPP[ ]*=.*|ASPP=$TOOLDIR/cc -arch arm$ARMARCH -no-integrated-as -c|" \ + -e "s|^MKDLL[ ]*=.*|MKDLL=$TOOLDIR/cc -arch arm$ARMARCH -isysroot $PLT$SDK -bundle -flat_namespace -undefined suppress|" \ + -e "s|^MKMAINDLL[ ]*=.*|MKMAINDLL=$TOOLDIR/cc -arch arm$ARMARCH -isysroot $PLT$SDK -bundle -flat_namespace -undefined suppress|" \ + config/Makefile + # Rebuild ocamlmklib, so libraries work with iOS. + rm myocamlbuild_config.ml + cd tools + make ocamlmklib + cd .. +} + +build2 () { + # Make iOS runtime + ARMARCH=v$1 + echo "xarm-build: ----- build phase 2, arm$ARMARCH -----" + cd asmrun; make all; cd .. + cd stdlib; make all allopt; cd .. + cd otherlibs/unix; make all allopt; cd ../.. + cd otherlibs/str; make all allopt; cd ../.. + cd otherlibs/num; make all allopt; cd ../.. + cd otherlibs/dynlink; make all allopt; cd ../.. + cd otherlibs/bigarray; make all allopt; cd ../.. + cd otherlibs/systhreads; make all allopt; cd ../.. + cd otherlibs/threads; make all allopt; cd ../.. + # Restore the saved Phase 1 .so files (see above). + find . -name '*.sophase1' -print | \ + while read f; do \ + fso="$(expr "$f" : '\(.*\)sophase1$')so"; mv -f $f $fso; \ + done +} + +# Bigger steps + +phase1 () { + config1 $1 && build1 $1 +} + +phase2 () { + config2 $1 && build2 $1 +} + +all () { + phase1 $1 && phase2 $1 +} + +# Special + +clean () { + rm -f myocamlbuild_config.ml + make clean +} + +stage () { + sudo rm -rf package-macosx/root/v$1 + make BINDIR="`pwd`"/package-macosx/root/v$1/bin \ + LIBDIR="`pwd`"/package-macosx/root/v$1/lib/ocaml \ + MANDIR="`pwd`"/package-macosx/root/v$1/man \ + install +} + +package () { + tools/make-package-macosx + sudo rm -rf package-macosx/root +} + +# Main + +if ! ARCHSTEP=$(args "$@"); then + exit $? +fi +set -- $ARCHSTEP + +# $1 architecture (6 / 7) +# $2 step + +case "$2" in +config1) config1 $1;; +build1) build1 $1;; +config2) config2 $1;; +build2) build2 $1;; +phase1) phase1 $1;; +phase2) phase2 $1;; +all) all $1;; +clean) clean ;; +stage) stage $1;; +package) package;; +*) echo "$USAGE" >&2 exit 1 ;; +esac Index: asmrun/signals_osdep.h =================================================================== --- asmrun/signals_osdep.h (.../vendor/ocaml/4.01.0) (revision 112) +++ asmrun/signals_osdep.h (.../trunk/ocamlxarm/4.0) (revision 112) @@ -61,6 +61,35 @@ #define RETURN_AFTER_STACK_OVERFLOW +/****************** ARM (7), MacOSX */ + +#elif defined(TARGET_arm) && defined(__arm) && defined (SYS_macosx) + + #define DECLARE_SIGNAL_HANDLER(name) \ + static void name(int sig, siginfo_t * info, void * context) + + #define SET_SIGACT(sigact,name) \ + sigact.sa_sigaction = (name); \ + sigact.sa_flags = SA_SIGINFO + + #include + #include + + #if !defined(MAC_OS_X_VERSION_10_5) \ + || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + #define CONTEXT_REG(r) r + #else + #define CONTEXT_REG(r) __##r + #endif + + typedef uint32_t context_reg; + #define CONTEXT_STATE (((ucontext_t *)context)->uc_mcontext->CONTEXT_REG(ss)) + #define CONTEXT_PC (CONTEXT_STATE.CONTEXT_REG(pc)) + #define CONTEXT_EXCEPTION_POINTER (CONTEXT_STATE.CONTEXT_REG(r[12])) + #define CONTEXT_YOUNG_PTR (CONTEXT_STATE.CONTEXT_REG(r[11])) + #define CONTEXT_SP (CONTEXT_STATE.CONTEXT_REG(sp)) + #define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr) + /****************** ARM, Linux */ #elif defined(TARGET_arm) && (defined(SYS_linux_eabi) \ @@ -139,7 +168,7 @@ /****************** I386, MacOS X */ -#elif defined(TARGET_i386) && defined(SYS_macosx) +#elif (defined(TARGET_i386) || (defined(TARGET_arm) && defined(__i386))) && defined(SYS_macosx) #define DECLARE_SIGNAL_HANDLER(name) \ static void name(int sig, siginfo_t * info, void * context) Index: asmrun/arm.S =================================================================== --- asmrun/arm.S (.../vendor/ocaml/4.01.0) (revision 112) +++ asmrun/arm.S (.../trunk/ocamlxarm/4.0) (revision 112) @@ -17,6 +17,39 @@ .syntax unified .text + +/* Apple compatibility macros */ +#if defined(SYS_macosx) +#define Glo(s) _##s +#define Loc(s) L##s +#if defined(MODEL_armv6) + .machine armv6 + .macro .funtype + .endm + .macro cbz + cmp $0, #0 + beq $1 + .endm +#else + .machine armv7 + .thumb + .macro .funtype + .thumb_func $0 + .endm +#endif + .macro .type + .endm + .macro .size + .endm +#else +#define Glo(s) s +#define Loc(s) .L##s + .macro .funtype symbol + .type \symbol, %function + .endm +#endif +/* End Apple compatibility macros */ + #if defined(SYS_linux_eabihf) && defined(MODEL_armv6) .arch armv6 .fpu vfpv2 @@ -74,196 +107,196 @@ /* Allocation functions and GC interface */ - .globl caml_system__code_begin -caml_system__code_begin: + .globl Glo(caml_system__code_begin) +Glo(caml_system__code_begin): .align 2 - .globl caml_call_gc -caml_call_gc: + .globl Glo(caml_call_gc) +Glo(caml_call_gc): CFI_STARTPROC PROFILE /* Record return address */ - ldr r12, =caml_last_return_address + ldr r12, Loc(Pcaml_last_return_address) str lr, [r12] -.Lcaml_call_gc: +Loc(caml_call_gc): /* Record lowest stack address */ - ldr r12, =caml_bottom_of_stack + ldr r12, Loc(Pcaml_bottom_of_stack) str sp, [r12] -#if defined(SYS_linux_eabihf) +#if defined(SYS_linux_eabihf) || defined(SYS_macosx) /* Save caller floating-point registers on the stack */ vpush {d0-d7}; CFI_ADJUST(64) #endif /* Save integer registers and return address on the stack */ push {r0-r7,r12,lr}; CFI_ADJUST(40) /* Store pointer to saved integer registers in caml_gc_regs */ - ldr r12, =caml_gc_regs + ldr r12, Loc(Pcaml_gc_regs) str sp, [r12] /* Save current allocation pointer for debugging purposes */ - ldr alloc_limit, =caml_young_ptr + ldr alloc_limit, Loc(Pcaml_young_ptr) str alloc_ptr, [alloc_limit] /* Save trap pointer in case an exception is raised during GC */ - ldr r12, =caml_exception_pointer + ldr r12, Loc(Pcaml_exception_pointer) str trap_ptr, [r12] /* Call the garbage collector */ - bl caml_garbage_collection + bl Glo(caml_garbage_collection) /* Restore integer registers and return address from the stack */ pop {r0-r7,r12,lr}; CFI_ADJUST(-40) -#if defined(SYS_linux_eabihf) +#if defined(SYS_linux_eabihf) || defined(SYS_macosx) /* Restore floating-point registers from the stack */ vpop {d0-d7}; CFI_ADJUST(-64) #endif /* Reload new allocation pointer and limit */ /* alloc_limit still points to caml_young_ptr */ - ldr r12, =caml_young_limit + ldr r12, Loc(Pcaml_young_limit) ldr alloc_ptr, [alloc_limit] ldr alloc_limit, [r12] /* Return to caller */ bx lr CFI_ENDPROC - .type caml_call_gc, %function - .size caml_call_gc, .-caml_call_gc + .funtype Glo(caml_call_gc) + .size Glo(caml_call_gc), .-Glo(caml_call_gc) .align 2 - .globl caml_alloc1 -caml_alloc1: + .globl Glo(caml_alloc1) +Glo(caml_alloc1): CFI_STARTPROC PROFILE -.Lcaml_alloc1: +Loc(caml_alloc1): sub alloc_ptr, alloc_ptr, 8 cmp alloc_ptr, alloc_limit bcc 1f bx lr 1: /* Record return address */ - ldr r7, =caml_last_return_address + ldr r7, Loc(Pcaml_last_return_address) str lr, [r7] /* Call GC (preserves r7) */ - bl .Lcaml_call_gc + bl Loc(caml_call_gc) /* Restore return address */ ldr lr, [r7] /* Try again */ - b .Lcaml_alloc1 + b Loc(caml_alloc1) CFI_ENDPROC - .type caml_alloc1, %function - .size caml_alloc1, .-caml_alloc1 + .funtype Glo(caml_alloc1) + .size Glo(caml_alloc1), .-Glo(caml_alloc1) .align 2 - .globl caml_alloc2 -caml_alloc2: + .globl Glo(caml_alloc2) +Glo(caml_alloc2): CFI_STARTPROC PROFILE -.Lcaml_alloc2: +Loc(caml_alloc2): sub alloc_ptr, alloc_ptr, 12 cmp alloc_ptr, alloc_limit bcc 1f bx lr 1: /* Record return address */ - ldr r7, =caml_last_return_address + ldr r7, Loc(Pcaml_last_return_address) str lr, [r7] /* Call GC (preserves r7) */ - bl .Lcaml_call_gc + bl Loc(caml_call_gc) /* Restore return address */ ldr lr, [r7] /* Try again */ - b .Lcaml_alloc2 + b Loc(caml_alloc2) CFI_ENDPROC - .type caml_alloc2, %function - .size caml_alloc2, .-caml_alloc2 + .funtype Glo(caml_alloc2) + .size Glo(caml_alloc2), .-Glo(caml_alloc2) .align 2 - .globl caml_alloc3 - .type caml_alloc3, %function -caml_alloc3: + .globl Glo(caml_alloc3) + .funtype Glo(caml_alloc3) +Glo(caml_alloc3): CFI_STARTPROC PROFILE -.Lcaml_alloc3: +Loc(caml_alloc3): sub alloc_ptr, alloc_ptr, 16 cmp alloc_ptr, alloc_limit bcc 1f bx lr 1: /* Record return address */ - ldr r7, =caml_last_return_address + ldr r7, Loc(Pcaml_last_return_address) str lr, [r7] /* Call GC (preserves r7) */ - bl .Lcaml_call_gc + bl Loc(caml_call_gc) /* Restore return address */ ldr lr, [r7] /* Try again */ - b .Lcaml_alloc3 + b Loc(caml_alloc3) CFI_ENDPROC - .type caml_alloc3, %function - .size caml_alloc3, .-caml_alloc3 + .funtype Glo(caml_alloc3) + .size Glo(caml_alloc3), .-Glo(caml_alloc3) .align 2 - .globl caml_allocN -caml_allocN: + .globl Glo(caml_allocN) +Glo(caml_allocN): CFI_STARTPROC PROFILE -.Lcaml_allocN: +Loc(caml_allocN): sub alloc_ptr, alloc_ptr, r7 cmp alloc_ptr, alloc_limit bcc 1f bx lr 1: /* Record return address */ - ldr r12, =caml_last_return_address + ldr r12, Loc(Pcaml_last_return_address) str lr, [r12] /* Call GC (preserves r7) */ - bl .Lcaml_call_gc + bl Loc(caml_call_gc) /* Restore return address */ - ldr r12, =caml_last_return_address + ldr r12, Loc(Pcaml_last_return_address) ldr lr, [r12] /* Try again */ - b .Lcaml_allocN + b Loc(caml_allocN) CFI_ENDPROC - .type caml_allocN, %function - .size caml_allocN, .-caml_allocN + .funtype Glo(caml_allocN) + .size Glo(caml_allocN), .-Glo(caml_allocN) /* Call a C function from OCaml */ /* Function to call is in r7 */ .align 2 - .globl caml_c_call -caml_c_call: + .globl Glo(caml_c_call) +Glo(caml_c_call): CFI_STARTPROC PROFILE /* Record lowest stack address and return address */ - ldr r5, =caml_last_return_address - ldr r6, =caml_bottom_of_stack + ldr r5, Loc(Pcaml_last_return_address) + ldr r6, Loc(Pcaml_bottom_of_stack) str lr, [r5] str sp, [r6] /* Preserve return address in callee-save register r4 */ mov r4, lr /* Make the exception handler alloc ptr available to the C code */ - ldr r5, =caml_young_ptr - ldr r6, =caml_exception_pointer + ldr r5, Loc(Pcaml_young_ptr) + ldr r6, Loc(Pcaml_exception_pointer) str alloc_ptr, [r5] str trap_ptr, [r6] /* Call the function */ blx r7 /* Reload alloc ptr and alloc limit */ - ldr r6, =caml_young_limit - ldr alloc_ptr, [r5] /* r5 still points to caml_young_ptr */ + ldr r6, Loc(Pcaml_young_limit) + ldr alloc_ptr, [r5] /* r5 still points to Glo(caml_young_ptr) */ ldr alloc_limit, [r6] /* Return */ bx r4 CFI_ENDPROC - .type caml_c_call, %function - .size caml_c_call, .-caml_c_call + .funtype Glo(caml_c_call) + .size Glo(caml_c_call), .-Glo(caml_c_call) /* Start the OCaml program */ .align 2 - .globl caml_start_program -caml_start_program: + .globl Glo(caml_start_program) +Glo(caml_start_program): CFI_STARTPROC PROFILE - ldr r12, =caml_program + ldr r12, Loc(Pcaml_program) /* Code shared with caml_callback* */ /* Address of OCaml code to call is in r12 */ /* Arguments to the OCaml code are in r0...r3 */ -.Ljump_to_caml: -#if defined(SYS_linux_eabihf) +Loc(jump_to_caml): +#if defined(SYS_linux_eabihf) || defined(SYS_macosx) /* Save callee-save floating-point registers */ vpush {d8-d15}; CFI_ADJUST(64) #endif @@ -271,9 +304,9 @@ push {r4-r8,r10,r11,lr}; CFI_ADJUST(32) /* 8-byte alignment */ /* Setup a callback link on the stack */ sub sp, sp, 16; CFI_ADJUST(16) /* 8-byte alignment */ - ldr r4, =caml_bottom_of_stack - ldr r5, =caml_last_return_address - ldr r6, =caml_gc_regs + ldr r4, Loc(Pcaml_bottom_of_stack) + ldr r5, Loc(Pcaml_last_return_address) + ldr r6, Loc(Pcaml_gc_regs) ldr r4, [r4] ldr r5, [r5] ldr r6, [r6] @@ -282,78 +315,78 @@ str r6, [sp, 8] /* Setup a trap frame to catch exceptions escaping the OCaml code */ sub sp, sp, 8; CFI_ADJUST(8) - ldr r6, =caml_exception_pointer - ldr r5, =.Ltrap_handler + ldr r6, Loc(Pcaml_exception_pointer) + ldr r5, Loc(Ptrap_handler) ldr r4, [r6] str r4, [sp, 0] str r5, [sp, 4] mov trap_ptr, sp /* Reload allocation pointers */ - ldr r4, =caml_young_ptr + ldr r4, Loc(Pcaml_young_ptr) ldr alloc_ptr, [r4] - ldr r4, =caml_young_limit + ldr r4, Loc(Pcaml_young_limit) ldr alloc_limit, [r4] /* Call the OCaml code */ blx r12 -.Lcaml_retaddr: +Loc(caml_retaddr): /* Pop the trap frame, restoring caml_exception_pointer */ - ldr r4, =caml_exception_pointer + ldr r4, Loc(Pcaml_exception_pointer) ldr r5, [sp, 0] str r5, [r4] add sp, sp, 8; CFI_ADJUST(-8) /* Pop the callback link, restoring the global variables */ -.Lreturn_result: - ldr r4, =caml_bottom_of_stack +Loc(return_result): + ldr r4, Loc(Pcaml_bottom_of_stack) ldr r5, [sp, 0] str r5, [r4] - ldr r4, =caml_last_return_address + ldr r4, Loc(Pcaml_last_return_address) ldr r5, [sp, 4] str r5, [r4] - ldr r4, =caml_gc_regs + ldr r4, Loc(Pcaml_gc_regs) ldr r5, [sp, 8] str r5, [r4] add sp, sp, 16; CFI_ADJUST(-16) /* Update allocation pointer */ - ldr r4, =caml_young_ptr + ldr r4, Loc(Pcaml_young_ptr) str alloc_ptr, [r4] /* Reload callee-save registers and return address */ pop {r4-r8,r10,r11,lr}; CFI_ADJUST(-32) -#if defined(SYS_linux_eabihf) +#if defined(SYS_linux_eabihf) || defined(SYS_macosx) /* Reload callee-save floating-point registers */ vpop {d8-d15}; CFI_ADJUST(-64) #endif bx lr CFI_ENDPROC - .type .Lcaml_retaddr, %function - .size .Lcaml_retaddr, .-.Lcaml_retaddr - .type caml_start_program, %function - .size caml_start_program, .-caml_start_program + .funtype Loc(caml_retaddr) + .size Loc(caml_retaddr), .-Loc(caml_retaddr) + .funtype Glo(caml_start_program) + .size Glo(caml_start_program), .-Glo(caml_start_program) /* The trap handler */ .align 2 -.Ltrap_handler: +Loc(trap_handler): CFI_STARTPROC /* Save exception pointer */ - ldr r12, =caml_exception_pointer + ldr r12, Loc(Pcaml_exception_pointer) str trap_ptr, [r12] /* Encode exception bucket as an exception result */ orr r0, r0, 2 /* Return it */ - b .Lreturn_result + b Loc(return_result) CFI_ENDPROC - .type .Ltrap_handler, %function - .size .Ltrap_handler, .-.Ltrap_handler + .funtype Loc(trap_handler) + .size Loc(trap_handler), .-Loc(trap_handler) /* Raise an exception from OCaml */ .align 2 - .globl caml_raise_exn -caml_raise_exn: + .globl Glo(caml_raise_exn) +Glo(caml_raise_exn): CFI_STARTPROC PROFILE /* Test if backtrace is active */ - ldr r1, =caml_backtrace_active + ldr r1, Loc(Pcaml_backtrace_active) ldr r1, [r1] cbz r1, 1f /* Preserve exception bucket in callee-save register r4 */ @@ -362,7 +395,7 @@ mov r1, lr /* arg2: pc of raise */ mov r2, sp /* arg3: sp of raise */ mov r3, trap_ptr /* arg4: sp of handler */ - bl caml_stash_backtrace + bl Glo(caml_stash_backtrace) /* Restore exception bucket */ mov r0, r4 1: /* Cut stack at current trap handler */ @@ -370,35 +403,35 @@ /* Pop previous handler and addr of trap, and jump to it */ pop {trap_ptr, pc} CFI_ENDPROC - .type caml_raise_exn, %function - .size caml_raise_exn, .-caml_raise_exn + .funtype Glo(caml_raise_exn) + .size Glo(caml_raise_exn), .-Glo(caml_raise_exn) /* Raise an exception from C */ .align 2 - .globl caml_raise_exception -caml_raise_exception: + .globl Glo(caml_raise_exception) +Glo(caml_raise_exception): CFI_STARTPROC PROFILE /* Reload trap ptr, alloc ptr and alloc limit */ - ldr trap_ptr, =caml_exception_pointer - ldr alloc_ptr, =caml_young_ptr - ldr alloc_limit, =caml_young_limit + ldr trap_ptr, Loc(Pcaml_exception_pointer) + ldr alloc_ptr, Loc(Pcaml_young_ptr) + ldr alloc_limit, Loc(Pcaml_young_limit) ldr trap_ptr, [trap_ptr] ldr alloc_ptr, [alloc_ptr] ldr alloc_limit, [alloc_limit] /* Test if backtrace is active */ - ldr r1, =caml_backtrace_active + ldr r1, Loc(Pcaml_backtrace_active) ldr r1, [r1] cbz r1, 1f /* Preserve exception bucket in callee-save register r4 */ mov r4, r0 - ldr r1, =caml_last_return_address /* arg2: pc of raise */ + ldr r1, Loc(Pcaml_last_return_address) /* arg2: pc of raise */ ldr r1, [r1] - ldr r2, =caml_bottom_of_stack /* arg3: sp of raise */ + ldr r2, Loc(Pcaml_bottom_of_stack) /* arg3: sp of raise */ ldr r2, [r2] mov r3, trap_ptr /* arg4: sp of handler */ - bl caml_stash_backtrace + bl Glo(caml_stash_backtrace) /* Restore exception bucket */ mov r0, r4 1: /* Cut stack at current trap handler */ @@ -406,14 +439,14 @@ /* Pop previous handler and addr of trap, and jump to it */ pop {trap_ptr, pc} CFI_ENDPROC - .type caml_raise_exception, %function - .size caml_raise_exception, .-caml_raise_exception + .funtype Glo(caml_raise_exception) + .size Glo(caml_raise_exception), .-Glo(caml_raise_exception) /* Callback from C to OCaml */ .align 2 - .globl caml_callback_exn -caml_callback_exn: + .globl Glo(caml_callback_exn) +Glo(caml_callback_exn): CFI_STARTPROC PROFILE /* Initial shuffling of arguments (r0 = closure, r1 = first arg) */ @@ -421,14 +454,14 @@ mov r0, r1 /* r0 = first arg */ mov r1, r12 /* r1 = closure environment */ ldr r12, [r12] /* code pointer */ - b .Ljump_to_caml + b Loc(jump_to_caml) CFI_ENDPROC - .type caml_callback_exn, %function - .size caml_callback_exn, .-caml_callback_exn + .funtype Glo(caml_callback_exn) + .size Glo(caml_callback_exn), .-Glo(caml_callback_exn) .align 2 - .globl caml_callback2_exn -caml_callback2_exn: + .globl Glo(caml_callback2_exn) +Glo(caml_callback2_exn): CFI_STARTPROC PROFILE /* Initial shuffling of arguments (r0 = closure, r1 = arg1, r2 = arg2) */ @@ -436,15 +469,15 @@ mov r0, r1 /* r0 = first arg */ mov r1, r2 /* r1 = second arg */ mov r2, r12 /* r2 = closure environment */ - ldr r12, =caml_apply2 - b .Ljump_to_caml + ldr r12, Loc(Pcaml_apply2) + b Loc(jump_to_caml) CFI_ENDPROC - .type caml_callback2_exn, %function - .size caml_callback2_exn, .-caml_callback2_exn + .funtype Glo(caml_callback2_exn) + .size Glo(caml_callback2_exn), .-Glo(caml_callback2_exn) .align 2 - .globl caml_callback3_exn -caml_callback3_exn: + .globl Glo(caml_callback3_exn) +Glo(caml_callback3_exn): CFI_STARTPROC PROFILE /* Initial shuffling of arguments */ @@ -454,38 +487,67 @@ mov r1, r2 /* r1 = second arg */ mov r2, r3 /* r2 = third arg */ mov r3, r12 /* r3 = closure environment */ - ldr r12, =caml_apply3 - b .Ljump_to_caml + ldr r12, Loc(Pcaml_apply3) + b Loc(jump_to_caml) CFI_ENDPROC - .type caml_callback3_exn, %function - .size caml_callback3_exn, .-caml_callback3_exn + .funtype Glo(caml_callback3_exn) + .size Glo(caml_callback3_exn), .-Glo(caml_callback3_exn) .align 2 - .globl caml_ml_array_bound_error -caml_ml_array_bound_error: + .globl Glo(caml_ml_array_bound_error) +Glo(caml_ml_array_bound_error): CFI_STARTPROC PROFILE /* Load address of [caml_array_bound_error] in r7 */ - ldr r7, =caml_array_bound_error + ldr r7, Loc(Pcaml_array_bound_error) /* Call that function */ - b caml_c_call + b Glo(caml_c_call) CFI_ENDPROC - .type caml_ml_array_bound_error, %function - .size caml_ml_array_bound_error, .-caml_ml_array_bound_error + .funtype Glo(caml_ml_array_bound_error) + .size Glo(caml_ml_array_bound_error), .-Glo(caml_ml_array_bound_error) - .globl caml_system__code_end -caml_system__code_end: + .globl Glo(caml_system__code_end) +Glo(caml_system__code_end): /* GC roots for callback */ .data .align 2 - .globl caml_system__frametable -caml_system__frametable: + .globl Glo(caml_system__frametable) +Glo(caml_system__frametable): .word 1 /* one descriptor */ - .word .Lcaml_retaddr /* return address into callback */ + .word Loc(caml_retaddr) /* return address into callback */ .short -1 /* negative frame size => use callback link */ .short 0 /* no roots */ .align 2 - .type caml_system__frametable, %object - .size caml_system__frametable, .-caml_system__frametable + .type Glo(caml_system__frametable), %object + .size Glo(caml_system__frametable), .-Glo(caml_system__frametable) + +/* Pool of addresses loaded into registers */ + + .text + .align 2 +Loc(Pcaml_last_return_address): + .long Glo(caml_last_return_address) +Loc(Pcaml_bottom_of_stack): + .long Glo(caml_bottom_of_stack) +Loc(Pcaml_gc_regs): + .long Glo(caml_gc_regs) +Loc(Pcaml_young_ptr): + .long Glo(caml_young_ptr) +Loc(Pcaml_exception_pointer): + .long Glo(caml_exception_pointer) +Loc(Pcaml_young_limit): + .long Glo(caml_young_limit) +Loc(Pcaml_program): + .long Glo(caml_program) +Loc(Ptrap_handler): + .long Loc(trap_handler) +Loc(Pcaml_backtrace_active): + .long Glo(caml_backtrace_active) +Loc(Pcaml_apply2): + .long Glo(caml_apply2) +Loc(Pcaml_apply3): + .long Glo(caml_apply3) +Loc(Pcaml_array_bound_error): + .long Glo(caml_array_bound_error) Index: asmrun/Makefile =================================================================== --- asmrun/Makefile (.../vendor/ocaml/4.01.0) (revision 112) +++ asmrun/Makefile (.../trunk/ocamlxarm/4.0) (revision 112) @@ -180,7 +180,8 @@ exit 2; } .S.p.o: - $(ASPP) -DSYS_$(SYSTEM) $(ASPPPROFFLAGS) -o $*.p.o $*.S + $(ASPP) -DSYS_$(SYSTEM) -DMODEL_$(MODEL) $(ASPPPROFFLAGS) \ + -o $*.p.o $*.S .c.d.o: ln -s -f $*.c $*.d.c