aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-01-15 02:23:13 -0800
committeriximeow <me@iximeow.net>2020-01-15 02:23:13 -0800
commita38fe698c2e00a798231ad0ccd984912b593f15a (patch)
tree4316dab52d0989789accc0717fd595879acbbad8
parent53a6a79595e100b16b85d75676bcfee56cbd40f0 (diff)
add more sse2 instructions (packed shift by immediate, mostly)
really need to adjust OperandCode, almost out of one-off options...
-rw-r--r--src/display.rs4
-rw-r--r--src/lib.rs117
-rw-r--r--test/test.rs21
3 files changed, 128 insertions, 14 deletions
diff --git a/src/display.rs b/src/display.rs
index f3400f6..29e718e 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -567,11 +567,13 @@ impl fmt::Display for Opcode {
&Opcode::PSHUFW => write!(f, "pshufw"),
&Opcode::PSHUFD => write!(f, "pshufd"),
&Opcode::PSLLD => write!(f, "pslld"),
+ &Opcode::PSLLDQ => write!(f, "pslldq"),
&Opcode::PSLLQ => write!(f, "psllq"),
&Opcode::PSLLW => write!(f, "psllw"),
&Opcode::PSRAD => write!(f, "psrad"),
&Opcode::PSRAW => write!(f, "psraw"),
&Opcode::PSRLD => write!(f, "psrld"),
+ &Opcode::PSRLDQ => write!(f, "psrldq"),
&Opcode::PSRLQ => write!(f, "psrlq"),
&Opcode::PSRLW => write!(f, "psrlw"),
&Opcode::PSUBB => write!(f, "psubb"),
@@ -1314,11 +1316,13 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color
Opcode::PSHUFW |
Opcode::PSHUFB |
Opcode::PSLLD |
+ Opcode::PSLLDQ |
Opcode::PSLLQ |
Opcode::PSLLW |
Opcode::PSRAD |
Opcode::PSRAW |
Opcode::PSRLD |
+ Opcode::PSRLDQ |
Opcode::PSRLQ |
Opcode::PSRLW |
Opcode::PSUBB |
diff --git a/src/lib.rs b/src/lib.rs
index 28523ab..0e02bbe 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -747,11 +747,13 @@ pub enum Opcode {
PSHUFW,
PSHUFD,
PSLLD,
+ PSLLDQ,
PSLLQ,
PSLLW,
PSRAD,
PSRAW,
PSRLD,
+ PSRLDQ,
PSRLQ,
PSRLW,
PSUBB,
@@ -2753,10 +2755,6 @@ pub enum OperandCode {
AX_Xv,
DX_AX,
E_G_xmm,
- E_G_ymm,
- E_G_zmm,
- G_E_ymm,
- G_E_zmm,
Ev_Ivs,
Ew_Sw,
Fw,
@@ -2786,6 +2784,9 @@ pub enum OperandCode {
ModRM_0x0f71,
ModRM_0x0f72,
ModRM_0x0f73,
+ ModRM_0x660f71,
+ ModRM_0x660f72,
+ ModRM_0x660f73,
ModRM_0x0fc7,
Nothing,
Implied,
@@ -3031,12 +3032,12 @@ const OPCODE_660F_MAP: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQA), OperandCode::G_E_xmm),
// 0x70
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),
- 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_0x660f71),
+ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f72),
+ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f73),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQB), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQW), OperandCode::G_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQD), 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),
@@ -5327,7 +5328,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 };
instruction.operands[0] = OperandSpec::RegMMM;
instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
- instruction.operands[1] = OperandSpec::ImmI8;
+ instruction.operands[1] = OperandSpec::ImmU8;
},
OperandCode::ModRM_0x0f72 => {
instruction.operand_count = 2;
@@ -5356,7 +5357,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 };
instruction.operands[0] = OperandSpec::RegMMM;
instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
- instruction.operands[1] = OperandSpec::ImmI8;
+ instruction.operands[1] = OperandSpec::ImmU8;
},
OperandCode::ModRM_0x0f73 => {
instruction.operand_count = 2;
@@ -5382,7 +5383,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 };
instruction.operands[0] = OperandSpec::RegMMM;
instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
- instruction.operands[1] = OperandSpec::ImmI8;
+ instruction.operands[1] = OperandSpec::ImmU8;
},
OperandCode::ModRM_0x660f38 => {
let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?;
@@ -5432,6 +5433,96 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
};
}
+ OperandCode::ModRM_0x660f71 => {
+ instruction.operand_count = 2;
+
+ let modrm = read_modrm(&mut bytes_iter, length)?;
+ if modrm & 0xc0 != 0xc0 {
+ return Err(DecodeError::InvalidOperand);
+ }
+
+ let r = (modrm >> 3) & 7;
+ match r {
+ 2 => {
+ instruction.opcode = Opcode::PSRLW;
+ }
+ 4 => {
+ instruction.opcode = Opcode::PSRAW;
+ }
+ 6 => {
+ instruction.opcode = Opcode::PSLLW;
+ }
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+
+ instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 };
+ instruction.operands[0] = OperandSpec::RegMMM;
+ instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
+ instruction.operands[1] = OperandSpec::ImmU8;
+ },
+ OperandCode::ModRM_0x660f72 => {
+ instruction.operand_count = 2;
+
+ let modrm = read_modrm(&mut bytes_iter, length)?;
+ if modrm & 0xc0 != 0xc0 {
+ return Err(DecodeError::InvalidOperand);
+ }
+
+ let r = (modrm >> 3) & 7;
+ match r {
+ 2 => {
+ instruction.opcode = Opcode::PSRLD;
+ }
+ 4 => {
+ instruction.opcode = Opcode::PSRAD;
+ }
+ 6 => {
+ instruction.opcode = Opcode::PSLLD;
+ }
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+
+ instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 };
+ instruction.operands[0] = OperandSpec::RegMMM;
+ instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
+ instruction.operands[1] = OperandSpec::ImmU8;
+ },
+ OperandCode::ModRM_0x660f73 => {
+ instruction.operand_count = 2;
+
+ let modrm = read_modrm(&mut bytes_iter, length)?;
+ if modrm & 0xc0 != 0xc0 {
+ return Err(DecodeError::InvalidOperand);
+ }
+
+ let r = (modrm >> 3) & 7;
+ match r {
+ 2 => {
+ instruction.opcode = Opcode::PSRLQ;
+ }
+ 3 => {
+ instruction.opcode = Opcode::PSRLDQ;
+ }
+ 6 => {
+ instruction.opcode = Opcode::PSLLQ;
+ }
+ 7 => {
+ instruction.opcode = Opcode::PSLLDQ;
+ }
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+
+ instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 };
+ instruction.operands[0] = OperandSpec::RegMMM;
+ instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
+ instruction.operands[1] = OperandSpec::ImmU8;
+ },
OperandCode::G_mm_Edq => {
instruction.operands[1] = mem_oper;
instruction.modrm_rrr.bank = RegisterBank::MM;
diff --git a/test/test.rs b/test/test.rs
index 5187df8..7248117 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -127,7 +127,6 @@ fn test_sse3() {
test_invalid_under(&InstDecoder::minimal().with_sse3(), bytes);
test_invalid_under(&InstDecoder::default(), bytes);
}
-
test_instr(&[0xf2, 0x0f, 0xf0, 0x0f], "lddqu xmm1, [rdi]");
test_instr_invalid(&[0xf2, 0x0f, 0xf0, 0xcf]);
test_instr(&[0xf2, 0x0f, 0xd0, 0x0f], "addsubps xmm1, [rdi]");
@@ -365,6 +364,26 @@ fn test_sse() {
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");