aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-08-09 02:33:05 -0700
committeriximeow <me@iximeow.net>2020-08-09 02:33:05 -0700
commitc3257be8b0b5c9f6f5c1c2ad6d48dfa726ec6413 (patch)
treec8acf966e028f2d43d09203112b3a5208473fbaa
parent4e61dc5e3ea882022e815814ed324fa7515923a6 (diff)
no more incomplete decoder for vex instructions
for now
-rw-r--r--src/long_mode/vex.rs35
-rw-r--r--test/long_mode/mod.rs20
2 files changed, 46 insertions, 9 deletions
diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs
index 7c4e27d..bbfd508 100644
--- a/src/long_mode/vex.rs
+++ b/src/long_mode/vex.rs
@@ -826,12 +826,33 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operand_count = 4;
Ok(())
}
-
- VEXOperandCode::G_V_E_xmm_xmm4 |
- VEXOperandCode::G_V_E_ymm_ymm4 |
- VEXOperandCode::G_V_ymm_E_xmm |
+ VEXOperandCode::G_V_ymm_E_xmm => {
+ let modrm = read_modrm(bytes, length)?;
+ instruction.modrm_rrr =
+ RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex().x(), RegisterBank::Y);
+ instruction.vex_reg.bank = RegisterBank::Y;
+ let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ instruction.operands[0] = OperandSpec::RegRRR;
+ instruction.operands[1] = OperandSpec::RegVex;
+ instruction.operands[2] = mem_oper;
+ instruction.operand_count = 3;
+ Ok(())
+ }
VEXOperandCode::G_V_xmm_Ew_imm8 => {
- Err(DecodeError::IncompleteDecoder) // :)
+ let modrm = read_modrm(bytes, length)?;
+ instruction.modrm_rrr =
+ RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex().x(), RegisterBank::X);
+ instruction.vex_reg.bank = RegisterBank::X;
+ // TODO: but the memory access is word-sized
+ let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ instruction.operands[0] = OperandSpec::RegRRR;
+ instruction.operands[1] = OperandSpec::RegVex;
+ instruction.operands[2] = mem_oper;
+ instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.operands[3] = OperandSpec::ImmI8;
+ instruction.operand_count = 4;
+ Ok(())
+
}
}
@@ -2667,9 +2688,9 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &
VEXOperandCode::G_V_E_xmm_imm8
}),
0x42 => (Opcode::VMPSADBW, if L {
- VEXOperandCode::G_E_ymm_imm8
+ VEXOperandCode::G_V_E_ymm_imm8
} else {
- VEXOperandCode::G_E_xmm_imm8
+ VEXOperandCode::G_V_E_xmm_imm8
}),
0x44 => (Opcode::VPCLMULQDQ, if L {
instruction.opcode = Opcode::Invalid;
diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs
index c56c732..3a912b6 100644
--- a/test/long_mode/mod.rs
+++ b/test/long_mode/mod.rs
@@ -1398,11 +1398,27 @@ fn test_vex() {
test_instr(&[0xc4, 0xc3, 0x75, 0x46, 0x7c, 0x12, 0x05, 0x61], "vperm2i128 ymm7, ymm1, [r10 + rdx * 1 + 0x5], 0x61");
test_instr(&[0xc4, 0xc3, 0x75, 0x4a, 0x7c, 0x12, 0x05, 0x61], "vblendvps ymm7, ymm1, [r10 + rdx * 1 + 0x5], ymm6");
test_instr(&[0xc4, 0xc3, 0x71, 0x4a, 0x7c, 0x12, 0x05, 0x61], "vblendvps xmm7, xmm1, [r10 + rdx * 1 + 0x5], xmm6");
- test_instr(&[0xc4, 0xc3, 0x71, 0x4a, 0xcc, 0x61], "vblendvps xmm7, xmm1, xmm12, xmm6");
+ test_instr(&[0xc4, 0xc3, 0x71, 0x4a, 0xdc, 0x61], "vblendvps xmm3, xmm1, xmm12, xmm6");
test_instr(&[0xc4, 0xc3, 0x75, 0x4b, 0x7c, 0x12, 0x05, 0x61], "vblendvpd ymm7, ymm1, [r10 + rdx * 1 + 0x5], ymm6");
test_instr(&[0xc4, 0xc3, 0x71, 0x4b, 0x7c, 0x12, 0x05, 0x61], "vblendvpd xmm7, xmm1, [r10 + rdx * 1 + 0x5], xmm6");
- test_instr(&[0xc4, 0xc3, 0x71, 0x4b, 0xcc, 0x61], "vblendvpd xmm7, xmm1, xmm12, xmm6");
+ test_instr(&[0xc4, 0xc3, 0x71, 0x4b, 0xdc, 0x61], "vblendvpd xmm3, xmm1, xmm12, xmm6");
test_instr(&[0xc4, 0xc3, 0x71, 0x4c, 0x7c, 0x12, 0x05, 0x61], "vpblendvb xmm7, xmm1, [r10 + rdx * 1 + 0x5], xmm6");
+
+ test_instr(&[0xc5, 0xc9, 0xf1, 0x0f], "vpsllw xmm1, xmm6, [rdi]");
+ test_instr(&[0xc5, 0xc9, 0xf1, 0xcf], "vpsllw xmm1, xmm6, xmm7");
+ test_instr(&[0xc5, 0xcd, 0xf1, 0x0f], "vpsllw ymm1, ymm6, [rdi]");
+ test_instr(&[0xc5, 0xcd, 0xf1, 0xcf], "vpsllw ymm1, ymm6, xmm7");
+ test_instr(&[0xc5, 0xc9, 0xf2, 0x0f], "vpslld xmm1, xmm6, [rdi]");
+ test_instr(&[0xc5, 0xc9, 0xf2, 0xcf], "vpslld xmm1, xmm6, xmm7");
+ test_instr(&[0xc5, 0xcd, 0xf2, 0x0f], "vpslld ymm1, ymm6, [rdi]");
+ test_instr(&[0xc5, 0xcd, 0xf2, 0xcf], "vpslld ymm1, ymm6, xmm7");
+ test_instr(&[0xc5, 0xc9, 0xf3, 0x0f], "vpsllq xmm1, xmm6, [rdi]");
+ test_instr(&[0xc5, 0xc9, 0xf3, 0xcf], "vpsllq xmm1, xmm6, xmm7");
+ test_instr(&[0xc5, 0xcd, 0xf3, 0x0f], "vpsllq ymm1, ymm6, [rdi]");
+ test_instr(&[0xc5, 0xcd, 0xf3, 0xcf], "vpsllq ymm1, ymm6, xmm7");
+
+ test_instr(&[0xc5, 0xf1, 0xc4, 0xd8, 0x78], "vpinsrw xmm3, xmm1, eax, 0x78");
+ test_instr(&[0xc5, 0xf1, 0xc4, 0x18, 0x78], "vpinsrw xmm3, xmm1, [rax], 0x78");
}
#[test]