MachInst backends: handle SourceLocs out-of-band, not in Insts.
In existing MachInst backends, many instructions -- any that can trap or result in a relocation -- carry `SourceLoc` values in order to propagate the location-in-original-source to use to describe resulting traps or relocation errors. This is quite tedious, and also error-prone: it is likely that the necessary plumbing will be missed in some cases, and in any case, it's unnecessarily verbose. This PR factors out the `SourceLoc` handling so that it is tracked during emission as part of the `EmitState`, and plumbed through automatically by the machine-independent framework. Instruction emission code that directly emits trap or relocation records can query the current location as necessary. Then we only need to ensure that memory references and trap instructions, at their (one) emission point rather than their (many) lowering/generation points, are wired up correctly. This does have the side-effect that some loads and stores that do not correspond directly to user code's heap accesses will have unnecessary but harmless trap metadata. For example, the load that fetches a code offset from a jump table will have a 'heap out of bounds' trap record attached to it; but because it is bounds-checked, and will never actually trap if the lowering is correct, this should be harmless. The simplicity improvement here seemed more worthwhile to me than plumbing through a "corresponds to user-level load/store" bit, because the latter is a bit complex when we allow for op merging. Closes #2290: though it does not implement a full "metadata" scheme as described in that issue, this seems simpler overall.
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
|
||||
use crate::ir;
|
||||
use crate::ir::types::*;
|
||||
use crate::ir::SourceLoc;
|
||||
use crate::isa;
|
||||
use crate::isa::arm32::inst::*;
|
||||
use crate::machinst::*;
|
||||
@@ -217,7 +216,7 @@ impl ABIMachineSpec for Arm32MachineDeps {
|
||||
rm: limit_reg,
|
||||
});
|
||||
insts.push(Inst::TrapIf {
|
||||
trap_info: (ir::SourceLoc::default(), ir::TrapCode::StackOverflow),
|
||||
trap_info: ir::TrapCode::StackOverflow,
|
||||
// Here `Lo` == "less than" when interpreting the two
|
||||
// operands as unsigned integers.
|
||||
cond: Cond::Lo,
|
||||
@@ -366,7 +365,6 @@ impl ABIMachineSpec for Arm32MachineDeps {
|
||||
dest: &CallDest,
|
||||
uses: Vec<Reg>,
|
||||
defs: Vec<Writable<Reg>>,
|
||||
loc: SourceLoc,
|
||||
opcode: ir::Opcode,
|
||||
tmp: Writable<Reg>,
|
||||
_callee_conv: isa::CallConv,
|
||||
@@ -381,7 +379,6 @@ impl ABIMachineSpec for Arm32MachineDeps {
|
||||
dest: name.clone(),
|
||||
uses,
|
||||
defs,
|
||||
loc,
|
||||
opcode,
|
||||
}),
|
||||
},
|
||||
@@ -393,7 +390,6 @@ impl ABIMachineSpec for Arm32MachineDeps {
|
||||
rt: tmp,
|
||||
name: Box::new(name.clone()),
|
||||
offset: 0,
|
||||
srcloc: loc,
|
||||
},
|
||||
));
|
||||
insts.push((
|
||||
@@ -403,7 +399,6 @@ impl ABIMachineSpec for Arm32MachineDeps {
|
||||
rm: tmp.to_reg(),
|
||||
uses,
|
||||
defs,
|
||||
loc,
|
||||
opcode,
|
||||
}),
|
||||
},
|
||||
@@ -416,7 +411,6 @@ impl ABIMachineSpec for Arm32MachineDeps {
|
||||
rm: *reg,
|
||||
uses,
|
||||
defs,
|
||||
loc,
|
||||
opcode,
|
||||
}),
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! 32-bit ARM ISA: binary code emission.
|
||||
|
||||
use crate::binemit::{Reloc, StackMap};
|
||||
use crate::ir::SourceLoc;
|
||||
use crate::isa::arm32::inst::*;
|
||||
|
||||
use core::convert::TryFrom;
|
||||
@@ -229,6 +230,8 @@ pub struct EmitState {
|
||||
pub(crate) nominal_sp_to_fp: i64,
|
||||
/// Safepoint stack map for upcoming instruction, as provided to `pre_safepoint()`.
|
||||
stack_map: Option<StackMap>,
|
||||
/// Source location of next machine code instruction to be emitted.
|
||||
cur_srcloc: SourceLoc,
|
||||
}
|
||||
|
||||
impl MachInstEmitState<Inst> for EmitState {
|
||||
@@ -237,12 +240,17 @@ impl MachInstEmitState<Inst> for EmitState {
|
||||
virtual_sp_offset: 0,
|
||||
nominal_sp_to_fp: abi.frame_size() as i64,
|
||||
stack_map: None,
|
||||
cur_srcloc: SourceLoc::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn pre_safepoint(&mut self, stack_map: StackMap) {
|
||||
self.stack_map = Some(stack_map);
|
||||
}
|
||||
|
||||
fn pre_sourceloc(&mut self, srcloc: SourceLoc) {
|
||||
self.cur_srcloc = srcloc;
|
||||
}
|
||||
}
|
||||
|
||||
impl EmitState {
|
||||
@@ -253,6 +261,10 @@ impl EmitState {
|
||||
fn clear_post_insn(&mut self) {
|
||||
self.stack_map = None;
|
||||
}
|
||||
|
||||
fn cur_srcloc(&self) -> SourceLoc {
|
||||
self.cur_srcloc
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EmitInfo {
|
||||
@@ -456,17 +468,13 @@ impl MachInstEmit for Inst {
|
||||
let inst = enc_32_regs(inst, None, None, None, Some(rn));
|
||||
emit_32(inst, sink);
|
||||
}
|
||||
&Inst::Store {
|
||||
rt,
|
||||
ref mem,
|
||||
srcloc,
|
||||
bits,
|
||||
} => {
|
||||
&Inst::Store { rt, ref mem, bits } => {
|
||||
let (mem_insts, mem) = mem_finalize(mem, state);
|
||||
for inst in mem_insts.into_iter() {
|
||||
inst.emit(sink, emit_info, state);
|
||||
}
|
||||
if let Some(srcloc) = srcloc {
|
||||
let srcloc = state.cur_srcloc();
|
||||
if srcloc != SourceLoc::default() {
|
||||
// Register the offset at which the store instruction starts.
|
||||
sink.add_trap(srcloc, TrapCode::HeapOutOfBounds);
|
||||
}
|
||||
@@ -496,7 +504,6 @@ impl MachInstEmit for Inst {
|
||||
&Inst::Load {
|
||||
rt,
|
||||
ref mem,
|
||||
srcloc,
|
||||
bits,
|
||||
sign_extend,
|
||||
} => {
|
||||
@@ -504,7 +511,8 @@ impl MachInstEmit for Inst {
|
||||
for inst in mem_insts.into_iter() {
|
||||
inst.emit(sink, emit_info, state);
|
||||
}
|
||||
if let Some(srcloc) = srcloc {
|
||||
let srcloc = state.cur_srcloc();
|
||||
if srcloc != SourceLoc::default() {
|
||||
// Register the offset at which the load instruction starts.
|
||||
sink.add_trap(srcloc, TrapCode::HeapOutOfBounds);
|
||||
}
|
||||
@@ -696,23 +704,24 @@ impl MachInstEmit for Inst {
|
||||
}
|
||||
},
|
||||
&Inst::Call { ref info } => {
|
||||
sink.add_reloc(info.loc, Reloc::Arm32Call, &info.dest, 0);
|
||||
let srcloc = state.cur_srcloc();
|
||||
sink.add_reloc(srcloc, Reloc::Arm32Call, &info.dest, 0);
|
||||
emit_32(0b11110_0_0000000000_11_0_1_0_00000000000, sink);
|
||||
if info.opcode.is_call() {
|
||||
sink.add_call_site(info.loc, info.opcode);
|
||||
sink.add_call_site(srcloc, info.opcode);
|
||||
}
|
||||
}
|
||||
&Inst::CallInd { ref info } => {
|
||||
let srcloc = state.cur_srcloc();
|
||||
sink.put2(0b01000111_1_0000_000 | (machreg_to_gpr(info.rm) << 3));
|
||||
if info.opcode.is_call() {
|
||||
sink.add_call_site(info.loc, info.opcode);
|
||||
sink.add_call_site(srcloc, info.opcode);
|
||||
}
|
||||
}
|
||||
&Inst::LoadExtName {
|
||||
rt,
|
||||
ref name,
|
||||
offset,
|
||||
srcloc,
|
||||
} => {
|
||||
// maybe nop2 (0|2) bytes (pc is now 4-aligned)
|
||||
// ldr rt, [pc, #4] 4 bytes
|
||||
@@ -729,7 +738,6 @@ impl MachInstEmit for Inst {
|
||||
let inst = Inst::Load {
|
||||
rt,
|
||||
mem,
|
||||
srcloc: Some(srcloc),
|
||||
bits: 32,
|
||||
sign_extend: false,
|
||||
};
|
||||
@@ -740,6 +748,7 @@ impl MachInstEmit for Inst {
|
||||
};
|
||||
inst.emit(sink, emit_info, state);
|
||||
|
||||
let srcloc = state.cur_srcloc();
|
||||
sink.add_reloc(srcloc, Reloc::Abs4, name, offset.into());
|
||||
sink.put4(0);
|
||||
}
|
||||
@@ -784,7 +793,8 @@ impl MachInstEmit for Inst {
|
||||
sink.put2(inst);
|
||||
}
|
||||
&Inst::Udf { trap_info } => {
|
||||
let (srcloc, code) = trap_info;
|
||||
let srcloc = state.cur_srcloc();
|
||||
let code = trap_info;
|
||||
sink.add_trap(srcloc, code);
|
||||
sink.put2(0b11011110_00000000);
|
||||
}
|
||||
|
||||
@@ -1244,7 +1244,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(0),
|
||||
mem: AMode::reg_plus_reg(rreg(1), rreg(2), 0),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
},
|
||||
"41F80200",
|
||||
@@ -1254,7 +1253,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(8),
|
||||
mem: AMode::reg_plus_reg(rreg(9), rreg(10), 3),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
},
|
||||
"49F83A80",
|
||||
@@ -1264,7 +1262,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(0),
|
||||
mem: AMode::RegOffset(rreg(1), 4095),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
},
|
||||
"C1F8FF0F",
|
||||
@@ -1274,7 +1271,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(8),
|
||||
mem: AMode::RegOffset(rreg(9), 0),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
},
|
||||
"C9F80080",
|
||||
@@ -1284,7 +1280,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(7),
|
||||
mem: AMode::RegOffset(rreg(11), 65535),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
},
|
||||
"4FF6FF7C4BF80C70",
|
||||
@@ -1294,7 +1289,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(10),
|
||||
mem: AMode::RegOffset(rreg(4), 16777215),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
},
|
||||
"4FF6FF7CC0F2FF0C44F80CA0",
|
||||
@@ -1304,7 +1298,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(0),
|
||||
mem: AMode::reg_plus_reg(rreg(1), rreg(2), 0),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
},
|
||||
"21F80200",
|
||||
@@ -1314,7 +1307,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(8),
|
||||
mem: AMode::reg_plus_reg(rreg(9), rreg(10), 2),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
},
|
||||
"29F82A80",
|
||||
@@ -1324,7 +1316,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(0),
|
||||
mem: AMode::RegOffset(rreg(1), 3210),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
},
|
||||
"A1F88A0C",
|
||||
@@ -1334,7 +1325,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(8),
|
||||
mem: AMode::RegOffset(rreg(9), 1),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
},
|
||||
"A9F80180",
|
||||
@@ -1344,7 +1334,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(7),
|
||||
mem: AMode::RegOffset(rreg(11), 65535),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
},
|
||||
"4FF6FF7C2BF80C70",
|
||||
@@ -1354,7 +1343,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(10),
|
||||
mem: AMode::RegOffset(rreg(4), 16777215),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
},
|
||||
"4FF6FF7CC0F2FF0C24F80CA0",
|
||||
@@ -1364,7 +1352,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(0),
|
||||
mem: AMode::reg_plus_reg(rreg(1), rreg(2), 0),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
},
|
||||
"01F80200",
|
||||
@@ -1374,7 +1361,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(8),
|
||||
mem: AMode::reg_plus_reg(rreg(9), rreg(10), 1),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
},
|
||||
"09F81A80",
|
||||
@@ -1384,7 +1370,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(0),
|
||||
mem: AMode::RegOffset(rreg(1), 4),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
},
|
||||
"81F80400",
|
||||
@@ -1394,7 +1379,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(8),
|
||||
mem: AMode::RegOffset(rreg(9), 777),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
},
|
||||
"89F80983",
|
||||
@@ -1404,7 +1388,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(7),
|
||||
mem: AMode::RegOffset(rreg(11), 65535),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
},
|
||||
"4FF6FF7C0BF80C70",
|
||||
@@ -1414,7 +1397,6 @@ fn test_arm32_emit() {
|
||||
Inst::Store {
|
||||
rt: rreg(10),
|
||||
mem: AMode::RegOffset(rreg(4), 16777215),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
},
|
||||
"4FF6FF7CC0F2FF0C04F80CA0",
|
||||
@@ -1424,7 +1406,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(0),
|
||||
mem: AMode::reg_plus_reg(rreg(1), rreg(2), 0),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1435,7 +1416,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(8),
|
||||
mem: AMode::reg_plus_reg(rreg(9), rreg(10), 1),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1446,7 +1426,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(0),
|
||||
mem: AMode::RegOffset(rreg(1), 55),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1457,7 +1436,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(8),
|
||||
mem: AMode::RegOffset(rreg(9), 1234),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1468,7 +1446,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(7),
|
||||
mem: AMode::RegOffset(rreg(11), 9876),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1479,7 +1456,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(10),
|
||||
mem: AMode::RegOffset(rreg(4), 252645135),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1490,7 +1466,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(0),
|
||||
mem: AMode::PCRel(-56),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1501,7 +1476,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(8),
|
||||
mem: AMode::PCRel(1024),
|
||||
srcloc: None,
|
||||
bits: 32,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1512,7 +1486,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(0),
|
||||
mem: AMode::reg_plus_reg(rreg(1), rreg(2), 0),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
sign_extend: true,
|
||||
},
|
||||
@@ -1523,7 +1496,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(8),
|
||||
mem: AMode::reg_plus_reg(rreg(9), rreg(10), 2),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1534,7 +1506,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(0),
|
||||
mem: AMode::RegOffset(rreg(1), 55),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1545,7 +1516,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(8),
|
||||
mem: AMode::RegOffset(rreg(9), 1234),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
sign_extend: true,
|
||||
},
|
||||
@@ -1556,7 +1526,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(7),
|
||||
mem: AMode::RegOffset(rreg(11), 9876),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
sign_extend: true,
|
||||
},
|
||||
@@ -1567,7 +1536,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(10),
|
||||
mem: AMode::RegOffset(rreg(4), 252645135),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1578,7 +1546,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(0),
|
||||
mem: AMode::PCRel(56),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1589,7 +1556,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(8),
|
||||
mem: AMode::PCRel(-1000),
|
||||
srcloc: None,
|
||||
bits: 16,
|
||||
sign_extend: true,
|
||||
},
|
||||
@@ -1600,7 +1566,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(0),
|
||||
mem: AMode::reg_plus_reg(rreg(1), rreg(2), 0),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
sign_extend: true,
|
||||
},
|
||||
@@ -1611,7 +1576,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(8),
|
||||
mem: AMode::reg_plus_reg(rreg(9), rreg(10), 3),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1622,7 +1586,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(0),
|
||||
mem: AMode::RegOffset(rreg(1), 55),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1633,7 +1596,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(8),
|
||||
mem: AMode::RegOffset(rreg(9), 1234),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
sign_extend: true,
|
||||
},
|
||||
@@ -1644,7 +1606,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(7),
|
||||
mem: AMode::RegOffset(rreg(11), 9876),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
sign_extend: true,
|
||||
},
|
||||
@@ -1655,7 +1616,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(10),
|
||||
mem: AMode::RegOffset(rreg(4), 252645135),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1666,7 +1626,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(0),
|
||||
mem: AMode::PCRel(72),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
sign_extend: false,
|
||||
},
|
||||
@@ -1677,7 +1636,6 @@ fn test_arm32_emit() {
|
||||
Inst::Load {
|
||||
rt: writable_rreg(8),
|
||||
mem: AMode::PCRel(-1234),
|
||||
srcloc: None,
|
||||
bits: 8,
|
||||
sign_extend: true,
|
||||
},
|
||||
@@ -1961,7 +1919,7 @@ fn test_arm32_emit() {
|
||||
insns.push((
|
||||
Inst::TrapIf {
|
||||
cond: Cond::Eq,
|
||||
trap_info: (SourceLoc::default(), TrapCode::Interrupt),
|
||||
trap_info: TrapCode::Interrupt,
|
||||
},
|
||||
"40F0018000DE",
|
||||
"bne 2 ; udf #0",
|
||||
@@ -1969,14 +1927,14 @@ fn test_arm32_emit() {
|
||||
insns.push((
|
||||
Inst::TrapIf {
|
||||
cond: Cond::Hs,
|
||||
trap_info: (SourceLoc::default(), TrapCode::Interrupt),
|
||||
trap_info: TrapCode::Interrupt,
|
||||
},
|
||||
"C0F0018000DE",
|
||||
"blo 2 ; udf #0",
|
||||
));
|
||||
insns.push((
|
||||
Inst::Udf {
|
||||
trap_info: (SourceLoc::default(), TrapCode::Interrupt),
|
||||
trap_info: TrapCode::Interrupt,
|
||||
},
|
||||
"00DE",
|
||||
"udf #0",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use crate::binemit::CodeOffset;
|
||||
use crate::ir::types::{B1, B16, B32, B8, I16, I32, I8, IFLAGS};
|
||||
use crate::ir::{ExternalName, Opcode, SourceLoc, TrapCode, Type};
|
||||
use crate::ir::{ExternalName, Opcode, TrapCode, Type};
|
||||
use crate::machinst::*;
|
||||
use crate::{settings, CodegenError, CodegenResult};
|
||||
|
||||
@@ -83,7 +83,6 @@ pub struct CallInfo {
|
||||
pub dest: ExternalName,
|
||||
pub uses: Vec<Reg>,
|
||||
pub defs: Vec<Writable<Reg>>,
|
||||
pub loc: SourceLoc,
|
||||
pub opcode: Opcode,
|
||||
}
|
||||
|
||||
@@ -94,7 +93,6 @@ pub struct CallIndInfo {
|
||||
pub rm: Reg,
|
||||
pub uses: Vec<Reg>,
|
||||
pub defs: Vec<Writable<Reg>>,
|
||||
pub loc: SourceLoc,
|
||||
pub opcode: Opcode,
|
||||
}
|
||||
|
||||
@@ -218,7 +216,6 @@ pub enum Inst {
|
||||
Store {
|
||||
rt: Reg,
|
||||
mem: AMode,
|
||||
srcloc: Option<SourceLoc>,
|
||||
bits: u8,
|
||||
},
|
||||
|
||||
@@ -227,7 +224,6 @@ pub enum Inst {
|
||||
Load {
|
||||
rt: Writable<Reg>,
|
||||
mem: AMode,
|
||||
srcloc: Option<SourceLoc>,
|
||||
bits: u8,
|
||||
sign_extend: bool,
|
||||
},
|
||||
@@ -276,7 +272,6 @@ pub enum Inst {
|
||||
LoadExtName {
|
||||
rt: Writable<Reg>,
|
||||
name: Box<ExternalName>,
|
||||
srcloc: SourceLoc,
|
||||
offset: i32,
|
||||
},
|
||||
|
||||
@@ -308,13 +303,13 @@ pub enum Inst {
|
||||
/// unit to the register allocator.
|
||||
TrapIf {
|
||||
cond: Cond,
|
||||
trap_info: (SourceLoc, TrapCode),
|
||||
trap_info: TrapCode,
|
||||
},
|
||||
|
||||
/// An instruction guaranteed to always be undefined and to trigger an illegal instruction at
|
||||
/// runtime.
|
||||
Udf {
|
||||
trap_info: (SourceLoc, TrapCode),
|
||||
trap_info: TrapCode,
|
||||
},
|
||||
|
||||
/// A "breakpoint" instruction, used for e.g. traps and debug breakpoints.
|
||||
@@ -390,7 +385,6 @@ impl Inst {
|
||||
Inst::Load {
|
||||
rt: into_reg,
|
||||
mem,
|
||||
srcloc: None,
|
||||
bits,
|
||||
sign_extend: false,
|
||||
}
|
||||
@@ -405,7 +399,6 @@ impl Inst {
|
||||
Inst::Store {
|
||||
rt: from_reg,
|
||||
mem,
|
||||
srcloc: None,
|
||||
bits,
|
||||
}
|
||||
}
|
||||
@@ -1189,7 +1182,6 @@ impl Inst {
|
||||
rt,
|
||||
ref name,
|
||||
offset,
|
||||
srcloc: _srcloc,
|
||||
} => {
|
||||
let rt = rt.show_rru(mb_rru);
|
||||
format!("ldr {}, [pc, #4] ; b 4 ; data {:?} + {}", rt, name, offset)
|
||||
|
||||
@@ -386,19 +386,8 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
let base = input_to_reg(ctx, inputs[1], NarrowValueMode::None);
|
||||
|
||||
let mem = AMode::RegOffset(base, i64::from(off));
|
||||
let memflags = ctx.memflags(insn).expect("memory flags");
|
||||
|
||||
let srcloc = if !memflags.notrap() {
|
||||
Some(ctx.srcloc(insn))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
ctx.emit(Inst::Store {
|
||||
rt,
|
||||
mem,
|
||||
srcloc,
|
||||
bits,
|
||||
});
|
||||
ctx.emit(Inst::Store { rt, mem, bits });
|
||||
}
|
||||
Opcode::Load
|
||||
| Opcode::Uload8
|
||||
@@ -429,17 +418,10 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
assert_eq!(inputs.len(), 2, "only one input for store memory operands");
|
||||
let base = input_to_reg(ctx, inputs[1], NarrowValueMode::None);
|
||||
let mem = AMode::RegOffset(base, i64::from(off));
|
||||
let memflags = ctx.memflags(insn).expect("memory flags");
|
||||
|
||||
let srcloc = if !memflags.notrap() {
|
||||
Some(ctx.srcloc(insn))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
ctx.emit(Inst::Load {
|
||||
rt: out_reg,
|
||||
mem,
|
||||
srcloc,
|
||||
bits,
|
||||
sign_extend,
|
||||
});
|
||||
@@ -484,7 +466,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
ctx.emit(Inst::Bkpt);
|
||||
}
|
||||
Opcode::Trap => {
|
||||
let trap_info = (ctx.srcloc(insn), inst_trapcode(ctx.data(insn)).unwrap());
|
||||
let trap_info = inst_trapcode(ctx.data(insn)).unwrap();
|
||||
ctx.emit(Inst::Udf { trap_info })
|
||||
}
|
||||
Opcode::Trapif => {
|
||||
@@ -496,7 +478,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
debug_assert_eq!(ctx.data(cmp_insn).opcode(), Opcode::Ifcmp);
|
||||
emit_cmp(ctx, cmp_insn);
|
||||
|
||||
let trap_info = (ctx.srcloc(insn), inst_trapcode(ctx.data(insn)).unwrap());
|
||||
let trap_info = inst_trapcode(ctx.data(insn)).unwrap();
|
||||
let condcode = inst_condcode(ctx.data(insn)).unwrap();
|
||||
let cond = lower_condcode(condcode);
|
||||
|
||||
@@ -512,7 +494,6 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
}
|
||||
Opcode::Call | Opcode::CallIndirect => {
|
||||
let loc = ctx.srcloc(insn);
|
||||
let caller_conv = ctx.abi().call_conv();
|
||||
let (mut abi, inputs) = match op {
|
||||
Opcode::Call => {
|
||||
@@ -522,7 +503,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
assert_eq!(inputs.len(), sig.params.len());
|
||||
assert_eq!(outputs.len(), sig.returns.len());
|
||||
(
|
||||
Arm32ABICaller::from_func(sig, &extname, dist, loc, caller_conv)?,
|
||||
Arm32ABICaller::from_func(sig, &extname, dist, caller_conv)?,
|
||||
&inputs[..],
|
||||
)
|
||||
}
|
||||
@@ -532,7 +513,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
assert_eq!(inputs.len() - 1, sig.params.len());
|
||||
assert_eq!(outputs.len(), sig.returns.len());
|
||||
(
|
||||
Arm32ABICaller::from_ptr(sig, ptr, loc, op, caller_conv)?,
|
||||
Arm32ABICaller::from_ptr(sig, ptr, op, caller_conv)?,
|
||||
&inputs[1..],
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user