machinst x64: emit nop of variable sizes;
This commit is contained in:
@@ -2720,10 +2720,85 @@ pub(crate) fn emit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Inst::Nop { len } => {
|
Inst::Nop { len } => {
|
||||||
if *len == 0 {
|
// These encodings can all be found in Intel's architecture manual, at the NOP
|
||||||
// Nothing to emit.
|
// instruction description.
|
||||||
} else {
|
let mut len = *len;
|
||||||
unimplemented!("non-zero nop opcodes.");
|
while len != 0 {
|
||||||
|
let emitted = u8::min(len, 9);
|
||||||
|
match emitted {
|
||||||
|
0 => {}
|
||||||
|
1 => sink.put1(0x90), // NOP
|
||||||
|
2 => {
|
||||||
|
// 66 NOP
|
||||||
|
sink.put1(0x66);
|
||||||
|
sink.put1(0x90);
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
// NOP [EAX]
|
||||||
|
sink.put1(0x0F);
|
||||||
|
sink.put1(0x1F);
|
||||||
|
sink.put1(0x00);
|
||||||
|
}
|
||||||
|
4 => {
|
||||||
|
// NOP 0(EAX), with 0 a 1-byte immediate.
|
||||||
|
sink.put1(0x0F);
|
||||||
|
sink.put1(0x1F);
|
||||||
|
sink.put1(0x40);
|
||||||
|
sink.put1(0x00);
|
||||||
|
}
|
||||||
|
5 => {
|
||||||
|
// NOP [EAX, EAX, 1]
|
||||||
|
sink.put1(0x0F);
|
||||||
|
sink.put1(0x1F);
|
||||||
|
sink.put1(0x44);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
}
|
||||||
|
6 => {
|
||||||
|
// 66 NOP [EAX, EAX, 1]
|
||||||
|
sink.put1(0x66);
|
||||||
|
sink.put1(0x0F);
|
||||||
|
sink.put1(0x1F);
|
||||||
|
sink.put1(0x44);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
}
|
||||||
|
7 => {
|
||||||
|
// NOP 0[EAX], but 0 is a 4 bytes immediate.
|
||||||
|
sink.put1(0x0F);
|
||||||
|
sink.put1(0x1F);
|
||||||
|
sink.put1(0x80);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
}
|
||||||
|
8 => {
|
||||||
|
// NOP 0[EAX, EAX, 1], with 0 a 4 bytes immediate.
|
||||||
|
sink.put1(0x0F);
|
||||||
|
sink.put1(0x1F);
|
||||||
|
sink.put1(0x84);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
}
|
||||||
|
9 => {
|
||||||
|
// 66 NOP 0[EAX, EAX, 1], with 0 a 4 bytes immediate.
|
||||||
|
sink.put1(0x66);
|
||||||
|
sink.put1(0x0F);
|
||||||
|
sink.put1(0x1F);
|
||||||
|
sink.put1(0x84);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
sink.put1(0x00);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
len -= emitted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2487,7 +2487,7 @@ impl MachInst for Inst {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn gen_nop(preferred_size: usize) -> Inst {
|
fn gen_nop(preferred_size: usize) -> Inst {
|
||||||
Inst::nop(preferred_size as u8)
|
Inst::nop((preferred_size % 16) as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_direct_reload(&self, _reg: VirtualReg, _slot: SpillSlot) -> Option<Inst> {
|
fn maybe_direct_reload(&self, _reg: VirtualReg, _slot: SpillSlot) -> Option<Inst> {
|
||||||
|
|||||||
Reference in New Issue
Block a user