use std::collections::HashMap;
use super::x86_instr_info::OperandType;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
#[allow(non_camel_case_types)]
pub enum X86FullOpcode {
MOVrr = 400,
MOVrm,
MOVmr,
MOVri,
MOVmi,
MOVSD,
MOVSS,
MOVAPS,
MOVUPS,
MOVDQA,
MOVDQU,
MOVZX,
MOVSXD,
MOVBE,
MOVD,
MOVQ,
CMOVO,
CMOVNO,
CMOVB_FULL,
CMOVAE_FULL,
CMOVE_FULL,
CMOVNE_FULL,
CMOVBE_FULL,
CMOVA_FULL,
CMOVS_FULL,
CMOVNS_FULL,
CMOVP_FULL,
CMOVNP_FULL,
CMOVL_FULL,
CMOVGE_FULL,
CMOVLE_FULL,
CMOVG_FULL,
XCHG,
BSWAP,
CMPXCHG,
CMPXCHG8B,
CMPXCHG16B,
PUSHA,
POPA,
CWD,
CDQ,
CQO,
CBW,
CWDE,
CDQE,
ADD,
ADC,
SUB,
SBB,
MUL,
IMUL,
DIV,
IDIV,
INC,
DEC,
NEG,
CMP,
CMPXCHG_FULL,
XADD,
AAA,
AAS,
AAM,
AAD,
DAA,
DAS,
AND,
OR,
XOR,
NOT,
TEST,
SHL,
SHR,
SAR,
ROL,
ROR,
RCL,
RCR,
SHLD,
SHRD,
MOVS,
CMPS,
SCAS,
LODS,
STOS,
REP,
REPE,
REPNE,
REPZ,
REPNZ,
JMP,
JO,
JNO,
JB_FULL,
JAE_FULL,
JE_FULL,
JNE_FULL,
JBE_FULL,
JA_FULL,
JS_FULL,
JNS_FULL,
JP_FULL,
JNP_FULL,
JL_FULL,
JGE_FULL,
JLE_FULL,
JG_FULL,
LOOP,
LOOPE,
LOOPNE,
CALL,
RET,
IRET,
INT,
INTO,
BOUND,
ENTER,
LEAVE,
STC,
CLC,
CMC,
STD,
CLD,
STI,
CLI,
LAHF,
SAHF,
PUSHF,
POPF,
SETO,
SETNO,
SETB,
SETAE,
SETE,
SETNE,
SETBE,
SETA,
SETS,
SETNS,
SETP,
SETNP,
SETL,
SETGE,
SETLE,
SETG,
IN,
OUT,
INS,
OUTS,
HLT,
WAIT,
LOCK,
LGDT,
SGDT,
LIDT,
SIDT,
LLDT,
SLDT,
LTR,
STR,
LMSW,
SMSW,
INVLPG,
INVD,
WBINVD,
RDMSR,
WRMSR,
RDTSC,
RDTSCP,
RDPMC,
CPUID,
SYSCALL,
SYSRET,
SYSENTER,
SYSEXIT,
FLD,
FST,
FSTP,
FILD,
FIST,
FISTP,
FBLD,
FBSTP,
FADD,
FSUB,
FMUL,
FDIV,
FABS,
FCHS,
FSQRT,
FPREM,
FPREM1,
FCOM,
FCOMP,
FCOMPP,
FUCOM,
FUCOMP,
FUCOMPP,
FTST,
FXAM,
FSIN,
FCOS,
FSINCOS,
FPTAN,
FPATAN,
F2XM1,
FYL2X,
FYL2XP1,
FLDZ,
FLD1,
FLDPI,
FLDL2T,
FLDL2E,
FLDLG2,
FLDLN2,
FNCLEX,
FNDISI,
FNENI,
FNINIT,
FNSTSW,
FNSTCW,
FLDCW,
FSTCW,
FSTSW,
FFREE,
FDECSTP,
FINCSTP,
FXCH,
MOVD_MMX,
MOVQ_MMX,
PACKSSWB,
PACKSSDW,
PACKUSWB,
PADDB,
PADDW,
PADDD,
PADDSB,
PADDSW,
PADDUSB,
PADDUSW,
PSUBB,
PSUBW,
PSUBD,
PSUBSB,
PSUBSW,
PSUBUSB,
PSUBUSW,
PMULLW,
PMULHW,
PMADDWD,
PCMPEQB,
PCMPEQW,
PCMPEQD,
PCMPGTB,
PCMPGTW,
PCMPGTD,
PAND,
PANDN,
POR,
PXOR,
PSLLW,
PSLLD,
PSLLQ,
PSRLW,
PSRLD,
PSRLQ,
PSRAW,
PSRAD,
PUNPCKHBW,
PUNPCKHWD,
PUNPCKHDQ,
PUNPCKLBW,
PUNPCKLWD,
PUNPCKLDQ,
ADDPS,
ADDSS,
SUBPS,
SUBSS,
MULPS,
MULSS,
DIVPS,
DIVSS,
RCPPS,
RCPSS,
SQRTPS,
SQRTSS,
RSQRTPS,
RSQRTSS,
MAXPS,
MAXSS,
MINPS,
MINSS,
ANDPS,
ANDNPS,
ORPS,
XORPS,
CMPPS,
CMPSS,
SHUFPS,
UNPCKHPS,
UNPCKLPS,
MOVMSKPS,
MOVHLPS,
MOVLHPS,
MOVLPS,
MOVHPS,
ADDPD,
ADDSD,
SUBPD,
SUBSD,
MULPD,
MULSD,
DIVPD,
DIVSD,
SQRTPD,
SQRTSD,
MAXPD,
MAXSD,
MINPD,
MINSD,
ANDPD,
ANDNPD,
ORPD,
XORPD,
CMPPD,
CMPSD,
SHUFPD,
UNPCKHPD,
UNPCKLPD,
MOVMSKPD,
MOVUPD,
MOVAPD,
MOVLPD,
MOVHPD,
CVTDQ2PD,
CVTDQ2PS,
CVTPD2DQ,
CVTPD2PS,
CVTPS2DQ,
CVTPS2PD,
CVTSD2SI,
CVTSD2SS,
CVTSI2SD,
CVTSI2SS,
CVTSS2SD,
CVTSS2SI,
CVTTPD2DQ,
CVTTPS2DQ,
CVTTSD2SI,
CVTTSS2SI,
PADDB_128,
PADDW_128,
PADDD_128,
PADDQ_128,
PSUBB_128,
PSUBW_128,
PSUBD_128,
PSUBQ_128,
PMULUDQ,
PMULLW_128,
PMULHW_128,
PMULHUW,
PSADBW,
PAVGB,
PAVGW,
PMINUB,
PMINSW,
PMAXUB,
PMAXSW,
PSLLW_128,
PSLLD_128,
PSLLQ_128,
PSRLW_128,
PSRLD_128,
PSRLQ_128,
PSRAW_128,
PSRAD_128,
MASKMOVDQU,
MOVQ2DQ,
MOVDQ2Q,
PUNPCKLBW_128,
PUNPCKLWD_128,
PUNPCKLDQ_128,
PUNPCKLQDQ,
PUNPCKHBW_128,
PUNPCKHWD_128,
PUNPCKHDQ_128,
PUNPCKHQDQ,
PACKSSWB_128,
PACKSSDW_128,
PACKUSWB_128,
PAND_128,
PANDN_128,
POR_128,
PXOR_128,
PCMPEQB_128,
PCMPEQW_128,
PCMPEQD_128,
ADDSUBPS,
ADDSUBPD,
HADDPS,
HADDPD,
HSUBPS,
HSUBPD,
MOVSLDUP,
MOVSHDUP,
MOVDDUP,
LDDQU,
FISTTP,
MONITOR,
MWAIT,
PHADDW,
PHADDD,
PHADDSW,
PHSUBW,
PHSUBD,
PHSUBSW,
PMADDUBSW,
PMULHRSW,
PSHUFB,
PSIGNB,
PSIGNW,
PSIGND,
PABSB,
PABSW,
PABSD,
PALIGNR,
PSHUFB_ALT,
PMULLD,
PMULDQ,
DPPS,
DPPD,
BLENDPS,
BLENDPD,
BLENDVPS,
BLENDVPD,
PMINSB,
PMINSD,
PMINUW,
PMINUD,
PMAXSB,
PMAXSD,
PMAXUW,
PMAXUD,
PACKUSDW,
PCMPEQQ,
PINSRB,
PINSRD,
PINSRQ,
PEXTRB,
PEXTRD,
PEXTRQ,
PTEST,
ROUNDPS,
ROUNDPD,
ROUNDSS,
ROUNDSD,
CRC32,
EXTRACTPS,
INSERTPS,
PMOVSXBW,
PMOVSXBD,
PMOVSXBQ,
PMOVSXWD,
PMOVSXWQ,
PMOVSXDQ,
PMOVZXBW,
PMOVZXBD,
PMOVZXBQ,
PMOVZXWD,
PMOVZXWQ,
PMOVZXDQ,
MPSADBW,
PHMINPOSUW,
PCMPESTRI,
PCMPESTRM,
PCMPISTRI,
PCMPISTRM,
PCMPGTQ,
VADDPS,
VADDPD,
VADDSS,
VADDSD,
VSUBPS,
VSUBPD,
VSUBSS,
VSUBSD,
VMULPS,
VMULPD,
VMULSS,
VMULSD,
VDIVPS,
VDIVPD,
VDIVSS,
VDIVSD,
VANDPS,
VANDNPS,
VORPS,
VXORPS,
VZEROALL,
VZEROUPPER,
VMOVAPS,
VMOVUPS,
VMOVAPD,
VMOVUPD,
VBROADCASTSS,
VBROADCASTSD,
VBROADCASTF128,
VPERMILPS,
VPERMILPD,
VPERM2F128,
VEXTRACTF128,
VINSERTF128,
VCVTPH2PS,
VCVTPS2PH,
VPBROADCASTB,
VPBROADCASTW,
VPBROADCASTD,
VPBROADCASTQ,
VPERMQ,
VPERMPD,
VPERM2I128,
VPGATHERDD,
VPGATHERDQ,
VPGATHERQD,
VPGATHERQQ,
VPMASKMOVD,
VPMASKMOVQ,
VPSLLVD,
VPSLLVQ,
VPSRLVD,
VPSRLVQ,
VPSRAVD,
VFMADD132PS,
VFMADD132PD,
VFMADD132SS,
VFMADD132SD,
VFMADD213PS,
VFMADD213PD,
VFMADD213SS,
VFMADD213SD,
VFMADD231PS,
VFMADD231PD,
VFMADD231SS,
VFMADD231SD,
VFMSUB132PS,
VFMSUB132PD,
VFMSUB132SS,
VFMSUB132SD,
VFMSUB213PS,
VFMSUB213PD,
VFMSUB213SS,
VFMSUB213SD,
VFMSUB231PS,
VFMSUB231PD,
VFMSUB231SS,
VFMSUB231SD,
VFNMADD132PS,
VFNMADD132PD,
VFNMADD132SS,
VFNMADD132SD,
VFNMADD213PS,
VFNMADD213PD,
VFNMADD213SS,
VFNMADD213SD,
VFNMADD231PS,
VFNMADD231PD,
VFNMADD231SS,
VFNMADD231SD,
VFNMSUB132PS,
VFNMSUB132PD,
VFNMSUB132SS,
VFNMSUB132SD,
VFNMSUB213PS,
VFNMSUB213PD,
VFNMSUB213SS,
VFNMSUB213SD,
VFNMSUB231PS,
VFNMSUB231PD,
VFNMSUB231SS,
VFNMSUB231SD,
ANDN,
BEXTR,
BLSI,
BLSMSK,
BLSR,
BZHI,
MULX,
PDEP,
PEXT,
RORX,
SARX,
SHLX,
SHRX,
TZCNT,
LZCNT,
ADCX,
ADOX,
SHA1RNDS4,
SHA1NEXTE,
SHA1MSG1,
SHA1MSG2,
SHA256RNDS2,
SHA256MSG1,
SHA256MSG2,
AESENC,
AESENCLAST,
AESDEC,
AESDECLAST,
AESKEYGENASSIST,
AESIMC,
RDRAND,
RDSEED,
VPADDD_Z,
VPADDQ_Z,
VPSUBD_Z,
VPSUBQ_Z,
VPMULLD_Z,
VPMULLQ_Z,
VPANDD_Z,
VPANDQ_Z,
VPORD_Z,
VPORQ_Z,
VPXORD_Z,
VPXORQ_Z,
VPSLLVD_Z,
VPSRLVD_Z,
VPSRAVD_Z,
VPERMD_Z,
VPERMQ_Z,
VPERMPS_Z,
VPERMPD_Z,
VCOMPRESSPS_Z,
VCOMPRESSPD_Z,
VEXPANDPS_Z,
VEXPANDPD_Z,
VPBROADCASTD_Z,
VPBROADCASTQ_Z,
VPBROADCASTSS_Z,
VPBROADCASTSD_Z,
VMOVDQU8_Z,
VMOVDQU16_Z,
VMOVDQU32_Z,
VMOVDQU64_Z,
VPCMPEQD_Z,
VPCMPEQQ_Z,
VPCMPGTD_Z,
VPCMPGTQ_Z,
KAND,
KANDN,
KNOT,
KOR,
KXNOR,
KXOR,
KADD,
KSHIFTL,
KSHIFTR,
KTEST,
KMOV,
KUNPCK,
VADDPD_Z,
VADDPS_Z,
VMULPD_Z,
VMULPS_Z,
VADDSD_Z,
VADDSS_Z,
VMULSD_Z,
VMULSS_Z,
VFMADD132PD_Z,
VFMADD213PD_Z,
VFMADD231PD_Z,
VFMADD132PS_Z,
VFMADD213PS_Z,
VFMADD231PS_Z,
VALIGND_Z,
VALIGNQ_Z,
VDBPSADBW_Z,
VPABSQ_Z,
VPABSQ,
VPMADD52LUQ_Z,
VPMADD52HUQ_Z,
TILELOADD,
TILESTORED,
TILERELEASE,
TILEZERO,
TDPBSSD,
TDPBSUD,
TDPBUSD,
TDPBUUD,
TDPBF16PS,
TDPFP16PS,
TCMMIMFP16PS,
TCMMRLFP16PS,
ENDBR32,
ENDBR64,
INCSSP,
RDSSP,
SETSSBSY,
CLRSSBSY,
WRSS,
WRUSS,
CLDEMOTE,
CLFLUSH,
CLFLUSHOPT,
CLWB,
PREFETCH,
PREFETCHW,
PREFETCHWT1,
RDPID,
RDFSBASE,
RDGSBASE,
WRFSBASE,
WRGSBASE,
PTWRITE,
UMONITOR,
UMWAIT,
TPAUSE,
SERIALIZE,
VPERMB_Z,
VPERMI2B_Z,
VPERMT2B_Z,
VPCOMPRESSB_Z,
VPCOMPRESSW_Z,
VPEXPANDB_Z,
VPEXPANDW_Z,
VPCONFLICTD_Z,
VPCONFLICTQ_Z,
VPLZCNTD_Z,
VPLZCNTQ_Z,
VPOPCNTB_Z,
VPOPCNTW_Z,
VPOPCNTD_Z,
VPOPCNTQ_Z,
VGETMANTPS_Z,
VGETMANTPD_Z,
VGETMANTSS_Z,
VGETMANTSD_Z,
VGETEXPPS_Z,
VGETEXPPD_Z,
VGETEXPSS_Z,
VGETEXPSD_Z,
VRNDSCALEPS_Z,
VRNDSCALEPD_Z,
VRNDSCALESS_Z,
VRNDSCALESD_Z,
VREDUCEPS_Z,
VREDUCEPD_Z,
VREDUCESS_Z,
VREDUCESD_Z,
VRANGEPS_Z,
VRANGEPD_Z,
VRANGESS_Z,
VRANGESD_Z,
VFIXUPIMMPS_Z,
VFIXUPIMMPD_Z,
VFIXUPIMMSS_Z,
VFIXUPIMMSD_Z,
VSCALEFPS_Z,
VSCALEFPD_Z,
VSCALEFSS_Z,
VSCALEFSD_Z,
VFPCLASSPS_Z,
VFPCLASSPD_Z,
VFPCLASSSS_Z,
VFPCLASSSD_Z,
VDBPSADBW_Z_512,
KADDW_Z,
KANDB_Z,
KANDW_Z,
KANDNB_Z,
KANDNW_Z,
KNOTB_Z,
KNOTW_Z,
KORB_Z,
KORW_Z,
KXNORB_Z,
KXNORW_Z,
KXORB_Z,
KXORW_Z,
KORTESTB_Z,
KORTESTW_Z,
KTESTB_Z,
KTESTW_Z,
KUNPCKBW_Z,
KUNPCKWD_Z,
VCVTNE2PS2BF16_Z,
VCVTNEPS2BF16_Z,
VDPBF16PS_Z,
VADDPH_Z,
VADDSH_Z,
VSUBPH_Z,
VSUBSH_Z,
VMULPH_Z,
VMULSH_Z,
VDIVPH_Z,
VDIVSH_Z,
VFMADD132PH_Z,
VFMADD213PH_Z,
VFMADD231PH_Z,
VFMSUB132PH_Z,
VFMSUB213PH_Z,
VFMSUB231PH_Z,
VFNMADD132PH_Z,
VFNMADD213PH_Z,
VFNMADD231PH_Z,
VFNMSUB132PH_Z,
VFNMSUB213PH_Z,
VFNMSUB231PH_Z,
VMAXPH_Z,
VMAXSH_Z,
VMINPH_Z,
VMINSH_Z,
VSQRTPH_Z,
VSQRTSH_Z,
VCVTPH2W_Z,
VCVTPH2UW_Z,
VCVTPH2DQ_Z,
VCVTPH2UDQ_Z,
VCVTPH2QQ_Z,
VCVTPH2UQQ_Z,
VCVTW2PH_Z,
VCVTUW2PH_Z,
VCVTDQ2PH_Z,
VCVTUDQ2PH_Z,
VCVTQQ2PH_Z,
VCVTUQQ2PH_Z,
VCVTPH2PSX_Z,
VCVTPS2PHX_Z,
VCVTPH2PD_Z,
VCVTPD2PH_Z,
VFPCLASSPH_Z,
VGETMANTPH_Z,
VGETEXPPH_Z,
VRNDSCALEPH_Z,
VREDUCEPH_Z,
VRANGEPH_Z,
VSCALEFPH_Z,
VPCOMPRESSB_256,
VPCOMPRESSW_256,
VPEXPANDB_256,
VPEXPANDW_256,
VPSHLDVW,
VPSHLDVD,
VPSHLDVQ,
VPSHRDVW,
VPSHRDVD,
VPSHRDVQ,
VGF2P8AFFINEINVQB_Z,
VGF2P8AFFINEQB_Z,
VGF2P8MULB_Z,
VAESDEC_Z,
VAESDECLAST_Z,
VAESENC_Z,
VAESENCLAST_Z,
VPCLMULQDQ_Z,
ENQCMD,
ENQCMDS,
MOVDIRI,
MOVDIR64B,
PCONFIG,
CLUI,
STUI,
TESTUI,
SENDUIP,
UIRET,
XBEGIN,
XEND,
XABORT,
XTEST,
LOADIWKEY,
AESENC128KL,
AESDEC128KL,
AESENC256KL,
AESDEC256KL,
AESENCWIDE128KL,
AESDECWIDE128KL,
AESENCWIDE256KL,
AESDECWIDE256KL,
ENCODEKEY128,
ENCODEKEY256,
HRESET,
URDMSR,
UWRMSR,
RDSSPD,
RDSSPQ,
INCSSPD,
INCSSPQ,
RSTORSSP,
SAVEPREVSSP,
WRSSD,
WRSSQ,
WRUSSD,
WRUSSQ,
VPDPBSUD,
VPDPBSUDS,
VPDPBUUD,
VPDPBUUDS,
VP2INTERSECTD,
VP2INTERSECTQ,
VADDPH,
VMULPH,
VDIVPH,
VSUBPH,
VMINPH,
VMAXPH,
VSQRTPH,
VCVTNE2PS2BF16,
VDPBF16PS,
VCVTNEEBF162PS,
VCVTNEEPH2PS,
LDTILECFG,
STTILECFG,
TILECONFIG,
ERETS,
ERETU,
LKGS,
CMPCCXADD,
AADD,
AAND,
AOR,
AXOR,
WRMSRNS,
RDMSRLIST,
WRMSRLIST,
}
impl X86FullOpcode {
pub fn as_u32(self) -> u32 {
self as u32
}
pub fn mnemonic(self) -> &'static str {
FULL_OPCODE_MNEMONICS[self.as_u32() as usize - 400]
}
pub fn intel_mnemonic(self) -> &'static str {
FULL_OPCODE_INTEL_MNEMONICS[self.as_u32() as usize - 400]
}
pub fn num_operands(self) -> u8 {
FULL_OPCODE_NUM_OPERANDS[self.as_u32() as usize - 400]
}
pub fn encoding_form(self) -> EncodingForm {
FULL_OPCODE_ENCODING_FORMS[self.as_u32() as usize - 400]
}
pub fn is_cmov(self) -> bool {
matches!(
self,
X86FullOpcode::CMOVO
| X86FullOpcode::CMOVNO
| X86FullOpcode::CMOVB_FULL
| X86FullOpcode::CMOVAE_FULL
| X86FullOpcode::CMOVE_FULL
| X86FullOpcode::CMOVNE_FULL
| X86FullOpcode::CMOVBE_FULL
| X86FullOpcode::CMOVA_FULL
| X86FullOpcode::CMOVS_FULL
| X86FullOpcode::CMOVNS_FULL
| X86FullOpcode::CMOVP_FULL
| X86FullOpcode::CMOVNP_FULL
| X86FullOpcode::CMOVL_FULL
| X86FullOpcode::CMOVGE_FULL
| X86FullOpcode::CMOVLE_FULL
| X86FullOpcode::CMOVG_FULL
)
}
pub fn is_jcc(self) -> bool {
matches!(
self,
X86FullOpcode::JO
| X86FullOpcode::JNO
| X86FullOpcode::JB_FULL
| X86FullOpcode::JAE_FULL
| X86FullOpcode::JE_FULL
| X86FullOpcode::JNE_FULL
| X86FullOpcode::JBE_FULL
| X86FullOpcode::JA_FULL
| X86FullOpcode::JS_FULL
| X86FullOpcode::JNS_FULL
| X86FullOpcode::JP_FULL
| X86FullOpcode::JNP_FULL
| X86FullOpcode::JL_FULL
| X86FullOpcode::JGE_FULL
| X86FullOpcode::JLE_FULL
| X86FullOpcode::JG_FULL
)
}
pub fn is_setcc(self) -> bool {
matches!(
self,
X86FullOpcode::SETO
| X86FullOpcode::SETNO
| X86FullOpcode::SETB
| X86FullOpcode::SETAE
| X86FullOpcode::SETE
| X86FullOpcode::SETNE
| X86FullOpcode::SETBE
| X86FullOpcode::SETA
| X86FullOpcode::SETS
| X86FullOpcode::SETNS
| X86FullOpcode::SETP
| X86FullOpcode::SETNP
| X86FullOpcode::SETL
| X86FullOpcode::SETGE
| X86FullOpcode::SETLE
| X86FullOpcode::SETG
)
}
pub fn is_vex(self) -> bool {
matches!(
self.encoding_form(),
EncodingForm::VEX | EncodingForm::VEX3Byte
)
}
pub fn is_evex(self) -> bool {
matches!(self.encoding_form(), EncodingForm::EVEX)
}
pub fn is_legacy(self) -> bool {
matches!(
self.encoding_form(),
EncodingForm::Legacy | EncodingForm::LegacyREX
)
}
pub fn base_opcode(self) -> u8 {
FULL_OPCODE_BASE_BYTES[self.as_u32() as usize - 400]
}
pub fn opcode_map(self) -> u8 {
FULL_OPCODE_MAPS[self.as_u32() as usize - 400]
}
pub fn mandatory_prefix(self) -> u8 {
FULL_OPCODE_MANDATORY_PREFIX[self.as_u32() as usize - 400]
}
pub fn requires_modrm(self) -> bool {
FULL_OPCODE_REQUIRES_MODRM[self.as_u32() as usize - 400]
}
pub fn modrm_extension(self) -> u8 {
FULL_OPCODE_MODRM_EXT[self.as_u32() as usize - 400]
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum EncodingForm {
Legacy,
LegacyREX,
VEX,
VEX3Byte,
XOP,
EVEX,
None,
}
#[derive(Debug, Clone)]
pub struct InstrEncodingInfo {
pub opcode: X86FullOpcode,
pub mnemonic: &'static str,
pub intel_mnemonic: &'static str,
pub num_operands: u8,
pub encoding_form: EncodingForm,
pub base_opcode: u8,
pub opcode_map: u8,
pub mandatory_prefix: u8,
pub requires_modrm: bool,
pub modrm_extension: u8,
pub operand_types: &'static [OperandType],
pub is_terminator: bool,
pub is_branch: bool,
pub is_call: bool,
pub is_return: bool,
pub is_compare: bool,
pub is_move_immediate: bool,
pub is_convert: bool,
pub has_side_effects: bool,
pub may_load: bool,
pub may_store: bool,
pub is_commutative: bool,
pub is_three_address: bool,
}
use EncodingForm::{Legacy, LegacyREX, VEX3Byte, EVEX, VEX};
pub(crate) const FULL_OPCODE_MNEMONICS: &[&str] = &[
"mov",
"mov",
"mov",
"mov",
"mov",
"movsd",
"movss",
"movaps",
"movups",
"movdqa",
"movdqu",
"movzx",
"movsxd",
"movbe",
"movd",
"movq",
"cmovno",
"cmovb",
"cmovae",
"cmove",
"cmovne",
"cmovbe",
"cmova",
"cmovs",
"cmovns",
"cmovp",
"cmovnp",
"cmovl",
"cmovge",
"cmovle",
"cmovg",
"bswap",
"cmpxchg",
"cmpxchg8b",
"cmpxchg16b",
"pusha",
"popa",
"cwd",
"cdq",
"cqo",
"cbw",
"cwde",
"cdqe",
"adc",
"sub",
"sbb",
"mul",
"imul",
"div",
"idiv",
"inc",
"dec",
"neg",
"cmp",
"cmpxchg",
"xadd",
"aaa",
"aas",
"aam",
"aad",
"daa",
"das",
"or",
"xor",
"not",
"test",
"shr",
"sar",
"rol",
"ror",
"rcl",
"rcr",
"shld",
"shrd",
"cmps",
"scas",
"lods",
"stos",
"rep",
"repe",
"repne",
"repz",
"repnz",
"jo",
"jno",
"jb",
"jae",
"je",
"jne",
"jbe",
"ja",
"js",
"jns",
"jp",
"jnp",
"jl",
"jge",
"jle",
"jg",
"loop",
"loope",
"loopne",
"call",
"ret",
"iret",
"int",
"into",
"bound",
"enter",
"leave",
"clc",
"cmc",
"std",
"cld",
"sti",
"cli",
"lahf",
"sahf",
"pushf",
"popf",
"setno",
"setb",
"setae",
"sete",
"setne",
"setbe",
"seta",
"sets",
"setns",
"setp",
"setnp",
"setl",
"setge",
"setle",
"setg",
"out",
"ins",
"outs",
"hlt",
"wait",
"lock",
"lgdt",
"sgdt",
"lidt",
"sidt",
"lldt",
"sldt",
"ltr",
"str",
"lmsw",
"smsw",
"invlpg",
"invd",
"wbinvd",
"rdmsr",
"wrmsr",
"rdtsc",
"rdtscp",
"rdpmc",
"cpuid",
"syscall",
"sysret",
"sysenter",
"sysexit",
"fst",
"fstp",
"fild",
"fist",
"fistp",
"fbld",
"fbstp",
"fadd",
"fsub",
"fmul",
"fdiv",
"fabs",
"fchs",
"fsqrt",
"fprem",
"fprem1",
"fcom",
"fcomp",
"fcompp",
"fucom",
"fucomp",
"fucompp",
"ftst",
"fxam",
"fsin",
"fcos",
"fsincos",
"fptan",
"fpatan",
"f2xm1",
"fyl2x",
"fyl2xp1",
"fldz",
"fld1",
"fldpi",
"fldl2t",
"fldl2e",
"fldlg2",
"fldln2",
"fnclex",
"fndisi",
"fneni",
"fninit",
"fnstsw",
"fnstcw",
"fldcw",
"fstcw",
"fstsw",
"ffree",
"fdecstp",
"fincstp",
"fxch",
"movq",
"packsswb",
"packssdw",
"packuswb",
"paddb",
"paddw",
"paddd",
"paddsb",
"paddsw",
"paddusb",
"paddusw",
"psubb",
"psubw",
"psubd",
"psubsb",
"psubsw",
"psubusb",
"psubusw",
"pmullw",
"pmulhw",
"pmaddwd",
"pcmpeqb",
"pcmpeqw",
"pcmpeqd",
"pcmpgtb",
"pcmpgtw",
"pcmpgtd",
"pand",
"pandn",
"por",
"pxor",
"psllw",
"pslld",
"psllq",
"psrlw",
"psrld",
"psrlq",
"psraw",
"psrad",
"punpckhbw",
"punpckhwd",
"punpckhdq",
"punpcklbw",
"punpcklwd",
"punpckldq",
"addss",
"subps",
"subss",
"mulps",
"mulss",
"divps",
"divss",
"rcpps",
"rcpss",
"sqrtps",
"sqrtss",
"rsqrtps",
"rsqrtss",
"maxps",
"maxss",
"minps",
"minss",
"andps",
"andnps",
"orps",
"xorps",
"cmpps",
"cmpss",
"shufps",
"unpckhps",
"unpcklps",
"movmskps",
"movhlps",
"movlhps",
"movlps",
"movhps",
"addsd",
"subpd",
"subsd",
"mulpd",
"mulsd",
"divpd",
"divsd",
"sqrtpd",
"sqrtsd",
"maxpd",
"maxsd",
"minpd",
"minsd",
"andpd",
"andnpd",
"orpd",
"xorpd",
"cmppd",
"cmpsd",
"shufpd",
"unpckhpd",
"unpcklpd",
"movmskpd",
"movupd",
"movapd",
"movlpd",
"movhpd",
"cvtdq2pd",
"cvtdq2ps",
"cvtpd2dq",
"cvtpd2ps",
"cvtps2dq",
"cvtps2pd",
"cvtsd2si",
"cvtsd2ss",
"cvtsi2sd",
"cvtsi2ss",
"cvtss2sd",
"cvtss2si",
"cvttpd2dq",
"cvttps2dq",
"cvttsd2si",
"cvttss2si",
"paddb",
"paddw",
"paddd",
"paddq",
"psubb",
"psubw",
"psubd",
"psubq",
"pmuludq",
"pmullw",
"pmulhw",
"pmulhuw",
"psadbw",
"pavgb",
"pavgw",
"pminub",
"pminsw",
"pmaxub",
"pmaxsw",
"psllw",
"pslld",
"psllq",
"psrlw",
"psrld",
"psrlq",
"psraw",
"psrad",
"maskmovdqu",
"movq2dq",
"movdq2q",
"punpcklbw",
"punpcklwd",
"punpckldq",
"punpcklqdq",
"punpckhbw",
"punpckhwd",
"punpckhdq",
"punpckhqdq",
"packsswb",
"packssdw",
"packuswb",
"pand",
"pandn",
"por",
"pxor",
"pcmpeqb",
"pcmpeqw",
"pcmpeqd",
"addsubpd",
"haddps",
"haddpd",
"hsubps",
"hsubpd",
"movsldup",
"movshdup",
"movddup",
"lddqu",
"fisttp",
"monitor",
"mwait",
"phaddd",
"phaddsw",
"phsubw",
"phsubd",
"phsubsw",
"pmaddubsw",
"pmulhrsw",
"pshufb",
"psignb",
"psignw",
"psignd",
"pabsb",
"pabsw",
"pabsd",
"palignr",
"pshufb",
"pmuldq",
"dpps",
"dppd",
"blendps",
"blendpd",
"blendvps",
"blendvpd",
"pminsb",
"pminsd",
"pminuw",
"pminud",
"pmaxsb",
"pmaxsd",
"pmaxuw",
"pmaxud",
"packusdw",
"pcmpeqq",
"pinsrb",
"pinsrd",
"pinsrq",
"pextrb",
"pextrd",
"pextrq",
"ptest",
"roundps",
"roundpd",
"roundss",
"roundsd",
"crc32",
"extractps",
"insertps",
"pmovsxbw",
"pmovsxbd",
"pmovsxbq",
"pmovsxwd",
"pmovsxwq",
"pmovsxdq",
"pmovzxbw",
"pmovzxbd",
"pmovzxbq",
"pmovzxwd",
"pmovzxwq",
"pmovzxdq",
"mpsadbw",
"phminposuw",
"pcmpestrm",
"pcmpistri",
"pcmpistrm",
"pcmpgtq",
"vaddpd",
"vaddss",
"vaddsd",
"vsubps",
"vsubpd",
"vsubss",
"vsubsd",
"vmulps",
"vmulpd",
"vmulss",
"vmulsd",
"vdivps",
"vdivpd",
"vdivss",
"vdivsd",
"vandps",
"vandnps",
"vorps",
"vxorps",
"vzeroall",
"vzeroupper",
"vmovaps",
"vmovups",
"vmovapd",
"vmovupd",
"vbroadcastss",
"vbroadcastsd",
"vbroadcastf128",
"vpermilps",
"vpermilpd",
"vperm2f128",
"vextractf128",
"vinsertf128",
"vcvtph2ps",
"vcvtps2ph",
"vpbroadcastw",
"vpbroadcastd",
"vpbroadcastq",
"vpermq",
"vpermpd",
"vperm2i128",
"vpgatherdd",
"vpgatherdq",
"vpgatherqd",
"vpgatherqq",
"vpmaskmovd",
"vpmaskmovq",
"vpsllvd",
"vpsllvq",
"vpsrlvd",
"vpsrlvq",
"vpsravd",
"vfmadd132pd",
"vfmadd132ss",
"vfmadd132sd",
"vfmadd213ps",
"vfmadd213pd",
"vfmadd213ss",
"vfmadd213sd",
"vfmadd231ps",
"vfmadd231pd",
"vfmadd231ss",
"vfmadd231sd",
"vfmsub132ps",
"vfmsub132pd",
"vfmsub132ss",
"vfmsub132sd",
"vfmsub213ps",
"vfmsub213pd",
"vfmsub213ss",
"vfmsub213sd",
"vfmsub231ps",
"vfmsub231pd",
"vfmsub231ss",
"vfmsub231sd",
"vfnmadd132ps",
"vfnmadd132pd",
"vfnmadd132ss",
"vfnmadd132sd",
"vfnmadd213ps",
"vfnmadd213pd",
"vfnmadd213ss",
"vfnmadd213sd",
"vfnmadd231ps",
"vfnmadd231pd",
"vfnmadd231ss",
"vfnmadd231sd",
"vfnmsub132ps",
"vfnmsub132pd",
"vfnmsub132ss",
"vfnmsub132sd",
"vfnmsub213ps",
"vfnmsub213pd",
"vfnmsub213ss",
"vfnmsub213sd",
"vfnmsub231ps",
"vfnmsub231pd",
"vfnmsub231ss",
"vfnmsub231sd",
"bextr",
"blsi",
"blsmsk",
"blsr",
"bzhi",
"mulx",
"pdep",
"pext",
"rorx",
"sarx",
"shlx",
"shrx",
"tzcnt",
"lzcnt",
"adox",
"sha1nexte",
"sha1msg1",
"sha1msg2",
"sha256rnds2",
"sha256msg1",
"sha256msg2",
"aesenclast",
"aesdec",
"aesdeclast",
"aeskeygenassist",
"aesimc",
"rdseed",
"vpaddq",
"vpsubd",
"vpsubq",
"vpmulld",
"vpmullq",
"vpandd",
"vpandq",
"vpord",
"vporq",
"vpxord",
"vpxorq",
"vpsllvd",
"vpsrlvd",
"vpsravd",
"vpermd",
"vpermq",
"vpermps",
"vpermpd",
"vcompressps",
"vcompresspd",
"vexpandps",
"vexpandpd",
"vpbroadcastd",
"vpbroadcastq",
"vpbroadcastss",
"vpbroadcastsd",
"vmovdqu8",
"vmovdqu16",
"vmovdqu32",
"vmovdqu64",
"vpcmpeqd",
"vpcmpeqq",
"vpcmpgtd",
"vpcmpgtq",
"kand",
"kandn",
"knot",
"kor",
"kxnor",
"kxor",
"kadd",
"kshiftl",
"kshiftr",
"ktest",
"kmov",
"kunpck",
"vaddpd",
"vaddps",
"vmulpd",
"vmulps",
"vaddsd",
"vaddss",
"vmulsd",
"vmulss",
"vfmadd132pd",
"vfmadd213pd",
"vfmadd231pd",
"vfmadd132ps",
"vfmadd213ps",
"vfmadd231ps",
"valignd",
"valignq",
"vdbpsadbw",
"vpabsq",
"vpabsq",
"vpmadd52luq",
"vpmadd52huq",
"tilestored",
"tilerelease",
"tilezero",
"tdpbssd",
"tdpbsud",
"tdpbusd",
"tdpbuud",
"tdpbf16ps",
"tdpfp16ps",
"tcmmimfp16ps",
"tcmmrlfp16ps",
"endbr64",
"incssp",
"rdssp",
"setssbsy",
"clrssbsy",
"wrss",
"wruss",
"clflush",
"clflushopt",
"clwb",
"prefetch",
"prefetchw",
"prefetchwt1",
"rdfsbase",
"rdgsbase",
"wrfsbase",
"wrgsbase",
"umwait",
"tpause",
"vpermi2b",
"vpermt2b",
"vpcompressb",
"vpcompressw",
"vpexpandb",
"vpexpandw",
"vpconflictd",
"vpconflictq",
"vplzcntd",
"vplzcntq",
"vpopcntb",
"vpopcntw",
"vpopcntd",
"vpopcntq",
"vgetmantps",
"vgetmantpd",
"vgetmantss",
"vgetmantsd",
"vgetexpps",
"vgetexppd",
"vgetexpss",
"vgetexpsd",
"vrndscaleps",
"vrndscalepd",
"vrndscaless",
"vrndscalesd",
"vreduceps",
"vreducepd",
"vreducess",
"vreducesd",
"vrangeps",
"vrangepd",
"vrangess",
"vrangesd",
"vfixupimmps",
"vfixupimmpd",
"vfixupimmss",
"vfixupimmsd",
"vscalefps",
"vscalefpd",
"vscalefss",
"vscalefsd",
"vfclassps",
"vfclasspd",
"vfclassss",
"vfclasssd",
"vdbpsadbw",
"kaddw",
"kandb",
"kandw",
"kandnb",
"kandnw",
"knotb",
"knotw",
"korb",
"korw",
"kxnorb",
"kxnorw",
"kxorb",
"kxorw",
"kortestb",
"kortestw",
"ktestb",
"ktestw",
"kunpckbw",
"kunpckwd",
"vcvtne2ps2bf16",
"vcvtneps2bf16",
"vdpbf16ps",
"vaddph",
"vaddsh",
"vsubph",
"vsubsh",
"vmulph",
"vmulsh",
"vdivph",
"vdivsh",
"vfmadd132ph",
"vfmadd213ph",
"vfmadd231ph",
"vfmsub132ph",
"vfmsub213ph",
"vfmsub231ph",
"vfnmadd132ph",
"vfnmadd213ph",
"vfnmadd231ph",
"vfnmsub132ph",
"vfnmsub213ph",
"vfnmsub231ph",
"vmaxph",
"vmaxsh",
"vminph",
"vminsh",
"vsqrtph",
"vsqrtsh",
"vcvtph2w",
"vcvtph2uw",
"vcvtph2dq",
"vcvtph2udq",
"vcvtph2qq",
"vcvtph2uqq",
"vcvtw2ph",
"vcvtuw2ph",
"vcvtdq2ph",
"vcvtudq2ph",
"vcvtqq2ph",
"vcvtuqq2ph",
"vcvtph2psx",
"vcvtps2phx",
"vcvtph2pd",
"vcvtpd2ph",
"vfclassph",
"vgetmantph",
"vgetexpph",
"vrndscaleph",
"vreduceph",
"vrangeph",
"vscalefph",
"vpcompressb",
"vpcompressw",
"vpexpandb",
"vpexpandw",
"vpshldvw",
"vpshldvd",
"vpshldvq",
"vpshrdvw",
"vpshrdvd",
"vpshrdvq",
"vgf2p8affineinvqb",
"vgf2p8affineqb",
"vgf2p8mulb",
"vaesdec",
"vaesdeclast",
"vaesenc",
"vaesenclast",
"vpclmulqdq",
"enqcmds",
"movdiri",
"movdir64b",
"stui",
"testui",
"senduip",
"uiret",
"xend",
"xabort",
"xtest",
"aesenc128kl",
"aesdec128kl",
"aesenc256kl",
"aesdec256kl",
"aesencwide128kl",
"aesdecwide128kl",
"aesencwide256kl",
"aesdecwide256kl",
"encodekey128",
"encodekey256",
"urdmsr",
"uwrmsr",
"vpshufbitqmb",
"vpcompressd",
"vpcompressq",
"vpexpandd",
"vpexpandq",
"vpdpbusd",
"vpdpbusds",
"vpdpwssd",
"vpdpwssds",
"vpdpbssd",
"vpdpbssds",
"vpdpbsdd",
"vpdpbsds",
"vbcstnebf162ps",
"vbcstnesh2ps",
"vcvtneebf162ps",
"vcvtneeph2ps",
"vcvtneobf162ps",
"vcvtneoph2ps",
"vcvtneps2bf16",
"cmpbexadd",
"cmpbxadd",
"cmplexadd",
"cmplxadd",
"cmpnexadd",
"cmpnpxadd",
"cmpnoxadd",
"cmpoxadd",
"cmppxadd",
"cmpsxadd",
"cmpzxadd",
"cmpnaexadd",
"prefetchit0",
"prefetchit1",
"aadd",
"aand",
"aor",
"axor",
"wrmsrns",
"rdmsrlist",
"wrmsrlist",
"endbr32",
"endbr64",
"rdsspd",
"rdsspq",
"incsspd",
"incsspq",
"rstorssp",
"saveprevssp",
"setssbsy",
"clrssbsy",
"wrssd",
"wrssq",
"wrussd",
"wrussq",
"loadiwkey",
"aesenc128kl",
"aesdec128kl",
"aesenc256kl",
"aesdec256kl",
"aesencwide128kl",
"aesdecwide128kl",
"aesencwide256kl",
"aesdecwide256kl",
"encodekey128",
"encodekey256",
"hreset",
];
pub(crate) const FULL_OPCODE_INTEL_MNEMONICS: &[&str] = &[
"mov",
"mov",
"mov",
"mov",
"mov",
"movsd",
"movss",
"movaps",
"movups",
"movdqa",
"movdqu",
"movzx",
"movsxd",
"movbe",
"movd",
"movq",
"cmovno",
"cmovb",
"cmovae",
"cmove",
"cmovne",
"cmovbe",
"cmova",
"cmovs",
"cmovns",
"cmovp",
"cmovnp",
"cmovl",
"cmovge",
"cmovle",
"cmovg",
"bswap",
"cmpxchg",
"cmpxchg8b",
"cmpxchg16b",
"pusha",
"popa",
"cwd",
"cdq",
"cqo",
"cbw",
"cwde",
"cdqe",
"adc",
"sub",
"sbb",
"mul",
"imul",
"div",
"idiv",
"inc",
"dec",
"neg",
"cmp",
"cmpxchg",
"xadd",
"aaa",
"aas",
"aam",
"aad",
"daa",
"das",
"or",
"xor",
"not",
"test",
"shr",
"sar",
"rol",
"ror",
"rcl",
"rcr",
"shld",
"shrd",
"cmps",
"scas",
"lods",
"stos",
"rep",
"repe",
"repne",
"repz",
"repnz",
"jo",
"jno",
"jb",
"jae",
"je",
"jne",
"jbe",
"ja",
"js",
"jns",
"jp",
"jnp",
"jl",
"jge",
"jle",
"jg",
"loop",
"loope",
"loopne",
"call",
"ret",
"iret",
"int",
"into",
"bound",
"enter",
"leave",
"clc",
"cmc",
"std",
"cld",
"sti",
"cli",
"lahf",
"sahf",
"pushf",
"popf",
"setno",
"setb",
"setae",
"sete",
"setne",
"setbe",
"seta",
"sets",
"setns",
"setp",
"setnp",
"setl",
"setge",
"setle",
"setg",
"out",
"ins",
"outs",
"hlt",
"wait",
"lock",
"lgdt",
"sgdt",
"lidt",
"sidt",
"lldt",
"sldt",
"ltr",
"str",
"lmsw",
"smsw",
"invlpg",
"invd",
"wbinvd",
"rdmsr",
"wrmsr",
"rdtsc",
"rdtscp",
"rdpmc",
"cpuid",
"syscall",
"sysret",
"sysenter",
"sysexit",
"fst",
"fstp",
"fild",
"fist",
"fistp",
"fbld",
"fbstp",
"fadd",
"fsub",
"fmul",
"fdiv",
"fabs",
"fchs",
"fsqrt",
"fprem",
"fprem1",
"fcom",
"fcomp",
"fcompp",
"fucom",
"fucomp",
"fucompp",
"ftst",
"fxam",
"fsin",
"fcos",
"fsincos",
"fptan",
"fpatan",
"f2xm1",
"fyl2x",
"fyl2xp1",
"fldz",
"fld1",
"fldpi",
"fldl2t",
"fldl2e",
"fldlg2",
"fldln2",
"fnclex",
"fndisi",
"fneni",
"fninit",
"fnstsw",
"fnstcw",
"fldcw",
"fstcw",
"fstsw",
"ffree",
"fdecstp",
"fincstp",
"fxch",
"movq",
"packsswb",
"packssdw",
"packuswb",
"paddb",
"paddw",
"paddd",
"paddsb",
"paddsw",
"paddusb",
"paddusw",
"psubb",
"psubw",
"psubd",
"psubsb",
"psubsw",
"psubusb",
"psubusw",
"pmullw",
"pmulhw",
"pmaddwd",
"pcmpeqb",
"pcmpeqw",
"pcmpeqd",
"pcmpgtb",
"pcmpgtw",
"pcmpgtd",
"pand",
"pandn",
"por",
"pxor",
"psllw",
"pslld",
"psllq",
"psrlw",
"psrld",
"psrlq",
"psraw",
"psrad",
"punpckhbw",
"punpckhwd",
"punpckhdq",
"punpcklbw",
"punpcklwd",
"punpckldq",
"addss",
"subps",
"subss",
"mulps",
"mulss",
"divps",
"divss",
"rcpps",
"rcpss",
"sqrtps",
"sqrtss",
"rsqrtps",
"rsqrtss",
"maxps",
"maxss",
"minps",
"minss",
"andps",
"andnps",
"orps",
"xorps",
"cmpps",
"cmpss",
"shufps",
"unpckhps",
"unpcklps",
"movmskps",
"movhlps",
"movlhps",
"movlps",
"movhps",
"addsd",
"subpd",
"subsd",
"mulpd",
"mulsd",
"divpd",
"divsd",
"sqrtpd",
"sqrtsd",
"maxpd",
"maxsd",
"minpd",
"minsd",
"andpd",
"andnpd",
"orpd",
"xorpd",
"cmppd",
"cmpsd",
"shufpd",
"unpckhpd",
"unpcklpd",
"movmskpd",
"movupd",
"movapd",
"movlpd",
"movhpd",
"cvtdq2pd",
"cvtdq2ps",
"cvtpd2dq",
"cvtpd2ps",
"cvtps2dq",
"cvtps2pd",
"cvtsd2si",
"cvtsd2ss",
"cvtsi2sd",
"cvtsi2ss",
"cvtss2sd",
"cvtss2si",
"cvttpd2dq",
"cvttps2dq",
"cvttsd2si",
"cvttss2si",
"paddb",
"paddw",
"paddd",
"paddq",
"psubb",
"psubw",
"psubd",
"psubq",
"pmuludq",
"pmullw",
"pmulhw",
"pmulhuw",
"psadbw",
"pavgb",
"pavgw",
"pminub",
"pminsw",
"pmaxub",
"pmaxsw",
"psllw",
"pslld",
"psllq",
"psrlw",
"psrld",
"psrlq",
"psraw",
"psrad",
"maskmovdqu",
"movq2dq",
"movdq2q",
"punpcklbw",
"punpcklwd",
"punpckldq",
"punpcklqdq",
"punpckhbw",
"punpckhwd",
"punpckhdq",
"punpckhqdq",
"packsswb",
"packssdw",
"packuswb",
"pand",
"pandn",
"por",
"pxor",
"pcmpeqb",
"pcmpeqw",
"pcmpeqd",
"addsubpd",
"haddps",
"haddpd",
"hsubps",
"hsubpd",
"movsldup",
"movshdup",
"movddup",
"lddqu",
"fisttp",
"monitor",
"mwait",
"phaddd",
"phaddsw",
"phsubw",
"phsubd",
"phsubsw",
"pmaddubsw",
"pmulhrsw",
"pshufb",
"psignb",
"psignw",
"psignd",
"pabsb",
"pabsw",
"pabsd",
"palignr",
"pshufb",
"pmuldq",
"dpps",
"dppd",
"blendps",
"blendpd",
"blendvps",
"blendvpd",
"pminsb",
"pminsd",
"pminuw",
"pminud",
"pmaxsb",
"pmaxsd",
"pmaxuw",
"pmaxud",
"packusdw",
"pcmpeqq",
"pinsrb",
"pinsrd",
"pinsrq",
"pextrb",
"pextrd",
"pextrq",
"ptest",
"roundps",
"roundpd",
"roundss",
"roundsd",
"crc32",
"extractps",
"insertps",
"pmovsxbw",
"pmovsxbd",
"pmovsxbq",
"pmovsxwd",
"pmovsxwq",
"pmovsxdq",
"pmovzxbw",
"pmovzxbd",
"pmovzxbq",
"pmovzxwd",
"pmovzxwq",
"pmovzxdq",
"mpsadbw",
"phminposuw",
"pcmpestrm",
"pcmpistri",
"pcmpistrm",
"pcmpgtq",
"vaddpd",
"vaddss",
"vaddsd",
"vsubps",
"vsubpd",
"vsubss",
"vsubsd",
"vmulps",
"vmulpd",
"vmulss",
"vmulsd",
"vdivps",
"vdivpd",
"vdivss",
"vdivsd",
"vandps",
"vandnps",
"vorps",
"vxorps",
"vzeroall",
"vzeroupper",
"vmovaps",
"vmovups",
"vmovapd",
"vmovupd",
"vbroadcastss",
"vbroadcastsd",
"vbroadcastf128",
"vpermilps",
"vpermilpd",
"vperm2f128",
"vextractf128",
"vinsertf128",
"vcvtph2ps",
"vcvtps2ph",
"vpbroadcastw",
"vpbroadcastd",
"vpbroadcastq",
"vpermq",
"vpermpd",
"vperm2i128",
"vpgatherdd",
"vpgatherdq",
"vpgatherqd",
"vpgatherqq",
"vpmaskmovd",
"vpmaskmovq",
"vpsllvd",
"vpsllvq",
"vpsrlvd",
"vpsrlvq",
"vpsravd",
"vfmadd132pd",
"vfmadd132ss",
"vfmadd132sd",
"vfmadd213ps",
"vfmadd213pd",
"vfmadd213ss",
"vfmadd213sd",
"vfmadd231ps",
"vfmadd231pd",
"vfmadd231ss",
"vfmadd231sd",
"vfmsub132ps",
"vfmsub132pd",
"vfmsub132ss",
"vfmsub132sd",
"vfmsub213ps",
"vfmsub213pd",
"vfmsub213ss",
"vfmsub213sd",
"vfmsub231ps",
"vfmsub231pd",
"vfmsub231ss",
"vfmsub231sd",
"vfnmadd132ps",
"vfnmadd132pd",
"vfnmadd132ss",
"vfnmadd132sd",
"vfnmadd213ps",
"vfnmadd213pd",
"vfnmadd213ss",
"vfnmadd213sd",
"vfnmadd231ps",
"vfnmadd231pd",
"vfnmadd231ss",
"vfnmadd231sd",
"vfnmsub132ps",
"vfnmsub132pd",
"vfnmsub132ss",
"vfnmsub132sd",
"vfnmsub213ps",
"vfnmsub213pd",
"vfnmsub213ss",
"vfnmsub213sd",
"vfnmsub231ps",
"vfnmsub231pd",
"vfnmsub231ss",
"vfnmsub231sd",
"bextr",
"blsi",
"blsmsk",
"blsr",
"bzhi",
"mulx",
"pdep",
"pext",
"rorx",
"sarx",
"shlx",
"shrx",
"tzcnt",
"lzcnt",
"adox",
"sha1nexte",
"sha1msg1",
"sha1msg2",
"sha256rnds2",
"sha256msg1",
"sha256msg2",
"aesenclast",
"aesdec",
"aesdeclast",
"aeskeygenassist",
"aesimc",
"rdseed",
"vpaddq",
"vpsubd",
"vpsubq",
"vpmulld",
"vpmullq",
"vpandd",
"vpandq",
"vpord",
"vporq",
"vpxord",
"vpxorq",
"vpsllvd",
"vpsrlvd",
"vpsravd",
"vpermd",
"vpermq",
"vpermps",
"vpermpd",
"vcompressps",
"vcompresspd",
"vexpandps",
"vexpandpd",
"vpbroadcastd",
"vpbroadcastq",
"vpbroadcastss",
"vpbroadcastsd",
"vmovdqu8",
"vmovdqu16",
"vmovdqu32",
"vmovdqu64",
"vpcmpeqd",
"vpcmpeqq",
"vpcmpgtd",
"vpcmpgtq",
"kand",
"kandn",
"knot",
"kor",
"kxnor",
"kxor",
"kadd",
"kshiftl",
"kshiftr",
"ktest",
"kmov",
"kunpck",
"vaddpd",
"vaddps",
"vmulpd",
"vmulps",
"vaddsd",
"vaddss",
"vmulsd",
"vmulss",
"vfmadd132pd",
"vfmadd213pd",
"vfmadd231pd",
"vfmadd132ps",
"vfmadd213ps",
"vfmadd231ps",
"valignd",
"valignq",
"vdbpsadbw",
"vpabsq",
"vpabsq",
"vpmadd52luq",
"vpmadd52huq",
"tilestored",
"tilerelease",
"tilezero",
"tdpbssd",
"tdpbsud",
"tdpbusd",
"tdpbuud",
"tdpbf16ps",
"tdpfp16ps",
"tcmmimfp16ps",
"tcmmrlfp16ps",
"endbr64",
"incssp",
"rdssp",
"setssbsy",
"clrssbsy",
"wrss",
"wruss",
"clflush",
"clflushopt",
"clwb",
"prefetch",
"prefetchw",
"prefetchwt1",
"rdfsbase",
"rdgsbase",
"wrfsbase",
"wrgsbase",
"umwait",
"tpause",
"vpermi2b",
"vpermt2b",
"vpcompressb",
"vpcompressw",
"vpexpandb",
"vpexpandw",
"vpconflictd",
"vpconflictq",
"vplzcntd",
"vplzcntq",
"vpopcntb",
"vpopcntw",
"vpopcntd",
"vpopcntq",
"vgetmantps",
"vgetmantpd",
"vgetmantss",
"vgetmantsd",
"vgetexpps",
"vgetexppd",
"vgetexpss",
"vgetexpsd",
"vrndscaleps",
"vrndscalepd",
"vrndscaless",
"vrndscalesd",
"vreduceps",
"vreducepd",
"vreducess",
"vreducesd",
"vrangeps",
"vrangepd",
"vrangess",
"vrangesd",
"vfixupimmps",
"vfixupimmpd",
"vfixupimmss",
"vfixupimmsd",
"vscalefps",
"vscalefpd",
"vscalefss",
"vscalefsd",
"vfclassps",
"vfclasspd",
"vfclassss",
"vfclasssd",
"vdbpsadbw",
"kaddw",
"kandb",
"kandw",
"kandnb",
"kandnw",
"knotb",
"knotw",
"korb",
"korw",
"kxnorb",
"kxnorw",
"kxorb",
"kxorw",
"kortestb",
"kortestw",
"ktestb",
"ktestw",
"kunpckbw",
"kunpckwd",
"vcvtne2ps2bf16",
"vcvtneps2bf16",
"vdpbf16ps",
"vaddph",
"vaddsh",
"vsubph",
"vsubsh",
"vmulph",
"vmulsh",
"vdivph",
"vdivsh",
"vfmadd132ph",
"vfmadd213ph",
"vfmadd231ph",
"vfmsub132ph",
"vfmsub213ph",
"vfmsub231ph",
"vfnmadd132ph",
"vfnmadd213ph",
"vfnmadd231ph",
"vfnmsub132ph",
"vfnmsub213ph",
"vfnmsub231ph",
"vmaxph",
"vmaxsh",
"vminph",
"vminsh",
"vsqrtph",
"vsqrtsh",
"vcvtph2w",
"vcvtph2uw",
"vcvtph2dq",
"vcvtph2udq",
"vcvtph2qq",
"vcvtph2uqq",
"vcvtw2ph",
"vcvtuw2ph",
"vcvtdq2ph",
"vcvtudq2ph",
"vcvtqq2ph",
"vcvtuqq2ph",
"vcvtph2psx",
"vcvtps2phx",
"vcvtph2pd",
"vcvtpd2ph",
"vfclassph",
"vgetmantph",
"vgetexpph",
"vrndscaleph",
"vreduceph",
"vrangeph",
"vscalefph",
"vpcompressb",
"vpcompressw",
"vpexpandb",
"vpexpandw",
"vpshldvw",
"vpshldvd",
"vpshldvq",
"vpshrdvw",
"vpshrdvd",
"vpshrdvq",
"vgf2p8affineinvqb",
"vgf2p8affineqb",
"vgf2p8mulb",
"vaesdec",
"vaesdeclast",
"vaesenc",
"vaesenclast",
"vpclmulqdq",
"enqcmds",
"movdiri",
"movdir64b",
"stui",
"testui",
"senduip",
"uiret",
"xend",
"xabort",
"xtest",
"aesenc128kl",
"aesdec128kl",
"aesenc256kl",
"aesdec256kl",
"aesencwide128kl",
"aesdecwide128kl",
"aesencwide256kl",
"aesdecwide256kl",
"encodekey128",
"encodekey256",
"urdmsr",
"uwrmsr",
"VPSHUFBITQMB",
"VPCOMPRESSD",
"VPCOMPRESSQ",
"VPEXPANDD",
"VPEXPANDQ",
"VPDPBUSD",
"VPDPBUSDS",
"VPDPWSSD",
"VPDPWSSDS",
"VPDPBSSD",
"VPDPBSSDS",
"VPDPBSDD",
"VPDPBSDS",
"VBCSTNEBF162PS",
"VBCSTNESH2PS",
"VCVTNEEBF162PS",
"VCVTNEEPH2PS",
"VCVTNEOBF162PS",
"VCVTNEOPH2PS",
"VCVTNEPS2BF16",
"CMPBEXADD",
"CMPBXADD",
"CMPLEXADD",
"CMPLXADD",
"CMPNEXADD",
"CMPNPXADD",
"CMPNOXADD",
"CMPOXADD",
"CMPPXADD",
"CMPSXADD",
"CMPZXADD",
"CMPNAEXADD",
"PREFETCHIT0",
"PREFETCHIT1",
"AADD",
"AAND",
"AOR",
"AXOR",
"WRMSRNS",
"RDMSRLIST",
"WRMSRLIST",
];
const FULL_OPCODE_NUM_OPERANDS: &[u8] = &[
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 2, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 1, 1, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 1, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
];
const FULL_OPCODE_ENCODING_FORMS: &[EncodingForm] = &[
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
Legacy,
Legacy,
Legacy,
LegacyREX,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
EncodingForm::None,
EncodingForm::None,
EncodingForm::None,
EncodingForm::None,
EncodingForm::None,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
EncodingForm::None,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX,
VEX,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
VEX3Byte,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
Legacy,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
EVEX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
LegacyREX,
Legacy,
Legacy,
LegacyREX,
LegacyREX,
LegacyREX,
];
const FULL_OPCODE_BASE_BYTES: &[u8] = &[
0x89, 0x8B, 0x89, 0xB8, 0xC7, 0x10, 0xF3, 0x0F, 0x28, 0x0F, 0x10, 0x6F, 0x7F, 0x0F, 0xB6, 0x0F,
0xBE, 0x63, 0x0F, 0x38, 0xF0, 0x6E, 0x7E, 0x6E, 0x7E, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x0F, 0xC8, 0x0F, 0xB0, 0xC7, 0x0F, 0xC7, 0x60,
0x61, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x11, 0x29, 0x19, 0xF7, 0xF7, 0xF7, 0xF7, 0xFF, 0xFF,
0xF7, 0x39, 0x0F, 0xB0, 0x0F, 0xC0, 0x37, 0x3F, 0xD4, 0xD5, 0x27, 0x2F, 0x09, 0x31, 0xF7, 0x85,
0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0x0F, 0xA4, 0x0F, 0xAC, 0xA6, 0xAE, 0xAC, 0xAA, 0xF3, 0xF3,
0xF2, 0xF3, 0xF2, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
0x7D, 0x7E, 0x7F, 0xE2, 0xE1, 0xE0, 0xE8, 0xC3, 0xCF, 0xCD, 0xCE, 0x62, 0xC8, 0xC9, 0xF8, 0xF5,
0xFD, 0xFC, 0xFB, 0xFA, 0x9F, 0x9E, 0x9C, 0x9D, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xE6, 0x6C, 0x6E, 0xF4, 0x9B, 0xF0, 0x0F, 0x01, 0x0F,
0x01, 0x0F, 0x01, 0x0F, 0x01, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x01, 0x0F,
0x01, 0x0F, 0x01, 0x0F, 0x08, 0x0F, 0x09, 0x0F, 0x32, 0x0F, 0x30, 0x0F, 0x31, 0x01, 0xF9, 0x0F,
0x01, 0x33, 0x0F, 0xA2, 0x0F, 0x05, 0x0F, 0x07, 0x0F, 0x34, 0x0F, 0x35, 0xD9, 0xD9, 0xDB, 0xDB,
0xDB, 0xDF, 0xDF, 0xD8, 0xD8, 0xD8, 0xD8, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD8, 0xD8, 0xDE, 0xDD,
0xDD, 0xDE, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
0xD9, 0xD9, 0xD9, 0xDB, 0xDB, 0xDB, 0xDB, 0xDD, 0xD9, 0xD9, 0xD9, 0xDD, 0xDD, 0xD9, 0xD9, 0x6F,
0x63, 0x6B, 0x67, 0xFC, 0xFD, 0xFE, 0xEC, 0xED, 0xDC, 0xDD, 0xF8, 0xF9, 0xFA, 0xE8, 0xE9, 0xD8,
0xD9, 0xD5, 0xE5, 0xF5, 0x74, 0x75, 0x76, 0x64, 0x65, 0x66, 0xDB, 0xDF, 0xEB, 0xEF, 0xF1, 0xF2,
0xF3, 0xD1, 0xD2, 0xD3, 0xE1, 0xE2, 0x68, 0x69, 0x6A, 0x60, 0x61, 0x62, 0xF3, 0x0F, 0x58, 0x5C,
0xF3, 0x0F, 0x5C, 0x59, 0xF3, 0x0F, 0x59, 0x5E, 0xF3, 0x0F, 0x5E, 0x53, 0xF3, 0x0F, 0x53, 0x51,
0xF3, 0x0F, 0x51, 0x52, 0xF3, 0x0F, 0x52, 0x5F, 0xF3, 0x0F, 0x5F, 0x5D, 0xF3, 0x0F, 0x5D, 0x54,
0x55, 0x56, 0x57, 0xC2, 0xF3, 0x0F, 0xC2, 0xC6, 0x15, 0x14, 0x50, 0x12, 0x16, 0x12, 0x16, 0xF2,
0x0F, 0x58, 0x5C, 0xF2, 0x0F, 0x5C, 0x59, 0xF2, 0x0F, 0x59, 0x5E, 0xF2, 0x0F, 0x5E, 0x51, 0xF2,
0x0F, 0x51, 0x5F, 0xF2, 0x0F, 0x5F, 0x5D, 0xF2, 0x0F, 0x5D, 0x54, 0x55, 0x56, 0x57, 0xC2, 0xF2,
0x0F, 0xC2, 0xC6, 0x15, 0x14, 0x50, 0x10, 0x28, 0x12, 0x16, 0xE6, 0x5B, 0xE6, 0x5A, 0x5B, 0x5A,
0xF2, 0x0F, 0x2D, 0xF2, 0x0F, 0x5A, 0xF2, 0x0F, 0x2A, 0xF3, 0x0F, 0x2A, 0xF3, 0x0F, 0x5A, 0xF2,
0x0F, 0x2C, 0xE6, 0xE6, 0xF2, 0x0F, 0x2C, 0xF3, 0x0F, 0x2C, 0xFC, 0xFD, 0xFE, 0xD4, 0xF8, 0xF9,
0xFA, 0xFB, 0xF4, 0xD5, 0xE5, 0xE4, 0xF6, 0xE0, 0xE3, 0xDA, 0xEA, 0xDE, 0xEE, 0xF1, 0xF2, 0xF3,
0xD1, 0xD2, 0xD3, 0xE1, 0xE2, 0xF7, 0xD6, 0xD6, 0x60, 0x61, 0x62, 0x6C, 0x68, 0x69, 0x6A, 0x6D,
0x63, 0x6B, 0x67, 0xDB, 0xDF, 0xEB, 0x74, 0x75, 0x76, 0xD0, 0x7C, 0x7C, 0x7D, 0x7D, 0x12, 0x16,
0x12, 0xF0, 0xDB, 0x0F, 0x01, 0xC8, 0x0F, 0x01, 0xC9, 0x02, 0x03, 0x05, 0x06, 0x07, 0x04, 0x0B,
0x00, 0x08, 0x09, 0x0A, 0x1C, 0x1D, 0x1E, 0x0F, 0x00, 0x28, 0x40, 0x41, 0x0C, 0x0D, 0x14, 0x15,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x2E, 0x2F, 0x2B, 0x29, 0x20, 0x22, 0x22, 0x14, 0x16, 0x16,
0x17, 0x08, 0x09, 0x0A, 0x0B, 0x38, 0xF0, 0x10, 0x17, 0x21, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x42, 0x41, 0x60, 0x62, 0x62, 0x37, 0x58, 0x58, 0x58, 0x5C,
0x5C, 0x5C, 0x5C, 0x59, 0x59, 0x59, 0x59, 0x5E, 0x5E, 0x5E, 0x5E, 0x54, 0x55, 0x56, 0x57, 0x77,
0x77, 0x28, 0x10, 0x28, 0x10, 0x18, 0x19, 0x1A, 0x0C, 0x0D, 0x16, 0x19, 0x18, 0x13, 0x1D, 0x79,
0x58, 0x59, 0x36, 0x16, 0x46, 0x90, 0x90, 0x90, 0x90, 0x8C, 0x8E, 0x47, 0x47, 0x45, 0x45, 0x46,
0x98, 0x99, 0x99, 0xA8, 0xA8, 0xA9, 0xA9, 0xB8, 0xB8, 0xB9, 0xB9, 0x9A, 0x9A, 0x9B, 0x9B, 0xAA,
0xAA, 0xAB, 0xAB, 0xBA, 0xBA, 0xBB, 0xBB, 0x9C, 0x9C, 0x9D, 0x9D, 0xAC, 0xAC, 0xAD, 0xAD, 0xBC,
0xBC, 0xBD, 0xBD, 0x9E, 0x9E, 0x9F, 0x9F, 0xAE, 0xAE, 0xAF, 0xAF, 0xBE, 0xBE, 0xBF, 0xBF, 0xF7,
0xF3, 0xF3, 0xF3, 0xF5, 0xF6, 0xF5, 0xF5, 0xF2, 0xF7, 0xF7, 0xF7, 0xF3, 0xF3, 0xF6, 0xC8, 0xC9,
0xCA, 0xCB, 0xCD, 0xCE, 0xDD, 0xDE, 0xDF, 0xDF, 0xDB, 0xC7, 0xD4, 0xFA, 0xFB, 0x40, 0x40, 0xDB,
0xDB, 0xEB, 0xEB, 0xEF, 0xEF, 0x47, 0x45, 0x47, 0x45, 0x36, 0x36, 0x1D, 0x1D, 0x8A, 0x8A, 0x88,
0x88, 0x8A, 0x8A, 0x88, 0x88, 0x58, 0x58, 0x7C, 0x58, 0x18, 0x18, 0x6F, 0x6F, 0x7F, 0x7F, 0x7E,
0x7E, 0x6E, 0x6E, 0x76, 0x29, 0x75, 0x37, 0x41, 0x42, 0x44, 0x45, 0x46, 0x47, 0x4A, 0x4A, 0x33,
0x4A, 0x4B, 0x4B, 0x58, 0x58, 0x59, 0x59, 0x58, 0x58, 0x59, 0x59, 0x98, 0xA8, 0xB8, 0x98, 0xA8,
0xB8, 0x03, 0x03, 0x42, 0x42, 0x1E, 0x1F, 0xB4, 0xB5, 0xB4, 0xB5, 0x4B, 0x49, 0x49, 0x5E, 0x5F,
0x5E, 0x5F, 0x5C, 0x5C, 0x6C, 0x6C, 0x1E, 0x01, 0x1E, 0x01, 0x01, 0x01, 0x01, 0xAE, 0xAE, 0xAE,
0x0D, 0x0D, 0x0D, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
const FULL_OPCODE_MAPS: &[u8] = &[
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3,
3, 3, 2, 3, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
];
const FULL_OPCODE_MANDATORY_PREFIX: &[u8] = &[
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 1, 1, 1, 1, 1, 1,
1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
];
const FULL_OPCODE_REQUIRES_MODRM: &[bool] = &[
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, false, false, false, false, false, false, false, false,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, false,
false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, false, false,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, false, false, false, false, false, true, true, true, true, true, true, true, true,
true, true, true, true, false, false, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false,
false, false, true, true, true, true, true, true, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, true, true, true,
true, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, false, false, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true,
false, false, false, true, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true,
];
const FULL_OPCODE_MODRM_EXT: &[u8] = &[
255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 5, 255, 1, 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 4, 5, 6, 7, 0, 1, 3, 7, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 2, 255, 4, 5, 7, 0, 1, 2, 3, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 2, 2, 3, 3, 2, 2, 3, 3, 6, 6, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 2, 3, 0, 2, 3, 4, 6, 0, 4, 1, 6, 255, 255, 255, 255, 255, 2, 3, 3, 4, 5, 5, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 3, 2, 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 6, 7, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255,
];
#[allow(dead_code)]
fn verify_array_lengths() {
let len = FULL_OPCODE_MNEMONICS.len();
assert_eq!(len, FULL_OPCODE_INTEL_MNEMONICS.len());
assert_eq!(len, FULL_OPCODE_NUM_OPERANDS.len());
assert_eq!(len, FULL_OPCODE_ENCODING_FORMS.len());
assert_eq!(len, FULL_OPCODE_BASE_BYTES.len());
assert_eq!(len, FULL_OPCODE_MAPS.len());
assert_eq!(len, FULL_OPCODE_MANDATORY_PREFIX.len());
assert_eq!(len, FULL_OPCODE_REQUIRES_MODRM.len());
assert_eq!(len, FULL_OPCODE_MODRM_EXT.len());
}
pub struct X86FullInstrInfo {
infos: HashMap<X86FullOpcode, InstrEncodingInfo>,
by_mnemonic: HashMap<String, X86FullOpcode>,
}
impl X86FullInstrInfo {
pub fn new() -> Self {
let mut info = X86FullInstrInfo {
infos: HashMap::new(),
by_mnemonic: HashMap::new(),
};
info.init();
info
}
fn init(&mut self) {
let count = FULL_OPCODE_MNEMONICS.len();
for idx in 0..count {
let disc = (400 + idx) as u32;
let opcode: X86FullOpcode = unsafe { std::mem::transmute(disc) };
let mnemonic = FULL_OPCODE_MNEMONICS[idx];
let encoding_info = InstrEncodingInfo {
opcode,
mnemonic: FULL_OPCODE_MNEMONICS[idx],
intel_mnemonic: FULL_OPCODE_INTEL_MNEMONICS[idx],
num_operands: FULL_OPCODE_NUM_OPERANDS[idx],
encoding_form: FULL_OPCODE_ENCODING_FORMS[idx],
base_opcode: FULL_OPCODE_BASE_BYTES[idx],
opcode_map: FULL_OPCODE_MAPS[idx],
mandatory_prefix: FULL_OPCODE_MANDATORY_PREFIX[idx],
requires_modrm: FULL_OPCODE_REQUIRES_MODRM[idx],
modrm_extension: FULL_OPCODE_MODRM_EXT[idx],
operand_types: &[],
is_terminator: opcode.is_jcc()
|| opcode.is_setcc()
|| matches!(
opcode,
X86FullOpcode::JMP
| X86FullOpcode::RET
| X86FullOpcode::IRET
| X86FullOpcode::HLT
),
is_branch: opcode.is_jcc()
|| matches!(
opcode,
X86FullOpcode::JMP | X86FullOpcode::CALL | X86FullOpcode::RET
),
is_call: matches!(opcode, X86FullOpcode::CALL),
is_return: matches!(opcode, X86FullOpcode::RET | X86FullOpcode::IRET),
is_compare: matches!(
opcode,
X86FullOpcode::CMP
| X86FullOpcode::TEST
| X86FullOpcode::CMPPS
| X86FullOpcode::CMPSS
| X86FullOpcode::CMPPD
| X86FullOpcode::CMPSD
| X86FullOpcode::FTST
| X86FullOpcode::FCOM
| X86FullOpcode::FCOMP
| X86FullOpcode::FCOMPP
| X86FullOpcode::FUCOM
| X86FullOpcode::FUCOMP
| X86FullOpcode::FUCOMPP
| X86FullOpcode::FXAM
| X86FullOpcode::PTEST
| X86FullOpcode::PCMPEQB
| X86FullOpcode::PCMPEQW
| X86FullOpcode::PCMPEQD
| X86FullOpcode::PCMPEQQ
| X86FullOpcode::PCMPGTB
| X86FullOpcode::PCMPGTW
| X86FullOpcode::PCMPGTD
| X86FullOpcode::PCMPGTQ
| X86FullOpcode::KTEST
),
is_move_immediate: matches!(opcode, X86FullOpcode::MOVri | X86FullOpcode::MOVmi),
is_convert: matches!(
opcode,
X86FullOpcode::CVTSD2SI
| X86FullOpcode::CVTSD2SS
| X86FullOpcode::CVTSI2SD
| X86FullOpcode::CVTSI2SS
| X86FullOpcode::CVTSS2SD
| X86FullOpcode::CVTSS2SI
| X86FullOpcode::CVTTSD2SI
| X86FullOpcode::CVTTSS2SI
| X86FullOpcode::CVTDQ2PD
| X86FullOpcode::CVTDQ2PS
| X86FullOpcode::CVTPD2DQ
| X86FullOpcode::CVTPD2PS
| X86FullOpcode::CVTPS2DQ
| X86FullOpcode::CVTPS2PD
| X86FullOpcode::CVTTPD2DQ
| X86FullOpcode::CVTTPS2DQ
| X86FullOpcode::CWD
| X86FullOpcode::CDQ
| X86FullOpcode::CQO
| X86FullOpcode::CBW
| X86FullOpcode::CWDE
| X86FullOpcode::CDQE
| X86FullOpcode::MOVSXD
| X86FullOpcode::MOVZX
| X86FullOpcode::VCVTPH2PS
| X86FullOpcode::VCVTPS2PH
),
has_side_effects: matches!(
opcode,
X86FullOpcode::SYSCALL
| X86FullOpcode::SYSENTER
| X86FullOpcode::INT
| X86FullOpcode::HLT
| X86FullOpcode::RDTSC
| X86FullOpcode::RDTSCP
| X86FullOpcode::RDPMC
| X86FullOpcode::CPUID
| X86FullOpcode::IN
| X86FullOpcode::OUT
| X86FullOpcode::WRMSR
| X86FullOpcode::INVLPG
| X86FullOpcode::STI
| X86FullOpcode::CLI
| X86FullOpcode::MWAIT
| X86FullOpcode::MONITOR
),
may_load: matches!(
opcode,
X86FullOpcode::MOVrm
| X86FullOpcode::MOVZX
| X86FullOpcode::MOVSXD
| X86FullOpcode::POPA
| X86FullOpcode::POPA
| X86FullOpcode::POPF
| X86FullOpcode::LODS
| X86FullOpcode::SCAS
| X86FullOpcode::CMPS
| X86FullOpcode::IN
| X86FullOpcode::FLDCW
| X86FullOpcode::FLD
| X86FullOpcode::FILD
| X86FullOpcode::FBLD
| X86FullOpcode::LDDQU
) || opcode.mnemonic().starts_with("mov") && (idx >= 1 && idx <= 2),
may_store: matches!(
opcode,
X86FullOpcode::MOVmr
| X86FullOpcode::MOVmi
| X86FullOpcode::PUSHA
| X86FullOpcode::PUSHF
| X86FullOpcode::STOS
| X86FullOpcode::OUT
| X86FullOpcode::FST
| X86FullOpcode::FSTP
| X86FullOpcode::FIST
| X86FullOpcode::FISTP
| X86FullOpcode::FBSTP
| X86FullOpcode::FSTCW
| X86FullOpcode::FSTSW
),
is_commutative: matches!(
opcode,
X86FullOpcode::ADD
| X86FullOpcode::ADC
| X86FullOpcode::MUL
| X86FullOpcode::IMUL
| X86FullOpcode::AND
| X86FullOpcode::OR
| X86FullOpcode::XOR
| X86FullOpcode::ADCX
| X86FullOpcode::ADOX
| X86FullOpcode::FADD
| X86FullOpcode::FMUL
| X86FullOpcode::ADDPS
| X86FullOpcode::ADDSS
| X86FullOpcode::MULPS
| X86FullOpcode::MULSS
| X86FullOpcode::ADDPD
| X86FullOpcode::ADDSD
| X86FullOpcode::MULPD
| X86FullOpcode::MULSD
| X86FullOpcode::VADDPS
| X86FullOpcode::VADDPD
| X86FullOpcode::VMULPS
| X86FullOpcode::VMULPD
| X86FullOpcode::VFMADD132PS
| X86FullOpcode::VFMADD132PD
),
is_three_address: opcode.is_vex()
|| opcode.is_evex()
|| matches!(
opcode,
X86FullOpcode::IMUL | X86FullOpcode::SHLD | X86FullOpcode::SHRD
),
};
self.by_mnemonic
.insert(encoding_info.mnemonic.to_string(), opcode);
self.infos.insert(opcode, encoding_info);
}
}
pub fn get(&self, opcode: X86FullOpcode) -> Option<&InstrEncodingInfo> {
self.infos.get(&opcode)
}
pub fn find_by_mnemonic(&self, mnemonic: &str) -> Option<X86FullOpcode> {
self.by_mnemonic.get(mnemonic).copied()
}
pub fn get_base_opcode(&self, opcode: X86FullOpcode) -> u8 {
self.infos.get(&opcode).map(|i| i.base_opcode).unwrap_or(0)
}
pub fn get_opcode_map(&self, opcode: X86FullOpcode) -> u8 {
self.infos.get(&opcode).map(|i| i.opcode_map).unwrap_or(0)
}
pub fn get_mandatory_prefix(&self, opcode: X86FullOpcode) -> u8 {
self.infos
.get(&opcode)
.map(|i| i.mandatory_prefix)
.unwrap_or(0)
}
pub fn requires_modrm(&self, opcode: X86FullOpcode) -> bool {
self.infos
.get(&opcode)
.map(|i| i.requires_modrm)
.unwrap_or(false)
}
pub fn get_modrm_extension(&self, opcode: X86FullOpcode) -> u8 {
self.infos
.get(&opcode)
.map(|i| i.modrm_extension)
.unwrap_or(255)
}
pub fn encoding_form(&self, opcode: X86FullOpcode) -> EncodingForm {
self.infos
.get(&opcode)
.map(|i| i.encoding_form)
.unwrap_or(EncodingForm::Legacy)
}
pub fn lookup_by_bytes(
&self,
base_opcode: u8,
opcode_map: u8,
mandatory_prefix: u8,
) -> Option<X86FullOpcode> {
let count = FULL_OPCODE_MNEMONICS.len();
for idx in 0..count {
let disc = (400 + idx) as u32;
let opcode: X86FullOpcode = unsafe { std::mem::transmute(disc) };
if let Some(enc) = self.infos.get(&opcode) {
if enc.opcode_map == opcode_map
&& enc.base_opcode == base_opcode
&& enc.mandatory_prefix == mandatory_prefix
{
return Some(opcode);
}
}
}
Option::None
}
}
pub struct ExtInstrDesc {
pub mnemonic: &'static str,
pub intel_mnemonic: &'static str,
pub num_operands: u8,
pub encoding_form: EncodingForm,
pub base_opcode: u8,
pub opcode_map: u8,
pub mandatory_prefix: u8,
pub requires_modrm: bool,
pub modrm_extension: u8,
pub is_terminator: bool,
pub has_side_effects: bool,
pub may_load: bool,
pub may_store: bool,
}
impl X86FullInstrInfo {
pub fn get_extension_instructions() -> Vec<ExtInstrDesc> {
vec![
ExtInstrDesc {
mnemonic: "vpshufbitqmb",
intel_mnemonic: "VPSHUFBITQMB",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x8F,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpcompressd",
intel_mnemonic: "VPCOMPRESSD",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x8B,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: true,
},
ExtInstrDesc {
mnemonic: "vpcompressq",
intel_mnemonic: "VPCOMPRESSQ",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x8B,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: true,
},
ExtInstrDesc {
mnemonic: "vpexpandd",
intel_mnemonic: "VPEXPANDD",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x89,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpexpandq",
intel_mnemonic: "VPEXPANDQ",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x89,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpdpbusd",
intel_mnemonic: "VPDPBUSD",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x50,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpdpbusds",
intel_mnemonic: "VPDPBUSDS",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x51,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpdpwssd",
intel_mnemonic: "VPDPWSSD",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x52,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpdpwssds",
intel_mnemonic: "VPDPWSSDS",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x53,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpdpbssd",
intel_mnemonic: "VPDPBSSD",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x50,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpdpbssds",
intel_mnemonic: "VPDPBSSDS",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x51,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpdpbsdd",
intel_mnemonic: "VPDPBSDD",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x52,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpdpbsds",
intel_mnemonic: "VPDPBSDS",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x53,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpmadd52luq",
intel_mnemonic: "VPMADD52LUQ",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB4,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vpmadd52huq",
intel_mnemonic: "VPMADD52HUQ",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB5,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vbcstnebf162ps",
intel_mnemonic: "VBCSTNEBF162PS",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB1,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vbcstnesh2ps",
intel_mnemonic: "VBCSTNESH2PS",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB1,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtneebf162ps",
intel_mnemonic: "VCVTNEEBF162PS",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB2,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtneeph2ps",
intel_mnemonic: "VCVTNEEPH2PS",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB2,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtneobf162ps",
intel_mnemonic: "VCVTNEOBF162PS",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB3,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtneoph2ps",
intel_mnemonic: "VCVTNEOPH2PS",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB3,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtneps2bf16",
intel_mnemonic: "VCVTNEPS2BF16",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x72,
opcode_map: 3,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "cmpbexadd",
intel_mnemonic: "CMPBEXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xE0,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmpbxadd",
intel_mnemonic: "CMPBXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xE2,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmplexadd",
intel_mnemonic: "CMPLEXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xE4,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmplxadd",
intel_mnemonic: "CMPLXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xE6,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmpnexadd",
intel_mnemonic: "CMPNEXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xE8,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmpnpxadd",
intel_mnemonic: "CMPNPXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xEA,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmpnoxadd",
intel_mnemonic: "CMPNOXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xEC,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmpoxadd",
intel_mnemonic: "CMPOXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xEE,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmppxadd",
intel_mnemonic: "CMPPXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xE1,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmpsxadd",
intel_mnemonic: "CMPSXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xE3,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmpzxadd",
intel_mnemonic: "CMPZXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xE5,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "cmpnaexadd",
intel_mnemonic: "CMPNAEXADD",
num_operands: 3,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xE7,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "prefetchit0",
intel_mnemonic: "PREFETCHIT0",
num_operands: 1,
encoding_form: EncodingForm::Legacy,
base_opcode: 0x18,
opcode_map: 0,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 7,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "prefetchit1",
intel_mnemonic: "PREFETCHIT1",
num_operands: 1,
encoding_form: EncodingForm::Legacy,
base_opcode: 0x18,
opcode_map: 0,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 6,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "aadd",
intel_mnemonic: "AADD",
num_operands: 2,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xFC,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "aand",
intel_mnemonic: "AAND",
num_operands: 2,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xFC,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "aor",
intel_mnemonic: "AOR",
num_operands: 2,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xFC,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "axor",
intel_mnemonic: "AXOR",
num_operands: 2,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xFC,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: true,
},
ExtInstrDesc {
mnemonic: "wrmsrns",
intel_mnemonic: "WRMSRNS",
num_operands: 0,
encoding_form: EncodingForm::Legacy,
base_opcode: 0x01,
opcode_map: 0,
mandatory_prefix: 0,
requires_modrm: false,
modrm_extension: 255,
is_terminator: false,
has_side_effects: true,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "rdmsrlist",
intel_mnemonic: "RDMSRLIST",
num_operands: 1,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xC6,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: true,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "wrmsrlist",
intel_mnemonic: "WRMSRLIST",
num_operands: 1,
encoding_form: EncodingForm::LegacyREX,
base_opcode: 0xC6,
opcode_map: 1,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: true,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "sha512msg1",
intel_mnemonic: "SHA512MSG1",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xCC,
opcode_map: 2,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "sha512msg2",
intel_mnemonic: "SHA512MSG2",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xCD,
opcode_map: 2,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "sha512rnds2",
intel_mnemonic: "SHA512RNDS2",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xCB,
opcode_map: 2,
mandatory_prefix: 0,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vsm3msg1",
intel_mnemonic: "VSM3MSG1",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xDE,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vsm3msg2",
intel_mnemonic: "VSM3MSG2",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xDF,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vsm3rnds2",
intel_mnemonic: "VSM3RNDS2",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xDE,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vsm4key4",
intel_mnemonic: "VSM4KEY4",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xDA,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vsm4rnds4",
intel_mnemonic: "VSM4RNDS4",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xDB,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "xsusldtrk",
intel_mnemonic: "XSUSLDTRK",
num_operands: 0,
encoding_form: EncodingForm::Legacy,
base_opcode: 0x5B,
opcode_map: 0,
mandatory_prefix: 0,
requires_modrm: false,
modrm_extension: 255,
is_terminator: false,
has_side_effects: true,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "xresldtrk",
intel_mnemonic: "XRESLDTRK",
num_operands: 0,
encoding_form: EncodingForm::Legacy,
base_opcode: 0x5C,
opcode_map: 0,
mandatory_prefix: 0,
requires_modrm: false,
modrm_extension: 255,
is_terminator: false,
has_side_effects: true,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vp2intersectd",
intel_mnemonic: "VP2INTERSECTD",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x68,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vp2intersectq",
intel_mnemonic: "VP2INTERSECTQ",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x68,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vaddph",
intel_mnemonic: "VADDPH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x58,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vmulph",
intel_mnemonic: "VMULPH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x59,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vdivph",
intel_mnemonic: "VDIVPH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x5E,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vsubph",
intel_mnemonic: "VSUBPH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x5C,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vminph",
intel_mnemonic: "VMINPH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x5D,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vmaxph",
intel_mnemonic: "VMAXPH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x5F,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vsqrtph",
intel_mnemonic: "VSQRTPH",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x51,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vrndscaleph",
intel_mnemonic: "VRNDSCALEPH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x08,
opcode_map: 3,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtph2w",
intel_mnemonic: "VCVTPH2W",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x7D,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtw2ph",
intel_mnemonic: "VCVTW2PH",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x7D,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtph2uw",
intel_mnemonic: "VCVTPH2UW",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x7D,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtuw2ph",
intel_mnemonic: "VCVTUW2PH",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x7D,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfmadd132ph",
intel_mnemonic: "VFMADD132PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x98,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfmadd213ph",
intel_mnemonic: "VFMADD213PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xA8,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfmadd231ph",
intel_mnemonic: "VFMADD231PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB8,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfmsub132ph",
intel_mnemonic: "VFMSUB132PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x9A,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfmsub213ph",
intel_mnemonic: "VFMSUB213PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xAA,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfmsub231ph",
intel_mnemonic: "VFMSUB231PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xBA,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfnmadd132ph",
intel_mnemonic: "VFNMADD132PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x9C,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfnmadd213ph",
intel_mnemonic: "VFNMADD213PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xAC,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfnmadd231ph",
intel_mnemonic: "VFNMADD231PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xBC,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfnmsub132ph",
intel_mnemonic: "VFNMSUB132PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x9E,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfnmsub213ph",
intel_mnemonic: "VFNMSUB213PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xAE,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vfnmsub231ph",
intel_mnemonic: "VFNMSUB231PH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xBE,
opcode_map: 2,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcmpph",
intel_mnemonic: "VCMPPH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xC2,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vgetmantph",
intel_mnemonic: "VGETMANTPH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x26,
opcode_map: 3,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vgetexpph",
intel_mnemonic: "VGETEXPPH",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x42,
opcode_map: 0,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vscalefph",
intel_mnemonic: "VSCALEFPH",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x2C,
opcode_map: 3,
mandatory_prefix: 3,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtne2ps2bf16",
intel_mnemonic: "VCVTNE2PS2BF16",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x72,
opcode_map: 3,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtneebf162ps",
intel_mnemonic: "VCVTNEEBF162PS",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB2,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vcvtneobf162ps",
intel_mnemonic: "VCVTNEOBF162PS",
num_operands: 2,
encoding_form: EncodingForm::EVEX,
base_opcode: 0xB3,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "vdpbf16ps",
intel_mnemonic: "VDPBF16PS",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x52,
opcode_map: 2,
mandatory_prefix: 2,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "tdpbssd",
intel_mnemonic: "TDPBSSD",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x5E,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "tdpbsud",
intel_mnemonic: "TDPBSUD",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x5E,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "tdpbusd",
intel_mnemonic: "TDPBUSD",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x5E,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "tdpbuud",
intel_mnemonic: "TDPBUUD",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x5E,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "tdpbf16ps",
intel_mnemonic: "TDPBF16PS",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x5C,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "tdpfp16ps",
intel_mnemonic: "TDPFP16PS",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x5C,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "tileloadd",
intel_mnemonic: "TILELOADD",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x4B,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: true,
may_store: false,
},
ExtInstrDesc {
mnemonic: "tilestored",
intel_mnemonic: "TILESTORED",
num_operands: 3,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x4B,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: true,
},
ExtInstrDesc {
mnemonic: "tileconfig",
intel_mnemonic: "TILECONFIG",
num_operands: 1,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x49,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: true,
may_load: true,
may_store: false,
},
ExtInstrDesc {
mnemonic: "tilerelease",
intel_mnemonic: "TILERELEASE",
num_operands: 0,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x49,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: false,
modrm_extension: 255,
is_terminator: false,
has_side_effects: true,
may_load: false,
may_store: false,
},
ExtInstrDesc {
mnemonic: "tilezero",
intel_mnemonic: "TILEZERO",
num_operands: 1,
encoding_form: EncodingForm::EVEX,
base_opcode: 0x49,
opcode_map: 2,
mandatory_prefix: 1,
requires_modrm: true,
modrm_extension: 255,
is_terminator: false,
has_side_effects: false,
may_load: false,
may_store: true,
},
]
}
pub fn find_ext_by_mnemonic(mnemonic: &str) -> Option<ExtInstrDesc> {
Self::get_extension_instructions()
.into_iter()
.find(|e| e.mnemonic == mnemonic || e.intel_mnemonic == mnemonic)
}
pub fn extension_instruction_count() -> usize {
Self::get_extension_instructions().len()
}
}
impl Default for X86FullInstrInfo {
fn default() -> Self {
X86FullInstrInfo::new()
}
}
pub mod rex2_prefix {
pub const REX2: u8 = 0xD5;
pub fn build(
m0: bool,
r4: bool,
x4: bool,
b4: bool,
w: bool,
r3: bool,
x3: bool,
b3: bool,
) -> u8 {
((m0 as u8) << 7)
| ((r4 as u8) << 6)
| ((x4 as u8) << 5)
| ((b4 as u8) << 4)
| ((w as u8) << 3)
| ((r3 as u8) << 2)
| ((x3 as u8) << 1)
| (b3 as u8)
}
pub fn w() -> u8 {
build(false, false, false, false, true, false, false, false)
}
pub fn r4(rex2: u8) -> bool {
(rex2 >> 6) & 1 != 0
}
pub fn x4(rex2: u8) -> bool {
(rex2 >> 5) & 1 != 0
}
pub fn b4(rex2: u8) -> bool {
(rex2 >> 4) & 1 != 0
}
pub fn w_bit(rex2: u8) -> bool {
(rex2 >> 3) & 1 != 0
}
pub fn r3(rex2: u8) -> bool {
(rex2 >> 2) & 1 != 0
}
pub fn x3(rex2: u8) -> bool {
(rex2 >> 1) & 1 != 0
}
pub fn b3(rex2: u8) -> bool {
rex2 & 1 != 0
}
pub fn needed(reg1: u8, reg2: Option<u8>, rm: Option<u8>) -> bool {
reg1 >= 16 || reg2.map_or(false, |r| r >= 16) || rm.map_or(false, |r| r >= 16)
}
pub fn needed_3op(dst: u8, src1: u8, src2: u8) -> bool {
dst >= 16 || src1 >= 16 || src2 >= 16
}
pub fn build_for_regs(reg: u8, rm: u8, w: bool) -> [u8; 2] {
let needs_rex2 = reg >= 16 || rm >= 16;
if !needs_rex2 {
let rex = 0x40 | ((w as u8) << 3) | (((reg >> 3) & 1) << 2) | (((rm >> 3) & 1) << 0);
return [rex, 0];
}
let r4 = (reg >> 4) & 1 != 0;
let r3 = (reg >> 3) & 1 != 0;
let b4 = (rm >> 4) & 1 != 0;
let b3 = (rm >> 3) & 1 != 0;
let rex2 = build(false, r4, false, b4, w, r3, false, b3);
[REX2, rex2]
}
pub fn build_for_ndd(dst: u8, src1: u8, src2: u8, w: bool) -> [u8; 2] {
let needs_rex2 = dst >= 16 || src1 >= 16 || src2 >= 16;
if !needs_rex2 {
let rex = 0x40 | ((w as u8) << 3) | (((src1 >> 3) & 1) << 2) | (((src2 >> 3) & 1) << 0);
return [rex, 0];
}
let r4 = (src1 >> 4) & 1 != 0;
let r3 = (src1 >> 3) & 1 != 0;
let b4 = (src2 >> 4) & 1 != 0;
let b3 = (src2 >> 3) & 1 != 0;
let x4 = (dst >> 4) & 1 != 0;
let rex2 = build(false, r4, x4, b4, w, r3, false, b3);
[REX2, rex2]
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum EgprId {
R16 = 16,
R17 = 17,
R18 = 18,
R19 = 19,
R20 = 20,
R21 = 21,
R22 = 22,
R23 = 23,
R24 = 24,
R25 = 25,
R26 = 26,
R27 = 27,
R28 = 28,
R29 = 29,
R30 = 30,
R31 = 31,
}
impl EgprId {
pub fn number(&self) -> u8 {
*self as u8
}
pub fn name64(&self) -> &'static str {
match self {
Self::R16 => "r16",
Self::R17 => "r17",
Self::R18 => "r18",
Self::R19 => "r19",
Self::R20 => "r20",
Self::R21 => "r21",
Self::R22 => "r22",
Self::R23 => "r23",
Self::R24 => "r24",
Self::R25 => "r25",
Self::R26 => "r26",
Self::R27 => "r27",
Self::R28 => "r28",
Self::R29 => "r29",
Self::R30 => "r30",
Self::R31 => "r31",
}
}
pub fn name32(&self) -> &'static str {
match self {
Self::R16 => "r16d",
Self::R17 => "r17d",
Self::R18 => "r18d",
Self::R19 => "r19d",
Self::R20 => "r20d",
Self::R21 => "r21d",
Self::R22 => "r22d",
Self::R23 => "r23d",
Self::R24 => "r24d",
Self::R25 => "r25d",
Self::R26 => "r26d",
Self::R27 => "r27d",
Self::R28 => "r28d",
Self::R29 => "r29d",
Self::R30 => "r30d",
Self::R31 => "r31d",
}
}
pub fn name16(&self) -> &'static str {
match self {
Self::R16 => "r16w",
Self::R17 => "r17w",
Self::R18 => "r18w",
Self::R19 => "r19w",
Self::R20 => "r20w",
Self::R21 => "r21w",
Self::R22 => "r22w",
Self::R23 => "r23w",
Self::R24 => "r24w",
Self::R25 => "r25w",
Self::R26 => "r26w",
Self::R27 => "r27w",
Self::R28 => "r28w",
Self::R29 => "r29w",
Self::R30 => "r30w",
Self::R31 => "r31w",
}
}
pub fn name8(&self) -> &'static str {
match self {
Self::R16 => "r16b",
Self::R17 => "r17b",
Self::R18 => "r18b",
Self::R19 => "r19b",
Self::R20 => "r20b",
Self::R21 => "r21b",
Self::R22 => "r22b",
Self::R23 => "r23b",
Self::R24 => "r24b",
Self::R25 => "r25b",
Self::R26 => "r26b",
Self::R27 => "r27b",
Self::R28 => "r28b",
Self::R29 => "r29b",
Self::R30 => "r30b",
Self::R31 => "r31b",
}
}
pub fn needs_rex2(&self) -> bool {
true }
}
pub fn is_egpr(reg_num: u8) -> bool {
reg_num >= 16 && reg_num <= 31
}
pub fn needs_rex2_prefix(reg_num: u8) -> bool {
reg_num >= 16
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types)]
pub enum ApkNddForm {
ADD_NDD,
SUB_NDD,
AND_NDD,
OR_NDD,
XOR_NDD,
ADC_NDD,
SBB_NDD,
IMUL_NDD,
CMP_NDD,
SHL_NDD,
SHR_NDD,
SAR_NDD,
ROL_NDD,
ROR_NDD,
NEG_NDD,
NOT_NDD,
INC_NDD,
DEC_NDD,
}
impl ApkNddForm {
pub fn mnemonic(&self) -> &'static str {
match self {
Self::ADD_NDD => "add",
Self::SUB_NDD => "sub",
Self::AND_NDD => "and",
Self::OR_NDD => "or",
Self::XOR_NDD => "xor",
Self::ADC_NDD => "adc",
Self::SBB_NDD => "sbb",
Self::IMUL_NDD => "imul",
Self::CMP_NDD => "cmp",
Self::SHL_NDD => "shl",
Self::SHR_NDD => "shr",
Self::SAR_NDD => "sar",
Self::ROL_NDD => "rol",
Self::ROR_NDD => "ror",
Self::NEG_NDD => "neg",
Self::NOT_NDD => "not",
Self::INC_NDD => "inc",
Self::DEC_NDD => "dec",
}
}
pub fn legacy_opcode(&self) -> u8 {
match self {
Self::ADD_NDD => 0x01, Self::SUB_NDD => 0x29, Self::AND_NDD => 0x21, Self::OR_NDD => 0x09, Self::XOR_NDD => 0x31, Self::ADC_NDD => 0x11, Self::SBB_NDD => 0x19, Self::IMUL_NDD => 0xAF, Self::CMP_NDD => 0x39, Self::SHL_NDD => 0x20, Self::SHR_NDD => 0x28, Self::SAR_NDD => 0x38, Self::ROL_NDD => 0x00, Self::ROR_NDD => 0x08, Self::NEG_NDD => 0xD8, Self::NOT_NDD => 0xD0, Self::INC_NDD => 0xC0, Self::DEC_NDD => 0xC8, }
}
pub fn num_operands(&self) -> u8 {
match self {
Self::NEG_NDD | Self::NOT_NDD | Self::INC_NDD | Self::DEC_NDD => 2,
Self::CMP_NDD => 3, _ => 3,
}
}
pub fn is_commutative(&self) -> bool {
matches!(
self,
Self::ADD_NDD
| Self::AND_NDD
| Self::OR_NDD
| Self::XOR_NDD
| Self::ADC_NDD
| Self::IMUL_NDD
)
}
pub fn dst_type(&self) -> OperandType {
match self {
Self::CMP_NDD => OperandType::Reg64, _ => OperandType::Reg64,
}
}
pub fn src1_type(&self) -> OperandType {
OperandType::Reg64
}
pub fn src2_type(&self) -> OperandType {
match self {
Self::SHL_NDD | Self::SHR_NDD | Self::SAR_NDD | Self::ROL_NDD | Self::ROR_NDD => {
OperandType::Imm8
}
_ => OperandType::Reg64,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ApkConditionalCompare {
pub condition: X86ConditionCode,
pub is_test: bool,
pub src_flags: ApkFlagsReg,
pub dst_flags: ApkFlagsReg,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ApkFlagsReg {
Flags,
EFlags,
RFlags,
CondFlags,
}
impl ApkFlagsReg {
pub fn name(&self) -> &'static str {
match self {
Self::Flags => "flags",
Self::EFlags => "eflags",
Self::RFlags => "rflags",
Self::CondFlags => "condflags",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum X86ConditionCode {
O = 0, NO = 1, B = 2, NB = 3, Z = 4, NZ = 5, BE = 6, A = 7, S = 8, NS = 9, P = 10, NP = 11, L = 12, GE = 13, LE = 14, G = 15, T = 16, F = 17, }
impl X86ConditionCode {
pub fn mnemonic(&self) -> &'static str {
match self {
Self::O => "o",
Self::NO => "no",
Self::B => "b",
Self::NB => "nb",
Self::Z => "z",
Self::NZ => "nz",
Self::BE => "be",
Self::A => "a",
Self::S => "s",
Self::NS => "ns",
Self::P => "p",
Self::NP => "np",
Self::L => "l",
Self::GE => "ge",
Self::LE => "le",
Self::G => "g",
Self::T => "t",
Self::F => "f",
}
}
pub fn is_negating(&self) -> bool {
matches!(self, Self::F)
}
}
impl ApkConditionalCompare {
pub fn ccmp(
condition: X86ConditionCode,
src_flags: ApkFlagsReg,
dst_flags: ApkFlagsReg,
) -> Self {
Self {
condition,
is_test: false,
src_flags,
dst_flags,
}
}
pub fn ctest(
condition: X86ConditionCode,
src_flags: ApkFlagsReg,
dst_flags: ApkFlagsReg,
) -> Self {
Self {
condition,
is_test: true,
src_flags,
dst_flags,
}
}
pub fn mnemonic(&self) -> String {
if self.is_test {
format!("ctest{}", self.condition.mnemonic())
} else {
format!("ccmp{}", self.condition.mnemonic())
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Push2Pop2 {
pub reg1: u8,
pub reg2: u8,
pub is_pop: bool,
}
impl Push2Pop2 {
pub fn push2(reg1: u8, reg2: u8) -> Self {
Self {
reg1,
reg2,
is_pop: false,
}
}
pub fn pop2(reg1: u8, reg2: u8) -> Self {
Self {
reg1,
reg2,
is_pop: true,
}
}
pub fn mnemonic(&self) -> &'static str {
if self.is_pop {
"pop2"
} else {
"push2"
}
}
pub fn opcode(&self) -> u8 {
if self.is_pop {
0x8F } else {
0xFF }
}
pub fn encode_modrm(&self) -> u8 {
let rm = self.reg2 & 0x7;
let reg = self.reg1 & 0x7;
let opcode_ext = if self.is_pop { 0 } else { 6 }; (0xC0) | ((opcode_ext & 0x7) << 3) | rm
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ApkZeroUpper {
None,
ZeroUpper,
Explicit,
}
impl ApkZeroUpper {
pub fn is_enabled(&self) -> bool {
!matches!(self, Self::None)
}
pub fn evex_bit(&self) -> bool {
matches!(self, Self::Explicit)
}
}
#[derive(Debug, Clone)]
pub struct ApkInstructionRegistry {
pub mnemonic_count: HashMap<String, usize>,
pub apx_enabled: bool,
pub egpr_available: bool,
pub ndd_supported: bool,
pub ccmpx_supported: bool,
pub push2pop2_supported: bool,
}
impl ApkInstructionRegistry {
pub fn new(apx_enabled: bool) -> Self {
Self {
mnemonic_count: HashMap::new(),
apx_enabled,
egpr_available: apx_enabled,
ndd_supported: apx_enabled,
ccmpx_supported: apx_enabled,
push2pop2_supported: apx_enabled,
}
}
pub fn all_apx_mnemonics() -> Vec<&'static str> {
vec![
"andn", "bextr", "blsi", "blsmsk", "blsr", "bzhi", "incssp", "invpcid", "mulx", "pcommit", "pdep", "pext", "rdsspd", "rdsspq", "rdpkru", "wrssd", "wrssq", "wrussd", "wrussq", "rstorssp", "sarx", "shlx", "shrx", "tzcnt", "tzcnti", "lzcnt", "add", "sub", "and", "or", "xor", "adc", "sbb", "imul", "cmp", "shl", "shr", "sar",
"rol", "ror", "neg", "not", "inc", "dec", "ccmpo", "ccmpno", "ccmpb", "ccmpnb", "ccmpz", "ccmpnz", "ccmpbe", "ccmpa", "ccmps",
"ccmpns", "ccmpp", "ccmpnp", "ccmpl", "ccmpge", "ccmple", "ccmpg", "ccmpt", "ccmpf",
"ctesto", "ctestno", "ctestb", "ctestnb", "ctestz", "ctestnz", "ctestbe", "ctesta",
"ctests", "ctestns", "ctestp", "ctestnp", "ctestl", "ctestge", "ctestle", "ctestg",
"ctestt", "ctestf", "push2", "pop2",
]
}
pub fn apx_form_count() -> usize {
18 + 18 + 18 + 2
}
pub fn is_apx_mnemonic(mnemonic: &str) -> bool {
Self::all_apx_mnemonics().contains(&mnemonic)
}
pub fn describe_ndd(form: ApkNddForm) -> String {
format!(
"APX NDD {} ({} operands, commutative: {})",
form.mnemonic(),
form.num_operands(),
form.is_commutative()
)
}
pub fn describe_ccmp(cc: &ApkConditionalCompare) -> String {
format!(
"APX {} (flags: {} -> {})",
cc.mnemonic(),
cc.src_flags.name(),
cc.dst_flags.name()
)
}
pub fn describe_push2pop2(pp: &Push2Pop2) -> String {
format!("APX {} r{}, r{}", pp.mnemonic(), pp.reg1, pp.reg2)
}
}
impl Default for ApkInstructionRegistry {
fn default() -> Self {
Self::new(false)
}
}
#[derive(Debug, Clone)]
pub struct ApkInstrDesc {
pub mnemonic: &'static str,
pub base_opcode: u8,
pub opcode_map: u8,
pub num_operands: u8,
pub needs_rex2: bool,
pub is_ndd: bool,
pub has_side_effects: bool,
pub category: &'static str,
}
pub static APX_INSTRUCTION_TABLE: &[ApkInstrDesc] = &[
ApkInstrDesc {
mnemonic: "andn",
base_opcode: 0xF2,
opcode_map: 1,
num_operands: 3,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi1",
},
ApkInstrDesc {
mnemonic: "bextr",
base_opcode: 0xF7,
opcode_map: 1,
num_operands: 3,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi1",
},
ApkInstrDesc {
mnemonic: "blsi",
base_opcode: 0xF3,
opcode_map: 1,
num_operands: 2,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi1",
},
ApkInstrDesc {
mnemonic: "blsmsk",
base_opcode: 0xF3,
opcode_map: 1,
num_operands: 2,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi1",
},
ApkInstrDesc {
mnemonic: "blsr",
base_opcode: 0xF3,
opcode_map: 1,
num_operands: 2,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi1",
},
ApkInstrDesc {
mnemonic: "bzhi",
base_opcode: 0xF5,
opcode_map: 1,
num_operands: 3,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi2",
},
ApkInstrDesc {
mnemonic: "mulx",
base_opcode: 0xF6,
opcode_map: 2,
num_operands: 3,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi2",
},
ApkInstrDesc {
mnemonic: "pdep",
base_opcode: 0xF5,
opcode_map: 2,
num_operands: 3,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi2",
},
ApkInstrDesc {
mnemonic: "pext",
base_opcode: 0xF5,
opcode_map: 2,
num_operands: 3,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi2",
},
ApkInstrDesc {
mnemonic: "sarx",
base_opcode: 0xF7,
opcode_map: 2,
num_operands: 3,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi2",
},
ApkInstrDesc {
mnemonic: "shlx",
base_opcode: 0xF7,
opcode_map: 2,
num_operands: 3,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi2",
},
ApkInstrDesc {
mnemonic: "shrx",
base_opcode: 0xF7,
opcode_map: 2,
num_operands: 3,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi2",
},
ApkInstrDesc {
mnemonic: "tzcnt",
base_opcode: 0xBC,
opcode_map: 1,
num_operands: 2,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi1",
},
ApkInstrDesc {
mnemonic: "tzcnti",
base_opcode: 0xBC,
opcode_map: 1,
num_operands: 2,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "bmi1",
},
ApkInstrDesc {
mnemonic: "lzcnt",
base_opcode: 0xBD,
opcode_map: 1,
num_operands: 2,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "abm",
},
ApkInstrDesc {
mnemonic: "incssp",
base_opcode: 0xAE,
opcode_map: 1,
num_operands: 1,
needs_rex2: false,
is_ndd: false,
has_side_effects: true,
category: "cet",
},
ApkInstrDesc {
mnemonic: "rdsspd",
base_opcode: 0x1E,
opcode_map: 1,
num_operands: 1,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "cet",
},
ApkInstrDesc {
mnemonic: "rdsspq",
base_opcode: 0x1E,
opcode_map: 1,
num_operands: 1,
needs_rex2: true,
is_ndd: false,
has_side_effects: false,
category: "cet",
},
ApkInstrDesc {
mnemonic: "wrssd",
base_opcode: 0x1E,
opcode_map: 1,
num_operands: 2,
needs_rex2: false,
is_ndd: false,
has_side_effects: true,
category: "cet",
},
ApkInstrDesc {
mnemonic: "wrssq",
base_opcode: 0x1E,
opcode_map: 1,
num_operands: 2,
needs_rex2: true,
is_ndd: false,
has_side_effects: true,
category: "cet",
},
ApkInstrDesc {
mnemonic: "wrussd",
base_opcode: 0x1E,
opcode_map: 1,
num_operands: 2,
needs_rex2: false,
is_ndd: false,
has_side_effects: true,
category: "cet",
},
ApkInstrDesc {
mnemonic: "wrussq",
base_opcode: 0x1E,
opcode_map: 1,
num_operands: 2,
needs_rex2: true,
is_ndd: false,
has_side_effects: true,
category: "cet",
},
ApkInstrDesc {
mnemonic: "rstorssp",
base_opcode: 0x01,
opcode_map: 1,
num_operands: 1,
needs_rex2: false,
is_ndd: false,
has_side_effects: true,
category: "cet",
},
ApkInstrDesc {
mnemonic: "rdpkru",
base_opcode: 0xEE,
opcode_map: 1,
num_operands: 0,
needs_rex2: false,
is_ndd: false,
has_side_effects: false,
category: "pku",
},
ApkInstrDesc {
mnemonic: "invpcid",
base_opcode: 0x82,
opcode_map: 2,
num_operands: 2,
needs_rex2: false,
is_ndd: false,
has_side_effects: true,
category: "system",
},
ApkInstrDesc {
mnemonic: "add_ndd",
base_opcode: 0x01,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "sub_ndd",
base_opcode: 0x29,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "and_ndd",
base_opcode: 0x21,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "or_ndd",
base_opcode: 0x09,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "xor_ndd",
base_opcode: 0x31,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "adc_ndd",
base_opcode: 0x11,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "sbb_ndd",
base_opcode: 0x19,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "imul_ndd",
base_opcode: 0xAF,
opcode_map: 1,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "cmp_ndd",
base_opcode: 0x39,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "shl_ndd",
base_opcode: 0x20,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "shr_ndd",
base_opcode: 0x28,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "sar_ndd",
base_opcode: 0x38,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "rol_ndd",
base_opcode: 0x00,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "ror_ndd",
base_opcode: 0x08,
opcode_map: 0,
num_operands: 3,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "neg_ndd",
base_opcode: 0xD8,
opcode_map: 0,
num_operands: 2,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "not_ndd",
base_opcode: 0xD0,
opcode_map: 0,
num_operands: 2,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "inc_ndd",
base_opcode: 0xC0,
opcode_map: 0,
num_operands: 2,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
ApkInstrDesc {
mnemonic: "dec_ndd",
base_opcode: 0xC8,
opcode_map: 0,
num_operands: 2,
needs_rex2: true,
is_ndd: true,
has_side_effects: true,
category: "ndd",
},
];
pub fn lookup_apx_instr(mnemonic: &str) -> Option<&'static ApkInstrDesc> {
APX_INSTRUCTION_TABLE
.iter()
.find(|d| d.mnemonic == mnemonic)
}
pub fn apx_instrs_by_category(category: &str) -> Vec<&'static ApkInstrDesc> {
APX_INSTRUCTION_TABLE
.iter()
.filter(|d| d.category == category)
.collect()
}
pub fn apx_instr_count_by_category(category: &str) -> usize {
APX_INSTRUCTION_TABLE
.iter()
.filter(|d| d.category == category)
.count()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
#[allow(non_camel_case_types)]
pub enum ApkFeature {
APX = 0,
EGPR = 1,
NDD = 2,
CCMP = 3,
PPX = 4,
ZU = 5,
UINTR = 6,
IMZ = 7,
EGPR16 = 8,
EGPR32 = 9,
NDD_BMI = 10,
}
impl ApkFeature {
pub fn name(&self) -> &'static str {
match self {
Self::APX => "apx",
Self::EGPR => "egpr",
Self::NDD => "ndd",
Self::CCMP => "ccmp",
Self::PPX => "ppx",
Self::ZU => "zu",
Self::UINTR => "uintr",
Self::IMZ => "imz",
Self::EGPR16 => "egpr16",
Self::EGPR32 => "egpr32",
Self::NDD_BMI => "ndd_bmi",
}
}
pub fn cpuid_info(&self) -> (u32, u32, u32) {
match self {
Self::APX | Self::EGPR | Self::NDD | Self::CCMP | Self::PPX | Self::ZU => (7, 1, 0),
Self::UINTR => (7, 0, 0),
Self::IMZ => (7, 2, 0),
Self::EGPR16 | Self::EGPR32 => (7, 1, 0),
Self::NDD_BMI => (7, 1, 0),
}
}
pub fn cpuid_bit(&self) -> u32 {
match self {
Self::APX => 21,
Self::EGPR => 22,
Self::NDD => 23,
Self::CCMP => 24,
Self::PPX => 25,
Self::ZU => 26,
Self::UINTR => 5,
Self::IMZ => 2,
Self::EGPR16 => 6,
Self::EGPR32 => 7,
Self::NDD_BMI => 28,
}
}
pub fn required_for_category(category: &str) -> Vec<Self> {
match category {
"bmi1" | "bmi2" | "abm" => vec![Self::APX],
"cet" => vec![Self::APX],
"pku" => vec![Self::APX],
"system" => vec![Self::APX],
"ndd" => vec![Self::APX, Self::NDD, Self::EGPR],
"ccmp" => vec![Self::APX, Self::CCMP],
"ppx" => vec![Self::APX, Self::PPX],
_ => vec![Self::APX],
}
}
}
#[derive(Debug, Clone)]
pub struct ApkFeatureSet {
pub features: u64,
pub apx_available: bool,
}
impl ApkFeatureSet {
pub fn new(feature_bits: u64) -> Self {
Self {
features: feature_bits,
apx_available: feature_bits & (1 << ApkFeature::APX as u32) != 0,
}
}
pub fn has(&self, feature: ApkFeature) -> bool {
self.features & (1 << feature as u32) != 0
}
pub fn has_egpr(&self) -> bool {
self.has(ApkFeature::EGPR)
}
pub fn has_ndd(&self) -> bool {
self.has(ApkFeature::NDD)
}
pub fn has_ccmp(&self) -> bool {
self.has(ApkFeature::CCMP)
}
pub fn has_ppx(&self) -> bool {
self.has(ApkFeature::PPX)
}
pub fn enabled_features(&self) -> Vec<&'static str> {
let all = [
ApkFeature::APX,
ApkFeature::EGPR,
ApkFeature::NDD,
ApkFeature::CCMP,
ApkFeature::PPX,
ApkFeature::ZU,
ApkFeature::UINTR,
ApkFeature::IMZ,
ApkFeature::EGPR16,
ApkFeature::EGPR32,
ApkFeature::NDD_BMI,
];
all.iter()
.filter(|f| self.has(**f))
.map(|f| f.name())
.collect()
}
pub fn all_enabled() -> Self {
let mut f = 0u64;
for feat in &[
ApkFeature::APX,
ApkFeature::EGPR,
ApkFeature::NDD,
ApkFeature::CCMP,
ApkFeature::PPX,
ApkFeature::ZU,
ApkFeature::EGPR16,
ApkFeature::EGPR32,
ApkFeature::NDD_BMI,
] {
f |= 1 << (*feat as u32);
}
Self::new(f)
}
}
impl Default for ApkFeatureSet {
fn default() -> Self {
Self::new(0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_full_opcode_count() {
let info = X86FullInstrInfo::new();
let count = info.infos.len();
assert!(
count >= 700,
"Expected at least 700 instructions, got {}",
count
);
}
#[test]
fn test_movrr_lookup() {
let info = X86FullInstrInfo::new();
let enc = info.get(X86FullOpcode::MOVrr).unwrap();
assert_eq!(enc.mnemonic, "mov");
assert_eq!(enc.num_operands, 2);
assert_eq!(enc.requires_modrm, true);
assert_eq!(enc.encoding_form, EncodingForm::Legacy);
}
#[test]
fn test_cmov_classification() {
assert!(X86FullOpcode::CMOVO.is_cmov());
assert!(X86FullOpcode::CMOVG_FULL.is_cmov());
assert!(!X86FullOpcode::ADD.is_cmov());
}
#[test]
fn test_jcc_classification() {
assert!(X86FullOpcode::JE_FULL.is_jcc());
assert!(X86FullOpcode::JG_FULL.is_jcc());
assert!(!X86FullOpcode::JMP.is_jcc());
assert!(!X86FullOpcode::CALL.is_jcc());
}
#[test]
fn test_setcc_classification() {
assert!(X86FullOpcode::SETE.is_setcc());
assert!(X86FullOpcode::SETG.is_setcc());
assert!(!X86FullOpcode::ADD.is_setcc());
}
#[test]
fn test_vex_classification() {
assert!(X86FullOpcode::VADDPS.is_vex());
assert!(X86FullOpcode::VPERMILPS.is_vex());
assert!(!X86FullOpcode::ADDPS.is_vex());
}
#[test]
fn test_evex_classification() {
assert!(X86FullOpcode::VPADDD_Z.is_evex());
assert!(X86FullOpcode::VCOMPRESSPS_Z.is_evex());
assert!(!X86FullOpcode::VADDPS.is_evex());
}
#[test]
fn test_system_has_side_effects() {
let info = X86FullInstrInfo::new();
let enc = info.get(X86FullOpcode::SYSCALL).unwrap();
assert!(enc.has_side_effects);
let enc = info.get(X86FullOpcode::HLT).unwrap();
assert!(enc.has_side_effects);
}
#[test]
fn test_find_by_mnemonic() {
let info = X86FullInstrInfo::new();
let op = info.find_by_mnemonic("add");
assert_eq!(op, Some(X86FullOpcode::ADD));
let op = info.find_by_mnemonic("vaddps");
assert_eq!(op, Some(X86FullOpcode::VADDPS));
let op = info.find_by_mnemonic("aesenc");
assert_eq!(op, Some(X86FullOpcode::AESENC));
}
#[test]
fn test_fma_instructions() {
let info = X86FullInstrInfo::new();
let enc = info.get(X86FullOpcode::VFMADD132PD).unwrap();
assert_eq!(enc.encoding_form, EncodingForm::VEX3Byte);
assert!(enc.is_commutative);
assert!(enc.is_three_address);
}
#[test]
fn test_avx512_present() {
let info = X86FullInstrInfo::new();
let enc = info.get(X86FullOpcode::VPADDD_Z).unwrap();
assert_eq!(enc.encoding_form, EncodingForm::EVEX);
assert_eq!(enc.num_operands, 3);
}
#[test]
fn test_amx_present() {
let info = X86FullInstrInfo::new();
let enc = info.get(X86FullOpcode::TILELOADD).unwrap();
assert!(enc.mnemonic == "tileloadd");
let enc = info.get(X86FullOpcode::TDPBSSD).unwrap();
assert_eq!(enc.num_operands, 3);
}
#[test]
fn test_cet_present() {
let info = X86FullInstrInfo::new();
let enc = info.get(X86FullOpcode::ENDBR64).unwrap();
assert_eq!(enc.num_operands, 0);
assert!(!enc.has_side_effects);
}
#[test]
fn test_serialize_present() {
let info = X86FullInstrInfo::new();
let enc = info.get(X86FullOpcode::SERIALIZE).unwrap();
assert_eq!(enc.mnemonic, "serialize");
}
#[test]
fn test_all_opcodes_have_mnemonic() {
let info = X86FullInstrInfo::new();
for (op, enc) in &info.infos {
assert!(
!enc.mnemonic.is_empty(),
"Opcode {:?} has empty mnemonic",
op
);
}
}
#[test]
fn test_opcode_mnemonic_unique_count() {
let info = X86FullInstrInfo::new();
let unique_count = info.by_mnemonic.len();
assert!(
unique_count >= 400,
"Expected at least 400 unique mnemonics, got {}",
unique_count
);
}
}