[machinst x64]: allow addressing of constants
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
use super::regs::{self, show_ireg_sized};
|
||||
use super::EmitState;
|
||||
use crate::ir::condcodes::{FloatCC, IntCC};
|
||||
use crate::isa::x64::inst::Inst;
|
||||
use crate::machinst::*;
|
||||
use regalloc::{
|
||||
PrettyPrint, PrettyPrintSized, RealRegUniverse, Reg, RegClass, RegUsageCollector,
|
||||
@@ -104,6 +105,9 @@ pub enum SyntheticAmode {
|
||||
/// A (virtual) offset to the "nominal SP" value, which will be recomputed as we push and pop
|
||||
/// within the function.
|
||||
NominalSPOffset { simm32: u32 },
|
||||
|
||||
/// A virtual offset to a constant that will be emitted in the constant section of the buffer.
|
||||
ConstantOffset(VCodeConstant),
|
||||
}
|
||||
|
||||
impl SyntheticAmode {
|
||||
@@ -118,6 +122,7 @@ impl SyntheticAmode {
|
||||
SyntheticAmode::NominalSPOffset { .. } => {
|
||||
// Nothing to do; the base is SP and isn't involved in regalloc.
|
||||
}
|
||||
SyntheticAmode::ConstantOffset(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,10 +132,11 @@ impl SyntheticAmode {
|
||||
SyntheticAmode::NominalSPOffset { .. } => {
|
||||
// Nothing to do.
|
||||
}
|
||||
SyntheticAmode::ConstantOffset(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn finalize(&self, state: &mut EmitState) -> Amode {
|
||||
pub(crate) fn finalize(&self, state: &mut EmitState, buffer: &MachBuffer<Inst>) -> Amode {
|
||||
match self {
|
||||
SyntheticAmode::Real(addr) => addr.clone(),
|
||||
SyntheticAmode::NominalSPOffset { simm32 } => {
|
||||
@@ -142,6 +148,9 @@ impl SyntheticAmode {
|
||||
);
|
||||
Amode::imm_reg(off as u32, regs::rsp())
|
||||
}
|
||||
SyntheticAmode::ConstantOffset(c) => {
|
||||
Amode::rip_relative(buffer.get_label_for_constant(*c))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,6 +168,7 @@ impl PrettyPrint for SyntheticAmode {
|
||||
SyntheticAmode::NominalSPOffset { simm32 } => {
|
||||
format!("rsp({} + virtual offset)", *simm32 as i32)
|
||||
}
|
||||
SyntheticAmode::ConstantOffset(c) => format!("const({:?})", c),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,7 +533,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
RegMemImm::Mem { addr } => {
|
||||
let amode = addr.finalize(state);
|
||||
let amode = addr.finalize(state, sink);
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -592,7 +592,7 @@ pub(crate) fn emit(
|
||||
|
||||
RegMemImm::Mem { addr } => {
|
||||
// Here we revert to the "normal" G-E ordering.
|
||||
let amode = addr.finalize(state);
|
||||
let amode = addr.finalize(state, sink);
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -649,7 +649,7 @@ pub(crate) fn emit(
|
||||
rex_flags,
|
||||
),
|
||||
RegMem::Mem { addr: src } => {
|
||||
let amode = src.finalize(state);
|
||||
let amode = src.finalize(state, sink);
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -715,7 +715,7 @@ pub(crate) fn emit(
|
||||
emit_std_enc_enc(sink, prefix, opcode, 1, subopcode, src, rex_flags)
|
||||
}
|
||||
RegMem::Mem { addr: src } => {
|
||||
let amode = src.finalize(state);
|
||||
let amode = src.finalize(state, sink);
|
||||
emit_std_enc_mem(sink, state, prefix, opcode, 1, subopcode, &amode, rex_flags);
|
||||
}
|
||||
}
|
||||
@@ -736,7 +736,7 @@ pub(crate) fn emit(
|
||||
emit_std_enc_enc(sink, prefix, 0xF7, 1, subopcode, src, rex_flags)
|
||||
}
|
||||
RegMem::Mem { addr: src } => {
|
||||
let amode = src.finalize(state);
|
||||
let amode = src.finalize(state, sink);
|
||||
emit_std_enc_mem(sink, state, prefix, 0xF7, 1, subopcode, &amode, rex_flags);
|
||||
}
|
||||
}
|
||||
@@ -981,7 +981,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
RegMem::Mem { addr: src } => {
|
||||
let src = &src.finalize(state);
|
||||
let src = &src.finalize(state, sink);
|
||||
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
@@ -998,7 +998,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
Inst::Mov64MR { src, dst } => {
|
||||
let src = &src.finalize(state);
|
||||
let src = &src.finalize(state, sink);
|
||||
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
@@ -1013,7 +1013,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
Inst::LoadEffectiveAddress { addr, dst } => {
|
||||
let amode = addr.finalize(state);
|
||||
let amode = addr.finalize(state, sink);
|
||||
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
@@ -1075,7 +1075,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
RegMem::Mem { addr: src } => {
|
||||
let src = &src.finalize(state);
|
||||
let src = &src.finalize(state, sink);
|
||||
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
@@ -1092,7 +1092,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
Inst::MovRM { size, src, dst } => {
|
||||
let dst = &dst.finalize(state);
|
||||
let dst = &dst.finalize(state, sink);
|
||||
|
||||
match size {
|
||||
1 => {
|
||||
@@ -1248,7 +1248,7 @@ pub(crate) fn emit(
|
||||
emit_std_reg_reg(sink, prefix, opcode_bytes, 2, dst.to_reg(), *reg, rex);
|
||||
}
|
||||
RegMemImm::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -1307,7 +1307,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
RegMemImm::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
// Whereas here we revert to the "normal" G-E ordering.
|
||||
let opcode = if *size == 1 { 0x3A } else { 0x3B };
|
||||
emit_std_reg_mem(sink, state, prefix, opcode, 1, *reg_g, addr, rex);
|
||||
@@ -1367,7 +1367,7 @@ pub(crate) fn emit(
|
||||
emit_std_reg_reg(sink, prefix, opcode, 2, reg_g.to_reg(), *reg_e, rex_flags);
|
||||
}
|
||||
RegMem::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -1418,7 +1418,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
RegMemImm::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
emit_std_enc_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -1484,7 +1484,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
RegMem::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
emit_std_enc_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -1582,7 +1582,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
RegMem::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
emit_std_enc_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -1728,7 +1728,7 @@ pub(crate) fn emit(
|
||||
);
|
||||
}
|
||||
RegMem::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -1841,7 +1841,7 @@ pub(crate) fn emit(
|
||||
emit_std_reg_reg(sink, prefix, opcode, length, reg_g.to_reg(), *reg_e, rex);
|
||||
}
|
||||
RegMem::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -1986,7 +1986,7 @@ pub(crate) fn emit(
|
||||
}
|
||||
}
|
||||
RegMem::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
assert!(
|
||||
!regs_swapped,
|
||||
"No existing way to encode a mem argument in the ModRM r/m field."
|
||||
@@ -2020,7 +2020,7 @@ pub(crate) fn emit(
|
||||
SseOpcode::Movupd => (LegacyPrefixes::_66, 0x0F11),
|
||||
_ => unimplemented!("Opcode {:?} not implemented", op),
|
||||
};
|
||||
let dst = &dst.finalize(state);
|
||||
let dst = &dst.finalize(state, sink);
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
state,
|
||||
@@ -2087,7 +2087,7 @@ pub(crate) fn emit(
|
||||
emit_std_reg_reg(sink, prefix, opcode, 2, reg_g.to_reg(), *reg_e, rex);
|
||||
}
|
||||
RegMem::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
emit_std_reg_mem(sink, state, prefix, opcode, 2, reg_g.to_reg(), addr, rex);
|
||||
}
|
||||
}
|
||||
@@ -2107,7 +2107,7 @@ pub(crate) fn emit(
|
||||
emit_std_reg_reg(sink, prefix, opcode, len, *dst, *reg, rex);
|
||||
}
|
||||
RegMem::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
let addr = &addr.finalize(state, sink);
|
||||
emit_std_reg_mem(sink, state, prefix, opcode, len, *dst, addr, rex);
|
||||
}
|
||||
}
|
||||
@@ -2621,7 +2621,7 @@ pub(crate) fn emit(
|
||||
types::I64 => (LegacyPrefixes::_F0, RexFlags::set_w(), 0x0FB1),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let amode = dst.finalize(state);
|
||||
let amode = dst.finalize(state, sink);
|
||||
emit_std_reg_mem(sink, state, prefix, opcodes, 2, *src, &amode, rex);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user