cranelift-codegen: Add support for immediate to memory moves in x64 (#5461)
This change adds support for immediate to memory moves in x64 which are needed by Winch for zeroing local slots. This change follows the guideline in `isa/x64/inst/emit` and uses other instructions (immediate to register moves) as a base for the test cases. The instruction encoding expectation was derived by assembling each instruction and inspecting the assembly with `objdump`.
This commit is contained in:
@@ -670,6 +670,38 @@ pub(crate) fn emit(
|
||||
}
|
||||
}
|
||||
|
||||
Inst::MovImmM { size, simm64, dst } => {
|
||||
let dst = &dst.finalize(state, sink).with_allocs(allocs);
|
||||
let default_rex = RexFlags::clear_w();
|
||||
let default_opcode = 0xC7;
|
||||
let bytes = size.to_bytes();
|
||||
let prefix = LegacyPrefixes::None;
|
||||
|
||||
let (opcode, rex, size, prefix) = match *size {
|
||||
// In the 8-bit case, we don't need to enforce REX flags via
|
||||
// `always_emit_if_8bit_needed()` since the destination
|
||||
// operand is a memory operand, not a possibly 8-bit register.
|
||||
OperandSize::Size8 => (0xC6, default_rex, bytes, prefix),
|
||||
OperandSize::Size16 => (0xC7, default_rex, bytes, LegacyPrefixes::_66),
|
||||
OperandSize::Size64 => {
|
||||
if !low32_will_sign_extend_to_64(*simm64) {
|
||||
panic!("Immediate-to-memory moves require immediate operand to sign-extend to 64 bits.");
|
||||
}
|
||||
|
||||
(default_opcode, RexFlags::from(*size), bytes, prefix)
|
||||
}
|
||||
|
||||
_ => (default_opcode, default_rex, bytes, prefix),
|
||||
};
|
||||
|
||||
// 8-bit C6 /0 ib
|
||||
// 16-bit 0x66 C7 /0 iw
|
||||
// 32-bit C7 /0 id
|
||||
// 64-bit REX.W C7 /0 id
|
||||
emit_std_enc_mem(sink, prefix, opcode, 1, /*subopcode*/ 0, dst, rex, 0);
|
||||
emit_simm(sink, size, *simm64 as u32);
|
||||
}
|
||||
|
||||
Inst::MovRR { size, src, dst } => {
|
||||
let src = allocs.next(src.to_reg());
|
||||
let dst = allocs.next(dst.to_reg().to_reg());
|
||||
|
||||
Reference in New Issue
Block a user