aboutsummaryrefslogtreecommitdiff
path: root/src/shared/evex.in
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2026-05-08 01:19:33 +0000
committeriximeow <me@iximeow.net>2026-05-25 01:43:55 +0000
commitf900cfe558b97d187226c6e0791ad8992ba8f4a0 (patch)
tree8909e645eed396945cba92e9e1a370579d9ce26a /src/shared/evex.in
parent307d39dedfabaa0a0400ba62cd9a418d3f94a582 (diff)
working through a bunch of avx512 stuff, regspec constructors are const
Diffstat (limited to 'src/shared/evex.in')
-rw-r--r--src/shared/evex.in344
1 files changed, 267 insertions, 77 deletions
diff --git a/src/shared/evex.in b/src/shared/evex.in
index 0aa7d95..07c82e5 100644
--- a/src/shared/evex.in
+++ b/src/shared/evex.in
@@ -1,6 +1,7 @@
use super::OperandSpec;
use super::FieldDescription;
use super::InnerDescription;
+use super::Prefixes;
use yaxpeax_arch::annotation::DescriptionSink;
@@ -312,6 +313,23 @@ fn check_mask_reg(inst: &Instruction) -> Result<(), DecodeError> {
}
#[inline(always)]
+fn check_allowed_zero_merge(prefixes: &Prefixes, oper: OperandSpec) -> Result<(), DecodeError> {
+ if prefixes.evex_unchecked().merge() {
+ // if evex.z is set
+
+ if oper.is_memory() {
+ // quoth APM,
+ // > 3.2.4 Exceptions Caused by Illegal EVEX encodings
+ // > ..
+ // > EVEX.z == 1 ... Instructions that do not specify {z} ... #UD
+ return Err(DecodeError::InvalidOperand);
+ }
+ }
+
+ Ok(())
+}
+
+#[inline(always)]
fn apply_broadcast(inst: &mut Instruction, item_size: u8, reg_size: u8) {
if inst.prefixes.evex_unchecked().broadcast() {
inst.mem_size = item_size;
@@ -436,6 +454,8 @@ pub(crate) fn read_evex_operands<
if instruction.prefixes.evex_unchecked().vex().w() {
if instruction.opcode == Opcode::VRSQRT14SS {
instruction.opcode = Opcode::VRSQRT14SD;
+ } else if instruction.opcode == Opcode::VRCP14SS {
+ instruction.opcode = Opcode::VRCP14SD;
}
}
@@ -471,6 +491,10 @@ pub(crate) fn read_evex_operands<
} else {
if instruction.prefixes.evex_unchecked().broadcast() {
return Err(DecodeError::InvalidOpcode);
+ } else {
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
}
instruction.mem_size = 8;
}
@@ -488,12 +512,6 @@ pub(crate) fn read_evex_operands<
instruction.operand_count = 3;
- if instruction.prefixes.evex_unchecked().vex().w() {
- if instruction.opcode == Opcode::VGETEXPSS {
- instruction.opcode = Opcode::VGETEXPSD;
- }
- }
-
if let OperandSpec::RegMMM = mem_oper {
if instruction.prefixes.evex_unchecked().broadcast() {
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae_noround;
@@ -554,7 +572,10 @@ pub(crate) fn read_evex_operands<
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae;
}
} else {
- if instruction.prefixes.evex_unchecked().broadcast() {
+ deny_broadcast(instruction)?;
+
+ if instruction.prefixes.evex_unchecked().lp() &&
+ instruction.prefixes.evex_unchecked().vex().l() {
return Err(DecodeError::InvalidOpcode);
}
@@ -763,6 +784,8 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::G_V_Ed_xmm_imm8_W0 => {
deny_mask_reg(instruction)?;
ensure_W(instruction, 0)?;
+ deny_z(instruction)?;
+ deny_broadcast(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -809,6 +832,9 @@ pub(crate) fn read_evex_operands<
return Err(DecodeError::InvalidOperand);
}
} else {
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.operands[0] = OperandSpec::RegRRR;
}
instruction.operands[1] = OperandSpec::RegVex;
@@ -817,6 +843,8 @@ pub(crate) fn read_evex_operands<
}
generated::EVEXOperandCode::G_V_xmm_Edq_imm8 => {
deny_mask_reg(instruction)?;
+ deny_z(instruction)?;
+ deny_broadcast(instruction)?;
let (sz, bank) = if instruction.prefixes.evex_unchecked().vex().w() {
if isa_has_qwords() {
@@ -847,6 +875,8 @@ pub(crate) fn read_evex_operands<
}
generated::EVEXOperandCode::G_V_xmm_Ebd_imm8 => {
deny_mask_reg(instruction)?;
+ deny_z(instruction)?;
+ deny_broadcast(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -900,25 +930,10 @@ pub(crate) fn read_evex_operands<
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.operand_count = 3;
-
- set_reg_sizes_from_ll(instruction)?;
- }
- generated::EVEXOperandCode::M_G_LL_W0 => {
- deny_vex_reg(instruction)?;
- deny_mask_reg(instruction)?;
-
- instruction.mem_size = regs_size(instruction);
-
- let modrm = read_modrm(words)?;
- set_rrr(instruction, modrm);
- let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::Y, sink)?;
if mem_oper == OperandSpec::RegMMM {
- return Err(DecodeError::InvalidOperand);
+ deny_broadcast(instruction)?;
}
- instruction.operands[0] = mem_oper;
- instruction.operands[1] = OperandSpec::RegRRR;
- instruction.operand_count = 2;
+ instruction.operand_count = 3;
set_reg_sizes_from_ll(instruction)?;
}
@@ -926,6 +941,8 @@ pub(crate) fn read_evex_operands<
deny_vex_reg(instruction)?;
deny_mask_reg(instruction)?;
ensure_W(instruction, 1)?;
+ deny_z(instruction)?;
+ deny_broadcast(instruction)?;
instruction.mem_size = regs_size(instruction);
@@ -945,12 +962,14 @@ pub(crate) fn read_evex_operands<
deny_vex_reg(instruction)?;
check_mask_reg(instruction)?;
ensure_W(instruction, 1)?;
+ deny_broadcast(instruction)?;
instruction.mem_size = regs_size(instruction);
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::Y, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.operands[0] = mem_oper.masked();
instruction.operands[1] = OperandSpec::RegRRR;
instruction.operand_count = 2;
@@ -960,6 +979,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::G_Ed_xmm_sae_W0 => {
deny_vex_reg(instruction)?;
deny_mask_reg(instruction)?;
+ deny_z(instruction)?;
// vucomiss and vcomiss both are W=0
ensure_W(instruction, 0)?;
@@ -968,12 +988,18 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if mem_oper.is_memory() {
+ deny_broadcast(instruction)?;
+ }
instruction.regs[0].bank = RegisterBank::X;
// in specific support of vcomisd/vucomisd
if instruction.prefixes.evex_unchecked().broadcast() {
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae_noround;
} else {
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.operands[0] = OperandSpec::RegRRR;
}
instruction.operands[1] = mem_oper;
@@ -981,7 +1007,8 @@ pub(crate) fn read_evex_operands<
}
generated::EVEXOperandCode::Gm_Eq_xmm_sae_W1 => {
deny_vex_reg(instruction)?;
- check_mask_reg(instruction)?;
+ deny_mask_reg(instruction)?;
+ deny_z(instruction)?;
// vucomisd and vcomisd both are W=1
ensure_W(instruction, 1)?;
@@ -990,12 +1017,18 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if mem_oper.is_memory() {
+ deny_broadcast(instruction)?;
+ }
instruction.regs[0].bank = RegisterBank::X;
// in specific support of vcomisd/vucomisd
if instruction.prefixes.evex_unchecked().broadcast() {
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae_noround;
} else {
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.operands[0] = OperandSpec::RegRRR;
}
instruction.operands[1] = mem_oper;
@@ -1005,6 +1038,7 @@ pub(crate) fn read_evex_operands<
deny_vex_reg(instruction)?;
check_mask_reg(instruction)?;
ensure_W(instruction, 1)?;
+ deny_broadcast(instruction)?;
instruction.mem_size = regs_size(instruction);
@@ -1073,6 +1107,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Maskm_V_E_LL_imm8_sae_bcast_W1 => {
check_mask_reg(instruction)?;
ensure_W(instruction, 1)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -1126,7 +1161,7 @@ pub(crate) fn read_evex_operands<
}
} else {
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
- apply_broadcast(instruction, 8, sz);
+ apply_broadcast(instruction, 4, sz);
set_reg_sizes_from_ll(instruction)?;
}
}
@@ -1365,9 +1400,8 @@ pub(crate) fn read_evex_operands<
}
generated::EVEXOperandCode::G_V_E_LL => {
deny_mask_reg(instruction)?;
- if [Opcode::VAESDECLAST, Opcode::VAESDEC, Opcode::VAESENC, Opcode::VAESENCLAST].contains(&instruction.opcode) {
- deny_z(instruction)?;
- }
+ deny_z(instruction)?;
+ deny_broadcast(instruction)?;
let sz = regs_size(instruction);
@@ -1444,6 +1478,9 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::Y, sink)?;
+ if instruction.prefixes.evex_unchecked().broadcast() && !mem_oper.is_memory() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1463,6 +1500,9 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::Y, sink)?;
+ if mem_oper == OperandSpec::RegMMM {
+ deny_broadcast(instruction)?;
+ }
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
instruction.operands[1] = mem_oper;
instruction.imm = read_imm_unsigned(words, 1)?;
@@ -1483,6 +1523,9 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::Y, sink)?;
+ if mem_oper == OperandSpec::RegMMM {
+ deny_broadcast(instruction)?;
+ }
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
instruction.operands[1] = mem_oper;
instruction.imm = read_imm_unsigned(words, 1)?;
@@ -1571,6 +1614,9 @@ pub(crate) fn read_evex_operands<
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
if instruction.prefixes.evex_unchecked().broadcast() {
+ if mem_oper.is_memory() {
+ return Err(DecodeError::InvalidOperand);
+ }
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae_noround;
} else {
if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
@@ -1595,8 +1641,6 @@ pub(crate) fn read_evex_operands<
if instruction.prefixes.evex_unchecked().vex().w() {
if instruction.opcode == Opcode::VSCALEFSS {
instruction.opcode = Opcode::VSCALEFSD;
- } else if instruction.opcode == Opcode::VRCP14SS {
- instruction.opcode = Opcode::VRCP14SD;
}
}
@@ -1604,6 +1648,9 @@ pub(crate) fn read_evex_operands<
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
if instruction.prefixes.evex_unchecked().broadcast() {
+ if mem_oper.is_memory() {
+ return Err(DecodeError::InvalidOpcode);
+ };
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae;
} else {
if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
@@ -1626,6 +1673,44 @@ pub(crate) fn read_evex_operands<
}
set_reg_sizes(instruction, RegisterBank::X);
}
+ generated::EVEXOperandCode::Gm_V_Ed_xmm_sae_noround => {
+ check_mask_reg(instruction)?;
+
+ if instruction.prefixes.evex_unchecked().vex().w() {
+ if instruction.opcode == Opcode::VGETEXPSS {
+ instruction.opcode = Opcode::VGETEXPSD;
+ }
+ }
+
+ let modrm = read_modrm(words)?;
+ set_rrr(instruction, modrm);
+ let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if instruction.prefixes.evex_unchecked().broadcast() {
+ if mem_oper.is_memory() {
+ return Err(DecodeError::InvalidOpcode);
+ };
+ instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae_noround;
+ } else {
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOperand);
+ }
+ instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
+ }
+ instruction.operands[1] = OperandSpec::RegVex;
+ instruction.operands[2] = mem_oper;
+ instruction.operand_count = 3;
+
+ if mem_oper == OperandSpec::RegMMM {
+ instruction.mem_size = 0;
+ } else {
+ if instruction.prefixes.evex_unchecked().vex().w() {
+ instruction.mem_size = 8;
+ } else {
+ instruction.mem_size = 4;
+ }
+ }
+ set_reg_sizes(instruction, RegisterBank::X);
+ }
generated::EVEXOperandCode::Gm_V_Ed_xmm_sae_W0 => {
check_mask_reg(instruction)?;
ensure_W(instruction, 0)?;
@@ -1665,6 +1750,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
if mem_oper == OperandSpec::RegMMM {
if instruction.prefixes.evex_unchecked().broadcast() {
// sae sets this to `vcvtps2ph ymm, zmm, imm8`
@@ -1698,6 +1784,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
if mem_oper == OperandSpec::RegMMM {
if instruction.prefixes.evex_unchecked().broadcast() {
// sae sets this to `vcvtps2ph ymm, zmm, imm8`
@@ -1732,6 +1819,7 @@ pub(crate) fn read_evex_operands<
set_rrr(instruction, modrm);
instruction.regs[0].bank = RegisterBank::Z;
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::Y, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
if mem_oper == OperandSpec::RegMMM {
if instruction.prefixes.evex_unchecked().broadcast() {
instruction.operands[0] = OperandSpec::RegMMM_maskmerge_sae_noround;
@@ -1739,6 +1827,9 @@ pub(crate) fn read_evex_operands<
instruction.operands[0] = OperandSpec::RegMMM_maskmerge;
}
} else {
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
if instruction.prefixes.evex_unchecked().broadcast() {
return Err(DecodeError::InvalidOperand);
} else {
@@ -1847,6 +1938,7 @@ pub(crate) fn read_evex_operands<
set_rrr(instruction, modrm);
instruction.regs[0].bank = RegisterBank::Z;
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::Y, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.mem_size = 32;
instruction.operands[0] = mem_oper.masked();
instruction.operands[1] = OperandSpec::RegRRR;
@@ -1966,6 +2058,7 @@ pub(crate) fn read_evex_operands<
check_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
deny_broadcast(instruction)?;
+ ensure_W(instruction, 0)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -2001,8 +2094,8 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Gm_ymm_E_xmm_W0 => {
check_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
- ensure_W(instruction, 0)?;
deny_broadcast(instruction)?;
+ ensure_W(instruction, 0)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -2039,6 +2132,7 @@ pub(crate) fn read_evex_operands<
check_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
deny_broadcast(instruction)?;
+ ensure_W(instruction, 0)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -2080,6 +2174,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::Y, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.regs[0].bank = RegisterBank::Z;
instruction.mem_size = 32;
instruction.operands[0] = mem_oper.masked();
@@ -2095,6 +2190,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.regs[0].bank = RegisterBank::Z;
instruction.mem_size = 16;
instruction.operands[0] = mem_oper.masked();
@@ -2110,6 +2206,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.regs[0].bank = RegisterBank::Y;
instruction.mem_size = 16;
instruction.operands[0] = mem_oper.masked();
@@ -2125,6 +2222,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.regs[0].bank = RegisterBank::Z;
instruction.mem_size = 8;
instruction.operands[0] = mem_oper.masked();
@@ -2140,6 +2238,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.regs[0].bank = RegisterBank::X;
instruction.mem_size = 8;
instruction.operands[0] = mem_oper.masked();
@@ -2155,6 +2254,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.regs[0].bank = RegisterBank::Y;
instruction.mem_size = 4;
instruction.operands[0] = mem_oper.masked();
@@ -2170,6 +2270,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.regs[0].bank = RegisterBank::X;
instruction.mem_size = 4;
instruction.operands[0] = mem_oper.masked();
@@ -2185,6 +2286,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.regs[0].bank = RegisterBank::X;
instruction.mem_size = 2;
instruction.operands[0] = mem_oper.masked();
@@ -2200,6 +2302,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.regs[0].bank = RegisterBank::Y;
instruction.mem_size = 8;
instruction.operands[0] = mem_oper.masked();
@@ -2408,6 +2511,7 @@ pub(crate) fn read_evex_operands<
instruction.regs[0].bank = RegisterBank::Y;
}
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.mem_size = 16;
instruction.operands[0] = mem_oper.masked();
instruction.operands[1] = OperandSpec::RegRRR;
@@ -2534,32 +2638,12 @@ pub(crate) fn read_evex_operands<
instruction.operands[3] = OperandSpec::ImmU8;
instruction.operand_count = 4;
}
- generated::EVEXOperandCode::VMOVQ_G_Ed_xmm => {
- deny_mask_reg(instruction)?;
- deny_vex_reg(instruction)?;
- ensure_W(instruction, 1)?;
- deny_broadcast(instruction)?;
-
- let modrm = read_modrm(words)?;
- set_rrr(instruction, modrm);
- instruction.regs[0].bank = RegisterBank::X;
- let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
-
- if mem_oper == OperandSpec::RegMMM {
- instruction.mem_size = 0;
- } else {
- instruction.mem_size = 8;
- }
-
- instruction.operands[0] = OperandSpec::RegRRR;
- instruction.operands[1] = mem_oper;
- instruction.operand_count = 2;
- }
generated::EVEXOperandCode::VMOVQ_Ed_G_xmm => {
deny_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
ensure_W(instruction, 1)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -2581,6 +2665,7 @@ pub(crate) fn read_evex_operands<
deny_vex_reg(instruction)?;
ensure_W(instruction, 1)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -2599,6 +2684,7 @@ pub(crate) fn read_evex_operands<
deny_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -2630,6 +2716,7 @@ pub(crate) fn read_evex_operands<
deny_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -2659,6 +2746,11 @@ pub(crate) fn read_evex_operands<
}
generated::EVEXOperandCode::Mask_V_E_LL_bcast => {
check_mask_reg(instruction)?;
+ deny_z(instruction)?;
+
+ if instruction.opcode == Opcode::VP2INTERSECTD {
+ deny_mask_reg(instruction)?;
+ }
let sz = regs_size(instruction);
@@ -2680,6 +2772,7 @@ pub(crate) fn read_evex_operands<
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
if mem_oper == OperandSpec::RegMMM {
instruction.mem_size = 0;
+ deny_broadcast(instruction)?;
}
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
instruction.operands[1] = OperandSpec::RegVex;
@@ -2696,6 +2789,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Mask_V_E_LL_bcast_W1 => {
check_mask_reg(instruction)?;
ensure_W(instruction, 1)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -2704,7 +2798,9 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
if mem_oper == OperandSpec::RegMMM {
+ deny_broadcast(instruction)?;
instruction.mem_size = 0;
}
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
@@ -2722,6 +2818,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Mask_V_E_LL_bcast_W0 => {
check_mask_reg(instruction)?;
ensure_W(instruction, 0)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -2731,6 +2828,7 @@ pub(crate) fn read_evex_operands<
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
if mem_oper == OperandSpec::RegMMM {
+ deny_broadcast(instruction)?;
instruction.mem_size = 0;
}
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
@@ -2773,6 +2871,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
if mem_oper == OperandSpec::RegMMM {
instruction.mem_size = 0;
}
@@ -2786,6 +2885,7 @@ pub(crate) fn read_evex_operands<
deny_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -2821,6 +2921,7 @@ pub(crate) fn read_evex_operands<
deny_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -2856,6 +2957,7 @@ pub(crate) fn read_evex_operands<
deny_vex_reg(instruction)?;
ensure_W(instruction, 1)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -2883,6 +2985,7 @@ pub(crate) fn read_evex_operands<
deny_vex_reg(instruction)?;
ensure_W(instruction, 0)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -2905,10 +3008,11 @@ pub(crate) fn read_evex_operands<
return Err(DecodeError::InvalidOperand);
}
}
- generated::EVEXOperandCode::G_E_LL_W0 => {
+ generated::EVEXOperandCode::G_M_LL_W0 => {
deny_mask_reg(instruction)?;
ensure_W(instruction, 0)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -2918,7 +3022,7 @@ pub(crate) fn read_evex_operands<
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
if mem_oper == OperandSpec::RegMMM {
- instruction.mem_size = 0;
+ return Err(DecodeError::InvalidOperand);
}
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
@@ -2926,20 +3030,20 @@ pub(crate) fn read_evex_operands<
set_reg_sizes_from_ll(instruction)?;
}
- generated::EVEXOperandCode::E_G_LL_W0 => {
+ generated::EVEXOperandCode::M_G_LL_W0 => {
+ deny_vex_reg(instruction)?;
deny_mask_reg(instruction)?;
ensure_W(instruction, 0)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
- let sz = regs_size(instruction);
-
- instruction.mem_size = sz;
+ instruction.mem_size = regs_size(instruction);
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
if mem_oper == OperandSpec::RegMMM {
- instruction.mem_size = 0;
+ return Err(DecodeError::InvalidOperand);
}
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
@@ -2959,6 +3063,7 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
if mem_oper == OperandSpec::RegMMM {
instruction.mem_size = 0;
}
@@ -2990,6 +3095,7 @@ pub(crate) fn read_evex_operands<
};
instruction.regs[0].bank = r_sz;
if mem_oper == OperandSpec::RegMMM {
+ deny_broadcast(instruction)?;
instruction.mem_size = 0;
instruction.regs[1].bank = m_sz;
} else {
@@ -3007,6 +3113,8 @@ pub(crate) fn read_evex_operands<
instruction.opcode = Opcode::VPLZCNTQ;
} else if instruction.opcode == Opcode::VRCP14PS {
instruction.opcode = Opcode::VRCP14PD;
+ } else if instruction.opcode == Opcode::VRSQRT14PS {
+ instruction.opcode = Opcode::VRSQRT14PD;
} else if instruction.opcode == Opcode::VPOPCNTD {
instruction.opcode = Opcode::VPOPCNTQ;
} else if instruction.opcode == Opcode::VPCONFLICTD {
@@ -3086,6 +3194,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Gm_LL_Ud => {
check_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
+ deny_broadcast(instruction)?;
if instruction.prefixes.evex_unchecked().vex().w() && isa_has_qwords() {
if instruction.opcode == Opcode::VPBROADCASTD {
@@ -3120,6 +3229,7 @@ pub(crate) fn read_evex_operands<
check_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
ensure_W(instruction, 0)?;
+ deny_broadcast(instruction)?;
let sz = regs_size(instruction);
@@ -3355,8 +3465,6 @@ pub(crate) fn read_evex_operands<
if instruction.prefixes.evex_unchecked().vex().w() {
if instruction.opcode == Opcode::VGETEXPPS {
instruction.opcode = Opcode::VGETEXPPD;
- } else if instruction.opcode == Opcode::VRSQRT14PS {
- instruction.opcode = Opcode::VRSQRT14PD;
}
}
@@ -3380,11 +3488,7 @@ pub(crate) fn read_evex_operands<
4
}, sz);
} else {
- if instruction.opcode == Opcode::VSQRTPS || instruction.opcode == Opcode::VCVTPS2DQ {
- instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae;
- } else {
- instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae_noround;
- }
+ instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae_noround;
set_reg_sizes(instruction, RegisterBank::Z);
}
} else {
@@ -3520,6 +3624,7 @@ pub(crate) fn read_evex_operands<
check_mask_reg(instruction)?;
ensure_W(instruction, 0)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -3546,6 +3651,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Mask_V_E_LL => {
check_mask_reg(instruction)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -3594,6 +3700,10 @@ pub(crate) fn read_evex_operands<
if instruction.prefixes.evex_unchecked().broadcast() {
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae_noround;
} else {
+ if instruction.prefixes.evex_unchecked().lp()
+ && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
}
instruction.operands[1] = OperandSpec::RegVex;
@@ -3626,6 +3736,10 @@ pub(crate) fn read_evex_operands<
if instruction.prefixes.evex_unchecked().broadcast() {
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae_noround;
} else {
+ if instruction.prefixes.evex_unchecked().lp()
+ && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
}
instruction.operands[1] = OperandSpec::RegVex;
@@ -3644,6 +3758,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Mask_V_E_LL_imm8 => {
check_mask_reg(instruction)?;
deny_broadcast(instruction)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
instruction.mem_size = sz;
@@ -3718,6 +3833,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Mask_E_LL_imm8_bcast => {
check_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -3763,6 +3879,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Mask_V_E_LL_imm8_sae_bcast_W0 => {
check_mask_reg(instruction)?;
ensure_W(instruction, 0)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -3809,6 +3926,7 @@ pub(crate) fn read_evex_operands<
}
generated::EVEXOperandCode::Mask_V_E_LL_imm8_bcast => {
check_mask_reg(instruction)?;
+ deny_z(instruction)?;
let sz = regs_size(instruction);
@@ -3890,6 +4008,9 @@ pub(crate) fn read_evex_operands<
apply_broadcast(instruction, item_size, sz);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if mem_oper == OperandSpec::RegMMM {
+ deny_broadcast(instruction)?;
+ }
instruction.operands[0] = OperandSpec::RegVex_maskmerge;
instruction.operands[1] = mem_oper;
instruction.imm = read_imm_unsigned(words, 1)?;
@@ -3978,17 +4099,14 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Gm_V_E_LL_imm8_W0 => {
check_mask_reg(instruction)?;
ensure_W(instruction, 0)?;
+ deny_broadcast(instruction)?;
let sz = regs_size(instruction);
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
- if mem_oper == OperandSpec::RegMMM {
- deny_broadcast(instruction)?;
- } else {
- instruction.mem_size = sz;
- }
+ instruction.mem_size = sz;
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -4013,6 +4131,9 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if mem_oper == OperandSpec::RegMMM {
+ deny_broadcast(instruction)?;
+ }
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -4023,7 +4144,9 @@ pub(crate) fn read_evex_operands<
set_reg_sizes_from_ll(instruction)?;
}
generated::EVEXOperandCode::G_V_E_LL_imm8 => {
- check_mask_reg(instruction)?;
+ deny_mask_reg(instruction)?;
+ deny_z(instruction)?;
+ deny_broadcast(instruction)?;
instruction.mem_size = regs_size(instruction);
@@ -4041,6 +4164,7 @@ pub(crate) fn read_evex_operands<
}
generated::EVEXOperandCode::Gm_V_E_LL_imm8 => {
check_mask_reg(instruction)?;
+ deny_broadcast(instruction)?;
instruction.mem_size = regs_size(instruction);
@@ -4067,6 +4191,9 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if mem_oper == OperandSpec::RegMMM {
+ deny_broadcast(instruction)?;
+ }
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -4235,6 +4362,7 @@ pub(crate) fn read_evex_operands<
}
generated::EVEXOperandCode::VCVTPH2PS => {
check_mask_reg(instruction)?;
+ ensure_W(instruction, 0)?;
deny_vex_reg(instruction)?;
if instruction.opcode == Opcode::VCVTPS2PD {
@@ -4248,6 +4376,9 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if instruction.opcode == Opcode::VCVTPH2PS && mem_oper.is_memory() {
+ deny_broadcast(instruction)?;
+ }
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
instruction.operands[1] = mem_oper;
instruction.operand_count = 2;
@@ -4439,6 +4570,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::VCVTTPD2DQ => {
check_mask_reg(instruction)?;
deny_vex_reg(instruction)?;
+ ensure_W(instruction, 1)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -4527,6 +4659,15 @@ pub(crate) fn read_evex_operands<
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if !instruction.prefixes.evex_unchecked().broadcast() {
+ if instruction.prefixes.evex_unchecked().lp() {
+ if instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOperand);
+ }
+ }
+ } else if mem_oper.is_memory() {
+ return Err(DecodeError::InvalidOperand);
+ }
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
instruction.operands[1] = OperandSpec::RegVex;
@@ -4673,6 +4814,8 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Edd_G_xmm_imm8 => {
deny_vex_reg(instruction)?;
deny_mask_reg(instruction)?;
+ deny_z(instruction)?;
+ deny_broadcast(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -4734,6 +4877,9 @@ pub(crate) fn read_evex_operands<
}
}
} else {
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
if instruction.prefixes.evex_unchecked().broadcast() {
return Err(DecodeError::InvalidOpcode);
}
@@ -4748,6 +4894,8 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::VEXTRACTPS => {
deny_vex_reg(instruction)?;
deny_mask_reg(instruction)?;
+ deny_z(instruction)?;
+ deny_broadcast(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -4768,6 +4916,8 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Ewd_G_xmm_imm8 => {
deny_vex_reg(instruction)?;
deny_mask_reg(instruction)?;
+ deny_z(instruction)?;
+ deny_broadcast(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -4788,6 +4938,8 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Ebd_G_xmm_imm8 => {
deny_vex_reg(instruction)?;
deny_mask_reg(instruction)?;
+ deny_z(instruction)?;
+ deny_broadcast(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -4840,6 +4992,10 @@ pub(crate) fn read_evex_operands<
if let OperandSpec::RegMMM = mem_oper {
instruction.mem_size = 0;
} else{
+ deny_broadcast(instruction)?;
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.mem_size = item_size;
}
if instruction.prefixes.evex_unchecked().broadcast() {
@@ -4857,13 +5013,18 @@ pub(crate) fn read_evex_operands<
}
generated::EVEXOperandCode::Gm_V_E_xmm_imm8_sae_W1 => {
ensure_W(instruction, 1)?;
+ check_mask_reg(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
if let OperandSpec::RegMMM = mem_oper {
/* no mem size */
- } else{
+ } else {
+ deny_broadcast(instruction)?;
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.mem_size = 8;
}
if instruction.prefixes.evex_unchecked().broadcast() {
@@ -4918,6 +5079,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::VMOVSD_10 => {
check_mask_reg(instruction)?;
ensure_W(instruction, 1)?;
+ deny_broadcast(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
@@ -4940,10 +5102,12 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::VMOVSD_11 => {
check_mask_reg(instruction)?;
ensure_W(instruction, 1)?;
+ deny_broadcast(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.operands[0] = mem_oper.masked();
if mem_oper == OperandSpec::RegMMM {
instruction.operands[1] = OperandSpec::RegVex;
@@ -4962,12 +5126,16 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::VMOVSS_10 => {
check_mask_reg(instruction)?;
ensure_W(instruction, 0)?;
+ deny_broadcast(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
instruction.operands[0] = OperandSpec::RegRRR_maskmerge;
if mem_oper == OperandSpec::RegMMM {
+ if instruction.prefixes.evex_unchecked().broadcast() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
instruction.operand_count = 3;
@@ -4984,10 +5152,12 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::VMOVSS_11 => {
check_mask_reg(instruction)?;
ensure_W(instruction, 0)?;
+ deny_broadcast(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ check_allowed_zero_merge(&instruction.prefixes, mem_oper)?;
instruction.operands[0] = mem_oper.masked();
if mem_oper == OperandSpec::RegMMM {
instruction.operands[1] = OperandSpec::RegVex;
@@ -5004,12 +5174,15 @@ pub(crate) fn read_evex_operands<
set_reg_sizes(instruction, RegisterBank::X);
}
generated::EVEXOperandCode::VCVTSI2SS => {
- check_mask_reg(instruction)?;
+ deny_mask_reg(instruction)?;
deny_z(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if mem_oper.is_memory() {
+ deny_broadcast(instruction)?;
+ }
if instruction.prefixes.evex_unchecked().broadcast() && mem_oper == OperandSpec::RegMMM {
if (!instruction.prefixes.evex_unchecked().vex().w() || !isa_has_qwords()) && instruction.opcode == Opcode::VCVTSI2SD {
instruction.operands[0] = OperandSpec::RegRRR;
@@ -5017,6 +5190,9 @@ pub(crate) fn read_evex_operands<
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae;
}
} else {
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.operands[0] = OperandSpec::RegRRR;
}
instruction.operands[1] = OperandSpec::RegVex;
@@ -5049,15 +5225,21 @@ pub(crate) fn read_evex_operands<
}
}
generated::EVEXOperandCode::VCVTTSS2SI => {
- check_mask_reg(instruction)?;
+ deny_mask_reg(instruction)?;
deny_z(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if mem_oper.is_memory() {
+ deny_broadcast(instruction)?;
+ }
if instruction.prefixes.evex_unchecked().broadcast() {
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae_noround;
} else {
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.operands[0] = OperandSpec::RegRRR;
}
if instruction.prefixes.evex_unchecked().vex().w() {
@@ -5076,15 +5258,21 @@ pub(crate) fn read_evex_operands<
instruction.operand_count = 2;
}
generated::EVEXOperandCode::VCVTSS2SI => {
- check_mask_reg(instruction)?;
+ deny_mask_reg(instruction)?;
deny_z(instruction)?;
let modrm = read_modrm(words)?;
set_rrr(instruction, modrm);
let mem_oper = read_E_vex(words, instruction, modrm, RegisterBank::X, sink)?;
+ if mem_oper.is_memory() {
+ deny_broadcast(instruction)?;
+ }
if instruction.prefixes.evex_unchecked().broadcast() {
instruction.operands[0] = OperandSpec::RegRRR_maskmerge_sae;
} else {
+ if instruction.prefixes.evex_unchecked().lp() && instruction.prefixes.evex_unchecked().vex().l() {
+ return Err(DecodeError::InvalidOpcode);
+ }
instruction.operands[0] = OperandSpec::RegRRR;
}
if instruction.prefixes.evex_unchecked().vex().w() {
@@ -5105,6 +5293,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Operands_12_W0 => {
deny_mask_reg(instruction)?;
deny_z(instruction)?;
+ deny_broadcast(instruction)?;
ensure_W(instruction, 0)?;
let modrm = read_modrm(words)?;
@@ -5130,6 +5319,7 @@ pub(crate) fn read_evex_operands<
generated::EVEXOperandCode::Operands_16_W0 => {
deny_mask_reg(instruction)?;
deny_z(instruction)?;
+ deny_broadcast(instruction)?;
ensure_W(instruction, 0)?;
let modrm = read_modrm(words)?;