machinst x64: add packed shifts
This commit is contained in:
@@ -4,6 +4,7 @@ use crate::ir::TrapCode;
|
||||
use crate::isa::x64::inst::args::*;
|
||||
use crate::isa::x64::inst::*;
|
||||
use crate::machinst::{MachBuffer, MachInstEmit, MachLabel};
|
||||
use core::convert::TryInto;
|
||||
use log::debug;
|
||||
use regalloc::{Reg, RegClass, Writable};
|
||||
use std::convert::TryFrom;
|
||||
@@ -1122,6 +1123,53 @@ pub(crate) fn emit(
|
||||
}
|
||||
}
|
||||
|
||||
Inst::XmmRmiReg { opcode, src, dst } => {
|
||||
let rex = RexFlags::clear_w();
|
||||
let prefix = LegacyPrefix::_66;
|
||||
if let RegMemImm::Imm { simm32 } = src {
|
||||
let (opcode_bytes, reg_digit) = match opcode {
|
||||
SseOpcode::Psllw => (0x0F71, 6),
|
||||
SseOpcode::Pslld => (0x0F72, 6),
|
||||
SseOpcode::Psllq => (0x0F73, 6),
|
||||
SseOpcode::Psraw => (0x0F71, 4),
|
||||
SseOpcode::Psrad => (0x0F72, 4),
|
||||
SseOpcode::Psrlw => (0x0F71, 2),
|
||||
SseOpcode::Psrld => (0x0F72, 2),
|
||||
SseOpcode::Psrlq => (0x0F73, 2),
|
||||
_ => panic!("invalid opcode: {}", opcode),
|
||||
};
|
||||
let dst_enc = reg_enc(dst.to_reg());
|
||||
emit_std_enc_enc(sink, prefix, opcode_bytes, 2, reg_digit, dst_enc, rex);
|
||||
let imm = (*simm32)
|
||||
.try_into()
|
||||
.expect("the immediate must be convertible to a u8");
|
||||
sink.put1(imm);
|
||||
} else {
|
||||
let opcode_bytes = match opcode {
|
||||
SseOpcode::Psllw => 0x0FF1,
|
||||
SseOpcode::Pslld => 0x0FF2,
|
||||
SseOpcode::Psllq => 0x0FF3,
|
||||
SseOpcode::Psraw => 0x0FE1,
|
||||
SseOpcode::Psrad => 0x0FE2,
|
||||
SseOpcode::Psrlw => 0x0FD1,
|
||||
SseOpcode::Psrld => 0x0FD2,
|
||||
SseOpcode::Psrlq => 0x0FD3,
|
||||
_ => panic!("invalid opcode: {}", opcode),
|
||||
};
|
||||
|
||||
match src {
|
||||
RegMemImm::Reg { reg } => {
|
||||
emit_std_reg_reg(sink, prefix, opcode_bytes, 2, dst.to_reg(), *reg, rex);
|
||||
}
|
||||
RegMemImm::Mem { addr } => {
|
||||
let addr = &addr.finalize(state);
|
||||
emit_std_reg_mem(sink, prefix, opcode_bytes, 2, dst.to_reg(), addr, rex);
|
||||
}
|
||||
RegMemImm::Imm { .. } => unreachable!(),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Inst::Cmp_RMI_R {
|
||||
size,
|
||||
src: src_e,
|
||||
|
||||
Reference in New Issue
Block a user