diff options
| author | iximeow <me@iximeow.net> | 2026-05-08 01:19:33 +0000 |
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2026-05-25 01:43:55 +0000 |
| commit | f900cfe558b97d187226c6e0791ad8992ba8f4a0 (patch) | |
| tree | 8909e645eed396945cba92e9e1a370579d9ce26a /src/shared | |
| parent | 307d39dedfabaa0a0400ba62cd9a418d3f94a582 (diff) | |
working through a bunch of avx512 stuff, regspec constructors are const
Diffstat (limited to 'src/shared')
| -rw-r--r-- | src/shared/evex.in | 344 | ||||
| -rw-r--r-- | src/shared/generated_evex.in | 56 |
2 files changed, 298 insertions, 102 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)?; diff --git a/src/shared/generated_evex.in b/src/shared/generated_evex.in index b2ca667..3f3764b 100644 --- a/src/shared/generated_evex.in +++ b/src/shared/generated_evex.in @@ -506,7 +506,6 @@ pub(crate) enum EVEXOperandCode { Gm_U_zmm_imm8_sae_W0, Gm_V_E_LL_sae_W1, Gm_U_zmm_sae_W0, - E_G_LL_W0, Ebd_G_xmm_imm8, Edd_G_xmm_imm8, Edm_xmm_G_xmm_W0, @@ -527,7 +526,7 @@ pub(crate) enum EVEXOperandCode { Eqm_xmm_G_zmm_W0, Ewd_G_xmm_imm8, Ewm_xmm_G_xmm_W0, - G_E_LL_W0, + G_M_LL_W0, G_Ed_xmm_sae_W0, G_LL_Mask, G_LL_Mask_W0, @@ -593,6 +592,7 @@ pub(crate) enum EVEXOperandCode { Gm_V_Ed_xmm_sae, Gm_V_Ed_xmm_sae_W0, Gm_V_Ed_xmm_sae_bcast, + Gm_V_Ed_xmm_sae_noround, Gm_V_Ed_xmm_sae_noround_W0, Gm_V_Eq_xmm_sae_W1, Gm_V_LL_E_xmm, @@ -666,7 +666,6 @@ pub(crate) enum EVEXOperandCode { VMOVD_7e, VMOVQ_7e, VMOVQ_Ed_G_xmm, - VMOVQ_G_Ed_xmm, VMOVSD_10, VMOVSD_11, VMOVSS_10, @@ -675,15 +674,23 @@ pub(crate) enum EVEXOperandCode { VPINSRW, } +// the APM and SDM describe the prefix bits as selecting no prefix, "66, f2, or f3" opcode extension. +// however, this is *not the order those bits are interpreted in*. compare APM and SDM encodings and +// you will see: +// > 0b00 -> none, +// > 0b01 -> 0x66, +// > 0b10 -> 0xf3, // !! +// > 0b11 -> 0xf2, // !! +// hence the ordering of table names below. pub(crate) const TABLES: [&'static [(u8, [(super::Opcode, EVEXOperandCode); 4])]; 12] = [ &EVEX_None_0f, &EVEX_66_0f, - &EVEX_f2_0f, &EVEX_f3_0f, + &EVEX_f2_0f, &DUMMY, &EVEX_66_0f38, - &EVEX_f2_0f38, &EVEX_f3_0f38, + &EVEX_f2_0f38, &DUMMY, &EVEX_66_0f3a, &DUMMY, @@ -701,12 +708,12 @@ const EVEX_None_0f: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 30] = [ (0x15, [(super::Opcode::VUNPCKHPS, EVEXOperandCode::Gm_V_Ed_LL_bcast_W0), (super::Opcode::VUNPCKHPS, EVEXOperandCode::Gm_V_Ed_LL_bcast_W0), (super::Opcode::VUNPCKHPS, EVEXOperandCode::Gm_V_Ed_LL_bcast_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x16, [(super::Opcode::Invalid, EVEXOperandCode::Operands_16_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing), (super::Opcode::Invalid, EVEXOperandCode::Nothing), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x17, [(super::Opcode::VMOVHPS, EVEXOperandCode::Mq_G_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing), (super::Opcode::Invalid, EVEXOperandCode::Nothing), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), - (0x28, [(super::Opcode::VMOVAPS, EVEXOperandCode::Gm_E_LL_sae_bcast_W0), (super::Opcode::VMOVAPS, EVEXOperandCode::Gm_E_LL_sae_bcast_W0), (super::Opcode::VMOVAPS, EVEXOperandCode::Gm_E_LL_sae_bcast_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), + (0x28, [(super::Opcode::VMOVAPS, EVEXOperandCode::Gm_E_LL_W0), (super::Opcode::VMOVAPS, EVEXOperandCode::Gm_E_LL_W0), (super::Opcode::VMOVAPS, EVEXOperandCode::Gm_E_LL_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x29, [(super::Opcode::VMOVAPS, EVEXOperandCode::Em_G_LL_W0), (super::Opcode::VMOVAPS, EVEXOperandCode::Em_G_LL_W0), (super::Opcode::VMOVAPS, EVEXOperandCode::Em_G_LL_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x2b, [(super::Opcode::VMOVNTPS, EVEXOperandCode::M_G_LL_W0), (super::Opcode::VMOVNTPS, EVEXOperandCode::M_G_LL_W0), (super::Opcode::VMOVNTPS, EVEXOperandCode::M_G_LL_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x2e, [(super::Opcode::VUCOMISS, EVEXOperandCode::G_Ed_xmm_sae_W0), (super::Opcode::VUCOMISS, EVEXOperandCode::G_Ed_xmm_sae_W0), (super::Opcode::VUCOMISS, EVEXOperandCode::G_Ed_xmm_sae_W0), (super::Opcode::VUCOMISS, EVEXOperandCode::G_Ed_xmm_sae_W0)]), (0x2f, [(super::Opcode::VCOMISS, EVEXOperandCode::G_Ed_xmm_sae_W0), (super::Opcode::VCOMISS, EVEXOperandCode::G_Ed_xmm_sae_W0), (super::Opcode::VCOMISS, EVEXOperandCode::G_Ed_xmm_sae_W0), (super::Opcode::VCOMISS, EVEXOperandCode::G_Ed_xmm_sae_W0)]), - (0x51, [(super::Opcode::VSQRTPS, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VSQRTPS, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VSQRTPS, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VSQRTPS, EVEXOperandCode::Gm_E_LL_sae_bcast)]), + (0x51, [(super::Opcode::VSQRTPS, EVEXOperandCode::Gm_E_LL_sae_bcast_W0), (super::Opcode::VSQRTPS, EVEXOperandCode::Gm_E_LL_sae_bcast_W0), (super::Opcode::VSQRTPS, EVEXOperandCode::Gm_E_LL_sae_bcast_W0), (super::Opcode::VSQRTPS, EVEXOperandCode::Gm_E_LL_sae_bcast_W0)]), (0x54, [(super::Opcode::VANDPS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VANDPS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VANDPS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x55, [(super::Opcode::VANDNPS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VANDNPS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VANDNPS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x56, [(super::Opcode::VORPS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VORPS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VORPS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), @@ -749,7 +756,7 @@ const EVEX_66_0f: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 100] = [ (0x58, [(super::Opcode::VADDPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VADDPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VADDPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VADDPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1)]), (0x59, [(super::Opcode::VMULPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VMULPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VMULPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VMULPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1)]), (0x5a, [(super::Opcode::VCVTPD2PS, EVEXOperandCode::Gm_xmm_E_xmm_sae_bcast_W1), (super::Opcode::VCVTPD2PS, EVEXOperandCode::Gm_xmm_E_ymm_sae_bcast_W1), (super::Opcode::VCVTPD2PS, EVEXOperandCode::Gm_ymm_E_zmm_sae_bcast_W1), (super::Opcode::VCVTPD2PS, EVEXOperandCode::Gm_ymm_U_zmm_sae_W1)]), - (0x5b, [(super::Opcode::VCVTPS2DQ, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VCVTPS2DQ, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VCVTPS2DQ, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VCVTPS2DQ, EVEXOperandCode::Gm_E_LL_sae_bcast)]), + (0x5b, [(super::Opcode::VCVTPS2DQ, EVEXOperandCode::Gm_E_LL_sae_bcast_W0), (super::Opcode::VCVTPS2DQ, EVEXOperandCode::Gm_E_LL_sae_bcast_W0), (super::Opcode::VCVTPS2DQ, EVEXOperandCode::Gm_E_LL_sae_bcast_W0), (super::Opcode::VCVTPS2DQ, EVEXOperandCode::Gm_E_LL_sae_bcast_W0)]), (0x5c, [(super::Opcode::VSUBPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VSUBPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VSUBPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VSUBPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1)]), (0x5d, [(super::Opcode::VMINPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VMINPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VMINPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VMINPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1)]), (0x5e, [(super::Opcode::VDIVPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VDIVPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VDIVPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1), (super::Opcode::VDIVPD, EVEXOperandCode::Gm_V_E_LL_sae_bcast_W1)]), @@ -806,7 +813,7 @@ const EVEX_66_0f: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 100] = [ (0xe4, [(super::Opcode::VPMULHUW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::VPMULHUW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::VPMULHUW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0xe5, [(super::Opcode::VPMULHW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::VPMULHW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::VPMULHW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0xe6, [(super::Opcode::VCVTTPD2DQ, EVEXOperandCode::VCVTTPD2DQ), (super::Opcode::VCVTTPD2DQ, EVEXOperandCode::VCVTTPD2DQ), (super::Opcode::VCVTTPD2DQ, EVEXOperandCode::VCVTTPD2DQ), (super::Opcode::VCVTTPD2DQ, EVEXOperandCode::VCVTTPD2DQ)]), - (0xe7, [(super::Opcode::VMOVNTDQ, EVEXOperandCode::E_G_LL_W0), (super::Opcode::VMOVNTDQ, EVEXOperandCode::E_G_LL_W0), (super::Opcode::VMOVNTDQ, EVEXOperandCode::E_G_LL_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), + (0xe7, [(super::Opcode::VMOVNTDQ, EVEXOperandCode::M_G_LL_W0), (super::Opcode::VMOVNTDQ, EVEXOperandCode::M_G_LL_W0), (super::Opcode::VMOVNTDQ, EVEXOperandCode::M_G_LL_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0xe8, [(super::Opcode::VPSUBSB, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::VPSUBSB, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::VPSUBSB, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0xe9, [(super::Opcode::VPSUBSW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::VPSUBSW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::VPSUBSW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0xea, [(super::Opcode::VPMINSW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::VPMINSW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::VPMINSW, EVEXOperandCode::Gm_V_E_LL), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), @@ -861,7 +868,7 @@ const EVEX_66_0f38: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 143] = [ (0x27, [(super::Opcode::VPTESTMD, EVEXOperandCode::Mask_V_E_LL_bcast), (super::Opcode::VPTESTMD, EVEXOperandCode::Mask_V_E_LL_bcast), (super::Opcode::VPTESTMD, EVEXOperandCode::Mask_V_E_LL_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x28, [(super::Opcode::VPMULDQ, EVEXOperandCode::Gm_V_E_LL_bcast_W1), (super::Opcode::VPMULDQ, EVEXOperandCode::Gm_V_E_LL_bcast_W1), (super::Opcode::VPMULDQ, EVEXOperandCode::Gm_V_E_LL_bcast_W1), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x29, [(super::Opcode::VPCMPEQQ, EVEXOperandCode::Mask_V_E_LL_bcast_W1), (super::Opcode::VPCMPEQQ, EVEXOperandCode::Mask_V_E_LL_bcast_W1), (super::Opcode::VPCMPEQQ, EVEXOperandCode::Mask_V_E_LL_bcast_W1), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), - (0x2a, [(super::Opcode::VMOVNTDQA, EVEXOperandCode::G_E_LL_W0), (super::Opcode::VMOVNTDQA, EVEXOperandCode::G_E_LL_W0), (super::Opcode::VMOVNTDQA, EVEXOperandCode::G_E_LL_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), + (0x2a, [(super::Opcode::VMOVNTDQA, EVEXOperandCode::G_M_LL_W0), (super::Opcode::VMOVNTDQA, EVEXOperandCode::G_M_LL_W0), (super::Opcode::VMOVNTDQA, EVEXOperandCode::G_M_LL_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x2b, [(super::Opcode::VPACKUSDW, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VPACKUSDW, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VPACKUSDW, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x2c, [(super::Opcode::VSCALEFPS, EVEXOperandCode::Gm_V_E_LL_sae_bcast), (super::Opcode::VSCALEFPS, EVEXOperandCode::Gm_V_E_LL_sae_bcast), (super::Opcode::VSCALEFPS, EVEXOperandCode::Gm_V_E_LL_sae_bcast), (super::Opcode::VSCALEFPS, EVEXOperandCode::Gm_V_E_LL_sae_bcast)]), (0x2d, [(super::Opcode::VSCALEFSS, EVEXOperandCode::Gm_V_Ed_xmm_sae), (super::Opcode::VSCALEFSS, EVEXOperandCode::Gm_V_Ed_xmm_sae), (super::Opcode::VSCALEFSS, EVEXOperandCode::Gm_V_Ed_xmm_sae), (super::Opcode::VSCALEFSS, EVEXOperandCode::Gm_V_Ed_xmm_sae)]), @@ -883,15 +890,15 @@ const EVEX_66_0f38: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 143] = [ (0x3f, [(super::Opcode::VPMAXUD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::VPMAXUD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::VPMAXUD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x40, [(super::Opcode::VPMULLD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::VPMULLD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::VPMULLD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x42, [(super::Opcode::VGETEXPPS, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VGETEXPPS, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VGETEXPPS, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VGETEXPPS, EVEXOperandCode::Gm_E_LL_sae_bcast)]), - (0x43, [(super::Opcode::VGETEXPSS, EVEXOperandCode::Gm_V_Ed_xmm_sae_bcast), (super::Opcode::VGETEXPSS, EVEXOperandCode::Gm_V_Ed_xmm_sae_bcast), (super::Opcode::VGETEXPSS, EVEXOperandCode::Gm_V_Ed_xmm_sae_bcast), (super::Opcode::VGETEXPSS, EVEXOperandCode::Gm_V_Ed_xmm_sae_bcast)]), + (0x43, [(super::Opcode::VGETEXPSS, EVEXOperandCode::Gm_V_Ed_xmm_sae_noround), (super::Opcode::VGETEXPSS, EVEXOperandCode::Gm_V_Ed_xmm_sae_noround), (super::Opcode::VGETEXPSS, EVEXOperandCode::Gm_V_Ed_xmm_sae_noround), (super::Opcode::VGETEXPSS, EVEXOperandCode::Gm_V_Ed_xmm_sae_noround)]), (0x44, [(super::Opcode::VPLZCNTD, EVEXOperandCode::Gm_E_LL_bcast), (super::Opcode::VPLZCNTD, EVEXOperandCode::Gm_E_LL_bcast), (super::Opcode::VPLZCNTD, EVEXOperandCode::Gm_E_LL_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x45, [(super::Opcode::VPSRLVD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::VPSRLVD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::VPSRLVD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x46, [(super::Opcode::VPSRAVD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::VPSRAVD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::VPSRAVD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x47, [(super::Opcode::VPSLLVD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::VPSLLVD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::VPSLLVD, EVEXOperandCode::Gm_V_E_LL_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x4c, [(super::Opcode::VRCP14PS, EVEXOperandCode::Gm_E_LL_bcast), (super::Opcode::VRCP14PS, EVEXOperandCode::Gm_E_LL_bcast), (super::Opcode::VRCP14PS, EVEXOperandCode::Gm_E_LL_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), - (0x4d, [(super::Opcode::VRCP14SS, EVEXOperandCode::Gm_V_Ed_xmm_sae), (super::Opcode::VRCP14SS, EVEXOperandCode::Gm_V_Ed_xmm_sae), (super::Opcode::VRCP14SS, EVEXOperandCode::Gm_V_Ed_xmm_sae), (super::Opcode::VRCP14SS, EVEXOperandCode::Gm_V_Ed_xmm_sae)]), - (0x4e, [(super::Opcode::VRSQRT14PS, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VRSQRT14PS, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::VRSQRT14PS, EVEXOperandCode::Gm_E_LL_sae_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), - (0x4f, [(super::Opcode::VRSQRT14SS, EVEXOperandCode::Gm_V_Ed_xmm), (super::Opcode::VRSQRT14SS, EVEXOperandCode::Gm_V_Ed_xmm), (super::Opcode::VRSQRT14SS, EVEXOperandCode::Gm_V_Ed_xmm), (super::Opcode::VRSQRT14SS, EVEXOperandCode::Gm_V_Ed_xmm)]), + (0x4d, [(super::Opcode::VRCP14SS, EVEXOperandCode::Gm_V_Ed_xmm), (super::Opcode::VRCP14SS, EVEXOperandCode::Gm_V_Ed_xmm), (super::Opcode::VRCP14SS, EVEXOperandCode::Gm_V_Ed_xmm), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), + (0x4e, [(super::Opcode::VRSQRT14PS, EVEXOperandCode::Gm_E_LL_bcast), (super::Opcode::VRSQRT14PS, EVEXOperandCode::Gm_E_LL_bcast), (super::Opcode::VRSQRT14PS, EVEXOperandCode::Gm_E_LL_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), + (0x4f, [(super::Opcode::VRSQRT14SS, EVEXOperandCode::Gm_V_Ed_xmm), (super::Opcode::VRSQRT14SS, EVEXOperandCode::Gm_V_Ed_xmm), (super::Opcode::VRSQRT14SS, EVEXOperandCode::Gm_V_Ed_xmm), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x50, [(super::Opcode::VPDPBUSD, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VPDPBUSD, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VPDPBUSD, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x51, [(super::Opcode::VPDPBUSDS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VPDPBUSDS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VPDPBUSDS, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x52, [(super::Opcode::VPDPWSSD, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VPDPWSSD, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::VPDPWSSD, EVEXOperandCode::Gm_V_E_LL_bcast_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), @@ -1021,7 +1028,7 @@ const EVEX_66_0f3a: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 51] = [ (0x56, [(super::Opcode::VREDUCEPS, EVEXOperandCode::Gm_E_LL_imm8_sae), (super::Opcode::VREDUCEPS, EVEXOperandCode::Gm_E_LL_imm8_sae), (super::Opcode::VREDUCEPS, EVEXOperandCode::Gm_E_LL_imm8_sae), (super::Opcode::VREDUCEPS, EVEXOperandCode::Gm_E_LL_imm8_sae)]), (0x57, [(super::Opcode::VREDUCESS, EVEXOperandCode::Gm_V_Ed_xmm_imm8_sae), (super::Opcode::VREDUCESS, EVEXOperandCode::Gm_V_Ed_xmm_imm8_sae), (super::Opcode::VREDUCESS, EVEXOperandCode::Gm_V_Ed_xmm_imm8_sae), (super::Opcode::VREDUCESS, EVEXOperandCode::Gm_V_Ed_xmm_imm8_sae)]), (0x66, [(super::Opcode::VFPCLASSPS, EVEXOperandCode::Mask_E_LL_imm8_bcast), (super::Opcode::VFPCLASSPS, EVEXOperandCode::Mask_E_LL_imm8_bcast), (super::Opcode::VFPCLASSPS, EVEXOperandCode::Mask_E_LL_imm8_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), - (0x67, [(super::Opcode::VFPCLASSSS, EVEXOperandCode::Mask_Ed_xmm_imm8), (super::Opcode::VFPCLASSSS, EVEXOperandCode::Mask_Ed_xmm_imm8), (super::Opcode::VFPCLASSSS, EVEXOperandCode::Mask_Ed_xmm_imm8), (super::Opcode::VFPCLASSSS, EVEXOperandCode::Mask_Ed_xmm_imm8)]), + (0x67, [(super::Opcode::VFPCLASSSS, EVEXOperandCode::Mask_Ed_xmm_imm8), (super::Opcode::VFPCLASSSS, EVEXOperandCode::Mask_Ed_xmm_imm8), (super::Opcode::VFPCLASSSS, EVEXOperandCode::Mask_Ed_xmm_imm8), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x70, [(super::Opcode::VPSHLDW, EVEXOperandCode::Gm_V_E_LL_imm8_W1), (super::Opcode::VPSHLDW, EVEXOperandCode::Gm_V_E_LL_imm8_W1), (super::Opcode::VPSHLDW, EVEXOperandCode::Gm_V_E_LL_imm8_W1), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x71, [(super::Opcode::VPSHLDD, EVEXOperandCode::Gm_V_E_LL_imm8_bcast), (super::Opcode::VPSHLDD, EVEXOperandCode::Gm_V_E_LL_imm8_bcast), (super::Opcode::VPSHLDD, EVEXOperandCode::Gm_V_E_LL_imm8_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x72, [(super::Opcode::VPSHRDW, EVEXOperandCode::Gm_V_E_LL_imm8_W1), (super::Opcode::VPSHRDW, EVEXOperandCode::Gm_V_E_LL_imm8_W1), (super::Opcode::VPSHRDW, EVEXOperandCode::Gm_V_E_LL_imm8_W1), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), @@ -1030,9 +1037,9 @@ const EVEX_66_0f3a: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 51] = [ (0xcf, [(super::Opcode::VGF2P8AFFINEINVQB, EVEXOperandCode::Gm_V_E_LL_imm8_bcast_W1), (super::Opcode::VGF2P8AFFINEINVQB, EVEXOperandCode::Gm_V_E_LL_imm8_bcast_W1), (super::Opcode::VGF2P8AFFINEINVQB, EVEXOperandCode::Gm_V_E_LL_imm8_bcast_W1), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), ]; -const EVEX_f2_0f: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 26] = [ - (0x10, [(super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_10), (super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_10), (super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_10), (super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_10)]),// W0 - (0x11, [(super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_11), (super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_11), (super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_11), (super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_11)]),// W0 +const EVEX_f3_0f: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 26] = [ + (0x10, [(super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_10), (super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_10), (super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_10), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]),// W0 + (0x11, [(super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_11), (super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_11), (super::Opcode::VMOVSS, EVEXOperandCode::VMOVSS_11), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]),// W0 (0x12, [(super::Opcode::VMOVSLDUP, EVEXOperandCode::Gm_E_LL_W0), (super::Opcode::VMOVSLDUP, EVEXOperandCode::Gm_E_LL_W0), (super::Opcode::VMOVSLDUP, EVEXOperandCode::Gm_E_LL_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x16, [(super::Opcode::VMOVSHDUP, EVEXOperandCode::Gm_E_LL_W0), (super::Opcode::VMOVSHDUP, EVEXOperandCode::Gm_E_LL_W0), (super::Opcode::VMOVSHDUP, EVEXOperandCode::Gm_E_LL_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x2a, [(super::Opcode::VCVTSI2SS, EVEXOperandCode::VCVTSI2SS), (super::Opcode::VCVTSI2SS, EVEXOperandCode::VCVTSI2SS), (super::Opcode::VCVTSI2SS, EVEXOperandCode::VCVTSI2SS), (super::Opcode::VCVTSI2SS, EVEXOperandCode::VCVTSI2SS)]), @@ -1059,7 +1066,7 @@ const EVEX_f2_0f: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 26] = [ (0xe6, [(super::Opcode::VCVTDQ2PD, EVEXOperandCode::VCVTUDQ2PD), (super::Opcode::VCVTDQ2PD, EVEXOperandCode::VCVTUDQ2PD), (super::Opcode::VCVTDQ2PD, EVEXOperandCode::VCVTUDQ2PD), (super::Opcode::VCVTDQ2PD, EVEXOperandCode::VCVTUDQ2PD)]), ]; -const EVEX_f2_0f38: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 28] = [ +const EVEX_f3_0f38: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 28] = [ (0x10, [(super::Opcode::VPMOVUSWB, EVEXOperandCode::Eqm_xmm_G_xmm_W0), (super::Opcode::VPMOVUSWB, EVEXOperandCode::Em_xmm_G_ymm_W0), (super::Opcode::VPMOVUSWB, EVEXOperandCode::Em_ymm_G_zmm_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x11, [(super::Opcode::VPMOVUSDB, EVEXOperandCode::Edm_xmm_G_xmm_W0), (super::Opcode::VPMOVUSDB, EVEXOperandCode::Eqm_xmm_G_ymm_W0), (super::Opcode::VPMOVUSDB, EVEXOperandCode::Em_xmm_G_zmm_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x12, [(super::Opcode::VPMOVUSQB, EVEXOperandCode::Ewm_xmm_G_xmm_W0), (super::Opcode::VPMOVUSQB, EVEXOperandCode::Edm_xmm_G_ymm_W0), (super::Opcode::VPMOVUSQB, EVEXOperandCode::Eqm_xmm_G_zmm_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), @@ -1090,9 +1097,9 @@ const EVEX_f2_0f38: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 28] = [ (0x72, [(super::Opcode::VCVTNEPS2BF16, EVEXOperandCode::Operands_72_W0), (super::Opcode::VCVTNEPS2BF16, EVEXOperandCode::Operands_72_W0), (super::Opcode::VCVTNEPS2BF16, EVEXOperandCode::Operands_72_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), ]; -const EVEX_f3_0f: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 24] = [ - (0x10, [(super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_10), (super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_10), (super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_10), (super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_10)]),// W1 - (0x11, [(super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_11), (super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_11), (super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_11), (super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_11)]),// W1 +const EVEX_f2_0f: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 23] = [ + (0x10, [(super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_10), (super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_10), (super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_10), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]),// W1 + (0x11, [(super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_11), (super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_11), (super::Opcode::VMOVSD, EVEXOperandCode::VMOVSD_11), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]),// W1 (0x12, [(super::Opcode::VMOVDDUP, EVEXOperandCode::Gm_E_LL_W1), (super::Opcode::VMOVDDUP, EVEXOperandCode::Gm_E_LL_W1), (super::Opcode::VMOVDDUP, EVEXOperandCode::Gm_E_LL_W1), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x2a, [(super::Opcode::VCVTSI2SD, EVEXOperandCode::VCVTSI2SS), (super::Opcode::VCVTSI2SD, EVEXOperandCode::VCVTSI2SS), (super::Opcode::VCVTSI2SD, EVEXOperandCode::VCVTSI2SS), (super::Opcode::VCVTSI2SD, EVEXOperandCode::VCVTSI2SS)]), (0x2c, [(super::Opcode::VCVTTSD2SI, EVEXOperandCode::Gd_Ed_xmm_sae), (super::Opcode::VCVTTSD2SI, EVEXOperandCode::Gd_Ed_xmm_sae), (super::Opcode::VCVTTSD2SI, EVEXOperandCode::Gd_Ed_xmm_sae), (super::Opcode::VCVTTSD2SI, EVEXOperandCode::Gd_Ed_xmm_sae)]), @@ -1104,20 +1111,19 @@ const EVEX_f3_0f: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 24] = [ (0x5c, [(super::Opcode::VSUBSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VSUBSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VSUBSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VSUBSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1)]), (0x5d, [(super::Opcode::VMINSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VMINSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VMINSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VMINSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1)]),// W1 (0x5e, [(super::Opcode::VDIVSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VDIVSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VDIVSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VDIVSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1)]), - (0x5f, [(super::Opcode::VMAXSD, EVEXOperandCode::Gm_V_E_xmm_sae), (super::Opcode::VMAXSD, EVEXOperandCode::Gm_V_E_xmm_sae), (super::Opcode::VMAXSD, EVEXOperandCode::Gm_V_E_xmm_sae), (super::Opcode::VMAXSD, EVEXOperandCode::Gm_V_E_xmm_sae)]),// W1 + (0x5f, [(super::Opcode::VMAXSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VMAXSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VMAXSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1), (super::Opcode::VMAXSD, EVEXOperandCode::Gm_V_E_xmm_sae_W1)]),// W1 (0x6f, [(super::Opcode::VMOVDQU8, EVEXOperandCode::Gm_E_LL), (super::Opcode::VMOVDQU8, EVEXOperandCode::Gm_E_LL), (super::Opcode::VMOVDQU8, EVEXOperandCode::Gm_E_LL), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x70, [(super::Opcode::VPSHUFLW, EVEXOperandCode::Gm_E_LL_imm8), (super::Opcode::VPSHUFLW, EVEXOperandCode::Gm_E_LL_imm8), (super::Opcode::VPSHUFLW, EVEXOperandCode::Gm_E_LL_imm8), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x78, [(super::Opcode::VCVTTSD2USI, EVEXOperandCode::Gd_Ed_xmm_sae), (super::Opcode::VCVTTSD2USI, EVEXOperandCode::Gd_Ed_xmm_sae), (super::Opcode::VCVTTSD2USI, EVEXOperandCode::Gd_Ed_xmm_sae), (super::Opcode::VCVTTSD2USI, EVEXOperandCode::Gd_Ed_xmm_sae)]), (0x79, [(super::Opcode::VCVTSD2USI, EVEXOperandCode::Gd_Ed_xmm_sae), (super::Opcode::VCVTSD2USI, EVEXOperandCode::Gd_Ed_xmm_sae), (super::Opcode::VCVTSD2USI, EVEXOperandCode::Gd_Ed_xmm_sae), (super::Opcode::VCVTSD2USI, EVEXOperandCode::Gd_Ed_xmm_sae)]), (0x7a, [(super::Opcode::VCVTUDQ2PS, EVEXOperandCode::VCVTDQ2PS), (super::Opcode::VCVTUDQ2PS, EVEXOperandCode::VCVTDQ2PS), (super::Opcode::VCVTUDQ2PS, EVEXOperandCode::VCVTDQ2PS), (super::Opcode::VCVTUDQ2PS, EVEXOperandCode::VCVTDQ2PS)]), (0x7b, [(super::Opcode::VCVTUSI2SD, EVEXOperandCode::VCVTUSI2SD), (super::Opcode::VCVTUSI2SD, EVEXOperandCode::VCVTUSI2SD), (super::Opcode::VCVTUSI2SD, EVEXOperandCode::VCVTUSI2SD), (super::Opcode::VCVTUSI2SD, EVEXOperandCode::VCVTUSI2SD)]), - (0x7e, [(super::Opcode::VMOVQ, EVEXOperandCode::VMOVQ_G_Ed_xmm), (super::Opcode::Invalid, EVEXOperandCode::Nothing), (super::Opcode::Invalid, EVEXOperandCode::Nothing), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x7f, [(super::Opcode::VMOVDQU8, EVEXOperandCode::Em_G_LL), (super::Opcode::VMOVDQU8, EVEXOperandCode::Em_G_LL), (super::Opcode::VMOVDQU8, EVEXOperandCode::Em_G_LL), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0xc2, [(super::Opcode::VCMPSD, EVEXOperandCode::Maskm_V_Eq_xmm_imm8_sae_W1), (super::Opcode::VCMPSD, EVEXOperandCode::Maskm_V_Eq_xmm_imm8_sae_W1), (super::Opcode::VCMPSD, EVEXOperandCode::Maskm_V_Eq_xmm_imm8_sae_W1), (super::Opcode::VCMPSD, EVEXOperandCode::Maskm_V_Eq_xmm_imm8_sae_W1)]), (0xe6, [(super::Opcode::VCVTPD2DQ, EVEXOperandCode::VCVTTPD2DQ), (super::Opcode::VCVTPD2DQ, EVEXOperandCode::VCVTTPD2DQ), (super::Opcode::VCVTPD2DQ, EVEXOperandCode::VCVTTPD2DQ), (super::Opcode::VCVTPD2DQ, EVEXOperandCode::VCVTTPD2DQ)]), ]; -const EVEX_f3_0f38: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 8] = [ +const EVEX_f2_0f38: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 8] = [ (0x52, [(super::Opcode::Invalid, EVEXOperandCode::Nothing), (super::Opcode::Invalid, EVEXOperandCode::Nothing), (super::Opcode::VP4DPWSSD, EVEXOperandCode::Gm_V_zmm_M_xmm_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x53, [(super::Opcode::Invalid, EVEXOperandCode::Nothing), (super::Opcode::Invalid, EVEXOperandCode::Nothing), (super::Opcode::VP4DPWSSDS, EVEXOperandCode::Gm_V_zmm_M_xmm_W0), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), (0x68, [(super::Opcode::VP2INTERSECTD, EVEXOperandCode::Mask_V_E_LL_bcast), (super::Opcode::VP2INTERSECTD, EVEXOperandCode::Mask_V_E_LL_bcast), (super::Opcode::VP2INTERSECTD, EVEXOperandCode::Mask_V_E_LL_bcast), (super::Opcode::Invalid, EVEXOperandCode::Nothing)]), |
