ISLE: Migrate call and return instructions (#3785)
This adds infrastructure to allow implementing call and return instructions in ISLE, and migrates the s390x back-end. To implement ABI details, this patch creates public accessors for `ABISig` and makes them accessible in ISLE. All actual code generation is then done in ISLE rules, following the information provided by that signature. [ Note that the s390x back end never requires multiple slots for a single argument - the infrastructure to handle this should already be present, however. ] To implement loops in ISLE rules, this patch uses regular tail recursion, employing a `Range` data structure holding a range of integers to be looped over.
This commit is contained in:
@@ -69,7 +69,6 @@ use crate::machinst::*;
|
||||
use crate::machinst::{RealReg, Reg, RegClass, Writable};
|
||||
use crate::settings;
|
||||
use crate::{CodegenError, CodegenResult};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use regalloc2::{PReg, PRegSet, VReg};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
@@ -80,9 +79,6 @@ use std::convert::TryFrom;
|
||||
/// Support for the S390x ABI from the callee side (within a function body).
|
||||
pub type S390xABICallee = ABICalleeImpl<S390xMachineDeps>;
|
||||
|
||||
/// Support for the S390x ABI from the caller side (at a callsite).
|
||||
pub type S390xABICaller = ABICallerImpl<S390xMachineDeps>;
|
||||
|
||||
/// ABI Register usage
|
||||
|
||||
fn in_int_reg(ty: Type) -> bool {
|
||||
@@ -616,57 +612,16 @@ impl ABIMachineSpec for S390xMachineDeps {
|
||||
}
|
||||
|
||||
fn gen_call(
|
||||
dest: &CallDest,
|
||||
uses: SmallVec<[Reg; 8]>,
|
||||
defs: SmallVec<[Writable<Reg>; 8]>,
|
||||
clobbers: PRegSet,
|
||||
opcode: ir::Opcode,
|
||||
tmp: Writable<Reg>,
|
||||
_dest: &CallDest,
|
||||
_uses: SmallVec<[Reg; 8]>,
|
||||
_defs: SmallVec<[Writable<Reg>; 8]>,
|
||||
_clobbers: PRegSet,
|
||||
_opcode: ir::Opcode,
|
||||
_tmp: Writable<Reg>,
|
||||
_callee_conv: isa::CallConv,
|
||||
_caller_conv: isa::CallConv,
|
||||
) -> SmallVec<[Inst; 2]> {
|
||||
let mut insts = SmallVec::new();
|
||||
match &dest {
|
||||
&CallDest::ExtName(ref name, RelocDistance::Near) => insts.push(Inst::Call {
|
||||
link: writable_gpr(14),
|
||||
info: Box::new(CallInfo {
|
||||
dest: name.clone(),
|
||||
uses,
|
||||
defs,
|
||||
clobbers,
|
||||
opcode,
|
||||
}),
|
||||
}),
|
||||
&CallDest::ExtName(ref name, RelocDistance::Far) => {
|
||||
insts.push(Inst::LoadExtNameFar {
|
||||
rd: tmp,
|
||||
name: Box::new(name.clone()),
|
||||
offset: 0,
|
||||
});
|
||||
insts.push(Inst::CallInd {
|
||||
link: writable_gpr(14),
|
||||
info: Box::new(CallIndInfo {
|
||||
rn: tmp.to_reg(),
|
||||
uses,
|
||||
defs,
|
||||
clobbers,
|
||||
opcode,
|
||||
}),
|
||||
});
|
||||
}
|
||||
&CallDest::Reg(reg) => insts.push(Inst::CallInd {
|
||||
link: writable_gpr(14),
|
||||
info: Box::new(CallIndInfo {
|
||||
rn: *reg,
|
||||
uses,
|
||||
defs,
|
||||
clobbers,
|
||||
opcode,
|
||||
}),
|
||||
}),
|
||||
}
|
||||
|
||||
insts
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
fn gen_memcpy(
|
||||
|
||||
Reference in New Issue
Block a user