Merge pull request #1570 from cfallin/fix-long-range-aarch64-call
Fix long-range (non-colocated) aarch64 calls to not use Arm64Call reloc, and fix simplejit to use new long-distance call.
This commit is contained in:
@@ -1061,7 +1061,7 @@ impl ABIBody for AArch64ABIBody {
|
||||
}
|
||||
|
||||
enum CallDest {
|
||||
ExtName(ir::ExternalName),
|
||||
ExtName(ir::ExternalName, RelocDistance),
|
||||
Reg(Reg),
|
||||
}
|
||||
|
||||
@@ -1102,6 +1102,7 @@ impl AArch64ABICall {
|
||||
pub fn from_func(
|
||||
sig: &ir::Signature,
|
||||
extname: &ir::ExternalName,
|
||||
dist: RelocDistance,
|
||||
loc: ir::SourceLoc,
|
||||
) -> AArch64ABICall {
|
||||
let sig = ABISig::from_func_sig(sig);
|
||||
@@ -1110,7 +1111,7 @@ impl AArch64ABICall {
|
||||
sig,
|
||||
uses,
|
||||
defs,
|
||||
dest: CallDest::ExtName(extname.clone()),
|
||||
dest: CallDest::ExtName(extname.clone(), dist),
|
||||
loc,
|
||||
opcode: ir::Opcode::Call,
|
||||
}
|
||||
@@ -1207,13 +1208,28 @@ impl ABICall for AArch64ABICall {
|
||||
fn gen_call(&self) -> Vec<Inst> {
|
||||
let (uses, defs) = (self.uses.clone(), self.defs.clone());
|
||||
match &self.dest {
|
||||
&CallDest::ExtName(ref name) => vec![Inst::Call {
|
||||
&CallDest::ExtName(ref name, RelocDistance::Near) => vec![Inst::Call {
|
||||
dest: name.clone(),
|
||||
uses,
|
||||
defs,
|
||||
loc: self.loc,
|
||||
opcode: self.opcode,
|
||||
}],
|
||||
&CallDest::ExtName(ref name, RelocDistance::Far) => vec![
|
||||
Inst::LoadExtName {
|
||||
rd: writable_spilltmp_reg(),
|
||||
name: name.clone(),
|
||||
offset: 0,
|
||||
srcloc: self.loc,
|
||||
},
|
||||
Inst::CallInd {
|
||||
rn: spilltmp_reg(),
|
||||
uses,
|
||||
defs,
|
||||
loc: self.loc,
|
||||
opcode: self.opcode,
|
||||
},
|
||||
],
|
||||
&CallDest::Reg(reg) => vec![Inst::CallInd {
|
||||
rn: reg,
|
||||
uses,
|
||||
|
||||
@@ -612,7 +612,10 @@ pub enum Inst {
|
||||
cond: Cond,
|
||||
},
|
||||
|
||||
/// A machine call instruction.
|
||||
/// A machine call instruction. N.B.: this allows only a +/- 128MB offset (it uses a relocation
|
||||
/// of type `Reloc::Arm64Call`); if the destination distance is not `RelocDistance::Near`, the
|
||||
/// code should use a `LoadExtName` / `CallInd` sequence instead, allowing an arbitrary 64-bit
|
||||
/// target.
|
||||
Call {
|
||||
dest: ExternalName,
|
||||
uses: Set<Reg>,
|
||||
|
||||
@@ -1233,7 +1233,8 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, insn: IRIns
|
||||
|
||||
Opcode::FuncAddr => {
|
||||
let rd = output_to_reg(ctx, outputs[0]);
|
||||
let extname = ctx.call_target(insn).unwrap().clone();
|
||||
let (extname, _) = ctx.call_target(insn).unwrap();
|
||||
let extname = extname.clone();
|
||||
let loc = ctx.srcloc(insn);
|
||||
ctx.emit(Inst::LoadExtName {
|
||||
rd,
|
||||
@@ -1249,7 +1250,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, insn: IRIns
|
||||
|
||||
Opcode::SymbolValue => {
|
||||
let rd = output_to_reg(ctx, outputs[0]);
|
||||
let (extname, offset) = ctx.symbol_value(insn).unwrap();
|
||||
let (extname, _, offset) = ctx.symbol_value(insn).unwrap();
|
||||
let extname = extname.clone();
|
||||
let loc = ctx.srcloc(insn);
|
||||
ctx.emit(Inst::LoadExtName {
|
||||
@@ -1264,12 +1265,15 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, insn: IRIns
|
||||
let loc = ctx.srcloc(insn);
|
||||
let (abi, inputs) = match op {
|
||||
Opcode::Call => {
|
||||
let extname = ctx.call_target(insn).unwrap();
|
||||
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());
|
||||
(AArch64ABICall::from_func(sig, &extname, loc), &inputs[..])
|
||||
(
|
||||
AArch64ABICall::from_func(sig, &extname, dist, loc),
|
||||
&inputs[..],
|
||||
)
|
||||
}
|
||||
Opcode::CallIndirect => {
|
||||
let ptr = input_to_reg(ctx, inputs[0], NarrowValueMode::ZeroExtend64);
|
||||
|
||||
Reference in New Issue
Block a user