Add MInst.XmmUnaryRmRImm to handle rounding instructions (#4823)
Add a new pseudo-instruction, XmmUnaryRmRImm, to handle instructions like roundss that only use their first register argument for the instruction's result. This has the added benefit of allowing the isle wrappers for those instructions to take an XmmMem argument, allowing for more cases where loads may be merged.
This commit is contained in:
@@ -1612,6 +1612,33 @@ pub(crate) fn emit(
|
||||
};
|
||||
}
|
||||
|
||||
Inst::XmmUnaryRmRImm { op, src, dst, imm } => {
|
||||
debug_assert!(!op.uses_src1());
|
||||
|
||||
let dst = allocs.next(dst.to_reg().to_reg());
|
||||
let src = src.clone().to_reg_mem().with_allocs(allocs);
|
||||
let rex = RexFlags::clear_w();
|
||||
|
||||
let (prefix, opcode, len) = match op {
|
||||
SseOpcode::Roundps => (LegacyPrefixes::_66, 0x0F3A08, 3),
|
||||
SseOpcode::Roundss => (LegacyPrefixes::_66, 0x0F3A0A, 3),
|
||||
SseOpcode::Roundpd => (LegacyPrefixes::_66, 0x0F3A09, 3),
|
||||
SseOpcode::Roundsd => (LegacyPrefixes::_66, 0x0F3A0B, 3),
|
||||
_ => unimplemented!("Opcode {:?} not implemented", op),
|
||||
};
|
||||
match src {
|
||||
RegMem::Reg { reg } => {
|
||||
emit_std_reg_reg(sink, prefix, opcode, len, dst, reg, rex);
|
||||
}
|
||||
RegMem::Mem { addr } => {
|
||||
let addr = &addr.finalize(state, sink);
|
||||
// N.B.: bytes_at_end == 1, because of the `imm` byte below.
|
||||
emit_std_reg_mem(sink, info, prefix, opcode, len, dst, addr, rex, 1);
|
||||
}
|
||||
}
|
||||
sink.put1(*imm);
|
||||
}
|
||||
|
||||
Inst::XmmUnaryRmREvex { op, src, dst } => {
|
||||
let dst = allocs.next(dst.to_reg().to_reg());
|
||||
let src = src.clone().to_reg_mem().with_allocs(allocs);
|
||||
@@ -1975,10 +2002,6 @@ pub(crate) fn emit(
|
||||
SseOpcode::Pextrw => (LegacyPrefixes::_66, 0x0FC5, 2),
|
||||
SseOpcode::Pextrd => (LegacyPrefixes::_66, 0x0F3A16, 3),
|
||||
SseOpcode::Pshufd => (LegacyPrefixes::_66, 0x0F70, 2),
|
||||
SseOpcode::Roundps => (LegacyPrefixes::_66, 0x0F3A08, 3),
|
||||
SseOpcode::Roundss => (LegacyPrefixes::_66, 0x0F3A0A, 3),
|
||||
SseOpcode::Roundpd => (LegacyPrefixes::_66, 0x0F3A09, 3),
|
||||
SseOpcode::Roundsd => (LegacyPrefixes::_66, 0x0F3A0B, 3),
|
||||
SseOpcode::Shufps => (LegacyPrefixes::None, 0x0FC6, 2),
|
||||
_ => unimplemented!("Opcode {:?} not implemented", op),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user