AArch64: Migrate calls and returns to ISLE. (#4788)
This commit is contained in:
@@ -5,7 +5,6 @@ use crate::binemit::CodeOffset;
|
||||
use crate::ir::types::*;
|
||||
use crate::ir::Inst as IRInst;
|
||||
use crate::ir::{InstructionData, Opcode};
|
||||
use crate::isa::aarch64::abi::*;
|
||||
use crate::isa::aarch64::inst::*;
|
||||
use crate::isa::aarch64::settings as aarch64_settings;
|
||||
use crate::machinst::lower::*;
|
||||
@@ -469,29 +468,7 @@ pub(crate) fn lower_insn_to_regs(
|
||||
}
|
||||
}
|
||||
|
||||
Opcode::Return => {
|
||||
for (i, input) in inputs.iter().enumerate() {
|
||||
// N.B.: according to the AArch64 ABI, the top bits of a register
|
||||
// (above the bits for the value's type) are undefined, so we
|
||||
// need not extend the return values.
|
||||
let src_regs = put_input_in_regs(ctx, *input);
|
||||
let retval_regs = ctx.retval(i);
|
||||
|
||||
assert_eq!(src_regs.len(), retval_regs.len());
|
||||
let ty = ctx.input_ty(insn, i);
|
||||
let (_, tys) = Inst::rc_for_type(ty)?;
|
||||
|
||||
src_regs
|
||||
.regs()
|
||||
.iter()
|
||||
.zip(retval_regs.regs().iter())
|
||||
.zip(tys.iter())
|
||||
.for_each(|((&src, &dst), &ty)| {
|
||||
ctx.emit(Inst::gen_move(dst, src, ty));
|
||||
});
|
||||
}
|
||||
// N.B.: the Ret itself is generated by the ABI.
|
||||
}
|
||||
Opcode::Return => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Ifcmp | Opcode::Ffcmp => {
|
||||
// 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(
|
||||
|
||||
Opcode::SymbolValue => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Call | Opcode::CallIndirect => {
|
||||
let caller_conv = ctx.abi().call_conv();
|
||||
let (mut abi, inputs) = match op {
|
||||
Opcode::Call => {
|
||||
let (extname, dist) = ctx.call_target(insn).unwrap();
|
||||
let extname = extname.clone();
|
||||
let sig = ctx.call_sig(insn).unwrap();
|
||||
assert!(inputs.len() == sig.params.len());
|
||||
assert!(outputs.len() == sig.returns.len());
|
||||
(
|
||||
AArch64Caller::from_func(sig, &extname, dist, caller_conv, flags)?,
|
||||
&inputs[..],
|
||||
)
|
||||
}
|
||||
Opcode::CallIndirect => {
|
||||
let ptr = put_input_in_reg(ctx, inputs[0], NarrowValueMode::ZeroExtend64);
|
||||
let sig = ctx.call_sig(insn).unwrap();
|
||||
assert!(inputs.len() - 1 == sig.params.len());
|
||||
assert!(outputs.len() == sig.returns.len());
|
||||
(
|
||||
AArch64Caller::from_ptr(sig, ptr, op, caller_conv, flags)?,
|
||||
&inputs[1..],
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
abi.emit_stack_pre_adjust(ctx);
|
||||
assert!(inputs.len() == abi.num_args());
|
||||
let mut arg_regs = vec![];
|
||||
for input in inputs {
|
||||
arg_regs.push(put_input_in_regs(ctx, *input))
|
||||
}
|
||||
for (i, arg_regs) in arg_regs.iter().enumerate() {
|
||||
abi.emit_copy_regs_to_buffer(ctx, i, *arg_regs);
|
||||
}
|
||||
for (i, arg_regs) in arg_regs.iter().enumerate() {
|
||||
abi.emit_copy_regs_to_arg(ctx, i, *arg_regs);
|
||||
}
|
||||
abi.emit_call(ctx);
|
||||
for (i, output) in outputs.iter().enumerate() {
|
||||
let retval_regs = get_output_reg(ctx, *output);
|
||||
abi.emit_copy_retval_to_regs(ctx, i, retval_regs);
|
||||
}
|
||||
abi.emit_stack_post_adjust(ctx);
|
||||
}
|
||||
Opcode::Call | Opcode::CallIndirect => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::GetPinnedReg => {
|
||||
let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user