s390x: use constraints for call arguments and return values (#5092)
Use the regalloc constraint-based CallArgList / CallRetList mechanism instead of directly using physregs in instructions.
This commit is contained in:
@@ -2283,12 +2283,11 @@
|
||||
;; Helper to perform a call to the __tls_get_offset library routine.
|
||||
(decl lib_call_tls_get_offset (Reg Reg SymbolReloc) Reg)
|
||||
(rule (lib_call_tls_get_offset got got_offset symbol)
|
||||
(let ((libcall LibCallInfo (lib_call_info_tls_get_offset symbol))
|
||||
(let ((tls_offset WritableReg (temp_writable_reg $I64))
|
||||
(libcall LibCallInfo (lib_call_info_tls_get_offset tls_offset got got_offset symbol))
|
||||
(_ Unit (lib_accumulate_outgoing_args_size libcall))
|
||||
(_ Unit (emit_mov $I64 (writable_gpr 12) got))
|
||||
(_ Unit (emit_mov $I64 (writable_gpr 2) got_offset))
|
||||
(_ Unit (emit_side_effect (lib_call libcall))))
|
||||
(copy_reg $I64 (writable_gpr 2))))
|
||||
tls_offset))
|
||||
|
||||
;; Helper to extract the current thread pointer from %a0/%a1.
|
||||
(decl thread_pointer () Reg)
|
||||
@@ -3905,34 +3904,39 @@
|
||||
(rule 1 (lower (call (func_ref_data sig_ref name (reloc_distance_near)) args))
|
||||
(let ((abi Sig (abi_sig sig_ref))
|
||||
(_ Unit (abi_accumulate_outgoing_args_size abi))
|
||||
(_ InstOutput (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(_ InstOutput (side_effect (abi_call abi name (Opcode.Call)))))
|
||||
(lower_call_rets abi (range 0 (abi_num_rets abi)) (output_builder_new))))
|
||||
(uses CallArgList (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(defs CallRetList (defs_init abi))
|
||||
(_ InstOutput (side_effect (abi_call abi name uses defs (Opcode.Call)))))
|
||||
(lower_call_rets abi defs (range 0 (abi_num_rets abi)) (output_builder_new))))
|
||||
|
||||
;; Direct call to an out-of-range function (implicitly via pointer).
|
||||
(rule (lower (call (func_ref_data sig_ref name _) args))
|
||||
(let ((abi Sig (abi_sig sig_ref))
|
||||
(_ Unit (abi_accumulate_outgoing_args_size abi))
|
||||
(_ InstOutput (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(uses CallArgList (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(defs CallRetList (defs_init abi))
|
||||
(target Reg (load_symbol_reloc (SymbolReloc.Absolute name 0)))
|
||||
(_ InstOutput (side_effect (abi_call_ind abi target (Opcode.Call)))))
|
||||
(lower_call_rets abi (range 0 (abi_num_rets abi)) (output_builder_new))))
|
||||
(_ InstOutput (side_effect (abi_call_ind abi target uses defs (Opcode.Call)))))
|
||||
(lower_call_rets abi defs (range 0 (abi_num_rets abi)) (output_builder_new))))
|
||||
|
||||
;; Indirect call.
|
||||
(rule (lower (call_indirect sig_ref ptr args))
|
||||
(let ((abi Sig (abi_sig sig_ref))
|
||||
(target Reg (put_in_reg ptr))
|
||||
(_ Unit (abi_accumulate_outgoing_args_size abi))
|
||||
(_ InstOutput (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(_ InstOutput (side_effect (abi_call_ind abi target (Opcode.CallIndirect)))))
|
||||
(lower_call_rets abi (range 0 (abi_num_rets abi)) (output_builder_new))))
|
||||
(uses CallArgList (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(defs CallRetList (defs_init abi))
|
||||
(_ InstOutput (side_effect (abi_call_ind abi target uses defs (Opcode.CallIndirect)))))
|
||||
(lower_call_rets abi defs (range 0 (abi_num_rets abi)) (output_builder_new))))
|
||||
|
||||
;; Lower function arguments.
|
||||
(decl lower_call_args (Sig Range ValueSlice) InstOutput)
|
||||
(decl lower_call_args (Sig Range ValueSlice) CallArgList)
|
||||
(rule (lower_call_args abi range args)
|
||||
(let ((_ InstOutput (lower_call_args_buffer abi range args))
|
||||
(_ InstOutput (lower_call_args_slots abi range args)))
|
||||
(lower_call_ret_arg abi)))
|
||||
(let ((uses CallArgListBuilder (args_builder_new))
|
||||
(_ InstOutput (lower_call_args_buffer abi range args))
|
||||
(_ InstOutput (lower_call_args_slots abi uses range args))
|
||||
(_ InstOutput (lower_call_ret_arg abi uses)))
|
||||
(args_builder_finish uses)))
|
||||
|
||||
;; Lower function arguments (part 1): prepare buffer copies.
|
||||
(decl lower_call_args_buffer (Sig Range ValueSlice) InstOutput)
|
||||
@@ -3943,31 +3947,31 @@
|
||||
(lower_call_args_buffer abi tail args)))
|
||||
|
||||
;; Lower function arguments (part 2): set up registers / stack slots.
|
||||
(decl lower_call_args_slots (Sig Range ValueSlice) InstOutput)
|
||||
(rule (lower_call_args_slots abi (range_empty) _) (output_none))
|
||||
(rule (lower_call_args_slots abi (range_unwrap head tail) args)
|
||||
(let ((_ Unit (copy_to_arg (abi_lane_order abi)
|
||||
(decl lower_call_args_slots (Sig CallArgListBuilder Range ValueSlice) InstOutput)
|
||||
(rule (lower_call_args_slots abi _ (range_empty) _) (output_none))
|
||||
(rule (lower_call_args_slots abi uses (range_unwrap head tail) args)
|
||||
(let ((_ Unit (copy_to_arg uses (abi_lane_order abi)
|
||||
0 (abi_get_arg abi head)
|
||||
(value_slice_get args head))))
|
||||
(lower_call_args_slots abi tail args)))
|
||||
(lower_call_args_slots abi uses tail args)))
|
||||
|
||||
;; Lower function arguments (part 3): implicit return-area pointer.
|
||||
(decl lower_call_ret_arg (Sig) InstOutput)
|
||||
(rule (lower_call_ret_arg (abi_no_ret_arg)) (output_none))
|
||||
(rule 1 (lower_call_ret_arg abi @ (abi_ret_arg (abi_arg_only_slot slot)))
|
||||
(decl lower_call_ret_arg (Sig CallArgListBuilder) InstOutput)
|
||||
(rule (lower_call_ret_arg (abi_no_ret_arg) _) (output_none))
|
||||
(rule 1 (lower_call_ret_arg abi @ (abi_ret_arg (abi_arg_only_slot slot)) uses)
|
||||
(let ((ret_arg Reg (load_addr (memarg_stack_off (abi_sized_stack_arg_space abi) 0)))
|
||||
(_ Unit (copy_reg_to_arg_slot 0 slot ret_arg)))
|
||||
(_ Unit (copy_reg_to_arg_slot uses (abi_lane_order abi) 0 slot ret_arg)))
|
||||
(output_none)))
|
||||
|
||||
;; Lower function return values by collecting them from registers / stack slots.
|
||||
(decl lower_call_rets (Sig Range InstOutputBuilder) InstOutput)
|
||||
(rule (lower_call_rets abi (range_empty) builder) (output_builder_finish builder))
|
||||
(rule (lower_call_rets abi (range_unwrap head tail) builder)
|
||||
(let ((ret ValueRegs (copy_from_arg (abi_lane_order abi)
|
||||
(decl lower_call_rets (Sig CallRetList Range InstOutputBuilder) InstOutput)
|
||||
(rule (lower_call_rets abi _ (range_empty) builder) (output_builder_finish builder))
|
||||
(rule (lower_call_rets abi defs (range_unwrap head tail) builder)
|
||||
(let ((ret ValueRegs (copy_from_arg defs (abi_lane_order abi)
|
||||
(abi_sized_stack_arg_space abi)
|
||||
(abi_get_ret abi head)))
|
||||
(_ Unit (output_builder_push builder ret)))
|
||||
(lower_call_rets abi tail builder)))
|
||||
(lower_call_rets abi defs tail builder)))
|
||||
|
||||
;;;; Rules for `get_{frame,stack}_pointer` and `get_return_address` ;;;;;;;;;;;;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user