aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-08-03 02:00:16 -0700
committeriximeow <me@iximeow.net>2020-08-09 01:38:57 -0700
commitda67f024060e36b016c2554fdca91a2a70ece235 (patch)
tree4c0b2b20015deebc39e4c97abb08d67de68cade1
parentb71ce923b78c1535dd3b1512bb9edad28a9808ce (diff)
vpsrlq
-rw-r--r--src/long_mode/vex.rs24
-rw-r--r--test/long_mode/mod.rs1
2 files changed, 19 insertions, 6 deletions
diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs
index bab8167..889d0a8 100644
--- a/src/long_mode/vex.rs
+++ b/src/long_mode/vex.rs
@@ -272,9 +272,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
return Err(DecodeError::InvalidOpcode);
}
}
- // VEXOperandCode::G_E_xmm_imm8 ? this is reg1, reg2, imm8, but r is used for
- // picking the opcode. is one of these actually the vex reg?
- Err(DecodeError::IncompleteDecoder) // :)
+ instruction.modrm_rrr =
+ RegSpec::from_parts(modrm & 7, instruction.prefixes.vex().r(), RegisterBank::X);
+ instruction.vex_reg.bank = RegisterBank::X;
+ instruction.operands[0] = OperandSpec::RegVex;
+ instruction.operands[1] = OperandSpec::RegRRR;
+ instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.operands[2] = OperandSpec::ImmI8;
+ instruction.operand_count = 3;
+ Ok(())
}
VEXOperandCode::VPS_73_L => {
let modrm = read_modrm(bytes, length)?;
@@ -301,9 +307,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
unreachable!("r is only three bits");
}
}
- // VEXOperandCode::G_E_ymm_imm8 ? this is reg1, reg2, imm8, but r is used for
- // picking the opcode. is one of these actually the vex reg?
- Err(DecodeError::IncompleteDecoder) // :)
+ instruction.modrm_rrr =
+ RegSpec::from_parts(modrm & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
+ instruction.vex_reg.bank = RegisterBank::Y;
+ instruction.operands[0] = OperandSpec::RegVex;
+ instruction.operands[1] = OperandSpec::RegRRR;
+ instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.operands[2] = OperandSpec::ImmI8;
+ instruction.operand_count = 3;
+ Ok(())
}
VEXOperandCode::VMOVSS_10 |
VEXOperandCode::VMOVSD_10 => {
diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs
index 7293b29..686ba6b 100644
--- a/test/long_mode/mod.rs
+++ b/test/long_mode/mod.rs
@@ -1386,6 +1386,7 @@ fn test_vex() {
test_instr_invalid(&[0xc4, 0xe3, 0xf9, 0x14, 0x00, 0xd0]);
test_instr_invalid(&[0xc4, 0xe3, 0xf9, 0x14, 0x00, 0x0a]);
test_instr(&[0xc5, 0xed, 0x71, 0xd0, 0x04], "vpsrlw ymm2, ymm0, 0x4");
+ test_instr(&[0xc5, 0xed, 0x73, 0xd4, 0x20], "vpsrlq ymm2, ymm4, 0x20");
test_instr(&[0xc4, 0xe3, 0xfd, 0x00, 0xc1, 0xa8], "vpermq ymm0, ymm1, 0xa8");
test_instr(&[0xc5, 0xfd, 0xea, 0xd1], "vpminsw ymm2, ymm0, ymm1");
test_instr(&[0xc5, 0xfd, 0xee, 0xd9], "vpmaxsw ymm3, ymm0, ymm1");