diff options
Diffstat (limited to 'asmcomp')
-rw-r--r-- | asmcomp/amd64/emit.mlp | 18 | ||||
-rw-r--r-- | asmcomp/amd64/proc.ml | 39 | ||||
-rw-r--r-- | asmcomp/arm/emit.mlp | 7 | ||||
-rw-r--r-- | asmcomp/arm/proc.ml | 36 | ||||
-rw-r--r-- | asmcomp/arm64/emit.mlp | 7 | ||||
-rw-r--r-- | asmcomp/arm64/proc.ml | 35 | ||||
-rw-r--r-- | asmcomp/i386/emit.mlp | 23 | ||||
-rw-r--r-- | asmcomp/i386/proc.ml | 30 | ||||
-rw-r--r-- | asmcomp/power/emit.mlp | 11 | ||||
-rw-r--r-- | asmcomp/power/proc.ml | 33 | ||||
-rw-r--r-- | asmcomp/printmach.ml | 2 | ||||
-rw-r--r-- | asmcomp/reg.ml | 1 | ||||
-rw-r--r-- | asmcomp/reg.mli | 23 | ||||
-rw-r--r-- | asmcomp/riscv/emit.mlp | 69 | ||||
-rw-r--r-- | asmcomp/riscv/proc.ml | 32 | ||||
-rw-r--r-- | asmcomp/s390x/emit.mlp | 9 | ||||
-rw-r--r-- | asmcomp/s390x/proc.ml | 25 |
17 files changed, 258 insertions, 142 deletions
diff --git a/asmcomp/amd64/emit.mlp b/asmcomp/amd64/emit.mlp index 16ff7f6161..eb38efbbe2 100644 --- a/asmcomp/amd64/emit.mlp +++ b/asmcomp/amd64/emit.mlp @@ -81,12 +81,13 @@ let frame_size env = (* includes return address *) let slot_offset env loc cl = match loc with - | Incoming n -> (frame_size env) + n + | Incoming n -> frame_size env + n | Local n -> if cl = 0 then env.stack_offset + n * 8 else env.stack_offset + (env.f.fun_num_stack_slots.(0) + n) * 8 | Outgoing n -> n + | Domainstate _ -> assert false (* not a stack slot *) (* Symbols *) @@ -171,14 +172,18 @@ let emit_Llabel env fallthrough lbl = (* Output a pseudo-register *) +let x86_data_type_for_stack_slot = function + | Float -> REAL8 + | _ -> QWORD + let reg env = function | { loc = Reg.Reg r } -> register_name r - | { loc = Stack s; typ = Float } as r -> - let ofs = slot_offset env s (register_class r) in - mem64 REAL8 ofs RSP - | { loc = Stack s } as r -> + | { loc = Stack(Domainstate n); typ = ty } -> + let ofs = n + Domainstate.(idx_of_field Domain_extra_params) * 8 in + mem64 (x86_data_type_for_stack_slot ty) ofs R14 + | { loc = Stack s; typ = ty } as r -> let ofs = slot_offset env s (register_class r) in - mem64 QWORD ofs RSP + mem64 (x86_data_type_for_stack_slot ty) ofs RSP | { loc = Unknown } -> assert false @@ -188,6 +193,7 @@ let reg64 = function let arg env i n = reg env i.arg.(n) let res env i n = reg env i.res.(n) + (* Output a reference to the lower 8, 16 or 32 bits of a register *) let reg_low_8_name = Array.map (fun r -> Reg8L r) int_reg_name diff --git a/asmcomp/amd64/proc.ml b/asmcomp/amd64/proc.ml index ed17640736..b7047a1ead 100644 --- a/asmcomp/amd64/proc.ml +++ b/asmcomp/amd64/proc.ml @@ -76,8 +76,6 @@ let win64 = Arch.win64 stub saves them into the GC regs block). *) -let max_arguments_for_tailcalls = 10 - let int_reg_name = match Config.ccomp_type with | "msvc" -> @@ -157,12 +155,15 @@ let word_addressed = false (* Calling conventions *) -let calling_conventions first_int last_int first_float last_float make_stack +let size_domainstate_args = 64 * size_int + +let calling_conventions first_int last_int first_float last_float + make_stack first_stack arg = let loc = Array.make (Array.length arg) Reg.dummy in let int = ref first_int in let float = ref first_float in - let ofs = ref 0 in + let ofs = ref first_stack in for i = 0 to Array.length arg - 1 do match arg.(i) with | Val | Int | Addr as ty -> @@ -183,21 +184,29 @@ let calling_conventions first_int last_int first_float last_float make_stack ofs := !ofs + size_float end done; - (loc, Misc.align !ofs 16) (* keep stack 16-aligned *) - -let incoming ofs = Incoming ofs -let outgoing ofs = Outgoing ofs + (loc, Misc.align (max 0 !ofs) 16) (* keep stack 16-aligned *) + +let incoming ofs = + if ofs >= 0 + then Incoming ofs + else Domainstate (ofs + size_domainstate_args) +let outgoing ofs = + if ofs >= 0 + then Outgoing ofs + else Domainstate (ofs + size_domainstate_args) let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" let loc_arguments arg = - calling_conventions 0 9 100 109 outgoing arg + calling_conventions 0 9 100 109 outgoing (- size_domainstate_args) arg let loc_parameters arg = let (loc, _ofs) = - calling_conventions 0 9 100 109 incoming arg - in - loc + calling_conventions 0 9 100 109 incoming (- size_domainstate_args) arg + in loc let loc_results res = - let (loc, _ofs) = calling_conventions 0 0 100 100 not_supported res in loc + let (loc, _ofs) = calling_conventions 0 0 100 100 not_supported 0 res + in loc + +let max_arguments_for_tailcalls = 10 (* in regs *) + 64 (* in domain state *) (* C calling conventions under Unix: first integer args in rdi, rsi, rdx, rcx, r8, r9 @@ -213,10 +222,10 @@ let loc_results res = Return value in rax or xmm0. *) let loc_external_results res = - let (loc, _ofs) = calling_conventions 0 0 100 100 not_supported res in loc + let (loc, _ofs) = calling_conventions 0 0 100 100 not_supported 0 res in loc let unix_loc_external_arguments arg = - calling_conventions 2 7 100 107 outgoing arg + calling_conventions 2 7 100 107 outgoing 0 arg let win64_int_external_arguments = [| 5 (*rcx*); 4 (*rdx*); 6 (*r8*); 7 (*r9*) |] diff --git a/asmcomp/arm/emit.mlp b/asmcomp/arm/emit.mlp index 350bcb7c3c..29d9c38ed6 100644 --- a/asmcomp/arm/emit.mlp +++ b/asmcomp/arm/emit.mlp @@ -74,13 +74,18 @@ let slot_offset env loc cl = | Outgoing n -> assert (n >= 0); n + | Domainstate _ -> assert false (* not a stack slot *) (* Output a stack reference *) let emit_stack env r = match r.loc with + | Stack (Domainstate n) -> + let ofs = n + Domainstate.(idx_of_field Domain_extra_params) * 8 in + `[domain_state_ptr, #{emit_int ofs}]` | Stack s -> - let ofs = slot_offset env s (register_class r) in `[sp, #{emit_int ofs}]` + let ofs = slot_offset env s (register_class r) in + `[sp, #{emit_int ofs}]` | _ -> fatal_error "Emit_arm.emit_stack" (* Output an addressing mode *) diff --git a/asmcomp/arm/proc.ml b/asmcomp/arm/proc.ml index 11313fce7f..e7e34f3618 100644 --- a/asmcomp/arm/proc.ml +++ b/asmcomp/arm/proc.ml @@ -109,6 +109,8 @@ let stack_slot slot ty = (* Calling conventions *) +let size_domainstate_args = 64 * size_int + let loc_int last_int make_stack int ofs = if !int <= last_int then begin let l = phys_reg !int in @@ -149,12 +151,12 @@ let loc_int_pair last_int make_stack int ofs = [| stack_lower; stack_upper |] end -let calling_conventions first_int last_int first_float last_float make_stack - arg = +let calling_conventions first_int last_int first_float last_float + make_stack first_stack arg = let loc = Array.make (Array.length arg) Reg.dummy in let int = ref first_int in let float = ref first_float in - let ofs = ref 0 in + let ofs = ref first_stack in for i = 0 to Array.length arg - 1 do match arg.(i) with | Val | Int | Addr -> @@ -162,28 +164,36 @@ let calling_conventions first_int last_int first_float last_float make_stack | Float -> loc.(i) <- loc_float last_float make_stack float ofs done; - (loc, Misc.align !ofs 8) (* keep stack 8-aligned *) - -let incoming ofs = Incoming ofs -let outgoing ofs = Outgoing ofs + (loc, Misc.align (max 0 !ofs) 8) (* keep stack 8-aligned *) + +let incoming ofs = + if ofs >= 0 + then Incoming ofs + else Domainstate (ofs + size_domainstate_args) +let outgoing ofs = + if ofs >= 0 + then Outgoing ofs + else Domainstate (ofs + size_domainstate_args) let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" (* OCaml calling convention: first integer args in r0...r7 first float args in d0...d15 (EABI+VFP) - remaining args on stack. + remaining args in domain state area, then on stack. Return values in r0...r7 or d0...d15. *) -let max_arguments_for_tailcalls = 8 +let max_arguments_for_tailcalls = 8 (* in regs *) + 64 (* in domain state *) let loc_arguments arg = - calling_conventions 0 7 100 115 outgoing arg + calling_conventions 0 7 100 115 outgoing (- size_domainstate_args) arg let loc_parameters arg = - let (loc, _) = calling_conventions 0 7 100 115 incoming arg in loc + let (loc, _) = + calling_conventions 0 7 100 115 incoming (- size_domainstate_args) arg + in loc let loc_results res = - let (loc, _) = calling_conventions 0 7 100 115 not_supported res in loc + let (loc, _) = calling_conventions 0 7 100 115 not_supported 0 res in loc (* C calling convention: first integer args in r0...r3 @@ -218,7 +228,7 @@ let loc_external_arguments ty_args = external_calling_conventions 0 3 100 107 outgoing ty_args let loc_external_results res = - let (loc, _) = calling_conventions 0 1 100 100 not_supported res + let (loc, _) = calling_conventions 0 1 100 100 not_supported 0 res in loc let loc_exn_bucket = phys_reg 0 diff --git a/asmcomp/arm64/emit.mlp b/asmcomp/arm64/emit.mlp index 9f0395e263..d3012f3b7f 100644 --- a/asmcomp/arm64/emit.mlp +++ b/asmcomp/arm64/emit.mlp @@ -104,13 +104,18 @@ let slot_offset env loc cl = | Outgoing n -> assert (n >= 0); n + | Domainstate _ -> assert false (* not a stack slot *) (* Output a stack reference *) let emit_stack env r = match r.loc with + | Stack (Domainstate n) -> + let ofs = n + Domainstate.(idx_of_field Domain_extra_params) * 8 in + `[{emit_reg reg_domain_state_ptr}, #{emit_int ofs}]` | Stack s -> - let ofs = slot_offset env s (register_class r) in `[sp, #{emit_int ofs}]` + let ofs = slot_offset env s (register_class r) in + `[sp, #{emit_int ofs}]` | _ -> fatal_error "Emit.emit_stack" (* Output an addressing mode *) diff --git a/asmcomp/arm64/proc.ml b/asmcomp/arm64/proc.ml index 7a6f10a69d..4a921875e3 100644 --- a/asmcomp/arm64/proc.ml +++ b/asmcomp/arm64/proc.ml @@ -107,6 +107,8 @@ let stack_slot slot ty = (* Calling conventions *) +let size_domainstate_args = 64 * size_int + let loc_int last_int make_stack int ofs = if !int <= last_int then begin let l = phys_reg !int in @@ -138,11 +140,11 @@ let loc_int32 last_int make_stack int ofs = end let calling_conventions - first_int last_int first_float last_float make_stack arg = + first_int last_int first_float last_float make_stack first_stack arg = let loc = Array.make (Array.length arg) Reg.dummy in let int = ref first_int in let float = ref first_float in - let ofs = ref 0 in + let ofs = ref first_stack in for i = 0 to Array.length arg - 1 do match arg.(i) with | Val | Int | Addr -> @@ -150,31 +152,40 @@ let calling_conventions | Float -> loc.(i) <- loc_float last_float make_stack float ofs done; - (loc, Misc.align !ofs 16) (* keep stack 16-aligned *) - -let incoming ofs = Incoming ofs -let outgoing ofs = Outgoing ofs + (loc, Misc.align (max 0 !ofs) 16) (* keep stack 16-aligned *) + +let incoming ofs = + if ofs >= 0 + then Incoming ofs + else Domainstate (ofs + size_domainstate_args) +let outgoing ofs = + if ofs >= 0 + then Outgoing ofs + else Domainstate (ofs + size_domainstate_args) let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" (* OCaml calling convention: first integer args in r0...r15 first float args in d0...d15 - remaining args on stack. + remaining args in domain state area, then on stack. Return values in r0...r15 or d0...d15. *) -let max_arguments_for_tailcalls = 16 +let max_arguments_for_tailcalls = 16 (* in regs *) + 64 (* in domain state *) + let last_int_register = if macosx then 7 else 15 let loc_arguments arg = - calling_conventions 0 last_int_register 100 115 outgoing arg + calling_conventions 0 last_int_register 100 115 + outgoing (- size_domainstate_args) arg let loc_parameters arg = let (loc, _) = - calling_conventions 0 last_int_register 100 115 incoming arg + calling_conventions 0 last_int_register 100 115 + incoming (- size_domainstate_args) arg in loc let loc_results res = let (loc, _) = - calling_conventions 0 last_int_register 100 115 not_supported res + calling_conventions 0 last_int_register 100 115 not_supported 0 res in loc @@ -208,7 +219,7 @@ let loc_external_arguments ty_args = external_calling_conventions 0 7 100 107 outgoing ty_args let loc_external_results res = - let (loc, _) = calling_conventions 0 1 100 100 not_supported res in loc + let (loc, _) = calling_conventions 0 1 100 100 not_supported 0 res in loc let loc_exn_bucket = phys_reg 0 diff --git a/asmcomp/i386/emit.mlp b/asmcomp/i386/emit.mlp index eb12cc96e5..b76af3687d 100644 --- a/asmcomp/i386/emit.mlp +++ b/asmcomp/i386/emit.mlp @@ -69,6 +69,7 @@ let slot_offset env loc cl = | Outgoing n -> assert (n >= 0); n + | Domainstate _ -> assert false (* not a stack slot *) (* Record symbols used and defined - at the end generate extern for those used but not defined *) @@ -138,16 +139,24 @@ let domain_field f r = let load_domain_state r = I.mov (sym32 "Caml_state") r +let x86_data_type_for_stack_slot = function + | Float -> REAL8 + | _ -> DWORD + +(* The Domainstate locations are mapped to a global array "caml_extra_params" + defined in runtime/i386*. We cannot access the domain state here + because in the i386 port there is no register that always point to the + domain state. A global array works because i386 does not + support multiple domains. *) + let reg env = function | { loc = Reg r } -> register_name r - | { loc = Stack(Incoming n | Outgoing n) } when n < 0 -> - sym32 "caml_extra_params" ~ofs:(n + 64) - | { loc = Stack s; typ = Float } as r -> - let ofs = slot_offset env s (register_class r) in - mem32 REAL8 ofs RSP - | { loc = Stack s } as r -> + | { loc = Stack(Domainstate n); typ = ty } -> + mem_sym (x86_data_type_for_stack_slot ty) + (emit_symbol "caml_extra_params") ~ofs:n + | { loc = Stack s; typ = ty } as r -> let ofs = slot_offset env s (register_class r) in - mem32 DWORD ofs RSP + mem32 (x86_data_type_for_stack_slot ty) ofs RSP | { loc = Unknown } -> fatal_error "Emit_i386.reg" diff --git a/asmcomp/i386/proc.ml b/asmcomp/i386/proc.ml index 53799397c4..fed3e678f9 100644 --- a/asmcomp/i386/proc.ml +++ b/asmcomp/i386/proc.ml @@ -101,23 +101,14 @@ let word_addressed = false (* Calling conventions *) -(* To supplement the processor's meagre supply of registers, we also - use some global memory locations to pass arguments beyond the 6th. - These globals are denoted by Incoming and Outgoing stack locations - with negative offsets, starting at -64. - Unlike arguments passed on stack, arguments passed in globals - do not prevent tail-call elimination. The caller stores arguments - in these globals immediately before the call, and the first thing the - callee does is copy them to registers or stack locations. - Neither GC nor thread context switches can occur between these two - times. *) +let size_domainstate_args = 64 * size_int let calling_conventions first_int last_int first_float last_float make_stack arg = let loc = Array.make (Array.length arg) Reg.dummy in let int = ref first_int in let float = ref first_float in - let ofs = ref (-64) in + let ofs = ref (- size_domainstate_args) in for i = 0 to Array.length arg - 1 do match arg.(i) with Val | Int | Addr as ty -> @@ -139,19 +130,26 @@ let calling_conventions first_int last_int first_float last_float make_stack done; (loc, Misc.align (max 0 !ofs) stack_alignment) -let incoming ofs = Incoming ofs -let outgoing ofs = Outgoing ofs +let incoming ofs = + if ofs >= 0 + then Incoming ofs + else Domainstate (ofs + size_domainstate_args) +let outgoing ofs = + if ofs >= 0 + then Outgoing ofs + else Domainstate (ofs + size_domainstate_args) let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" -(* Six arguments in integer registers plus eight in global memory. *) -let max_arguments_for_tailcalls = 14 - let loc_arguments arg = calling_conventions 0 5 100 99 outgoing arg let loc_parameters arg = let (loc, _ofs) = calling_conventions 0 5 100 99 incoming arg in loc let loc_results res = let (loc, _ofs) = calling_conventions 0 5 100 100 not_supported res in loc + +let max_arguments_for_tailcalls = + 6 (* in registers *) + 64 (* in domain state *) + let loc_external_arguments _arg = fatal_error "Proc.loc_external_arguments" let loc_external_results res = diff --git a/asmcomp/power/emit.mlp b/asmcomp/power/emit.mlp index 4ce02425d5..28d9023be1 100644 --- a/asmcomp/power/emit.mlp +++ b/asmcomp/power/emit.mlp @@ -49,15 +49,16 @@ let frame_size env = let slot_offset env loc cls = match loc with - Local n -> + | Local n -> reserved_stack_space + env.stack_offset + (if cls = 0 then env.f.fun_num_stack_slots.(1) * size_float + n * size_int else n * size_float) | Incoming n -> (* Callee's [reserved_stack_space] is included in [frame_size]. To access incoming arguments, add caller's [reserverd_stack_space]. *) - frame_size env + reserved_stack_space + n + frame_size env + reserved_stack_space + n | Outgoing n -> reserved_stack_space + n + | Domainstate _ -> assert false (* not a stack slot *) let retaddr_offset env = match abi with @@ -133,8 +134,12 @@ let emit_reg r = let emit_stack env r = match r.loc with + | Stack (Domainstate n) -> + let ofs = n + Domainstate.(idx_of_field Domain_extra_params) * 8 in + `{emit_int ofs}(30)` | Stack s -> - let ofs = slot_offset env s (register_class r) in `{emit_int ofs}(1)` + let ofs = slot_offset env s (register_class r) in + `{emit_int ofs}(1)` | _ -> Misc.fatal_error "Emit.emit_stack" (* Output the name of a symbol plus an optional offset *) diff --git a/asmcomp/power/proc.ml b/asmcomp/power/proc.ml index 2563d841b5..1a37578111 100644 --- a/asmcomp/power/proc.ml +++ b/asmcomp/power/proc.ml @@ -92,6 +92,8 @@ let stack_slot slot ty = (* Calling conventions *) +let size_domainstate_args = 64 * size_int + let loc_int last_int make_stack reg_use_stack int ofs = if !int <= last_int then begin let l = phys_reg !int in @@ -136,12 +138,12 @@ let loc_int_pair last_int make_stack int ofs = [| stack_lower; stack_upper |] end -let calling_conventions first_int last_int first_float last_float make_stack - arg = +let calling_conventions first_int last_int first_float last_float + make_stack first_stack arg = let loc = Array.make (Array.length arg) Reg.dummy in let int = ref first_int in let float = ref first_float in - let ofs = ref 0 in + let ofs = ref first_stack in for i = 0 to Array.length arg - 1 do match arg.(i) with | Val | Int | Addr -> @@ -149,23 +151,30 @@ let calling_conventions first_int last_int first_float last_float make_stack | Float -> loc.(i) <- loc_float last_float make_stack false int float ofs done; - (loc, Misc.align !ofs 16) (* keep stack 16-aligned *) - -let incoming ofs = Incoming ofs -let outgoing ofs = Outgoing ofs + (loc, Misc.align (max 0 !ofs) 16) (* keep stack 16-aligned *) + +let incoming ofs = + if ofs >= 0 + then Incoming ofs + else Domainstate (ofs + size_domainstate_args) +let outgoing ofs = + if ofs >= 0 + then Outgoing ofs + else Domainstate (ofs + size_domainstate_args) let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" -let max_arguments_for_tailcalls = 16 +let max_arguments_for_tailcalls = 16 (* in regs *) + 64 (* in domain state *) let loc_arguments arg = - calling_conventions 0 15 100 112 outgoing arg + calling_conventions 0 15 100 112 outgoing (- size_domainstate_args) arg let loc_parameters arg = - let (loc, _ofs) = calling_conventions 0 15 100 112 incoming arg + let (loc, _ofs) = + calling_conventions 0 15 100 112 incoming (- size_domainstate_args) arg in loc let loc_results res = - let (loc, _ofs) = calling_conventions 0 15 100 112 not_supported res + let (loc, _ofs) = calling_conventions 0 15 100 112 not_supported 0 res in loc (* C calling conventions for ELF32: @@ -244,7 +253,7 @@ let loc_external_arguments ty_args = (* Results are in GPR 3 and FPR 1 *) let loc_external_results res = - let (loc, _ofs) = calling_conventions 0 1 100 100 not_supported res + let (loc, _ofs) = calling_conventions 0 1 100 100 not_supported 0 res in loc (* Exceptions are in GPR 3 *) diff --git a/asmcomp/printmach.ml b/asmcomp/printmach.ml index a0afc1a48e..656f951185 100644 --- a/asmcomp/printmach.ml +++ b/asmcomp/printmach.ml @@ -38,6 +38,8 @@ let reg ppf r = fprintf ppf "[si%i]" s | Stack(Outgoing s) -> fprintf ppf "[so%i]" s + | Stack(Domainstate s) -> + fprintf ppf "[ds%i]" s end let regs ppf v = diff --git a/asmcomp/reg.ml b/asmcomp/reg.ml index 2311a529bb..29dcbf725d 100644 --- a/asmcomp/reg.ml +++ b/asmcomp/reg.ml @@ -56,6 +56,7 @@ and stack_location = Local of int | Incoming of int | Outgoing of int + | Domainstate of int type reg = t diff --git a/asmcomp/reg.mli b/asmcomp/reg.mli index ad462c20a2..38983279ea 100644 --- a/asmcomp/reg.mli +++ b/asmcomp/reg.mli @@ -42,6 +42,29 @@ and stack_location = Local of int | Incoming of int | Outgoing of int + | Domainstate of int + +(* The [stack_location] describes the location of pseudo-registers + that reside in memory. + - [Local] is a local variable or spilled register residing in the stack frame + of the current function + - [Incoming] is a function parameter that was passed on the stack. + This is the callee's view: the location is just above the callee's + stack frame, in the caller's stack frame. + - [Outgoing] is a function call argument that is passed on the stack. + This is the caller's view: the location is at the bottom of the + caller's stack frame. + - [Domainstate] is a function call argument that is passed not on stack + but in the [extra_params] section of the domain state + (see file [../runtime/caml/domain_state.*]). Unlike arguments passed + on stack, arguments passed via the domain state are compatible with + tail calls. However, domain state locations are shared between + all functions that run in a given domain, hence they are not preserved + by function calls or thread context switches. The caller stores + arguments in the domain state immediately before the call, and the + first thing the callee does is copy them to registers or [Local] + stack locations. Neither GC nor thread context switches can occur + between these two times. *) val dummy: t val create: Cmm.machtype_component -> t diff --git a/asmcomp/riscv/emit.mlp b/asmcomp/riscv/emit.mlp index a2b011f355..474a3c6857 100644 --- a/asmcomp/riscv/emit.mlp +++ b/asmcomp/riscv/emit.mlp @@ -39,12 +39,17 @@ let frame_size env = let slot_offset env loc cls = match loc with | Local n -> - if cls = 0 - then env.stack_offset + env.f.fun_num_stack_slots.(1) * size_float - + n * size_int - else env.stack_offset + n * size_float - | Incoming n -> frame_size env + n - | Outgoing n -> n + ("sp", + if cls = 0 + then env.stack_offset + env.f.fun_num_stack_slots.(1) * size_float + + n * size_int + else env.stack_offset + n * size_float) + | Incoming n -> + ("sp", frame_size env + n) + | Outgoing n -> + ("sp", n) + | Domainstate n -> + ("s11", n + Domainstate.(idx_of_field Domain_extra_params) * 8) (* Output a symbol *) @@ -108,38 +113,32 @@ let adjust_stack_offset env delta = env.stack_offset <- env.stack_offset + delta; cfi_adjust_cfa_offset delta -let emit_mem_op op src ofs = +let emit_mem_op ?(base = "sp") op src ofs = if is_immediate ofs then - ` {emit_string op} {emit_string src}, {emit_int ofs}(sp)\n` + ` {emit_string op} {emit_string src}, {emit_int ofs}({emit_string base})\n` else begin ` li {emit_reg reg_tmp}, {emit_int ofs}\n`; - ` add {emit_reg reg_tmp}, sp, {emit_reg reg_tmp}\n`; + ` add {emit_reg reg_tmp}, {emit_string base}, {emit_reg reg_tmp}\n`; ` {emit_string op} {emit_string src}, 0({emit_reg reg_tmp})\n` end -let emit_store src ofs = - emit_mem_op "sd" src ofs - -let emit_load dst ofs = - emit_mem_op "ld" dst ofs - let reload_ra n = - emit_load "ra" (n - size_addr) + emit_mem_op "ld" "ra" (n - size_addr) let store_ra n = - emit_store "ra" (n - size_addr) + emit_mem_op "sd" "ra" (n - size_addr) -let emit_store src ofs = - emit_store (reg_name src) ofs +let emit_store ?base src ofs = + emit_mem_op ?base "sd" (reg_name src) ofs -let emit_load dst ofs = - emit_load (reg_name dst) ofs +let emit_load ?base dst ofs = + emit_mem_op ?base "ld" (reg_name dst) ofs -let emit_float_load dst ofs = - emit_mem_op "fld" (reg_name dst) ofs +let emit_float_load ?base dst ofs = + emit_mem_op ?base "fld" (reg_name dst) ofs -let emit_float_store src ofs = - emit_mem_op "fsd" (reg_name src) ofs +let emit_float_store ?base src ofs = + emit_mem_op ?base "fsd" (reg_name src) ofs (* Record live pointers at call points *) @@ -151,7 +150,9 @@ let record_frame_label env live dbg = {typ = Val; loc = Reg r} -> live_offset := (r lsl 1) + 1 :: !live_offset | {typ = Val; loc = Stack s} as reg -> - live_offset := slot_offset env s (register_class reg) :: !live_offset + let (base, ofs) = slot_offset env s (register_class reg) in + assert (base = "sp"); + live_offset := ofs :: !live_offset | {typ = Addr} as r -> Misc.fatal_error ("bad GC root " ^ Reg.name r) | _ -> () @@ -259,17 +260,17 @@ let emit_instr env i = | {loc = Reg _; typ = Float}, {loc = Reg _; typ = (Val | Int | Addr)} -> ` fmv.x.d {emit_reg dst}, {emit_reg src}\n` | {loc = Reg _; typ = (Val | Int | Addr)}, {loc = Stack s} -> - let ofs = slot_offset env s (register_class dst) in - emit_store src ofs + let (base, ofs) = slot_offset env s (register_class dst) in + emit_store ~base src ofs | {loc = Reg _; typ = Float}, {loc = Stack s} -> - let ofs = slot_offset env s (register_class dst) in - emit_float_store src ofs + let (base, ofs) = slot_offset env s (register_class dst) in + emit_float_store ~base src ofs | {loc = Stack s; typ = (Val | Int | Addr)}, {loc = Reg _} -> - let ofs = slot_offset env s (register_class src) in - emit_load dst ofs + let (base, ofs) = slot_offset env s (register_class src) in + emit_load ~base dst ofs | {loc = Stack s; typ = Float}, {loc = Reg _} -> - let ofs = slot_offset env s (register_class src) in - emit_float_load dst ofs + let (base, ofs) = slot_offset env s (register_class src) in + emit_float_load ~base dst ofs | {loc = Stack _}, {loc = Stack _} | {loc = Unknown}, _ | _, {loc = Unknown} -> Misc.fatal_error "Emit: Imove" diff --git a/asmcomp/riscv/proc.ml b/asmcomp/riscv/proc.ml index 0b37de4c9e..1fdad2ae63 100644 --- a/asmcomp/riscv/proc.ml +++ b/asmcomp/riscv/proc.ml @@ -122,12 +122,14 @@ let stack_slot slot ty = (* Calling conventions *) +let size_domainstate_args = 64 * size_int + let calling_conventions - first_int last_int first_float last_float make_stack arg = + first_int last_int first_float last_float make_stack first_stack arg = let loc = Array.make (Array.length arg) Reg.dummy in let int = ref first_int in let float = ref first_float in - let ofs = ref 0 in + let ofs = ref first_stack in for i = 0 to Array.length arg - 1 do match arg.(i) with | Val | Int | Addr as ty -> @@ -147,32 +149,38 @@ let calling_conventions ofs := !ofs + size_float end done; - (loc, Misc.align !ofs 16) (* Keep stack 16-aligned. *) - -let incoming ofs = Incoming ofs -let outgoing ofs = Outgoing ofs + (loc, Misc.align (max 0 !ofs) 16) (* Keep stack 16-aligned. *) + +let incoming ofs = + if ofs >= 0 + then Incoming ofs + else Domainstate (ofs + size_domainstate_args) +let outgoing ofs = + if ofs >= 0 + then Outgoing ofs + else Domainstate (ofs + size_domainstate_args) let not_supported _ = fatal_error "Proc.loc_results: cannot call" -let max_arguments_for_tailcalls = 16 +let max_arguments_for_tailcalls = 16 (* in regs *) + 64 (* in domain state *) (* OCaml calling convention: first integer args in a0 .. a7, s2 .. s9 first float args in fa0 .. fa7, fs2 .. fs9 - remaining args on stack. + remaining args in domain state area, then on stack. Return values in a0 .. a7, s2 .. s9 or fa0 .. fa7, fs2 .. fs9. *) let loc_arguments arg = - calling_conventions 0 15 110 125 outgoing arg + calling_conventions 0 15 110 125 outgoing (- size_domainstate_args) arg let loc_parameters arg = let (loc, _ofs) = - calling_conventions 0 15 110 125 incoming arg + calling_conventions 0 15 110 125 incoming (- size_domainstate_args) arg in loc let loc_results res = let (loc, _ofs) = - calling_conventions 0 15 110 125 not_supported res + calling_conventions 0 15 110 125 not_supported 0 res in loc @@ -219,7 +227,7 @@ let loc_external_arguments ty_args = external_calling_conventions 0 7 110 117 outgoing arg let loc_external_results res = - let (loc, _ofs) = calling_conventions 0 1 110 111 not_supported res + let (loc, _ofs) = calling_conventions 0 1 110 111 not_supported 0 res in loc (* Exceptions are in a0 *) diff --git a/asmcomp/s390x/emit.mlp b/asmcomp/s390x/emit.mlp index 156084ea0c..5b2e5931dc 100644 --- a/asmcomp/s390x/emit.mlp +++ b/asmcomp/s390x/emit.mlp @@ -43,6 +43,7 @@ let slot_offset env loc cls = else env.stack_offset + n * size_float | Incoming n -> frame_size env + n | Outgoing n -> n + | Domainstate _ -> assert false (* not a stack slot *) (* Output a symbol *) @@ -93,8 +94,12 @@ let reg_r7 = check_phys_reg 5 "%r7" let emit_stack env r = match r.loc with - Stack s -> - let ofs = slot_offset env s (register_class r) in `{emit_int ofs}(%r15)` + | Stack (Domainstate n) -> + let ofs = n + Domainstate.(idx_of_field Domain_extra_params) * 8 in + `{emit_int ofs}(%r10)` + | Stack s -> + let ofs = slot_offset env s (register_class r) in + `{emit_int ofs}(%r15)` | _ -> fatal_error "Emit.emit_stack" diff --git a/asmcomp/s390x/proc.ml b/asmcomp/s390x/proc.ml index 3e15cf97c1..c9400e7c2d 100644 --- a/asmcomp/s390x/proc.ml +++ b/asmcomp/s390x/proc.ml @@ -96,6 +96,8 @@ let stack_slot slot ty = (* Calling conventions *) +let size_domainstate_args = 64 * size_int + let calling_conventions first_int last_int first_float last_float make_stack stack_ofs arg = let loc = Array.make (Array.length arg) Reg.dummy in @@ -121,19 +123,26 @@ let calling_conventions ofs := !ofs + size_float end done; - (loc, Misc.align !ofs 16) - (* Keep stack 16-aligned. *) - -let incoming ofs = Incoming ofs -let outgoing ofs = Outgoing ofs + (loc, Misc.align (max 0 !ofs) 16) (* Keep stack 16-aligned. *) + +let incoming ofs = + if ofs >= 0 + then Incoming ofs + else Domainstate (ofs + size_domainstate_args) +let outgoing ofs = + if ofs >= 0 + then Outgoing ofs + else Domainstate (ofs + size_domainstate_args) let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" -let max_arguments_for_tailcalls = 8 +let max_arguments_for_tailcalls = 8 (* in regs *) + 64 (* in domain state *) let loc_arguments arg = - calling_conventions 0 7 100 103 outgoing 0 arg + calling_conventions 0 7 100 103 outgoing (- size_domainstate_args) arg let loc_parameters arg = - let (loc, _ofs) = calling_conventions 0 7 100 103 incoming 0 arg in loc + let (loc, _ofs) = + calling_conventions 0 7 100 103 incoming (- size_domainstate_args) arg + in loc let loc_results res = let (loc, _ofs) = calling_conventions 0 7 100 103 not_supported 0 res in loc |