Skip to content

Commit b8a8439

Browse files
committed
Refactoring calling conventions.
1 parent 7d862d0 commit b8a8439

File tree

3 files changed

+124
-77
lines changed

3 files changed

+124
-77
lines changed

backend/amd64/proc.ml

+113-77
Original file line numberDiff line numberDiff line change
@@ -138,58 +138,112 @@ let word_addressed = false
138138

139139
let size_domainstate_args = 64 * size_int
140140

141+
module Hardware_registers : sig
142+
type t
143+
val make : int list -> t
144+
val take : t -> int option
145+
end = struct
146+
type t = int list ref
147+
let make l = ref l
148+
let take t =
149+
match !t with
150+
| [] -> None
151+
| hd :: tl -> t := tl; Some hd
152+
end
153+
154+
module Pseudo_registers : sig
155+
type t
156+
val make : ty:machtype_component -> stack_align: int option -> stack_size:int -> make_stack:(int -> Reg.stack_location) -> available_registers:Hardware_registers.t -> check:(Reg.t -> unit) -> t
157+
val allocate : t -> int ref -> Reg.t
158+
end = struct
159+
type t = {
160+
ty : machtype_component;
161+
stack_align : int option;
162+
stack_size : int;
163+
make_stack : int -> Reg.stack_location;
164+
available_registers : Hardware_registers.t;
165+
check : Reg.t -> unit;
166+
}
167+
let make : ty:machtype_component -> stack_align:int option -> stack_size:int -> make_stack:(int -> Reg.stack_location) -> available_registers:Hardware_registers.t -> check:(Reg.t -> unit) -> t
168+
= fun ~ty ~stack_align ~stack_size ~make_stack ~available_registers ~check ->
169+
{ ty; stack_align; stack_size; make_stack; available_registers; check; }
170+
let allocate t ofs =
171+
let res =
172+
match Hardware_registers.take t.available_registers with
173+
| Some reg -> phys_reg t.ty reg
174+
| None ->
175+
begin match t.stack_align with
176+
| None -> ()
177+
| Some alignment -> ofs := Misc.align !ofs alignment
178+
end;
179+
let slot = stack_slot (t.make_stack !ofs) t.ty in
180+
ofs := !ofs + t.stack_size;
181+
slot
182+
in
183+
t.check res;
184+
res
185+
end
186+
187+
module MachtypeComponentTbl = Hashtbl.Make (struct
188+
type t = Cmm.machtype_component
189+
let hash = Cmm.hash_machtype_component
190+
let equal = Cmm.equal_machtype_component
191+
end)
192+
141193
let calling_conventions
142-
~first_int
143-
~last_int
144-
~step_int
145-
~first_float
146-
~last_float
147-
~make_stack
148-
~first_stack
194+
~(int_registers : int list)
195+
~(float_registers : int list)
196+
~(make_stack : int -> Reg.stack_location)
197+
~(first_stack : int)
149198
arg =
150199
let loc = Array.make (Array.length arg) Reg.dummy in
151-
let int = ref first_int in
152-
let float = ref first_float in
200+
let int_registers = Hardware_registers.make int_registers in
201+
let float_registers = Hardware_registers.make float_registers in
153202
let ofs = ref first_stack in
203+
let not_destroyed_by_plt_stub reg =
204+
assert (not (Reg.Set.mem reg destroyed_by_plt_stub_set))
205+
in
206+
let pseudo_registers = MachtypeComponentTbl.create 8 in
207+
MachtypeComponentTbl.replace
208+
pseudo_registers
209+
Val
210+
(Pseudo_registers.make
211+
~ty:Val ~stack_align:None ~stack_size:size_int ~make_stack
212+
~available_registers:int_registers ~check:not_destroyed_by_plt_stub);
213+
MachtypeComponentTbl.replace
214+
pseudo_registers
215+
Int
216+
(Pseudo_registers.make
217+
~ty:Int ~stack_align:None ~stack_size:size_int ~make_stack
218+
~available_registers:int_registers ~check:not_destroyed_by_plt_stub);
219+
MachtypeComponentTbl.replace
220+
pseudo_registers
221+
Addr
222+
(Pseudo_registers.make
223+
~ty:Addr ~stack_align:None ~stack_size:size_int ~make_stack
224+
~available_registers:int_registers ~check:not_destroyed_by_plt_stub);
225+
MachtypeComponentTbl.replace
226+
pseudo_registers
227+
Float
228+
(Pseudo_registers.make
229+
~ty:Float ~stack_align:None ~stack_size:size_float ~make_stack
230+
~available_registers:float_registers ~check:ignore);
231+
MachtypeComponentTbl.replace
232+
pseudo_registers
233+
Vec128
234+
(Pseudo_registers.make
235+
~ty:Vec128 ~stack_align:(Some 16) ~stack_size:size_vec128 ~make_stack
236+
~available_registers:float_registers ~check:ignore);
237+
MachtypeComponentTbl.replace
238+
pseudo_registers
239+
Float32
240+
(Pseudo_registers.make
241+
~ty:Float32 ~stack_align:None ~stack_size:size_float ~make_stack
242+
~available_registers:float_registers ~check:ignore);
154243
for i = 0 to Array.length arg - 1 do
155-
match (arg.(i) : machtype_component) with
156-
| Val | Int | Addr as ty ->
157-
if !int <= last_int then begin
158-
loc.(i) <- phys_reg ty !int;
159-
int := !int + step_int
160-
end else begin
161-
loc.(i) <- stack_slot (make_stack !ofs) ty;
162-
ofs := !ofs + size_int
163-
end;
164-
assert (not (Reg.Set.mem loc.(i) destroyed_by_plt_stub_set))
165-
| Float ->
166-
if !float <= last_float then begin
167-
loc.(i) <- phys_reg Float !float;
168-
incr float
169-
end else begin
170-
loc.(i) <- stack_slot (make_stack !ofs) Float;
171-
ofs := !ofs + size_float
172-
end
173-
| Vec128 ->
174-
if !float <= last_float then begin
175-
loc.(i) <- phys_reg Vec128 !float;
176-
incr float
177-
end else begin
178-
ofs := Misc.align !ofs 16;
179-
loc.(i) <- stack_slot (make_stack !ofs) Vec128;
180-
ofs := !ofs + size_vec128
181-
end
182-
| Valx2 ->
183-
Misc.fatal_error "Unexpected machtype_component Valx2"
184-
| Float32 ->
185-
if !float <= last_float then begin
186-
loc.(i) <- phys_reg Float32 !float;
187-
incr float
188-
end else begin
189-
loc.(i) <- stack_slot (make_stack !ofs) Float32;
190-
(* float32 slots still take up a full word *)
191-
ofs := !ofs + size_float
192-
end
244+
match MachtypeComponentTbl.find_opt pseudo_registers arg.(i) with
245+
| Some pseudo_regs -> loc.(i) <- Pseudo_registers.allocate pseudo_regs ofs
246+
| None -> Misc.fatal_errorf "Unexpected machtype_component %a" Printcmm.machtype_component arg.(i)
193247
done;
194248
(* CR mslater: (SIMD) will need to be 32/64 if vec256/512 are used. *)
195249
(loc, Misc.align (max 0 !ofs) 16) (* keep stack 16-aligned *)
@@ -206,23 +260,17 @@ let not_supported _ofs = fatal_error "Proc.loc_results: cannot call"
206260

