aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-02-22 00:51:30 -0800
committeriximeow <me@iximeow.net>2020-02-22 00:52:38 -0800
commit33c520341b373ac18e7924eb9227615ac65c2618 (patch)
tree391dc486a4ed6b416c843dccbe82621435c9f5d8
parent2e95a3235cab8ae80fa0b49aa35a333765ba828f (diff)
support 660f sse2 instructions
this isn't quite all of sse2, but gets close. the f20f opcode map still needs some touching up. also fix `G_E_xmm_Ib` not respecting rex.r for the rrr operand
-rw-r--r--src/long_mode/display.rs58
-rw-r--r--src/long_mode/mod.rs284
-rw-r--r--test/test.rs367
3 files changed, 532 insertions, 177 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs
index be7ab0d..d45a98a 100644
--- a/src/long_mode/display.rs
+++ b/src/long_mode/display.rs
@@ -285,7 +285,9 @@ impl fmt::Display for Opcode {
&Opcode::CMPSS => write!(f, "cmpss"),
&Opcode::CMPSD => write!(f, "cmpsd"),
&Opcode::UNPCKLPS => write!(f, "unpcklps"),
+ &Opcode::UNPCKLPD => write!(f, "unpcklpd"),
&Opcode::UNPCKHPS => write!(f, "unpckhps"),
+ &Opcode::UNPCKHPD => write!(f, "unpckhpd"),
&Opcode::MOVUPS => write!(f, "movups"),
&Opcode::MOVQ2DQ => write!(f, "movq2dq"),
&Opcode::MOVDQ2Q => write!(f, "movdq2q"),
@@ -499,40 +501,61 @@ impl fmt::Display for Opcode {
&Opcode::SETLE => write!(f, "setle"),
&Opcode::SETG => write!(f, "setg"),
&Opcode::ADDPS => write!(f, "addps"),
+ &Opcode::ADDPD => write!(f, "addpd"),
&Opcode::ANDNPS => write!(f, "andnps"),
+ &Opcode::ANDNPD => write!(f, "andnpd"),
&Opcode::ANDPS => write!(f, "andps"),
+ &Opcode::ANDPD => write!(f, "andpd"),
&Opcode::BSWAP => write!(f, "bswap"),
&Opcode::CMPPS => write!(f, "cmpps"),
+ &Opcode::CMPPD => write!(f, "cmppd"),
+ &Opcode::COMISD => write!(f, "comisd"),
&Opcode::COMISS => write!(f, "comiss"),
&Opcode::CVTDQ2PS => write!(f, "cvtdq2ps"),
+ &Opcode::CVTPS2DQ => write!(f, "cvtps2dq"),
&Opcode::CVTPI2PS => write!(f, "cvtpi2ps"),
&Opcode::CVTPI2PD => write!(f, "cvtpi2pd"),
&Opcode::CVTPS2PD => write!(f, "cvtps2pd"),
+ &Opcode::CVTPD2PS => write!(f, "cvtpd2ps"),
&Opcode::CVTPS2PI => write!(f, "cvtps2pi"),
+ &Opcode::CVTPD2PI => write!(f, "cvtpd2pi"),
&Opcode::CVTTPS2PI => write!(f, "cvttps2pi"),
+ &Opcode::CVTTPD2PI => write!(f, "cvttpd2pi"),
+ &Opcode::CVTTPD2DQ => write!(f, "cvttpd2dq"),
&Opcode::DIVPS => write!(f, "divps"),
+ &Opcode::DIVPD => write!(f, "divpd"),
&Opcode::EMMS => write!(f, "emms"),
&Opcode::GETSEC => write!(f, "getsec"),
&Opcode::LFS => write!(f, "lfs"),
&Opcode::LGS => write!(f, "lgs"),
&Opcode::LSS => write!(f, "lss"),
&Opcode::MASKMOVQ => write!(f, "maskmovq"),
+ &Opcode::MASKMOVDQU => write!(f, "maskmovdqu"),
&Opcode::MAXPS => write!(f, "maxps"),
+ &Opcode::MAXPD => write!(f, "maxpd"),
&Opcode::MINPS => write!(f, "minps"),
+ &Opcode::MINPD => write!(f, "minpd"),
&Opcode::MOVAPS => write!(f, "movaps"),
&Opcode::MOVAPD => write!(f, "movapd"),
&Opcode::MOVD => write!(f, "movd"),
&Opcode::MOVLPS => write!(f, "movlps"),
+ &Opcode::MOVLPD => write!(f, "movlpd"),
&Opcode::MOVLHPS => write!(f, "movlhps"),
&Opcode::MOVHPS => write!(f, "movhps"),
+ &Opcode::MOVHPD => write!(f, "movhpd"),
&Opcode::MOVHLPS => write!(f, "movhlps"),
&Opcode::MOVUPD => write!(f, "movupd"),
&Opcode::MOVMSKPS => write!(f, "movmskps"),
+ &Opcode::MOVMSKPD => write!(f, "movmskpd"),
&Opcode::MOVNTI => write!(f, "movnti"),
&Opcode::MOVNTPS => write!(f, "movntps"),
+ &Opcode::MOVNTPD => write!(f, "movntpd"),
&Opcode::MOVNTQ => write!(f, "movntq"),
+ &Opcode::MOVNTDQ => write!(f, "movntdq"),
&Opcode::MULPS => write!(f, "mulps"),
+ &Opcode::MULPD => write!(f, "mulpd"),
&Opcode::ORPS => write!(f, "orps"),
+ &Opcode::ORPD => write!(f, "orpd"),
&Opcode::PACKSSDW => write!(f, "packssdw"),
&Opcode::PACKSSWB => write!(f, "packsswb"),
&Opcode::PACKUSWB => write!(f, "packuswb"),
@@ -601,17 +624,22 @@ impl fmt::Display for Opcode {
&Opcode::RSM => write!(f, "rsm"),
&Opcode::RSQRTPS => write!(f, "rsqrtps"),
&Opcode::SHLD => write!(f, "shld"),
+ &Opcode::SHUFPD => write!(f, "shufpd"),
&Opcode::SHUFPS => write!(f, "shufps"),
&Opcode::SLHD => write!(f, "slhd"),
&Opcode::SQRTPS => write!(f, "sqrtps"),
+ &Opcode::SQRTPD => write!(f, "sqrtpd"),
&Opcode::SUBPS => write!(f, "subps"),
+ &Opcode::SUBPD => write!(f, "subpd"),
&Opcode::SYSENTER => write!(f, "sysenter"),
&Opcode::SYSEXIT => write!(f, "sysexit"),
+ &Opcode::UCOMISD => write!(f, "ucomisd"),
&Opcode::UCOMISS => write!(f, "ucomiss"),
&Opcode::UD2E => write!(f, "ud2e"),
&Opcode::VMREAD => write!(f, "vmread"),
&Opcode::VMWRITE => write!(f, "vmwrite"),
&Opcode::XORPS => write!(f, "xorps"),
+ &Opcode::XORPD => write!(f, "xorpd"),
&Opcode::CBW => write!(f, "cbw"),
&Opcode::CWDE => write!(f, "cwde"),
&Opcode::CDQE => write!(f, "cdqe"),
@@ -623,6 +651,7 @@ impl fmt::Display for Opcode {
&Opcode::BLSI => write!(f, "blsi"),
&Opcode::BLSMSK => write!(f, "blsmsk"),
&Opcode::BLSR => write!(f, "blsr"),
+ &Opcode::VMCLEAR => write!(f, "vmclear"),
&Opcode::VMCALL => write!(f, "vmcall"),
&Opcode::VMLAUNCH => write!(f, "vmlaunch"),
&Opcode::VMRESUME => write!(f, "vmresume"),
@@ -1291,12 +1320,19 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::BLSMSK |
Opcode::BLSR |
Opcode::ADDPS |
+ Opcode::ADDPD |
Opcode::ANDNPS |
+ Opcode::ANDNPD |
Opcode::ANDPS |
+ Opcode::ANDPD |
+ Opcode::COMISD |
Opcode::COMISS |
Opcode::DIVPS |
+ Opcode::DIVPD |
Opcode::MULPS |
+ Opcode::MULPD |
Opcode::ORPS |
+ Opcode::ORPD |
Opcode::PADDB |
Opcode::PADDD |
Opcode::PADDQ |
@@ -1340,11 +1376,15 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::PXOR |
Opcode::RSQRTPS |
Opcode::SQRTPS |
+ Opcode::SQRTPD |
Opcode::SUBPS |
+ Opcode::SUBPD |
Opcode::XORPS |
+ Opcode::XORPD |
Opcode::RCPPS |
Opcode::SHLD |
Opcode::SLHD |
+ Opcode::UCOMISD |
Opcode::UCOMISS |
Opcode::IMUL => { write!(out, "{}", colors.arithmetic_op(self)) }
Opcode::POPF |
@@ -1553,33 +1593,44 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::BSWAP |
Opcode::CVTDQ2PD |
Opcode::CVTDQ2PS |
+ Opcode::CVTPS2DQ |
Opcode::CVTPD2DQ |
Opcode::CVTPI2PS |
Opcode::CVTPI2PD |
Opcode::CVTPS2PD |
+ Opcode::CVTPD2PS |
Opcode::CVTPS2PI |
+ Opcode::CVTPD2PI |
Opcode::CVTSD2SI |
Opcode::CVTSD2SS |
Opcode::CVTSI2SD |
Opcode::CVTSI2SS |
Opcode::CVTSS2SD |
Opcode::CVTSS2SI |
+ Opcode::CVTTPD2DQ |
Opcode::CVTTPS2DQ |
Opcode::CVTTPS2PI |
+ Opcode::CVTTPD2PI |
Opcode::CVTTSD2SI |
Opcode::CVTTSS2SI |
Opcode::MASKMOVQ |
+ Opcode::MASKMOVDQU |
Opcode::MOVAPS |
Opcode::MOVAPD |
Opcode::MOVD |
Opcode::MOVHPS |
+ Opcode::MOVHPD |
Opcode::MOVHLPS |
Opcode::MOVLPS |
+ Opcode::MOVLPD |
Opcode::MOVLHPS |
Opcode::MOVMSKPS |
+ Opcode::MOVMSKPD |
Opcode::MOVNTI |
Opcode::MOVNTPS |
+ Opcode::MOVNTPD |
Opcode::MOVNTQ |
+ Opcode::MOVNTDQ |
Opcode::MOVSD |
Opcode::MOVSS |
Opcode::MOVUPD |
@@ -1597,7 +1648,10 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::PACKSSWB |
Opcode::PACKUSWB |
Opcode::UNPCKHPS |
+ Opcode::UNPCKHPD |
Opcode::UNPCKLPS |
+ Opcode::UNPCKLPD |
+ Opcode::SHUFPD |
Opcode::SHUFPS |
Opcode::PMOVMSKB |
Opcode::LDDQU |
@@ -1722,9 +1776,11 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::PCMPISTRI |
Opcode::PCMPISTRM |
Opcode::PTEST |
+ Opcode::MAXPD |
Opcode::MAXPS |
Opcode::MAXSD |
Opcode::MAXSS |
+ Opcode::MINPD |
Opcode::MINPS |
Opcode::MINSD |
Opcode::MINSS |
@@ -1746,6 +1802,7 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::CMPSS |
Opcode::CMP |
Opcode::CMPPS |
+ Opcode::CMPPD |
Opcode::CMPXCHG => { write!(out, "{}", colors.comparison_op(self)) }
Opcode::WRMSR |
@@ -1797,6 +1854,7 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::UD2E |
Opcode::VMREAD |
Opcode::VMWRITE |
+ Opcode::VMCLEAR |
Opcode::VMCALL |
Opcode::VMLAUNCH |
Opcode::VMRESUME |
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 954ae95..522eff5 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -458,12 +458,15 @@ pub enum Opcode {
MOVDDUP,
HADDPS,
HSUBPS,
+ ADDSUBPD,
ADDSUBPS,
CVTSI2SS,
CVTSI2SD,
CVTTSD2SI,
CVTTPS2DQ,
CVTPD2DQ,
+ CVTPD2PS,
+ CVTPS2DQ,
CVTSD2SI,
CVTSD2SS,
CVTTSS2SI,
@@ -639,7 +642,9 @@ pub enum Opcode {
CMPSS,
CMPSD,
UNPCKLPS,
+ UNPCKLPD,
UNPCKHPS,
+ UNPCKHPD,
PSHUFHW,
PSHUFLW,
MOVUPS,
@@ -653,6 +658,7 @@ pub enum Opcode {
BLSI,
BLSMSK,
BLSR,
+ VMCLEAR,
VMCALL,
VMLAUNCH,
VMRESUME,
@@ -673,40 +679,59 @@ pub enum Opcode {
WRPKRU,
ADDPS,
+ ADDPD,
ANDNPS,
+ ANDNPD,
ANDPS,
+ ANDPD,
BSWAP,
+ CMPPD,
CMPPS,
+ COMISD,
COMISS,
CVTDQ2PS,
CVTPI2PS,
CVTPI2PD,
CVTPS2PD,
CVTPS2PI,
+ CVTPD2PI,
CVTTPS2PI,
+ CVTTPD2PI,
+ CVTTPD2DQ,
DIVPS,
+ DIVPD,
EMMS,
GETSEC,
LFS,
LGS,
LSS,
MASKMOVQ,
+ MASKMOVDQU,
MAXPS,
+ MAXPD,
MINPS,
+ MINPD,
MOVAPS,
MOVAPD,
MOVD,
MOVLPS,
+ MOVLPD,
MOVHPS,
+ MOVHPD,
MOVLHPS,
MOVHLPS,
MOVUPD,
MOVMSKPS,
+ MOVMSKPD,
MOVNTI,
MOVNTPS,
+ MOVNTPD,
MOVNTQ,
+ MOVNTDQ,
MULPS,
+ MULPD,
ORPS,
+ ORPD,
PACKSSDW,
PACKSSWB,
PACKUSWB,
@@ -775,17 +800,22 @@ pub enum Opcode {
RSM,
RSQRTPS,
SHLD,
+ SHUFPD,
SHUFPS,
SLHD,
SQRTPS,
+ SQRTPD,
SUBPS,
+ SUBPD,
SYSENTER,
SYSEXIT,
+ UCOMISD,
UCOMISS,
UD2E,
VMREAD,
VMWRITE,
XORPS,
+ XORPD,
VMOVDDUP,
VPSHUFLW,
@@ -1193,7 +1223,6 @@ pub enum Opcode {
PHADDW,
HSUBPD,
HADDPD,
- ADDSUBPD,
}
#[derive(Debug)]
@@ -2725,6 +2754,12 @@ impl PrefixRex {
}
#[allow(non_camel_case_types)]
+// might be able to pack these into a u8, but with `Operand` being u16 as well now there's little
+// point. table entries will have a padding byte per record already.
+//
+// many of the one-off per-opcode variants could be written as 'decide based on opcode' but trying
+// to pack this more tightly only makes sense if opcode were smaller, to get some space savings.
+#[repr(u16)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum OperandCode {
ModRM_0x0f00,
@@ -2778,21 +2813,25 @@ pub enum OperandCode {
ModRM_0x0f71,
ModRM_0x0f72,
ModRM_0x0f73,
+ ModRM_0x660f12,
+ ModRM_0x660f16,
ModRM_0x660f71,
ModRM_0x660f72,
ModRM_0x660f73,
+ ModRM_0x660fc7,
ModRM_0x0fc7,
Nothing,
// Implied,
Unsupported,
- AL_Ib,
- AX_Ib,
- Ib_AL,
- Ib_AX,
- AX_DX,
- AL_DX,
- DX_AX,
- DX_AL,
+ AL_Ib = 0x100,
+ AX_Ib = 0x101,
+ Ib_AL = 0x102,
+ Ib_AX = 0x103,
+ AX_DX = 0x104,
+ AL_DX = 0x105,
+ DX_AX = 0x106,
+ DX_AL = 0x107,
+ G_xmm_Ed_Ib = 0x1ef, // mirror G_xmm_Edq, but also read an immediate
Zv_R0 = 0x40,
Zv_R1 = 0x41,
Zv_R2 = 0x42,
@@ -2873,7 +2912,7 @@ pub enum OperandCode {
Gv_M = 0xdb,
G_mm_Edq = 0xdd,
G_mm_E = 0xdf,
- // G_xmm_Ed = 0xe1,
+ G_U_xmm = 0xe1,
G_xmm_Eq = 0xe3,
G_mm_E_xmm = 0xe5,
G_E_mm = 0xe7,
@@ -2933,12 +2972,12 @@ const OPCODE_660F_MAP: [OpcodeRecord; 256] = [
// 0x10
OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPD), OperandCode::G_E_xmm),
OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPD), OperandCode::E_G_xmm),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f12),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPD), OperandCode::M_G_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKLPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKHPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPD), OperandCode::ModRM_0x660f16),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPD), OperandCode::M_G_xmm),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
@@ -2959,11 +2998,11 @@ const OPCODE_660F_MAP: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPD), OperandCode::G_E_xmm),
OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPD), OperandCode::E_G_xmm),
OpcodeRecord(Interpretation::Instruction(Opcode::CVTPI2PD), OperandCode::G_xmm_E_mm),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTPD), OperandCode::M_G_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPD2PI), OperandCode::G_mm_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::CVTPD2PI), OperandCode::G_mm_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::UCOMISD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::COMISD), OperandCode::G_E_xmm),
// 0x30
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
@@ -2999,22 +3038,22 @@ const OPCODE_660F_MAP: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
// 0x50
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVMSKPD), OperandCode::Gd_U_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::SQRTPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::ANDPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::ANDNPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::ORPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::XORPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::ADDPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MULPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::CVTPD2PS), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2DQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::SUBPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MINPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::DIVPD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MAXPD), OperandCode::G_E_xmm),
// 0x60
OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLBW), OperandCode::G_E_xmm),
OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLWD), OperandCode::G_E_xmm),
@@ -3120,12 +3159,12 @@ const OPCODE_660F_MAP: [OpcodeRecord; 256] = [
// 0xc0
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::CMPPD), OperandCode::G_E_xmm_Ib),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PINSRW), OperandCode::G_xmm_Ed_Ib),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::G_E_xmm_Ib),
+ OpcodeRecord(Interpretation::Instruction(Opcode::SHUFPD), OperandCode::G_E_xmm_Ib),
+ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660fc7),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
@@ -3136,55 +3175,55 @@ const OPCODE_660F_MAP: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
// 0xd0
OpcodeRecord(Interpretation::Instruction(Opcode::ADDSUBPD), OperandCode::G_E_xmm),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSRLW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSRLD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSRLQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PADDQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PMULLW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::E_G_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PMOVMSKB), OperandCode::Gd_U_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PMINUB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PAND), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PADDUSB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PADDUSW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PMAXUB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PANDN), OperandCode::G_E_xmm),
// 0xe0
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PAVGB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSRAW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSRAD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PAVGW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PMULHUW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PMULHW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPD2DQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTDQ), OperandCode::M_G_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PMINSW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::POR), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PADDSB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PADDSW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PMAXSW), OperandCode::G_E_xmm),
OpcodeRecord(Interpretation::Instruction(Opcode::PXOR), OperandCode::G_E_xmm),
// 0xf0
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSLLW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSLLD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSLLQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PMULUDQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PMADDWD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSADBW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MASKMOVDQU), OperandCode::G_U_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSUBB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSUBW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSUBD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSUBQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PADDB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PADDW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PADDD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PADDQ), OperandCode::G_E_xmm),
];
fn read_opcode_660f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), DecodeError> {
@@ -5138,6 +5177,15 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.modrm_mmm.num &= 0b111;
instruction.operand_count = 2;
},
+ OperandCode::G_U_xmm => {
+ instruction.operands[1] = mem_oper;
+ instruction.modrm_rrr.bank = RegisterBank::X;
+ if mem_oper != OperandSpec::RegMMM {
+ return Err(DecodeError::InvalidOperand);
+ }
+ instruction.modrm_mmm.bank = RegisterBank::X;
+ instruction.operand_count = 2;
+ },
op @ OperandCode::G_M_xmm |
op @ OperandCode::G_E_xmm => {
instruction.modrm_rrr.bank = RegisterBank::X;
@@ -5158,7 +5206,8 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
let modrm = read_modrm(&mut bytes_iter, length)?;
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
- instruction.modrm_rrr = RegSpec { bank: RegisterBank::X, num: (modrm >> 3) & 7 };
+ instruction.modrm_rrr =
+ RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
instruction.operands[0] = OperandSpec::RegRRR;
instruction.imm =
read_num(&mut bytes_iter, 1)? as u8 as u64;
@@ -5379,6 +5428,36 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
instruction.operands[1] = OperandSpec::ImmU8;
},
+ OperandCode::ModRM_0x660f12 => {
+ // If this is reg-reg, interpret the instruction as 66-prefixed (no-op here)
+ // `movhlps`. If this is reg-mem, it's a `movlpd`.
+ let modrm = read_modrm(&mut bytes_iter, length)?;
+ if modrm & 0xc0 == 0xc0 {
+ instruction.opcode = Opcode::MOVHLPS;
+ } else {
+ instruction.opcode = Opcode::MOVLPD;
+ }
+ instruction.modrm_rrr =
+ RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
+ instruction.operands[0] = OperandSpec::RegRRR;
+ instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operand_count = 2;
+ }
+ OperandCode::ModRM_0x660f16 => {
+ // If this is reg-reg, interpret the instruction as 66-prefixed (no-op here)
+ // `movlhps`. If this is reg-mem, it's a `movhpd`.
+ let modrm = read_modrm(&mut bytes_iter, length)?;
+ if modrm & 0xc0 == 0xc0 {
+ instruction.opcode = Opcode::MOVLHPS;
+ } else {
+ instruction.opcode = Opcode::MOVHPD;
+ }
+ instruction.modrm_rrr =
+ RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
+ instruction.operands[0] = OperandSpec::RegRRR;
+ instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operand_count = 2;
+ }
OperandCode::ModRM_0x660f38 => {
let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?;
match op {
@@ -5517,6 +5596,24 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
instruction.operands[1] = OperandSpec::ImmU8;
},
+ OperandCode::ModRM_0x660fc7 => {
+ let modrm = read_modrm(&mut bytes_iter, length)?;
+
+ let r = (modrm >> 3) & 7;
+ match r {
+ 6 => {
+ instruction.opcode = Opcode::VMCLEAR;
+ instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 1 /* doesn't matter, something using this width is invalid */, length)?;
+ if instruction.operands[0] == OperandSpec::RegMMM {
+ return Err(DecodeError::InvalidOperand);
+ }
+ instruction.operand_count = 1;
+ }
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+ },
OperandCode::G_mm_Edq => {
instruction.operands[1] = mem_oper;
instruction.modrm_rrr.bank = RegisterBank::MM;
@@ -5581,6 +5678,17 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
},
+ OperandCode::G_xmm_Ed_Ib => {
+ instruction.operands[1] = mem_oper;
+ instruction.operands[2] = OperandSpec::ImmU8;
+ instruction.imm =
+ read_num(&mut bytes_iter, 1)? as u64;
+ *length += 1;
+ instruction.modrm_rrr.bank = RegisterBank::X;
+ if mem_oper == OperandSpec::RegMMM {
+ instruction.modrm_mmm.bank = RegisterBank::D;
+ }
+ },
OperandCode::G_xmm_Eq => {
instruction.operands[1] = mem_oper;
instruction.modrm_rrr.bank = RegisterBank::X;
diff --git a/test/test.rs b/test/test.rs
index 1bac590..e13f587 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -114,6 +114,284 @@ fn test_aesni() {
}
#[test]
+fn test_sse2() {
+ fn test_instr(bytes: &[u8], text: &'static str) {
+ // sse and sse2 are part of amd64, so x86_64, meaning even the minimal decoder must support
+ // them.
+ test_display_under(&InstDecoder::minimal(), bytes, text);
+ }
+
+ fn test_instr_invalid(bytes: &[u8]) {
+ test_invalid_under(&InstDecoder::minimal(), bytes);
+ test_invalid_under(&InstDecoder::default(), bytes);
+ }
+
+ test_instr(&[0x66, 0x4f, 0x0f, 0x12, 0xc3], "movhlps xmm8, xmm11"); // reg-reg form is movhlps
+ test_instr(&[0x66, 0x4f, 0x0f, 0x12, 0x03], "movlpd xmm8, [r11]"); // reg-mem is movlpd
+ test_instr(&[0x66, 0x4f, 0x0f, 0x13, 0x03], "movlpd [r11], xmm8");
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x13, 0xc3]);
+ test_instr(&[0x66, 0x4f, 0x0f, 0x14, 0x03], "unpcklpd xmm8, [r11]");
+ test_instr(&[0x66, 0x4f, 0x0f, 0x14, 0xc3], "unpcklpd xmm8, xmm11");
+ test_instr(&[0x66, 0x4f, 0x0f, 0x15, 0x03], "unpckhpd xmm8, [r11]");
+ test_instr(&[0x66, 0x4f, 0x0f, 0x15, 0xc3], "unpckhpd xmm8, xmm11");
+ test_instr(&[0x66, 0x4f, 0x0f, 0x16, 0x03], "movhpd xmm8, [r11]");
+ test_instr(&[0x66, 0x4f, 0x0f, 0x16, 0xc3], "movlhps xmm8, xmm11");
+ test_instr(&[0x66, 0x4f, 0x0f, 0x17, 0x03], "movhpd [r11], xmm8");
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x17, 0xc3]);
+
+ test_display(&[0x66, 0x4f, 0x0f, 0x28, 0xd0], "movapd xmm10, xmm8");
+ test_display(&[0x66, 0x4f, 0x0f, 0x28, 0x00], "movapd xmm8, [r8]");
+
+ test_display(&[0x66, 0x4f, 0x0f, 0x2a, 0xcf], "cvtpi2pd xmm9, mm7");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2a, 0x0f], "cvtpi2pd xmm9, [r15]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2b, 0x0f], "movntpd [r15], xmm9");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2c, 0xcf], "cvttpd2pi mm1, xmm15");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2c, 0x0f], "cvttpd2pi mm1, [r15]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2d, 0xcf], "cvtpd2pi mm1, xmm15");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2d, 0x0f], "cvtpd2pi mm1, [r15]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2e, 0xcf], "ucomisd xmm9, xmm15");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2e, 0x0f], "ucomisd xmm9, [r15]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2f, 0xcf], "comisd xmm9, xmm15");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2f, 0x0f], "comisd xmm9, [r15]");
+
+ /*
+ * .... 660f38
+ * .... 660f7f
+ */
+
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x50, 0x01]);
+ test_display(&[0x66, 0x4f, 0x0f, 0x50, 0xc1], "movmskpd r8d, xmm9");
+ test_display(&[0x66, 0x4f, 0x0f, 0x51, 0x01], "sqrtpd xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x52, 0x01], "rsqrtps xmm8, [r9]"); // note: NOT "rsqrtpd" - no such instruction exists, so fall back to just 0f52 parse.
+ test_display(&[0x66, 0x4f, 0x0f, 0x53, 0x01], "rcpps xmm8, [r9]"); // note: NOT "rcppd" - no such instruction exists, so fall back to just 0f53 parse.
+ test_display(&[0x66, 0x4f, 0x0f, 0x54, 0x01], "andpd xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x55, 0x01], "andnpd xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x56, 0x01], "orpd xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x57, 0x01], "xorpd xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x58, 0x01], "addpd xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x59, 0x01], "mulpd xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x5a, 0x01], "cvtpd2ps xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x5b, 0x01], "cvtps2dq xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x5c, 0x01], "subpd xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x5d, 0x01], "minpd xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x5e, 0x01], "divpd xmm8, [r9]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x5f, 0x01], "maxpd xmm8, [r9]");
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x60, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "punpcklbw xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x61, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "punpcklwd xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x62, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "punpckldq xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x63, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "packsswb xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x64, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "pcmpgtb xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x65, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "pcmpgtw xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x66, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "pcmpgtd xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x67, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "packuswb xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x68, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "punpckhbw xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x69, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "punpckhwd xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x6a, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "punpckhdq xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x6b, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "packssdw xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x6c, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "punpcklqdq xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x6d, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "punpckhqdq xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ // TODO: this needs to be clear that the operand is `dword`
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x6e, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "movq xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+ test_display(
+ &[0x66, 0x4f, 0x0f, 0x6f, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
+ "movdqa xmm11, [r12 + r11 * 4 - 0x334455cc]"
+ );
+
+ test_display(&[0x66, 0x48, 0x0f, 0x6e, 0xc0], "movq xmm0, rax");
+ test_display(&[0x66, 0x0f, 0x70, 0xc0, 0x4e], "pshufd xmm0, xmm0, 0x4e");
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x71, 0x10, 0x8f]);
+ test_display(&[0x66, 0x4f, 0x0f, 0x71, 0xd0, 0x8f], "psrlw xmm0, 0x8f");
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x71, 0x20, 0x8f]);
+ test_display(&[0x66, 0x4f, 0x0f, 0x71, 0xe0, 0x8f], "psraw xmm0, 0x8f");
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x71, 0x30, 0x8f]);
+ test_display(&[0x66, 0x4f, 0x0f, 0x71, 0xf0, 0x8f], "psllw xmm0, 0x8f");
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x72, 0x10, 0x8f]);
+ test_display(&[0x66, 0x4f, 0x0f, 0x72, 0xd0, 0x8f], "psrld xmm0, 0x8f");
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x72, 0x20, 0x8f]);
+ test_display(&[0x66, 0x4f, 0x0f, 0x72, 0xe0, 0x8f], "psrad xmm0, 0x8f");
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x72, 0x30, 0x8f]);
+ test_display(&[0x66, 0x4f, 0x0f, 0x72, 0xf0, 0x8f], "pslld xmm0, 0x8f");
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x10, 0x8f]);
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x18, 0x8f]);
+ test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xd0, 0x8f], "psrlq xmm0, 0x8f");
+ test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xd8, 0x8f], "psrldq xmm0, 0x8f");
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x30, 0x8f]);
+ test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x38, 0x8f]);
+ test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xf0, 0x8f], "psllq xmm0, 0x8f");
+ test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xf8, 0x8f], "pslldq xmm0, 0x8f");
+
+ test_instr(&[0x66, 0x0f, 0xc2, 0xc3, 0x08], "cmppd xmm0, xmm3, 0x8");
+ test_instr(&[0x66, 0x4f, 0x0f, 0xc2, 0xc3, 0x08], "cmppd xmm8, xmm11, 0x8");
+ test_instr(&[0x66, 0x4f, 0x0f, 0xc2, 0x03, 0x08], "cmppd xmm8, [r11], 0x8");
+
+ test_instr(&[0x66, 0x0f, 0xc4, 0xc3, 0x08], "pinsrw xmm0, ebx, 0x8");
+ test_instr(&[0x66, 0x4f, 0x0f, 0xc4, 0xc3, 0x08], "pinsrw xmm8, r11d, 0x8");
+
+ test_instr(&[0x66, 0x0f, 0xc4, 0x03, 0x08], "pinsrw xmm0, [rbx], 0x8");
+ test_instr(&[0x66, 0x4f, 0x0f, 0xc4, 0x03, 0x08], "pinsrw xmm8, [r11], 0x8");
+
+// test_instr(&[0x66, 0x0f, 0xc5, 0xc3, 0x08], "pextrw eax, xmm3, 0x8");
+// test_instr(&[0x66, 0x4f, 0x0f, 0xc5, 0xc3, 0x08], "pextrw r8d, xmm11, 0x8");
+// test_instr_invalid(&[0x66, 0x0f, 0xc5, 0x03, 0x08]);
+// test_instr_invalid(&[0x66, 0x0f, 0xc5, 0x40, 0x08]);
+// test_instr_invalid(&[0x66, 0x0f, 0xc5, 0x80, 0x08]);
+
+ test_instr(&[0x66, 0x4f, 0x0f, 0xc6, 0x03, 0x08], "shufpd xmm8, [r11], 0x8");
+ test_instr(&[0x66, 0x0f, 0xc6, 0x03, 0x08], "shufpd xmm0, [rbx], 0x8");
+ test_instr(&[0x66, 0x0f, 0xc6, 0xc3, 0x08], "shufpd xmm0, xmm3, 0x8");
+ test_instr(&[0x66, 0x0f, 0xd1, 0xc1], "psrlw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xd1, 0x01], "psrlw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xd2, 0xc1], "psrld xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xd2, 0x01], "psrld xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xd3, 0xc1], "psrlq xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xd3, 0x01], "psrlq xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xd4, 0xc1], "paddq xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xd4, 0x01], "paddq xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xd5, 0xc1], "pmullw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xd5, 0x01], "pmullw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xd6, 0xc1], "movq xmm1, xmm0");
+ test_instr(&[0x66, 0x0f, 0xd6, 0x01], "movq [rcx], xmm0");
+ test_instr(&[0x66, 0x0f, 0xd7, 0xc1], "pmovmskb eax, xmm1");
+ test_instr(&[0x66, 0x4f, 0x0f, 0xd7, 0xc1], "pmovmskb r8d, xmm9");
+ test_invalid(&[0x66, 0x0f, 0xd7, 0x01]);
+ test_instr(&[0x66, 0x0f, 0xd8, 0xc1], "psubusb xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xd8, 0x01], "psubusb xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xd9, 0xc1], "psubusw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xd9, 0x01], "psubusw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xda, 0xc1], "pminub xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xda, 0x01], "pminub xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xdb, 0xc1], "pand xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xdb, 0x01], "pand xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xdc, 0xc1], "paddusb xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xdc, 0x01], "paddusb xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xdd, 0xc1], "paddusw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xdd, 0x01], "paddusw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xde, 0xc1], "pmaxub xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xde, 0x01], "pmaxub xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xdf, 0xc1], "pandn xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xdf, 0x01], "pandn xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xe0, 0xc1], "pavgb xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xe0, 0x01], "pavgb xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xe1, 0xc1], "psraw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xe1, 0x01], "psraw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xe2, 0xc1], "psrad xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xe2, 0x01], "psrad xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xe3, 0xc1], "pavgw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xe3, 0x01], "pavgw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xe4, 0xc1], "pmulhuw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xe4, 0x01], "pmulhuw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xe5, 0xc1], "pmulhw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xe5, 0x01], "pmulhw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xe6, 0xc1], "cvttpd2dq xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xe6, 0x01], "cvttpd2dq xmm0, [rcx]");
+ test_invalid(&[0x66, 0x0f, 0xe7, 0xc1]);
+ test_instr(&[0x66, 0x0f, 0xe7, 0x01], "movntdq [rcx], xmm0");
+ test_instr(&[0x66, 0x0f, 0xe8, 0xc1], "psubsb xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xe8, 0x01], "psubsb xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xe9, 0xc1], "psubsw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xe9, 0x01], "psubsw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xea, 0xc1], "pminsw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xea, 0x01], "pminsw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xeb, 0xc3], "por xmm0, xmm3");
+ test_instr(&[0x66, 0x0f, 0xeb, 0xc4], "por xmm0, xmm4");
+ test_instr(&[0x66, 0x0f, 0xeb, 0xd3], "por xmm2, xmm3");
+ test_instr(&[0x66, 0x0f, 0xeb, 0x12], "por xmm2, [rdx]");
+ test_instr(&[0x66, 0x0f, 0xeb, 0xc1], "por xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xeb, 0x01], "por xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xec, 0xc1], "paddsb xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xec, 0x01], "paddsb xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xed, 0xc1], "paddsw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xed, 0x01], "paddsw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xee, 0xc1], "pmaxsw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xee, 0x01], "pmaxsw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xef, 0xc1], "pxor xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xef, 0x01], "pxor xmm0, [rcx]");
+ test_invalid(&[0x66, 0x0f, 0xf0, 0xc1]);
+ test_invalid(&[0x66, 0x0f, 0xf0, 0x01]);
+ test_instr(&[0x66, 0x0f, 0xf1, 0xc1], "psllw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xf1, 0x01], "psllw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xf2, 0xc1], "pslld xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xf2, 0x01], "pslld xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xf3, 0xc1], "psllq xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xf3, 0x01], "psllq xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xf4, 0xc1], "pmuludq xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xf4, 0x01], "pmuludq xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xf5, 0xc1], "pmaddwd xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xf5, 0x01], "pmaddwd xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xf6, 0xc1], "psadbw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xf6, 0x01], "psadbw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xf7, 0xc1], "maskmovdqu xmm0, xmm1");
+ test_invalid(&[0x66, 0x0f, 0xf7, 0x01]);
+ test_instr(&[0x66, 0x0f, 0xf8, 0xc1], "psubb xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xf8, 0x01], "psubb xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xf9, 0xc1], "psubw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xf9, 0x01], "psubw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xfa, 0xc1], "psubd xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xfa, 0x01], "psubd xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xfb, 0xc1], "psubq xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xfb, 0x01], "psubq xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xfc, 0xc1], "paddb xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xfc, 0x01], "paddb xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xfd, 0xc1], "paddw xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xfd, 0x01], "paddw xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xfe, 0xc1], "paddd xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xfe, 0x01], "paddd xmm0, [rcx]");
+ test_instr(&[0x66, 0x0f, 0xff, 0xc1], "paddq xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0xff, 0x01], "paddq xmm0, [rcx]");
+
+ test_instr(&[0x66, 0x0f, 0x74, 0xc1], "pcmpeqb xmm0, xmm1");
+ test_instr(&[0x66, 0x0f, 0x74, 0x12], "pcmpeqb xmm2, [rdx]");
+ test_instr(&[0x66, 0x0f, 0xf8, 0xc8], "psubb xmm1, xmm0");
+ test_instr(&[0x66, 0x0f, 0xf8, 0xd0], "psubb xmm2, xmm0");
+ test_instr(&[0x66, 0x0f, 0xf8, 0x12], "psubb xmm2, [rdx]");
+}
+
+#[test]
fn test_sse3() {
fn test_instr(bytes: &[u8], text: &'static str) {
test_display_under(&InstDecoder::minimal().with_sse3(), bytes, text);
@@ -298,94 +576,6 @@ fn test_E_decode() {
#[test]
fn test_sse() {
- test_display(
- &[0x66, 0x4f, 0x0f, 0x60, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "punpcklbw xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x61, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "punpcklwd xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x62, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "punpckldq xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x63, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "packsswb xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x64, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "pcmpgtb xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x65, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "pcmpgtw xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x66, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "pcmpgtd xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x67, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "packuswb xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x68, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "punpckhbw xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x69, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "punpckhwd xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x6a, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "punpckhdq xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x6b, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "packssdw xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x6c, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "punpcklqdq xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x6d, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "punpckhqdq xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- // this needs to be clear that the operand is `dword`
- test_display(
- &[0x66, 0x4f, 0x0f, 0x6e, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "movq xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
- test_display(
- &[0x66, 0x4f, 0x0f, 0x6f, 0x9c, 0x9c, 0x34, 0xaa, 0xbb, 0xcc],
- "movdqa xmm11, [r12 + r11 * 4 - 0x334455cc]"
- );
-
- test_display(&[0x66, 0x48, 0x0f, 0x6e, 0xc0], "movq xmm0, rax");
- test_display(&[0x66, 0x0f, 0x70, 0xc0, 0x4e], "pshufd xmm0, xmm0, 0x4e");
- test_invalid(&[0x66, 0x4f, 0x0f, 0x71, 0x10, 0x8f]);
- test_display(&[0x66, 0x4f, 0x0f, 0x71, 0xd0, 0x8f], "psrlw xmm0, 0x8f");
- test_invalid(&[0x66, 0x4f, 0x0f, 0x71, 0x20, 0x8f]);
- test_display(&[0x66, 0x4f, 0x0f, 0x71, 0xe0, 0x8f], "psraw xmm0, 0x8f");
- test_invalid(&[0x66, 0x4f, 0x0f, 0x71, 0x30, 0x8f]);
- test_display(&[0x66, 0x4f, 0x0f, 0x71, 0xf0, 0x8f], "psllw xmm0, 0x8f");
- test_invalid(&[0x66, 0x4f, 0x0f, 0x72, 0x10, 0x8f]);
- test_display(&[0x66, 0x4f, 0x0f, 0x72, 0xd0, 0x8f], "psrld xmm0, 0x8f");
- test_invalid(&[0x66, 0x4f, 0x0f, 0x72, 0x20, 0x8f]);
- test_display(&[0x66, 0x4f, 0x0f, 0x72, 0xe0, 0x8f], "psrad xmm0, 0x8f");
- test_invalid(&[0x66, 0x4f, 0x0f, 0x72, 0x30, 0x8f]);
- test_display(&[0x66, 0x4f, 0x0f, 0x72, 0xf0, 0x8f], "pslld xmm0, 0x8f");
- test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x10, 0x8f]);
- test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x18, 0x8f]);
- test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xd0, 0x8f], "psrlq xmm0, 0x8f");
- test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xd8, 0x8f], "psrldq xmm0, 0x8f");
- test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x30, 0x8f]);
- test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x38, 0x8f]);
- test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xf0, 0x8f], "psllq xmm0, 0x8f");
- test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xf8, 0x8f], "pslldq xmm0, 0x8f");
test_display(&[0x4f, 0x0f, 0x28, 0x00], "movaps xmm8, [r8]");
test_display(&[0x4f, 0x0f, 0x29, 0x00], "movaps [r8], xmm8");
test_display(&[0x4f, 0x0f, 0x2b, 0x00], "movntps [r8], xmm8");
@@ -408,7 +598,6 @@ fn test_sse() {
test_display(&[0x4f, 0x0f, 0x59, 0x00], "mulps xmm8, [r8]");
test_display(&[0x4f, 0x0f, 0x5a, 0x00], "cvtps2pd xmm8, [r8]");
test_display(&[0x4f, 0x0f, 0x5b, 0x00], "cvtdq2ps xmm8, [r8]");
- test_display(&[0x66, 0x4f, 0x0f, 0x5b, 0x00], "cvtdq2ps xmm8, [r8]");
test_display(&[0x67, 0x4f, 0x0f, 0x5b, 0x00], "cvtdq2ps xmm8, [r8d]");
test_display(&[0x4f, 0x66, 0x0f, 0x28, 0x00], "movapd xmm0, [rax]");
test_display(&[0x66, 0x4f, 0x0f, 0x28, 0x00], "movapd xmm8, [r8]");