aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-01-15 01:49:42 -0800
committeriximeow <me@iximeow.net>2020-01-15 01:49:42 -0800
commit53a6a79595e100b16b85d75676bcfee56cbd40f0 (patch)
treec4d1179ef3b214a0177b67dc53128424dc5bce48
parent95fbfd0165a6ed2aac9098ab015a25de68030a3b (diff)
add 660f6* series instructions as well as 660f70
this adds in some missing sse2 instructions in the alternate secondary opcode map. because these were missing, instructions were incorrectly decoded from the 0f opcode map, yielding mmx-operand versions of themselves (usually) there are undoubtedly more missing sse2 instructions from the 660f map.
-rw-r--r--src/display.rs8
-rw-r--r--src/lib.rs50
-rw-r--r--test/test.rs70
3 files changed, 110 insertions, 18 deletions
diff --git a/src/display.rs b/src/display.rs
index 4c97d5c..f3400f6 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -278,6 +278,7 @@ impl fmt::Display for Opcode {
match self {
&Opcode::POPCNT => write!(f, "popcnt"),
&Opcode::MOVDQU => write!(f, "movdqu"),
+ &Opcode::MOVDQA => write!(f, "movdqa"),
&Opcode::MOVQ => write!(f, "movq"),
&Opcode::CMPSS => write!(f, "cmpss"),
&Opcode::CMPSD => write!(f, "cmpsd"),
@@ -564,6 +565,7 @@ impl fmt::Display for Opcode {
&Opcode::POR => write!(f, "por"),
&Opcode::PSADBW => write!(f, "psadbw"),
&Opcode::PSHUFW => write!(f, "pshufw"),
+ &Opcode::PSHUFD => write!(f, "pshufd"),
&Opcode::PSLLD => write!(f, "pslld"),
&Opcode::PSLLQ => write!(f, "psllq"),
&Opcode::PSLLW => write!(f, "psllw"),
@@ -586,6 +588,8 @@ impl fmt::Display for Opcode {
&Opcode::PUNPCKLBW => write!(f, "punpcklbw"),
&Opcode::PUNPCKLDQ => write!(f, "punpckldq"),
&Opcode::PUNPCKLWD => write!(f, "punpcklwd"),
+ &Opcode::PUNPCKLQDQ => write!(f, "punpcklqdq"),
+ &Opcode::PUNPCKHQDQ => write!(f, "punpckhqdq"),
&Opcode::PXOR => write!(f, "pxor"),
&Opcode::RCPPS => write!(f, "rcpps"),
&Opcode::RSM => write!(f, "rsm"),
@@ -1306,6 +1310,7 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::PMULUDQ |
Opcode::POR |
Opcode::PSADBW |
+ Opcode::PSHUFD |
Opcode::PSHUFW |
Opcode::PSHUFB |
Opcode::PSLLD |
@@ -1578,6 +1583,8 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::PUNPCKLBW |
Opcode::PUNPCKLDQ |
Opcode::PUNPCKLWD |
+ Opcode::PUNPCKLQDQ |
+ Opcode::PUNPCKHQDQ |
Opcode::PACKSSDW |
Opcode::PACKSSWB |
Opcode::PACKUSWB |
@@ -1602,6 +1609,7 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::MOVSLDUP |
Opcode::MOVDQ2Q |
Opcode::MOVDQU |
+ Opcode::MOVDQA |
Opcode::MOVQ |
Opcode::MOVQ2DQ |
Opcode::MOVSHDUP |
diff --git a/src/lib.rs b/src/lib.rs
index 6941b9e..28523ab 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -636,6 +636,7 @@ pub enum Opcode {
JMPE,
POPCNT,
MOVDQU,
+ MOVDQA,
MOVQ,
CMPSS,
CMPSD,
@@ -744,6 +745,7 @@ pub enum Opcode {
POR,
PSADBW,
PSHUFW,
+ PSHUFD,
PSLLD,
PSLLQ,
PSLLW,
@@ -766,6 +768,8 @@ pub enum Opcode {
PUNPCKLBW,
PUNPCKLDQ,
PUNPCKLWD,
+ PUNPCKLQDQ,
+ PUNPCKHQDQ,
PXOR,
RCPPS,
RSM,
@@ -3009,24 +3013,24 @@ const OPCODE_660F_MAP: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
// 0x60
- 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::PUNPCKLBW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLWD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLDQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSWB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PACKUSWB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHBW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHWD), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHDQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSDW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLQDQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHQDQ), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::G_xmm_Eq),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQA), OperandCode::G_E_xmm),
// 0x70
- OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFD), 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),
@@ -5155,6 +5159,18 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
}
}
},
+ OperandCode::G_E_xmm_Ib => {
+ 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.operands[0] = OperandSpec::RegRRR;
+ instruction.imm =
+ read_num(&mut bytes_iter, 1)? as u8 as u64;
+ *length += 1;
+ instruction.operands[2] = OperandSpec::ImmI8;
+ instruction.operand_count = 3;
+ },
OperandCode::G_E_mm_Ib => {
let modrm = read_modrm(&mut bytes_iter, length)?;
diff --git a/test/test.rs b/test/test.rs
index 0945328..5187df8 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -4,7 +4,7 @@ extern crate yaxpeax_x86;
use std::fmt::Write;
use yaxpeax_arch::{Decoder, LengthedInstruction};
-use yaxpeax_x86::{DecodeError, Instruction, InstDecoder};
+use yaxpeax_x86::{DecodeError, InstDecoder};
fn test_invalid(data: &[u8]) {
test_invalid_under(&InstDecoder::default(), data);
@@ -297,6 +297,74 @@ 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_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");