aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--src/long_mode/mod.rs32
-rw-r--r--test/long_mode/mod.rs10
3 files changed, 31 insertions, 12 deletions
diff --git a/CHANGELOG b/CHANGELOG
index dcbe03c..54f1ada 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,7 @@
zero-extended to 64 bits for storage. writing to "eax" in this way implies the 32->64 bit
zero-extend, whereas writing to "ax" does not imply any zero-extension. mov reg-to-seg
is unchanged and uses a 16-bit form for source GPR.
+* fix pextr{b,w,d,q} and extractps first and second operands being backwards.
* reject 0f0d prefetch/nop with a register operand, which was incorrectly decoded before.
* maskmovq and maskmovdqu now have their implicit memory access size reported correctly.
* monitor now reports the memory access size of the monitored dword/qword.
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index de9a323..4165885 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -4034,6 +4034,7 @@ pub enum OperandCase {
PMOVX_G_E_xmm,
PMOVX_E_G_xmm,
G_Ev_xmm_Ib,
+ Ev_G_xmm_Ib,
G_E_mm_Ib,
MOVDIR64B,
MASKMOVDQU,
@@ -4392,6 +4393,7 @@ enum OperandCode {
PMOVX_G_E_xmm = OperandCodeBuilder::new().read_E().operand_case(OperandCase::PMOVX_G_E_xmm).bits(),
PMOVX_E_G_xmm = OperandCodeBuilder::new().read_E().operand_case(OperandCase::PMOVX_E_G_xmm).bits(),
G_Ev_xmm_Ib = OperandCodeBuilder::new().read_E().operand_case(OperandCase::G_Ev_xmm_Ib).bits(),
+ Ev_G_xmm_Ib = OperandCodeBuilder::new().read_E().operand_case(OperandCase::Ev_G_xmm_Ib).bits(),
G_E_mm_Ib = OperandCodeBuilder::new().read_E().operand_case(OperandCase::G_E_mm_Ib).bits(),
MASKMOVDQU = OperandCodeBuilder::new().read_E().reg_mem().operand_case(OperandCase::MASKMOVDQU).bits(),
}
@@ -6721,8 +6723,9 @@ fn read_operands<
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
}
- OperandCase::G_Ev_xmm_Ib => {
- instruction.operands[1] = mem_oper;
+ OperandCase::Ev_G_xmm_Ib => {
+ instruction.operands[1] = instruction.operands[0];
+ instruction.operands[0] = mem_oper;
instruction.regs[0].bank = RegisterBank::X;
instruction.imm =
read_num(words, 1)? as u8 as u64;
@@ -6732,6 +6735,21 @@ fn read_operands<
Opcode::PEXTRW => 2,
Opcode::PEXTRD => 4,
Opcode::EXTRACTPS => 4,
+ _ => 8,
+ };
+ } else {
+ instruction.regs[1].bank = RegisterBank::X;
+ }
+ instruction.operands[2] = OperandSpec::ImmI8;
+ instruction.operand_count = 3;
+ }
+ OperandCase::G_Ev_xmm_Ib => {
+ instruction.operands[1] = mem_oper;
+ instruction.regs[0].bank = RegisterBank::X;
+ instruction.imm =
+ read_num(words, 1)? as u8 as u64;
+ if instruction.operands[1] != OperandSpec::RegMMM {
+ instruction.mem_size = match instruction.opcode {
Opcode::INSERTPS => 4,
Opcode::PINSRB => 1,
Opcode::PINSRW => 2,
@@ -9282,7 +9300,7 @@ fn read_0f3a_opcode(&mut self, opcode: u8, prefixes: &mut Prefixes) -> Result<Op
if prefixes.operand_size() {
if opcode == 0x16 && prefixes.rex_unchecked().w() {
- return Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PEXTRQ), OperandCode::G_Ev_xmm_Ib));
+ return Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PEXTRQ), OperandCode::Ev_G_xmm_Ib));
} else if opcode == 0x22 && prefixes.rex_unchecked().w() {
return Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PINSRQ), OperandCode::G_Ev_xmm_Ib));
}
@@ -9296,10 +9314,10 @@ fn read_0f3a_opcode(&mut self, opcode: u8, prefixes: &mut Prefixes) -> Result<Op
0x0d => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::BLENDPD), OperandCode::G_E_xmm_Ib)),
0x0e => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PBLENDW), OperandCode::G_E_xmm_Ib)),
0x0f => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PALIGNR), OperandCode::G_E_xmm_Ib)),
- 0x14 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PEXTRB), OperandCode::G_Ev_xmm_Ib)),
- 0x15 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::G_Ev_xmm_Ib)),
- 0x16 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PEXTRD), OperandCode::G_Ev_xmm_Ib)),
- 0x17 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::EXTRACTPS), OperandCode::G_Ev_xmm_Ib)),
+ 0x14 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PEXTRB), OperandCode::Ev_G_xmm_Ib)),
+ 0x15 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::Ev_G_xmm_Ib)),
+ 0x16 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PEXTRD), OperandCode::Ev_G_xmm_Ib)),
+ 0x17 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::EXTRACTPS), OperandCode::Ev_G_xmm_Ib)),
0x20 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PINSRB), OperandCode::G_Ev_xmm_Ib)),
0x21 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::INSERTPS), OperandCode::G_Ev_xmm_Ib)),
0x22 => Ok(OpcodeRecord::new(Interpretation::Instruction(Opcode::PINSRD), OperandCode::G_Ev_xmm_Ib)),
diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs
index 7145325..9b378bd 100644
--- a/test/long_mode/mod.rs
+++ b/test/long_mode/mod.rs
@@ -868,14 +868,14 @@ fn test_sse4_1() {
test_instr(&[0x66, 0x0f, 0x3a, 0x0e, 0x06, 0x31], "pblendw xmm0, xmmword [rsi], 0x31");
test_invalid(&[0x0f, 0x3a, 0x0e, 0x06]);
- test_instr(&[0x66, 0x0f, 0x3a, 0x14, 0x06, 0x31], "pextrb xmm0, byte [rsi], 0x31");
+ test_instr(&[0x66, 0x0f, 0x3a, 0x14, 0x06, 0x31], "pextrb byte [rsi], xmm0, 0x31");
test_invalid(&[0x0f, 0x3a, 0x14, 0x06]);
- test_instr(&[0x66, 0x0f, 0x3a, 0x15, 0x06, 0x31], "pextrw xmm0, word [rsi], 0x31");
+ test_instr(&[0x66, 0x0f, 0x3a, 0x15, 0x06, 0x31], "pextrw word [rsi], xmm0, 0x31");
test_invalid(&[0x0f, 0x3a, 0x15, 0x06]);
- test_instr(&[0x66, 0x0f, 0x3a, 0x16, 0x06, 0x31], "pextrd xmm0, dword [rsi], 0x31");
+ test_instr(&[0x66, 0x0f, 0x3a, 0x16, 0x06, 0x31], "pextrd dword [rsi], xmm0, 0x31");
test_invalid(&[0x0f, 0x3a, 0x16, 0x06]);
- test_instr(&[0x66, 0x48, 0x0f, 0x3a, 0x16, 0x06, 0x31], "pextrq xmm0, qword [rsi], 0x31");
- test_instr(&[0x66, 0x0f, 0x3a, 0x17, 0x06, 0x31], "extractps xmm0, dword [rsi], 0x31");
+ test_instr(&[0x66, 0x48, 0x0f, 0x3a, 0x16, 0x06, 0x31], "pextrq qword [rsi], xmm0, 0x31");
+ test_instr(&[0x66, 0x0f, 0x3a, 0x17, 0x06, 0x31], "extractps dword [rsi], xmm0, 0x31");
test_invalid(&[0x0f, 0x3a, 0x17, 0x06]);
test_instr(&[0x66, 0x0f, 0x3a, 0x20, 0x06, 0x31], "pinsrb xmm0, byte [rsi], 0x31");