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:
Ulrich Weigand
2022-10-21 20:01:22 +02:00
committed by GitHub
parent 86e77953f8
commit 9dadba60a0
10 changed files with 317 additions and 240 deletions

View File

@@ -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` ;;;;;;;;;;;;