diff options
author | Xavier Leroy <xavierleroy@users.noreply.github.com> | 2020-07-28 16:40:55 +0200 |
---|---|---|
committer | EduardoRFS <theeduardorfs@gmail.com> | 2020-12-02 13:41:53 -0300 |
commit | 7b9612f12163b9657a2bb1b28c0cff4801e34579 (patch) | |
tree | bb8123c8adbacb8d4ebe75a3377b4ba868695d59 | |
parent | bdfca72d380d64691eb86302cd7daae7b17f3c24 (diff) | |
download | ocaml-7b9612f12163b9657a2bb1b28c0cff4801e34579.tar.gz |
Merge pull request #9699 from EduardoRFS/trunk-ios
Add support for iOS and macOS on ARM64
-rw-r--r-- | asmcomp/arm64/NOTES.md | 1 | ||||
-rw-r--r-- | asmcomp/arm64/emit.mlp | 60 | ||||
-rw-r--r-- | asmcomp/arm64/proc.ml | 11 | ||||
-rw-r--r-- | asmcomp/arm64/selection.ml | 2 | ||||
-rwxr-xr-x | configure | 62 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | runtime/arm64.S | 235 | ||||
-rw-r--r-- | runtime/caml/s.h.in | 4 | ||||
-rw-r--r-- | runtime/memprof.c | 2 | ||||
-rw-r--r-- | runtime/signals_osdep.h | 10 | ||||
-rw-r--r-- | runtime/sys.c | 7 | ||||
-rw-r--r-- | testsuite/tools/asmgen_arm64.S | 14 |
12 files changed, 288 insertions, 128 deletions
diff --git a/asmcomp/arm64/NOTES.md b/asmcomp/arm64/NOTES.md index e2134eb18e..68ba2a5af0 100644 --- a/asmcomp/arm64/NOTES.md +++ b/asmcomp/arm64/NOTES.md @@ -10,3 +10,4 @@ Debian architecture name: `arm64`. _ARM Architecture Reference Manual, ARMv8_, restricted to the AArch64 subset. * Application binary interface: _Procedure Call Standard for the ARM 64-bit Architecture (AArch64)_ + _Apple ARM64 Function Calling Conventions_ diff --git a/asmcomp/arm64/emit.mlp b/asmcomp/arm64/emit.mlp index e401f7b0a4..636da014a9 100644 --- a/asmcomp/arm64/emit.mlp +++ b/asmcomp/arm64/emit.mlp @@ -38,18 +38,35 @@ let reg_trap_ptr = phys_reg 23 let reg_alloc_ptr = phys_reg 24 let reg_alloc_limit = phys_reg 25 let reg_tmp1 = phys_reg 26 -let reg_x15 = phys_reg 15 +let reg_x8 = phys_reg 8 (* Output a label *) +let label_prefix = + if macosx then "L" else ".L" + let emit_label lbl = - emit_string ".L"; emit_int lbl + emit_string label_prefix; emit_int lbl (* Symbols *) let emit_symbol s = + if macosx then emit_string "_"; Emitaux.emit_symbol '$' s +(* Object types *) + +let emit_symbol_type emit_lbl_or_sym lbl_or_sym ty = + if not macosx then begin + ` .type {emit_lbl_or_sym lbl_or_sym}, %{emit_string ty}\n` + end + + +let emit_symbol_size sym = + if not macosx then begin + ` .size {emit_symbol sym}, .-{emit_symbol sym}\n` + end + (* Output a pseudo-register *) let emit_reg = function @@ -320,6 +337,8 @@ let float_literal f = (* Emit all pending literals *) let emit_literals() = if !float_literals <> [] then begin + if macosx then + ` .section __TEXT,__literal8,8byte_literals\n`; ` .align 3\n`; List.iter (fun (f, lbl) -> @@ -331,7 +350,10 @@ let emit_literals() = (* Emit code to load the address of a symbol *) let emit_load_symbol_addr dst s = - if not !Clflags.dlcode then begin + if macosx then begin + ` adrp {emit_reg dst}, {emit_symbol s}@GOTPAGE\n`; + ` ldr {emit_reg dst}, [{emit_reg dst}, {emit_symbol s}@GOTPAGEOFF]\n` + end else if not !Clflags.dlcode then begin ` adrp {emit_reg dst}, {emit_symbol s}\n`; ` add {emit_reg dst}, {emit_reg dst}, #:lo12:{emit_symbol s}\n` end else begin @@ -566,7 +588,7 @@ let assembly_code_for_allocation ?label_after_call_gc i ~n ~far = | 16 -> ` bl {emit_symbol "caml_alloc1"}\n` | 24 -> ` bl {emit_symbol "caml_alloc2"}\n` | 32 -> ` bl {emit_symbol "caml_alloc3"}\n` - | _ -> emit_intconst reg_x15 (Nativeint.of_int n); + | _ -> emit_intconst reg_x8 (Nativeint.of_int n); ` bl {emit_symbol "caml_allocN"}\n` end; `{emit_label lbl_frame}: add {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, #8\n` @@ -581,6 +603,17 @@ let emit_named_text_section func_name = else ` .text\n` +(* Emit code to load an emitted literal *) + +let emit_load_literal dst lbl = + if macosx then begin + ` adrp {emit_reg reg_tmp1}, {emit_label lbl}@PAGE\n`; + ` ldr {emit_reg dst}, [{emit_reg reg_tmp1}, {emit_label lbl}@PAGEOFF]\n` + end else begin + ` adrp {emit_reg reg_tmp1}, {emit_label lbl}\n`; + ` ldr {emit_reg dst}, [{emit_reg reg_tmp1}, #:lo12:{emit_label lbl}]\n` + end + (* Output the assembly code for an instruction *) let emit_instr i = @@ -633,8 +666,7 @@ let emit_instr i = ` fmov {emit_reg i.res.(0)}, #{emit_printf "%.7f" (Int64.float_of_bits f)}\n` else begin let lbl = float_literal f in - ` adrp {emit_reg reg_tmp1}, {emit_label lbl}\n`; - ` ldr {emit_reg i.res.(0)}, [{emit_reg reg_tmp1}, #:lo12:{emit_label lbl}]\n` + emit_load_literal i.res.(0) lbl end | Lop(Iconst_symbol s) -> emit_load_symbol_addr i.res.(0) s @@ -654,7 +686,7 @@ let emit_instr i = | Lop(Iextcall { func; alloc = false; label_after = _; }) -> ` bl {emit_symbol func}\n` | Lop(Iextcall { func; alloc = true; label_after; }) -> - emit_load_symbol_addr reg_x15 func; + emit_load_symbol_addr reg_x8 func; ` bl {emit_symbol "caml_c_call"}\n`; `{record_frame i.live false i.dbg ~label:label_after}\n` | Lop(Istackoffset n) -> @@ -954,7 +986,7 @@ let fundecl fundecl = emit_named_text_section !function_name; ` .align 3\n`; ` .globl {emit_symbol fundecl.fun_name}\n`; - ` .type {emit_symbol fundecl.fun_name}, %function\n`; + emit_symbol_type emit_symbol fundecl.fun_name "function"; `{emit_symbol fundecl.fun_name}:\n`; emit_debug_info fundecl.fun_dbg; cfi_startproc(); @@ -972,8 +1004,8 @@ let fundecl fundecl = assert (List.length !call_gc_sites = num_call_gc); assert (List.length !bound_error_sites = num_check_bound); cfi_endproc(); - ` .type {emit_symbol fundecl.fun_name}, %function\n`; - ` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`; + emit_symbol_type emit_symbol fundecl.fun_name "function"; + emit_symbol_size fundecl.fun_name; emit_literals() (* Emission of data *) @@ -1036,10 +1068,10 @@ let end_assembly () = `{emit_symbol lbl}:\n`; emit_frames { efa_code_label = (fun lbl -> - ` .type {emit_label lbl}, %function\n`; + emit_symbol_type emit_label lbl "function"; ` .quad {emit_label lbl}\n`); efa_data_label = (fun lbl -> - ` .type {emit_label lbl}, %object\n`; + emit_symbol_type emit_label lbl "object"; ` .quad {emit_label lbl}\n`); efa_16 = (fun n -> ` .short {emit_int n}\n`); efa_32 = (fun n -> ` .long {emit_int32 n}\n`); @@ -1049,8 +1081,8 @@ let end_assembly () = ` .long {emit_label lbl} - . + {emit_int32 ofs}\n`); 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`; + emit_symbol_type emit_symbol lbl "object"; + emit_symbol_size lbl; begin match Config.system with | "linux" -> (* Mark stack as non-executable *) diff --git a/asmcomp/arm64/proc.ml b/asmcomp/arm64/proc.ml index f9c73f2fdb..c95bbb9442 100644 --- a/asmcomp/arm64/proc.ml +++ b/asmcomp/arm64/proc.ml @@ -99,7 +99,7 @@ let all_phys_regs = let phys_reg n = if n < 100 then hard_int_reg.(n) else hard_float_reg.(n - 100) -let reg_x15 = phys_reg 15 +let reg_x8 = phys_reg 8 let reg_d7 = phys_reg 107 let stack_slot slot ty = @@ -165,13 +165,14 @@ let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" Return values in r0...r15 or d0...d15. *) let max_arguments_for_tailcalls = 16 +let last_int_register = if macosx then 7 else 15 let loc_arguments arg = - calling_conventions 0 15 100 115 outgoing arg + calling_conventions 0 last_int_register 100 115 outgoing arg let loc_parameters arg = - let (loc, _) = calling_conventions 0 15 100 115 incoming arg in loc + let (loc, _) = calling_conventions 0 last_int_register 100 115 incoming arg in loc let loc_results res = - let (loc, _) = calling_conventions 0 15 100 115 not_supported res in loc + let (loc, _) = calling_conventions 0 last_int_register 100 115 not_supported res in loc (* C calling convention: first integer args in r0...r7 @@ -252,7 +253,7 @@ let destroyed_at_oper = function | Iop(Iextcall { alloc = false; }) -> destroyed_at_c_call | Iop(Ialloc _) -> - [| reg_x15 |] + [| reg_x8 |] | Iop(Iintoffloat | Ifloatofint | Iload(Single, _) | Istore(Single, _, _)) -> [| reg_d7 |] (* d7 / s7 destroyed *) | _ -> [||] diff --git a/asmcomp/arm64/selection.ml b/asmcomp/arm64/selection.ml index 8b1ce1b687..45305de739 100644 --- a/asmcomp/arm64/selection.ml +++ b/asmcomp/arm64/selection.ml @@ -83,7 +83,7 @@ let inline_ops = "caml_int64_direct_bswap"; "caml_nativeint_direct_bswap" ] let use_direct_addressing _symb = - not !Clflags.dlcode + (not !Clflags.dlcode) && (not Arch.macosx) let is_stack_slot rv = Reg.(match rv with @@ -2311,6 +2311,52 @@ rm -f conftest.val } # ac_fn_c_compute_int +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including @@ -13471,6 +13517,10 @@ if test x"$enable_shared" != "xno"; then : natdynlink=true ;; #( x86_64-*-linux*) : natdynlink=true ;; #( + arm64-*-darwin*) : + natdynlink=true ;; #( + aarch64-*-darwin*) : + natdynlink=true ;; #( x86_64-*-darwin*) : natdynlink=true ;; #( s390x*-*-linux*) : @@ -13640,6 +13690,10 @@ fi; system=elf ;; #( arch=amd64; system=netbsd ;; #( x86_64-*-openbsd*) : arch=amd64; system=openbsd ;; #( + arm64-*-darwin*) : + arch=arm64; system=macosx ;; #( + aarch64-*-darwin*) : + arch=arm64; system=macosx ;; #( x86_64-*-darwin*) : arch=amd64; system=macosx ;; #( x86_64-*-mingw32) : @@ -14275,6 +14329,14 @@ if test "x$ac_cv_func_getcwd" = xyes; then : fi +ac_fn_c_check_decl "$LINENO" "system" "ac_cv_have_decl_system" "#include <stdlib.h> +" +if test "x$ac_cv_have_decl_system" = xyes; then : + $as_echo "#define HAS_SYSTEM 1" >>confdefs.h + +fi + + ## utime ## Note: this was defined in config/s-nt.h but the autoconf macros do not # seem to detect it properly on Windows so we hardcode the definition diff --git a/configure.ac b/configure.ac index 05e9934b1e..9c7a2bd68b 100644 --- a/configure.ac +++ b/configure.ac @@ -818,6 +818,8 @@ AS_IF([test x"$enable_shared" != "xno"], [[i[3456]86-*-linux*]], [natdynlink=true], [[i[3456]86-*-gnu*]], [natdynlink=true], [[x86_64-*-linux*]], [natdynlink=true], + [arm64-*-darwin*], [natdynlink=true], + [aarch64-*-darwin*], [natdynlink=true], [x86_64-*-darwin*], [natdynlink=true], [s390x*-*-linux*], [natdynlink=true], [powerpc*-*-linux*], [natdynlink=true], @@ -920,6 +922,10 @@ AS_CASE([$host], [arch=amd64; system=netbsd], [x86_64-*-openbsd*], [arch=amd64; system=openbsd], + [arm64-*-darwin*], + [arch=arm64; system=macosx], + [aarch64-*-darwin*], + [arch=arm64; system=macosx], [x86_64-*-darwin*], [arch=amd64; system=macosx], [x86_64-*-mingw32], @@ -1168,6 +1174,8 @@ AC_CHECK_FUNC([mkfifo], [AC_DEFINE([HAS_MKFIFO])]) AC_CHECK_FUNC([getcwd], [AC_DEFINE([HAS_GETCWD])]) +AC_CHECK_DECL([system], [AC_DEFINE([HAS_SYSTEM])], [], [[#include <stdlib.h>]]) + ## utime ## Note: this was defined in config/s-nt.h but the autoconf macros do not # seem to detect it properly on Windows so we hardcode the definition diff --git a/runtime/arm64.S b/runtime/arm64.S index afcb3797a8..4ac88aa592 100644 --- a/runtime/arm64.S +++ b/runtime/arm64.S @@ -24,10 +24,9 @@ #define TRAP_PTR x26 #define ALLOC_PTR x27 #define ALLOC_LIMIT x28 -#define ARG x15 +#define ADDITIONAL_ARG x8 #define TMP x16 #define TMP2 x17 -#define ARG_DOMAIN_STATE_PTR x18 #define C_ARG_1 x0 #define C_ARG_2 x1 @@ -51,24 +50,47 @@ #endif .set domain_curr_field, 0 +#if defined(SYS_macosx) +#define DOMAIN_STATE(c_type, name) DOMAIN_STATE c_type, name + .macro DOMAIN_STATE c_type, name + .equ domain_field_caml_\name, domain_curr_field + .set domain_curr_field, domain_curr_field + 1 + .endm +#else #define DOMAIN_STATE(c_type, name) \ .equ domain_field_caml_##name, domain_curr_field ; \ .set domain_curr_field, domain_curr_field + 1 +#endif #include "../runtime/caml/domain_state.tbl" #undef DOMAIN_STATE #define Caml_state(var) [x25, 8*domain_field_caml_##var] -#if defined(__PIC__) +/* Globals and labels */ +#if defined(SYS_macosx) +#define G(sym) _##sym +#define L(lbl) L##lbl +#else +#define G(sym) sym +#define L(lbl) .L##lbl +#endif + +#if defined(SYS_macosx) +#define ADDRGLOBAL(reg,symb) ADDRGLOBAL reg, symb + .macro ADDRGLOBAL reg, symb + adrp TMP2, G(\symb)@GOTPAGE + ldr \reg, [TMP2, G(\symb)@GOTPAGEOFF] + .endm +#elif defined(__PIC__) #define ADDRGLOBAL(reg,symb) \ - adrp TMP2, :got:symb; \ - ldr reg, [TMP2, #:got_lo12:symb] + adrp TMP2, :got:G(symb); \ + ldr reg, [TMP2, #:got_lo12:G(symb)] #else #define ADDRGLOBAL(reg,symb) \ - adrp reg, symb; \ - add reg, reg, #:lo12:symb + adrp reg, G(symb); \ + add reg, reg, #:lo12:G(symb) #endif @@ -80,24 +102,58 @@ #if defined(FUNCTION_SECTIONS) TEXT_SECTION(caml_hot__code_begin) - .globl caml_hot__code_begin -caml_hot__code_begin: + .globl G(caml_hot__code_begin) +G(caml_hot__code_begin): TEXT_SECTION(caml_hot__code_end) - .globl caml_hot__code_end -caml_hot__code_end: + .globl G(caml_hot__code_end) +G(caml_hot__code_end): #endif +#if defined(SYS_macosx) + +#define FUNCTION(name) FUNCTION name + .macro FUNCTION name + TEXT_SECTION(caml.##G(\name)) + .align 2 + .globl G(\name) +G(\name): + .endm +#define END_FUNCTION(name) + +#define OBJECT(name) OBJECT name + .macro OBJECT name + .data + .align 3 + .globl G(\name) +G(\name): + .endm +#define END_OBJECT(name) + +#else + #define FUNCTION(name) \ TEXT_SECTION(caml.##name); \ - .align 2; \ - .globl name; \ - .type name, %function; \ -name: + .align 2; \ + .globl G(name); \ + .type G(name), %function; \ +G(name): +#define END_FUNCTION(name) \ + .size G(name), .-G(name) + +#define OBJECT(name) \ + .data; \ + .align 3; \ + .globl G(name); \ + .type G(name), %object; \ +G(name): +#define END_OBJECT(name) \ + .size G(name), .-G(name) +#endif /* Allocation functions and GC interface */ - .globl caml_system__code_begin -caml_system__code_begin: + .globl G(caml_system__code_begin) +G(caml_system__code_begin): FUNCTION(caml_call_gc) CFI_STARTPROC @@ -106,7 +162,7 @@ FUNCTION(caml_call_gc) /* Record lowest stack address */ mov TMP, sp str TMP, Caml_state(bottom_of_stack) -.Lcaml_call_gc: +L(caml_call_gc): /* Set up stack space, saving return address and frame pointer */ /* (2 regs RA/GP, 24 allocatable int regs, 24 caller-save float regs) * 8 */ CFI_OFFSET(29, -400) @@ -150,7 +206,7 @@ FUNCTION(caml_call_gc) /* Save trap pointer in case an exception is raised during GC */ str TRAP_PTR, Caml_state(exception_pointer) /* Call the garbage collector */ - bl caml_garbage_collection + bl G(caml_garbage_collection) /* Restore registers */ ldp x0, x1, [sp, 16] ldp x2, x3, [sp, 32] @@ -183,7 +239,7 @@ FUNCTION(caml_call_gc) ldp x29, x30, [sp], 400 ret CFI_ENDPROC - .size caml_call_gc, .-caml_call_gc + END_FUNCTION(caml_call_gc) FUNCTION(caml_alloc1) CFI_STARTPROC @@ -206,19 +262,16 @@ FUNCTION(caml_alloc1) /* Record return address */ str x30, Caml_state(last_return_address) /* Call GC */ - bl .Lcaml_call_gc + bl L(caml_call_gc) /* Restore return address */ ldp x29, x30, [sp], 16 CFI_ADJUST(-16) /* Try again */ b 1b CFI_ENDPROC - .type caml_alloc1, %function - .size caml_alloc1, .-caml_alloc1 + END_FUNCTION(caml_alloc1) - .align 2 - .globl caml_alloc2 -caml_alloc2: +FUNCTION(caml_alloc2) CFI_STARTPROC 1: sub ALLOC_PTR, ALLOC_PTR, #24 cmp ALLOC_PTR, ALLOC_LIMIT @@ -235,15 +288,14 @@ caml_alloc2: /* Record return address */ str x30, Caml_state(last_return_address) /* Call GC */ - bl .Lcaml_call_gc + bl L(caml_call_gc) /* Restore return address */ ldp x29, x30, [sp], 16 CFI_ADJUST(-16) /* Try again */ b 1b CFI_ENDPROC - .type caml_alloc2, %function - .size caml_alloc2, .-caml_alloc2 + END_FUNCTION(caml_alloc2) FUNCTION(caml_alloc3) CFI_STARTPROC @@ -262,26 +314,22 @@ FUNCTION(caml_alloc3) /* Record return address */ str x30, Caml_state(last_return_address) /* Call GC */ - bl .Lcaml_call_gc + bl L(caml_call_gc) /* Restore return address */ ldp x29, x30, [sp], 16 CFI_ADJUST(-16) /* Try again */ b 1b CFI_ENDPROC - .type caml_alloc3, %function - .size caml_alloc3, .-caml_alloc3 + END_FUNCTION(caml_alloc3) - TEXT_SECTION(caml_allocN) - .align 2 - .globl caml_allocN -caml_allocN: +FUNCTION(caml_allocN) CFI_STARTPROC -1: sub ALLOC_PTR, ALLOC_PTR, ARG +1: sub ALLOC_PTR, ALLOC_PTR, ADDITIONAL_ARG cmp ALLOC_PTR, ALLOC_LIMIT b.lo 2f ret -2: add ALLOC_PTR, ALLOC_PTR, ARG +2: add ALLOC_PTR, ALLOC_PTR, ADDITIONAL_ARG stp x29, x30, [sp, -16]! CFI_ADJUST(16) /* Record the lowest address of the caller's stack frame. @@ -292,17 +340,17 @@ caml_allocN: /* Record return address */ str x30, Caml_state(last_return_address) /* Call GC. This preserves ARG */ - bl .Lcaml_call_gc + bl L(caml_call_gc) /* Restore return address */ ldp x29, x30, [sp], 16 CFI_ADJUST(-16) /* Try again */ b 1b CFI_ENDPROC - .size caml_allocN, .-caml_allocN + END_FUNCTION(caml_allocN) /* Call a C function from OCaml */ -/* Function to call is in ARG */ +/* Function to call is in ADDITIONAL_ARG */ FUNCTION(caml_c_call) CFI_STARTPROC @@ -317,27 +365,28 @@ FUNCTION(caml_c_call) str ALLOC_PTR, Caml_state(young_ptr) str TRAP_PTR, Caml_state(exception_pointer) /* Call the function */ - blr ARG + blr ADDITIONAL_ARG /* Reload alloc ptr and alloc limit */ ldr ALLOC_PTR, Caml_state(young_ptr) ldr ALLOC_LIMIT, Caml_state(young_limit) /* Return */ ret x19 CFI_ENDPROC - .size caml_c_call, .-caml_c_call + END_FUNCTION(caml_c_call) /* Start the OCaml program */ FUNCTION(caml_start_program) CFI_STARTPROC - mov ARG_DOMAIN_STATE_PTR, C_ARG_1 - ADDRGLOBAL(ARG, caml_program) + mov TMP, C_ARG_1 + ADDRGLOBAL(TMP2, caml_program) /* Code shared with caml_callback* */ -/* Address of OCaml code to call is in ARG */ +/* Address of domain state is in TMP */ +/* Address of OCaml code to call is in TMP2 */ /* Arguments to the OCaml code are in x0...x7 */ -.Ljump_to_caml: +L(jump_to_caml): /* Set up stack frame and save callee-save registers */ CFI_OFFSET(29, -160) CFI_OFFSET(30, -152) @@ -354,7 +403,7 @@ FUNCTION(caml_start_program) stp d12, d13, [sp, 128] stp d14, d15, [sp, 144] /* Load domain state pointer from argument */ - mov DOMAIN_STATE_PTR, ARG_DOMAIN_STATE_PTR + mov DOMAIN_STATE_PTR, TMP /* Setup a callback link on the stack */ ldr x8, Caml_state(bottom_of_stack) ldr x9, Caml_state(last_return_address) @@ -364,7 +413,7 @@ FUNCTION(caml_start_program) str x10, [sp, 16] /* Setup a trap frame to catch exceptions escaping the OCaml code */ ldr x8, Caml_state(exception_pointer) - adr x9, .Ltrap_handler + adr x9, L(trap_handler) stp x8, x9, [sp, -16]! CFI_ADJUST(16) add TRAP_PTR, sp, #0 @@ -372,14 +421,14 @@ FUNCTION(caml_start_program) ldr ALLOC_PTR, Caml_state(young_ptr) ldr ALLOC_LIMIT, Caml_state(young_limit) /* Call the OCaml code */ - blr ARG -.Lcaml_retaddr: + blr TMP2 +L(caml_retaddr): /* Pop the trap frame, restoring caml_exception_pointer */ ldr x8, [sp], 16 CFI_ADJUST(-16) str x8, Caml_state(exception_pointer) /* Pop the callback link, restoring the global variables */ -.Lreturn_result: +L(return_result): ldr x10, [sp, 16] ldp x8, x9, [sp], 32 CFI_ADJUST(-32) @@ -403,24 +452,20 @@ FUNCTION(caml_start_program) /* Return to C caller */ ret CFI_ENDPROC - .type .Lcaml_retaddr, %function - .size .Lcaml_retaddr, .-.Lcaml_retaddr - .size caml_start_program, .-caml_start_program + END_FUNCTION(caml_start_program) /* The trap handler */ .align 2 -.Ltrap_handler: +L(trap_handler): CFI_STARTPROC /* Save exception pointer */ str TRAP_PTR, Caml_state(exception_pointer) /* Encode exception bucket as an exception result */ orr x0, x0, #2 /* Return it */ - b .Lreturn_result + b L(return_result) CFI_ENDPROC - .type .Ltrap_handler, %function - .size .Ltrap_handler, .-.Ltrap_handler /* Raise an exception from OCaml */ @@ -442,12 +487,12 @@ FUNCTION(caml_raise_exn) mov x1, x30 /* arg2: pc of raise */ add x2, sp, #0 /* arg3: sp of raise */ mov x3, TRAP_PTR /* arg4: sp of handler */ - bl caml_stash_backtrace + bl G(caml_stash_backtrace) /* Restore exception bucket and raise */ mov x0, x19 b 1b CFI_ENDPROC - .size caml_raise_exn, .-caml_raise_exn + END_FUNCTION(caml_raise_exn) /* Raise an exception from C */ @@ -477,12 +522,12 @@ FUNCTION(caml_raise_exception) ldr x1, Caml_state(last_return_address) /* arg2: pc of raise */ ldr x2, Caml_state(bottom_of_stack) /* arg3: sp of raise */ mov x3, TRAP_PTR /* arg4: sp of handler */ - bl caml_stash_backtrace + bl G(caml_stash_backtrace) /* Restore exception bucket and raise */ mov x0, x19 b 1b CFI_ENDPROC - .size caml_raise_exception, .-caml_raise_exception + END_FUNCTION(caml_raise_exception) /* Callback from C to OCaml */ @@ -490,74 +535,64 @@ FUNCTION(caml_callback_asm) CFI_STARTPROC /* Initial shuffling of arguments */ /* (x0 = Caml_state, x1 = closure, [x2] = first arg) */ - mov ARG_DOMAIN_STATE_PTR, x0 + mov TMP, x0 ldr x0, [x2] /* x0 = first arg */ /* x1 = closure environment */ - ldr ARG, [x1] /* code pointer */ - b .Ljump_to_caml + ldr TMP2, [x1] /* code pointer */ + b L(jump_to_caml) CFI_ENDPROC - .type caml_callback_asm, %function - .size caml_callback_asm, .-caml_callback_asm + END_FUNCTION(caml_callback_asm) - TEXT_SECTION(caml_callback2_asm) - .align 2 - .globl caml_callback2_asm -caml_callback2_asm: +FUNCTION(caml_callback2_asm) CFI_STARTPROC /* Initial shuffling of arguments */ /* (x0 = Caml_state, x1 = closure, [x2] = arg1, [x2,8] = arg2) */ - mov ARG_DOMAIN_STATE_PTR, x0 - mov TMP, x1 + mov TMP, x0 + mov TMP2, x1 ldp x0, x1, [x2, 0] /* x0 = first arg, x1 = second arg */ - mov x2, TMP /* x2 = closure environment */ - ADDRGLOBAL(ARG, caml_apply2) - b .Ljump_to_caml + mov x2, TMP2 /* x2 = closure environment */ + ADDRGLOBAL(TMP2, caml_apply2) + b L(jump_to_caml) CFI_ENDPROC - .type caml_callback2_asm, %function - .size caml_callback2_asm, .-caml_callback2_asm + END_FUNCTION(caml_callback2_asm) - TEXT_SECTION(caml_callback3_asm) - .align 2 - .globl caml_callback3_asm -caml_callback3_asm: +FUNCTION(caml_callback3_asm) CFI_STARTPROC /* Initial shuffling of arguments */ /* (x0 = Caml_state, x1 = closure, [x2] = arg1, [x2,8] = arg2, [x2,16] = arg3) */ - mov ARG_DOMAIN_STATE_PTR, x0 + mov TMP, x0 mov x3, x1 /* x3 = closure environment */ ldp x0, x1, [x2, 0] /* x0 = first arg, x1 = second arg */ ldr x2, [x2, 16] /* x2 = third arg */ - ADDRGLOBAL(ARG, caml_apply3) - b .Ljump_to_caml + ADDRGLOBAL(TMP2, caml_apply3) + b L(jump_to_caml) CFI_ENDPROC - .size caml_callback3_asm, .-caml_callback3_asm + END_FUNCTION(caml_callback3_asm) FUNCTION(caml_ml_array_bound_error) CFI_STARTPROC - /* Load address of [caml_array_bound_error] in ARG */ - ADDRGLOBAL(ARG, caml_array_bound_error) + /* Load address of [caml_array_bound_error] in ADDITIONAL_ARG */ + ADDRGLOBAL(ADDITIONAL_ARG, caml_array_bound_error) /* Call that function */ - b caml_c_call + b G(caml_c_call) CFI_ENDPROC - .size caml_ml_array_bound_error, .-caml_ml_array_bound_error + END_FUNCTION(caml_ml_array_bound_error) - .globl caml_system__code_end -caml_system__code_end: + .globl G(caml_system__code_end) +G(caml_system__code_end): /* GC roots for callback */ - .data - .align 3 - .globl caml_system__frametable -caml_system__frametable: +OBJECT(caml_system__frametable) .quad 1 /* one descriptor */ - .quad .Lcaml_retaddr /* return address into callback */ + .quad L(caml_retaddr) /* return address into callback */ .short -1 /* negative frame size => use callback link */ .short 0 /* no roots */ .align 3 - .type caml_system__frametable, %object - .size caml_system__frametable, .-caml_system__frametable + END_OBJECT(caml_system__frametable) +#if !defined(SYS_macosx) /* Mark stack as non-executable */ .section .note.GNU-stack,"",%progbits +#endif diff --git a/runtime/caml/s.h.in b/runtime/caml/s.h.in index b618309d62..8cd0e180d0 100644 --- a/runtime/caml/s.h.in +++ b/runtime/caml/s.h.in @@ -106,6 +106,10 @@ /* Define HAS_GETCWD if the library provides the getcwd() function. */ +#undef HAS_SYSTEM + +/* Define HAS_SYSTEM if the library provides the system() function. */ + #undef HAS_UTIME #undef HAS_UTIMES diff --git a/runtime/memprof.c b/runtime/memprof.c index 4aba3ef91a..b76ba1a88f 100644 --- a/runtime/memprof.c +++ b/runtime/memprof.c @@ -98,7 +98,7 @@ static uintnat mt_generate_geom() bounded by the entropy provided by [mt_generate_uniform], which is 32bits. */ double res = 1 + logf(mt_generate_uniform()) * one_log1m_lambda; - if (res > Max_long) return Max_long; + if (res > (double)Max_long) return Max_long; return (uintnat)res; } diff --git a/runtime/signals_osdep.h b/runtime/signals_osdep.h index d507d5a6a6..4cdf92307a 100644 --- a/runtime/signals_osdep.h +++ b/runtime/signals_osdep.h @@ -47,8 +47,9 @@ #include <sys/ucontext.h> #include <AvailabilityMacros.h> - #if !defined(MAC_OS_X_VERSION_10_5) \ - || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + #if (!defined(MAC_OS_X_VERSION_10_5) \ + || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) \ + && !defined(__IPHONE_OS_VERSION_MIN_REQUIRED) #define CONTEXT_REG(r) r #else #define CONTEXT_REG(r) __##r @@ -249,8 +250,9 @@ #include <sys/ucontext.h> #include <AvailabilityMacros.h> - #if !defined(MAC_OS_X_VERSION_10_5) \ - || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + #if (!defined(MAC_OS_X_VERSION_10_5) \ + || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) \ + && !defined(__IPHONE_OS_VERSION_MIN_REQUIRED) #define CONTEXT_REG(r) r #else #define CONTEXT_REG(r) __##r diff --git a/runtime/sys.c b/runtime/sys.c index ab4704e509..d5636199c9 100644 --- a/runtime/sys.c +++ b/runtime/sys.c @@ -428,6 +428,7 @@ void caml_sys_init(char_os * exe_name, char_os **argv) #endif #endif +#ifdef HAS_SYSTEM CAMLprim value caml_sys_system_command(value command) { CAMLparam1 (command); @@ -450,6 +451,12 @@ CAMLprim value caml_sys_system_command(value command) retcode = 255; CAMLreturn (Val_int(retcode)); } +#else +CAMLprim value caml_sys_system_command(value command) +{ + caml_invalid_argument("Sys.command not implemented"); +} +#endif double caml_sys_time_include_children_unboxed(value include_children) { diff --git a/testsuite/tools/asmgen_arm64.S b/testsuite/tools/asmgen_arm64.S index 4b803d20b1..6a06f8d7e2 100644 --- a/testsuite/tools/asmgen_arm64.S +++ b/testsuite/tools/asmgen_arm64.S @@ -13,9 +13,15 @@ /* */ /**************************************************************************/ - .globl call_gen_code +#if defined(SYS_macosx) +#define G(sym) _##sym +#else +#define G(sym) sym +#endif + + .globl G(call_gen_code) .align 2 -call_gen_code: +G(call_gen_code): /* Set up stack frame and save callee-save registers */ stp x29, x30, [sp, -160]! add x29, sp, #0 @@ -51,8 +57,10 @@ call_gen_code: .globl caml_c_call .align 2 -caml_c_call: +G(caml_c_call): br x15 +#if !defined(SYS_macosx) /* Mark stack as non-executable */ .section .note.GNU-stack,"",%progbits +#endif |