diff options
| author | iximeow <me@iximeow.net> | 2026-05-11 02:00:25 +0000 |
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2026-05-11 02:00:46 +0000 |
| commit | 5d9f17ddd807bc9917adbb498d734d5f95554909 (patch) | |
| tree | 0bfd28a5cf5ee0652429398d1874802febd33e55 /src | |
| parent | 6f10e4663a04fcb86ac9d5b09dbc47ffb9b22151 (diff) | |
even more EVEX encoding precision, regspec constructors are const
Diffstat (limited to 'src')
| -rw-r--r-- | src/isa_settings.rs | 22 | ||||
| -rw-r--r-- | src/long_mode/mod.rs | 54 | ||||
| -rw-r--r-- | src/shared/evex.in | 188 | ||||
| -rw-r--r-- | src/shared/generated_evex.in | 31 |
4 files changed, 188 insertions, 107 deletions
diff --git a/src/isa_settings.rs b/src/isa_settings.rs index 20d2e3f..96233f3 100644 --- a/src/isa_settings.rs +++ b/src/isa_settings.rs @@ -91,6 +91,20 @@ macro_rules! gen_isa_settings { Opcode::VP4DPWSSD, ]; + // only present in Knights *? + static AVX512_ER: &[Opcode] = &[ + Opcode::VEXP2PD, + Opcode::VEXP2PS, + Opcode::VRCP28PD, + Opcode::VRCP28PS, + Opcode::VRCP28SD, + Opcode::VRCP28SS, + Opcode::VRSQRT28PD, + Opcode::VRSQRT28PS, + Opcode::VRSQRT28SD, + Opcode::VRSQRT28SS, + ]; + /// optionally reject or reinterpret instruction according to settings for this decode /// operation. pub(crate) fn revise_instruction(settings: &$featureful_decoder, inst: &mut $inst_ty) -> Result<(), $decode_err> { @@ -113,6 +127,8 @@ macro_rules! gen_isa_settings { return Err(<$decode_err>::InvalidOpcode); } else if !settings.avx512_4fmaps() && AVX512_4FMAPS.contains(&inst.opcode) { return Err(<$decode_err>::InvalidOpcode); + } else if !settings.avx512_er() && AVX512_ER.contains(&inst.opcode) { + return Err(<$decode_err>::InvalidOpcode); } else if avx512_baseline { // TODO: hack around missing avx feature set specificity. return Ok(()); @@ -823,6 +839,11 @@ macro_rules! gen_isa_settings { return Err(<$decode_err>::InvalidOpcode); } } + <$opcode>::HRESET => { + if !settings.hreset() { + return Err(<$decode_err>::InvalidOpcode); + } + } other => { if !settings.bmi1() { @@ -997,6 +1018,7 @@ macro_rules! gen_arch_isa_settings { avx512_ifma, with_avx512_ifma = 110; keylocker, with_keylocker = 111; + hreset, with_hreset = 112; { sse4 = { diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 4165885..1b5caf1 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -135,10 +135,8 @@ impl RegSpec { /// construct a `RegSpec` for x87 register `st(num)` #[inline] - pub fn st(num: u8) -> RegSpec { - if num >= 8 { - panic!("invalid x87 reg st({})", num); - } + pub const fn st(num: u8) -> RegSpec { + assert!(num < 8, "invalid x87 reg"); RegSpec { num, @@ -148,10 +146,8 @@ impl RegSpec { /// construct a `RegSpec` for xmm reg `num` #[inline] - pub fn xmm(num: u8) -> RegSpec { - if num >= 32 { - panic!("invalid x86 xmm reg {}", num); - } + pub const fn xmm(num: u8) -> RegSpec { + assert!(num < 32, "invalid x86 xmm reg"); RegSpec { num, @@ -161,10 +157,8 @@ impl RegSpec { /// construct a `RegSpec` for ymm reg `num` #[inline] - pub fn ymm(num: u8) -> RegSpec { - if num >= 32 { - panic!("invalid x86 ymm reg {}", num); - } + pub const fn ymm(num: u8) -> RegSpec { + assert!(num < 32, "invalid x86 ymm reg"); RegSpec { num, @@ -174,10 +168,8 @@ impl RegSpec { /// construct a `RegSpec` for zmm reg `num` #[inline] - pub fn zmm(num: u8) -> RegSpec { - if num >= 32 { - panic!("invalid x86 zmm reg {}", num); - } + pub const fn zmm(num: u8) -> RegSpec { + assert!(num < 32, "invalid x86 zmm reg"); RegSpec { num, @@ -187,10 +179,8 @@ impl RegSpec { /// construct a `RegSpec` for qword reg `num` #[inline] - pub fn q(num: u8) -> RegSpec { - if num >= 16 { - panic!("invalid x86 qword reg {}", num); - } + pub const fn q(num: u8) -> RegSpec { + assert!(num < 16, "invalid x86 qword reg"); RegSpec { num, @@ -200,10 +190,8 @@ impl RegSpec { /// construct a `RegSpec` for mask reg `num` #[inline] - pub fn mask(num: u8) -> RegSpec { - if num >= 8 { - panic!("invalid x86 mask reg {}", num); - } + pub const fn mask(num: u8) -> RegSpec { + assert!(num < 8, "invalid x86 mask reg"); RegSpec { num, @@ -213,10 +201,8 @@ impl RegSpec { /// construct a `RegSpec` for dword reg `num` #[inline] - pub fn d(num: u8) -> RegSpec { - if num >= 16 { - panic!("invalid x86 dword reg {}", num); - } + pub const fn d(num: u8) -> RegSpec { + assert!(num < 16, "invalid x86 dword reg"); RegSpec { num, @@ -227,9 +213,7 @@ impl RegSpec { /// construct a `RegSpec` for word reg `num` #[inline] pub fn w(num: u8) -> RegSpec { - if num >= 16 { - panic!("invalid x86 word reg {}", num); - } + assert!(num < 16, "invalid x86 word reg"); RegSpec { num, @@ -240,9 +224,7 @@ impl RegSpec { /// construct a `RegSpec` for non-rex byte reg `num` #[inline] pub fn rb(num: u8) -> RegSpec { - if num >= 16 { - panic!("invalid x86 rex-byte reg {}", num); - } + assert!(num < 16, "invalid x86 rex-byte reg"); let bank = if num < 4 { RegisterBank::B @@ -259,9 +241,7 @@ impl RegSpec { /// construct a `RegSpec` for non-rex byte reg `num` #[inline] pub fn b(num: u8) -> RegSpec { - if num >= 8 { - panic!("invalid x86 non-rex byte reg {}", num); - } + assert!(num < 8, "invalid x86 non-rex-byte reg"); RegSpec { num, diff --git a/src/shared/evex.in b/src/shared/evex.in index a15b59b..07c82e5 100644 --- a/src/shared/evex.in +++ b/src/shared/evex.in @@ -572,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); } @@ -781,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); @@ -827,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; @@ -835,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() { @@ -865,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); @@ -925,28 +937,12 @@ pub(crate) fn read_evex_operands< 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); - } - instruction.operands[0] = mem_oper; - instruction.operands[1] = OperandSpec::RegRRR; - instruction.operand_count = 2; - - set_reg_sizes_from_ll(instruction)?; - } generated::EVEXOperandCode::M_G_LL_W1 => { deny_vex_reg(instruction)?; deny_mask_reg(instruction)?; ensure_W(instruction, 1)?; + deny_z(instruction)?; + deny_broadcast(instruction)?; instruction.mem_size = regs_size(instruction); @@ -983,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)?; @@ -991,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; @@ -1005,6 +1008,7 @@ pub(crate) fn read_evex_operands< generated::EVEXOperandCode::Gm_Eq_xmm_sae_W1 => { deny_vex_reg(instruction)?; deny_mask_reg(instruction)?; + deny_z(instruction)?; // vucomisd and vcomisd both are W=1 ensure_W(instruction, 1)?; @@ -1013,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; @@ -1097,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); @@ -1389,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); @@ -1490,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)?; @@ -1510,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)?; @@ -1734,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` @@ -1767,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` @@ -1801,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; @@ -1808,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 { @@ -1916,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; @@ -2488,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; @@ -2614,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); @@ -2661,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); @@ -2679,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); @@ -2710,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); @@ -2878,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); @@ -2913,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); @@ -2948,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); @@ -2975,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); @@ -2997,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); @@ -3010,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; @@ -3018,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; @@ -3688,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; @@ -3720,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; @@ -3738,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; @@ -3812,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); @@ -3857,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); @@ -3903,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); @@ -3984,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)?; @@ -4072,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; @@ -4107,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; @@ -4117,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); @@ -4135,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); @@ -4161,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; @@ -4537,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); @@ -4780,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); @@ -4841,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); } @@ -4855,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); @@ -4875,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); @@ -4895,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); @@ -4947,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() { @@ -4964,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() { @@ -5126,6 +5180,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.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; @@ -5133,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; @@ -5171,9 +5231,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 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() { @@ -5198,9 +5264,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 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() { @@ -5221,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)?; @@ -5246,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 f2ccc76..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, @@ -667,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, @@ -676,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, @@ -807,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)]), @@ -862,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)]), @@ -1022,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)]), @@ -1031,7 +1037,7 @@ 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] = [ +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)]), @@ -1060,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)]), @@ -1091,7 +1097,7 @@ 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] = [ +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)]), @@ -1112,13 +1118,12 @@ const EVEX_f3_0f: [(u8, [(super::Opcode, EVEXOperandCode); 4]); 24] = [ (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)]), |