207261
let loc_arguments arg =
208262
calling_conventions
209-
~first_int:0
210-
~last_int:9
211-
~step_int:1
212-
~first_float:100
213-
~last_float:109
263+
~int_registers:[0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
264+
~float_registers:[100; 101; 102; 103; 104; 105; 106; 107; 108; 109]
214265
~make_stack:outgoing
215266
~first_stack:(- size_domainstate_args)
216267
arg
217268

218269
let loc_parameters arg =
219270
let (loc, _ofs) =
220271
calling_conventions
221-
~first_int:0
222-
~last_int:9
223-
~step_int:1
224-
~first_float:100
225-
~last_float:109
272+
~int_registers:[0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
273+
~float_registers:[100; 101; 102; 103; 104; 105; 106; 107; 108; 109]
226274
~make_stack:incoming
227275
~first_stack:(- size_domainstate_args)
228276
arg
@@ -231,22 +279,16 @@ let loc_parameters arg =
231279

232280
let loc_results_call res =
233281
calling_conventions
234-
~first_int:0
235-
~last_int:9
236-
~step_int:1
237-
~first_float:100
238-
~last_float:109
282+
~int_registers:[0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
283+
~float_registers:[100; 101; 102; 103; 104; 105; 106; 107; 108; 109]
239284
~make_stack:outgoing
240285
~first_stack:(- size_domainstate_args)
241286
res
242287
let loc_results_return res =
243288
let (loc, _ofs) =
244289
calling_conventions
245-
~first_int:0
246-
~last_int:9
247-
~step_int:1
248-
~first_float:100
249-
~last_float:109
290+
~int_registers:[0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
291+
~float_registers:[100; 101; 102; 103; 104; 105; 106; 107; 108; 109]
250292
~make_stack:incoming
251293
~first_stack:(- size_domainstate_args)
252294
res
@@ -272,23 +314,17 @@ let loc_external_results res =
272314
(* `~last_int:4 ~step_int:4` below is to get rdx as the second int register
273315
(See https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf, pages 21 and 22) *)
274316
calling_conventions
275-
~first_int:0
276-
~last_int:4
277-
~step_int:4
278-
~first_float:100
279-
~last_float:101
317+
~int_registers:[0; 4]
318+
~float_registers:[100; 101]
280319
~make_stack:not_supported
281320
~first_stack:0
282321
res
283322
in loc
284323

285324
let unix_loc_external_arguments arg =
286325
calling_conventions
287-
~first_int:2
288-
~last_int:7
289-
~step_int:1
290-
~first_float:100
291-
~last_float:107
326+
~int_registers:[2; 3; 4; 5; 6; 7]
327+
~float_registers:[100; 101; 102; 103; 104; 105; 106; 107]
292328
~make_stack:outgoing
293329
~first_stack:0
294330
arg

backend/cmm.ml

+9
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,15 @@ let equal_machtype_component (left : machtype_component)
692692
| Float32, (Val | Addr | Int | Float | Vec128 | Valx2) ->
693693
false
694694

695+
let hash_machtype_component : machtype_component -> int = function
696+
| Val -> 0
697+
| Addr -> 1
698+
| Int -> 2
699+
| Float -> 3
700+
| Vec128 -> 4
701+
| Float32 -> 5
702+
| Valx2 -> 6
703+
695704
let equal_exttype left right =
696705
match left, right with
697706
| XInt, XInt -> true

backend/cmm.mli

+2
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ val compare_machtype_component : machtype_component -> machtype_component -> int
558558

559559
val equal_machtype_component : machtype_component -> machtype_component -> bool
560560

561+
val hash_machtype_component : machtype_component -> int
562+
561563
val equal_exttype : exttype -> exttype -> bool
562564

563565
val equal_static_cast : static_cast -> static_cast -> bool

0 commit comments

Comments
 (0)