@@ -138,58 +138,112 @@ let word_addressed = false
138
138
139
139
let size_domainstate_args = 64 * size_int
140
140
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
+
141
193
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 )
149
198
arg =
150
199
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
153
202
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);
154
243
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)
193
247
done ;
194
248
(* CR mslater: (SIMD) will need to be 32/64 if vec256/512 are used. *)
195
249
(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"
206
260
207
261
let loc_arguments arg =
208
262
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 ]
214
265
~make_stack: outgoing
215
266
~first_stack: (- size_domainstate_args)
216
267
arg
217
268
218
269
let loc_parameters arg =
219
270
let (loc, _ofs) =
220
271
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 ]
226
274
~make_stack: incoming
227
275
~first_stack: (- size_domainstate_args)
228
276
arg
@@ -231,22 +279,16 @@ let loc_parameters arg =
231
279
232
280
let loc_results_call res =
233
281
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 ]
239
284
~make_stack: outgoing
240
285
~first_stack: (- size_domainstate_args)
241
286
res
242
287
let loc_results_return res =
243
288
let (loc, _ofs) =
244
289
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 ]
250
292
~make_stack: incoming
251
293
~first_stack: (- size_domainstate_args)
252
294
res
@@ -272,23 +314,17 @@ let loc_external_results res =
272
314
(* `~last_int:4 ~step_int:4` below is to get rdx as the second int register
273
315
(See https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf, pages 21 and 22) *)
274
316
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 ]
280
319
~make_stack: not_supported
281
320
~first_stack: 0
282
321
res
283
322
in loc
284
323
285
324
let unix_loc_external_arguments arg =
286
325
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 ]
292
328
~make_stack: outgoing
293
329
~first_stack: 0
294
330
arg
0 commit comments