machinst x64: implement SymbolValue and FuncAddr with a movabsq+reloc;
This commit is contained in:
@@ -1479,6 +1479,25 @@ pub(crate) fn emit(
|
|||||||
let dst = &dst.finalize(state);
|
let dst = &dst.finalize(state);
|
||||||
emit_std_reg_mem(sink, prefix, opcode, 2, *src, dst, rex);
|
emit_std_reg_mem(sink, prefix, opcode, 2, *src, dst, rex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inst::LoadExtName {
|
||||||
|
dst,
|
||||||
|
name,
|
||||||
|
offset,
|
||||||
|
srcloc,
|
||||||
|
} => {
|
||||||
|
// The full address can be encoded in the register, with a relocation.
|
||||||
|
let enc_dst = int_reg_enc(dst.to_reg());
|
||||||
|
sink.put1(0x48 | ((enc_dst >> 3) & 1));
|
||||||
|
sink.put1(0xB8 | (enc_dst & 7));
|
||||||
|
sink.add_reloc(*srcloc, Reloc::Abs8, name, *offset);
|
||||||
|
if flags.emit_all_ones_funcaddrs() {
|
||||||
|
sink.put8(u64::max_value());
|
||||||
|
} else {
|
||||||
|
sink.put8(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Inst::Hlt => {
|
Inst::Hlt => {
|
||||||
sink.put1(0xcc);
|
sink.put1(0xcc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,14 @@
|
|||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
|
use alloc::boxed::Box;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use smallvec::SmallVec;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::string::{String, ToString};
|
use std::string::{String, ToString};
|
||||||
|
|
||||||
use regalloc::RegUsageCollector;
|
use regalloc::RegUsageCollector;
|
||||||
use regalloc::{RealRegUniverse, Reg, RegClass, RegUsageMapper, SpillSlot, VirtualReg, Writable};
|
use regalloc::{RealRegUniverse, Reg, RegClass, RegUsageMapper, SpillSlot, VirtualReg, Writable};
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::binemit::CodeOffset;
|
use crate::binemit::CodeOffset;
|
||||||
use crate::ir::types::{B1, B128, B16, B32, B64, B8, F32, F64, I128, I16, I32, I64, I8};
|
use crate::ir::types::{B1, B128, B16, B32, B64, B8, F32, F64, I128, I16, I32, I64, I8};
|
||||||
@@ -270,6 +271,14 @@ pub enum Inst {
|
|||||||
/// An instruction that will always trigger the illegal instruction exception.
|
/// An instruction that will always trigger the illegal instruction exception.
|
||||||
Ud2 { trap_info: (SourceLoc, TrapCode) },
|
Ud2 { trap_info: (SourceLoc, TrapCode) },
|
||||||
|
|
||||||
|
/// Loads an external symbol in a register, with a relocation.
|
||||||
|
LoadExtName {
|
||||||
|
dst: Writable<Reg>,
|
||||||
|
name: Box<ExternalName>,
|
||||||
|
srcloc: SourceLoc,
|
||||||
|
offset: i64,
|
||||||
|
},
|
||||||
|
|
||||||
// =====================================
|
// =====================================
|
||||||
// Meta-instructions generating no code.
|
// Meta-instructions generating no code.
|
||||||
/// Marker, no-op in generated code: SP "virtual offset" is adjusted. This
|
/// Marker, no-op in generated code: SP "virtual offset" is adjusted. This
|
||||||
@@ -815,6 +824,15 @@ impl ShowWithRRU for Inst {
|
|||||||
Inst::TrapIf { cc, trap_code, .. } => {
|
Inst::TrapIf { cc, trap_code, .. } => {
|
||||||
format!("j{} ; ud2 {} ;", cc.invert().to_string(), trap_code)
|
format!("j{} ; ud2 {} ;", cc.invert().to_string(), trap_code)
|
||||||
}
|
}
|
||||||
|
Inst::LoadExtName {
|
||||||
|
dst, name, offset, ..
|
||||||
|
} => format!(
|
||||||
|
"{} {}+{}, {}",
|
||||||
|
ljustify("movaps".into()),
|
||||||
|
name,
|
||||||
|
offset,
|
||||||
|
show_ireg_sized(dst.to_reg(), mb_rru, 8),
|
||||||
|
),
|
||||||
Inst::VirtualSPOffsetAdj { offset } => format!("virtual_sp_offset_adjust {}", offset),
|
Inst::VirtualSPOffsetAdj { offset } => format!("virtual_sp_offset_adjust {}", offset),
|
||||||
Inst::Hlt => "hlt".into(),
|
Inst::Hlt => "hlt".into(),
|
||||||
Inst::Ud2 { trap_info } => format!("ud2 {}", trap_info.1),
|
Inst::Ud2 { trap_info } => format!("ud2 {}", trap_info.1),
|
||||||
@@ -958,6 +976,10 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
|
|||||||
target.get_regs_as_uses(collector);
|
target.get_regs_as_uses(collector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inst::LoadExtName { dst, .. } => {
|
||||||
|
collector.add_def(*dst);
|
||||||
|
}
|
||||||
|
|
||||||
Inst::Ret
|
Inst::Ret
|
||||||
| Inst::EpiloguePlaceholder
|
| Inst::EpiloguePlaceholder
|
||||||
| Inst::JmpKnown { .. }
|
| Inst::JmpKnown { .. }
|
||||||
@@ -1187,6 +1209,8 @@ fn x64_map_regs<RUM: RegUsageMapper>(inst: &mut Inst, mapper: &RUM) {
|
|||||||
|
|
||||||
Inst::JmpUnknown { ref mut target } => target.map_uses(mapper),
|
Inst::JmpUnknown { ref mut target } => target.map_uses(mapper),
|
||||||
|
|
||||||
|
Inst::LoadExtName { ref mut dst, .. } => map_def(mapper, dst),
|
||||||
|
|
||||||
Inst::Ret
|
Inst::Ret
|
||||||
| Inst::EpiloguePlaceholder
|
| Inst::EpiloguePlaceholder
|
||||||
| Inst::JmpKnown { .. }
|
| Inst::JmpKnown { .. }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use log::trace;
|
|||||||
use regalloc::{Reg, RegClass, Writable};
|
use regalloc::{Reg, RegClass, Writable};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
use alloc::boxed::Box;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
@@ -973,6 +974,32 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Opcode::FuncAddr => {
|
||||||
|
let dst = output_to_reg(ctx, outputs[0]);
|
||||||
|
let (extname, _) = ctx.call_target(insn).unwrap();
|
||||||
|
let extname = extname.clone();
|
||||||
|
let loc = ctx.srcloc(insn);
|
||||||
|
ctx.emit(Inst::LoadExtName {
|
||||||
|
dst,
|
||||||
|
name: Box::new(extname),
|
||||||
|
srcloc: loc,
|
||||||
|
offset: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Opcode::SymbolValue => {
|
||||||
|
let dst = output_to_reg(ctx, outputs[0]);
|
||||||
|
let (extname, _, offset) = ctx.symbol_value(insn).unwrap();
|
||||||
|
let extname = extname.clone();
|
||||||
|
let loc = ctx.srcloc(insn);
|
||||||
|
ctx.emit(Inst::LoadExtName {
|
||||||
|
dst,
|
||||||
|
name: Box::new(extname),
|
||||||
|
srcloc: loc,
|
||||||
|
offset,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Opcode::StackAddr => {
|
Opcode::StackAddr => {
|
||||||
let (stack_slot, offset) = match *ctx.data(insn) {
|
let (stack_slot, offset) = match *ctx.data(insn) {
|
||||||
InstructionData::StackLoad {
|
InstructionData::StackLoad {
|
||||||
|
|||||||
Reference in New Issue
Block a user