summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Leroy <xavierleroy@users.noreply.github.com>2020-07-28 16:40:55 +0200
committerEduardoRFS <theeduardorfs@gmail.com>2020-12-02 13:41:53 -0300
commit7b9612f12163b9657a2bb1b28c0cff4801e34579 (patch)
treebb8123c8adbacb8d4ebe75a3377b4ba868695d59
parentbdfca72d380d64691eb86302cd7daae7b17f3c24 (diff)
downloadocaml-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.md1
-rw-r--r--asmcomp/arm64/emit.mlp60
-rw-r--r--asmcomp/arm64/proc.ml11
-rw-r--r--asmcomp/arm64/selection.ml2
-rwxr-xr-xconfigure62
-rw-r--r--configure.ac8
-rw-r--r--runtime/arm64.S235
-rw-r--r--runtime/caml/s.h.in4
-rw-r--r--runtime/memprof.c2
-rw-r--r--runtime/signals_osdep.h10
-rw-r--r--runtime/sys.c7
-rw-r--r--testsuite/tools/asmgen_arm64.S14
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
diff --git a/configure b/configure
index 2aebfced80..ed4f946a85 100755
--- a/configure
+++ b/configure
@@ -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