Skip to content

Commit 8e8dfdf

Browse files
authored
AArch64: Migrate calls and returns to ISLE. (#4788)
1 parent ca6d648 commit 8e8dfdf

18 files changed

Lines changed: 280 additions & 327 deletions

File tree

cranelift/codegen/src/isa/aarch64/abi.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,12 @@ impl ABIMachineSpec for AArch64MachineDeps {
225225
slots: smallvec![
226226
ABIArgSlot::Reg {
227227
reg: lower_reg.to_real_reg().unwrap(),
228-
ty: param.value_type,
228+
ty: reg_types[0],
229229
extension: param.extension,
230230
},
231231
ABIArgSlot::Reg {
232232
reg: upper_reg.to_real_reg().unwrap(),
233-
ty: param.value_type,
233+
ty: reg_types[1],
234234
extension: param.extension,
235235
},
236236
],

cranelift/codegen/src/isa/aarch64/inst.isle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,3 +2818,11 @@
28182818
(let ((dst WritableReg (temp_writable_reg $I8X16))
28192819
(_ Unit (emit (MInst.IntToFpu op dst src))))
28202820
dst))
2821+
2822+
;;;; Helpers for Emitting Calls ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2823+
2824+
(decl gen_call (SigRef ExternalName RelocDistance ValueSlice) InstOutput)
2825+
(extern constructor gen_call gen_call)
2826+
2827+
(decl gen_call_indirect (SigRef Value ValueSlice) InstOutput)
2828+
(extern constructor gen_call_indirect gen_call_indirect)

cranelift/codegen/src/isa/aarch64/lower.isle

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,3 +2016,17 @@
20162016

20172017
(rule (lower (get_return_address))
20182018
(aarch64_link))
2019+
2020+
;;;; Rules for calls ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2021+
2022+
(rule (lower (call (func_ref_data sig_ref extname dist) inputs))
2023+
(gen_call sig_ref extname dist inputs))
2024+
2025+
(rule (lower (call_indirect sig_ref val inputs))
2026+
(gen_call_indirect sig_ref val inputs))
2027+
2028+
;;;; Rules for `return` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2029+
2030+
;; N.B.: the Ret itself is generated by the ABI.
2031+
(rule (lower (return args))
2032+
(lower_return (range 0 (value_slice_len args)) args))

cranelift/codegen/src/isa/aarch64/lower/isle.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
// Pull in the ISLE generated code.
44
pub mod generated_code;
5+
use generated_code::Context;
56

67
// Types that the generated ISLE code uses via `use super::*`.
78
use super::{
@@ -14,6 +15,7 @@ use super::{
1415
use crate::isa::aarch64::inst::{FPULeftShiftImm, FPURightShiftImm};
1516
use crate::isa::aarch64::lower::{lower_address, lower_splat_const};
1617
use crate::isa::aarch64::settings::Flags as IsaFlags;
18+
use crate::machinst::valueregs;
1719
use crate::machinst::{isle::*, InputSourceInst};
1820
use crate::settings::Flags;
1921
use crate::{
@@ -22,10 +24,11 @@ use crate::{
2224
immediates::*, types::*, AtomicRmwOp, ExternalName, Inst, InstructionData, MemFlags,
2325
TrapCode, Value, ValueList,
2426
},
27+
isa::aarch64::abi::{AArch64Caller, AArch64MachineDeps},
2528
isa::aarch64::inst::args::{ShiftOp, ShiftOpShiftImm},
2629
isa::aarch64::lower::{writable_vreg, writable_xreg, xreg},
2730
isa::unwind::UnwindInst,
28-
machinst::{ty_bits, InsnOutput, Lower, VCodeConstant, VCodeConstantData},
31+
machinst::{ty_bits, InsnOutput, Lower, MachInst, VCodeConstant, VCodeConstantData},
2932
};
3033
use regalloc2::PReg;
3134
use std::boxed::Box;
@@ -69,8 +72,13 @@ pub struct SinkableAtomicLoad {
6972
atomic_addr: Value,
7073
}
7174

72-
impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
75+
impl IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
76+
isle_prelude_method_helpers!(AArch64Caller);
77+
}
78+
79+
impl Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
7380
isle_prelude_methods!();
81+
isle_prelude_caller_methods!(AArch64MachineDeps, AArch64Caller);
7482

7583
fn sign_return_address_disabled(&mut self) -> Option<()> {
7684
if self.isa_flags.sign_return_address() {

cranelift/codegen/src/isa/aarch64/lower_inst.rs

Lines changed: 2 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use crate::binemit::CodeOffset;
55
use crate::ir::types::*;
66
use crate::ir::Inst as IRInst;
77
use crate::ir::{InstructionData, Opcode};
8-
use crate::isa::aarch64::abi::*;
98
use crate::isa::aarch64::inst::*;
109
use crate::isa::aarch64::settings as aarch64_settings;
1110
use crate::machinst::lower::*;
@@ -469,29 +468,7 @@ pub(crate) fn lower_insn_to_regs(
469468
}
470469
}
471470

472-
Opcode::Return => {
473-
for (i, input) in inputs.iter().enumerate() {
474-
// N.B.: according to the AArch64 ABI, the top bits of a register
475-
// (above the bits for the value's type) are undefined, so we
476-
// need not extend the return values.
477-
let src_regs = put_input_in_regs(ctx, *input);
478-
let retval_regs = ctx.retval(i);
479-
480-
assert_eq!(src_regs.len(), retval_regs.len());
481-
let ty = ctx.input_ty(insn, i);
482-
let (_, tys) = Inst::rc_for_type(ty)?;
483-
484-
src_regs
485-
.regs()
486-
.iter()
487-
.zip(retval_regs.regs().iter())
488-
.zip(tys.iter())
489-
.for_each(|((&src, &dst), &ty)| {
490-
ctx.emit(Inst::gen_move(dst, src, ty));
491-
});
492-
}
493-
// N.B.: the Ret itself is generated by the ABI.
494-
}
471+
Opcode::Return => implemented_in_isle(ctx),
495472

496473
Opcode::Ifcmp | Opcode::Ffcmp => {
497474
// An Ifcmp/Ffcmp must always be seen as a use of a brif/brff or trueif/trueff
@@ -577,52 +554,7 @@ pub(crate) fn lower_insn_to_regs(
577554

578555
Opcode::SymbolValue => implemented_in_isle(ctx),
579556

580-
Opcode::Call | Opcode::CallIndirect => {
581-
let caller_conv = ctx.abi().call_conv();
582-
let (mut abi, inputs) = match op {
583-
Opcode::Call => {
584-
let (extname, dist) = ctx.call_target(insn).unwrap();
585-
let extname = extname.clone();
586-
let sig = ctx.call_sig(insn).unwrap();
587-
assert!(inputs.len() == sig.params.len());
588-
assert!(outputs.len() == sig.returns.len());
589-
(
590-
AArch64Caller::from_func(sig, &extname, dist, caller_conv, flags)?,
591-
&inputs[..],
592-
)
593-
}
594-
Opcode::CallIndirect => {
595-
let ptr = put_input_in_reg(ctx, inputs[0], NarrowValueMode::ZeroExtend64);
596-
let sig = ctx.call_sig(insn).unwrap();
597-
assert!(inputs.len() - 1 == sig.params.len());
598-
assert!(outputs.len() == sig.returns.len());
599-
(
600-
AArch64Caller::from_ptr(sig, ptr, op, caller_conv, flags)?,
601-
&inputs[1..],
602-
)
603-
}
604-
_ => unreachable!(),
605-
};
606-
607-
abi.emit_stack_pre_adjust(ctx);
608-
assert!(inputs.len() == abi.num_args());
609-
let mut arg_regs = vec![];
610-
for input in inputs {
611-
arg_regs.push(put_input_in_regs(ctx, *input))
612-
}
613-
for (i, arg_regs) in arg_regs.iter().enumerate() {
614-
abi.emit_copy_regs_to_buffer(ctx, i, *arg_regs);
615-
}
616-
for (i, arg_regs) in arg_regs.iter().enumerate() {
617-
abi.emit_copy_regs_to_arg(ctx, i, *arg_regs);
618-
}
619-
abi.emit_call(ctx);
620-
for (i, output) in outputs.iter().enumerate() {
621-
let retval_regs = get_output_reg(ctx, *output);
622-
abi.emit_copy_retval_to_regs(ctx, i, retval_regs);
623-
}
624-
abi.emit_stack_post_adjust(ctx);
625-
}
557+
Opcode::Call | Opcode::CallIndirect => implemented_in_isle(ctx),
626558

627559
Opcode::GetPinnedReg => {
628560
let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap();

cranelift/codegen/src/isa/s390x/inst.isle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2940,8 +2940,8 @@
29402940
(rule (abi_ext_ty (ArgumentExtension.Sext) _) $I64)
29412941

29422942
;; Copy a return value to a set of registers.
2943-
(decl copy_to_regs (WritableValueRegs Value) Unit)
2944-
(rule (copy_to_regs (only_writable_reg reg) val @ (value_type ty))
2943+
(decl s390x_copy_to_regs (WritableValueRegs Value) Unit)
2944+
(rule (s390x_copy_to_regs (only_writable_reg reg) val @ (value_type ty))
29452945
(emit_mov ty reg val))
29462946

29472947

cranelift/codegen/src/isa/s390x/lower.isle

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4047,13 +4047,13 @@
40474047
;;;; Rules for `return` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
40484048

40494049
(rule (lower (return args))
4050-
(lower_return (range 0 (value_slice_len args)) args))
4050+
(s390x_lower_return (range 0 (value_slice_len args)) args))
40514051

4052-
(decl lower_return (Range ValueSlice) InstOutput)
4053-
(rule (lower_return (range_empty) _) (output_none))
4054-
(rule (lower_return (range_unwrap head tail) args)
4055-
(let ((_ Unit (copy_to_regs (retval head) (value_slice_get args head))))
4056-
(lower_return tail args)))
4052+
(decl s390x_lower_return (Range ValueSlice) InstOutput)
4053+
(rule (s390x_lower_return (range_empty) _) (output_none))
4054+
(rule (s390x_lower_return (range_unwrap head tail) args)
4055+
(let ((_ Unit (s390x_copy_to_regs (retval head) (value_slice_get args head))))
4056+
(s390x_lower_return tail args)))
40574057

40584058

40594059
;;;; Rules for `call` and `call_indirect` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

cranelift/codegen/src/isa/s390x/lower/isle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
isa::unwind::UnwindInst,
2323
isa::CallConv,
2424
machinst::abi_impl::ABIMachineSpec,
25-
machinst::{InsnOutput, Lower, VCodeConstant, VCodeConstantData},
25+
machinst::{InsnOutput, Lower, MachInst, VCodeConstant, VCodeConstantData},
2626
};
2727
use regalloc2::PReg;
2828
use smallvec::{smallvec, SmallVec};

cranelift/codegen/src/isa/x64/inst.isle

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,31 +1596,6 @@
15961596

15971597
;;;; Helpers for Emitting Loads ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15981598

1599-
;; Generate a move between two registers.
1600-
(decl gen_move (Type WritableReg Reg) MInst)
1601-
(extern constructor gen_move gen_move)
1602-
1603-
;; Copy a return value to a set of registers.
1604-
(decl copy_to_regs (WritableValueRegs Value) Unit)
1605-
(rule (copy_to_regs dsts val @ (value_type ty))
1606-
(let ((srcs ValueRegs (put_in_regs val)))
1607-
(copy_to_regs_range ty (value_regs_range srcs) dsts srcs)))
1608-
1609-
;; Helper for `copy_to_regs` that uses a range to index into the reg/value
1610-
;; vectors. Fails for the empty range.
1611-
(decl copy_to_regs_range (Type Range WritableValueRegs ValueRegs) Unit)
1612-
1613-
(rule (copy_to_regs_range ty (range_singleton idx) dsts srcs)
1614-
(let ((dst WritableReg (writable_regs_get dsts idx))
1615-
(src Reg (value_regs_get srcs idx)))
1616-
(emit (gen_move ty dst src))))
1617-
1618-
(rule (copy_to_regs_range ty (range_unwrap head tail) dsts srcs)
1619-
(let ((dst WritableReg (writable_regs_get dsts head))
1620-
(src Reg (value_regs_get srcs head))
1621-
(_ Unit (emit (gen_move ty dst src))))
1622-
(copy_to_regs_range ty tail dsts srcs)))
1623-
16241599
;; Helper for constructing a LoadExtName instruction.
16251600
(decl load_ext_name (ExternalName i64) Reg)
16261601
(rule (load_ext_name extname offset)

cranelift/codegen/src/isa/x64/lower.isle

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,13 +1441,6 @@
14411441
(rule (lower (return args))
14421442
(lower_return (range 0 (value_slice_len args)) args))
14431443

1444-
(decl lower_return (Range ValueSlice) InstOutput)
1445-
(rule (lower_return (range_empty) _) (output_none))
1446-
(rule (lower_return (range_unwrap head tail) args)
1447-
(let ((_ Unit (copy_to_regs (retval head) (value_slice_get args head))))
1448-
(lower_return tail args)))
1449-
1450-
14511444
;;;; Rules for `icmp` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14521445

14531446
(rule (lower (icmp cc a @ (value_type (fits_in_64 ty)) b))

0 commit comments

Comments
 (0)