use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types)]
pub enum X86Opcode {
NOP = 0,
INT3 = 2000,
UD2 = 2001,
MOV = 1,
MOVSX = 24,
MOVZX = 25,
MOVABS = 26,
CMOVO = 27,
CMOVNO = 28,
CMOVB = 29,
CMOVAE = 30,
CMOVE = 31,
CMOVNE = 32,
CMOVBE = 33,
CMOVA = 34,
CMOVS = 35,
CMOVNS = 36,
CMOVP = 37,
CMOVNP = 38,
CMOVL = 39,
CMOVGE = 40,
CMOVLE = 41,
CMOVG = 42,
XCHG = 43,
PUSH = 11,
POP = 12,
PUSHF = 44,
POPF = 45,
LEA = 19,
ADD = 2,
ADC = 46,
SUB = 3,
SBB = 47,
MUL = 4,
IMUL = 48,
DIV = 5,
IDIV = 49,
INC = 20,
DEC = 21,
NEG = 23,
AND = 6,
OR = 7,
XOR = 8,
NOT = 22,
TEST = 50,
SHL = 9,
SHR = 10,
SAR = 51,
ROL = 52,
ROR = 53,
RCL = 54,
RCR = 55,
SHLD = 56,
SHRD = 57,
JMP = 15,
JO = 58,
JNO = 59,
JB = 60,
JAE = 61,
JE = 16,
JNE = 17,
JBE = 62,
JA = 63,
JS = 64,
JNS = 65,
JP = 66,
JNP = 67,
JL = 68,
JGE = 69,
JLE = 70,
JG = 71,
CALL = 13,
RET = 14,
LOOP = 72,
LOOPE = 73,
LOOPNE = 74,
INT = 75,
SETO = 76,
SETNO = 77,
SETB = 78,
SETAE = 79,
SETE = 80,
SETNE = 81,
SETBE = 82,
SETA = 83,
SETS = 84,
SETNS = 85,
SETP = 86,
SETNP = 87,
SETL = 88,
SETGE = 89,
SETLE = 90,
SETG = 91,
MOVSB = 92,
MOVSW = 93,
MOVSD_STR = 94,
MOVSQ = 95,
CMPSB = 96,
CMPSW = 97,
CMPSD_STR = 98,
CMPSQ = 99,
STOSB = 100,
STOSW = 101,
STOSD_STR = 102,
STOSQ = 103,
LODSB = 104,
LODSW = 105,
LODSD_STR = 106,
LODSQ = 107,
SCASB = 108,
SCASW = 109,
SCASD_STR = 110,
SCASQ = 111,
REP = 112,
REPE = 113,
REPNE = 114,
CMP = 18,
MOVSS = 115,
MOVSD = 116,
ADDSS = 117,
ADDSD = 118,
SUBSS = 119,
SUBSD = 120,
MULSS = 121,
MULSD = 122,
DIVSS = 123,
DIVSD = 124,
SQRTSS = 125,
SQRTSD = 126,
MINSS = 127,
MINSD = 128,
MAXSS = 129,
MAXSD = 130,
CMPSS = 131,
CMPSD = 132,
CVTSI2SS = 133,
CVTSI2SD = 134,
CVTSS2SI = 135,
CVTSD2SI = 136,
CVTTSS2SI = 137,
CVTTSD2SI = 138,
ANDPS = 139,
ANDNPS = 140,
ORPS = 141,
XORPS = 142,
SHUFPS,
SHUFPD,
PSHUFD,
PSHUFHW,
PSHUFLW,
UNPCKLPS,
UNPCKHPS,
UNPCKLPD,
UNPCKHPD,
MOVHLPS,
MOVLHPS,
PEXTRB,
PEXTRW,
PEXTRD,
PEXTRQ,
PINSRB,
PINSRW,
PINSRD,
PINSRQ,
PUNPCKLBW,
PUNPCKLWD,
PUNPCKLDQ,
PUNPCKLQDQ,
PUNPCKHBW,
PUNPCKHWD,
PUNPCKHDQ,
PUNPCKHQDQ,
UCOMISS,
UCOMISD,
CVTSS2SD,
CVTSD2SS,
MOVD,
MOVQ,
ADDPS,
ADDPD,
SUBPS,
SUBPD,
MULPS,
MULPD,
DIVPS,
DIVPD,
RCPPS,
SQRTPS,
RSQRTPS,
ADDSUBPS,
ADDSUBPD,
HADDPS,
HADDPD,
HSUBPS,
HSUBPD,
MOVSLDUP,
MOVSHDUP,
MOVDDUP,
PHADDW,
PHADDD,
PHADDSW,
PMADDUBSW,
PHSUBW,
PHSUBD,
PHSUBSW,
PSIGNB,
PSIGNW,
PSIGND,
PABSB,
PABSW,
PABSD,
BLENDPS,
BLENDPD,
BLENDVPS,
BLENDVPD,
DPPS,
DPPD,
EXTRACTPS,
INSERTPS,
PMULLD,
PMULDQ,
PMINSB,
PMINSD,
PMINUW,
PMINUD,
PMAXSB,
PMAXSD,
PMAXUW,
PMAXUD,
PACKUSDW,
PCMPEQQ,
CRC32,
VADDPS,
VADDPD,
VADDSS,
VADDSD,
VSUBPS,
VSUBPD,
VMULPS,
VMULPD,
VDIVPS,
VDIVPD,
VANDPS,
VANDNPS,
VORPS,
VXORPS,
VBROADCASTSS,
VBROADCASTSD,
VPERMILPS,
VPERM2F128,
VZEROALL,
VZEROUPPER,
VPBROADCASTB,
VPBROADCASTW,
VPBROADCASTD,
VPBROADCASTQ,
VPERMQ,
VPERMPD,
VPGATHERDD,
VPGATHERDQ,
VPGATHERQD,
VPGATHERQQ,
VFMADD132PD,
VFMADD213PD,
VFMADD231PD,
VFMSUB132PD,
VFMSUB213PD,
VFMSUB231PD,
VFNMADD132PD,
VFNMADD213PD,
VFNMADD231PD,
VFNMSUB132PD,
VFNMSUB213PD,
VFNMSUB231PD,
VFMADD132PS,
VFMADD213PS,
VFMADD231PS,
VFMADD132SS,
VFMADD213SS,
VFMADD231SS,
VFMADD132SD,
VFMADD213SD,
VFMADD231SD,
ANDN,
BEXTR,
BLSI,
BLSMSK,
BLSR,
BZHI,
MULX,
PDEP,
PEXT,
RORX,
SARX,
SHLX,
SHRX,
TZCNT,
LZCNT,
SYSCALL,
SYSRET,
SYSENTER,
SYSEXIT,
NOP1,
NOP2,
NOP3,
NOP4,
NOP5,
NOP6,
NOP7,
NOP8,
NOP9,
BNDMK,
BNDCL,
BNDCU,
BNDCN,
BNDMOV,
BNDLDX,
BNDSTX,
CLAC,
STAC,
ENCLS,
ENCLU,
ENCLV,
GETSEC,
INVEPT,
INVVPID,
INVPCID,
VMFUNC,
VMCALL,
VMLAUNCH,
VMRESUME,
VMXOFF,
VMXON,
VMCLEAR,
VMPTRLD,
VMPTRST,
VMREAD,
VMWRITE,
MONITOR,
MWAIT,
MWAITX,
MONITORX,
RDPID,
RDRAND,
RDSEED,
RDTSC,
RDTSCP,
RDPMC,
SWAPGS,
UD0,
UD1,
VERR,
VERW,
LAR,
LSL,
SGDT,
SIDT,
SLDT,
STR,
LGDT,
LIDT,
LLDT,
LTR,
XABORT,
XBEGIN,
XEND,
XTEST,
XGETBV,
XSETBV,
XRSTOR,
XRSTORS,
XSAVE,
XSAVEC,
XSAVEOPT,
XSAVES,
XRSTORS64,
XSAVE64,
XSAVEC64,
XSAVEOPT64,
XSAVES64,
RDPRU,
CLZERO,
BSWAP,
BT,
BTS,
BTR,
BTC,
BSF,
BSR,
MOVSXD,
ANDPD,
ORPD,
XORPD,
ANDNPD,
CVTDQ2PS,
CVTPS2DQ,
CVTTPS2DQ,
VSUBSS,
VSUBSD,
VMULSS,
VMULSD,
VDIVSS,
VDIVSD,
VFMSUB132SS,
VFMSUB213SS,
VFMSUB231SS,
VFNMSUB132SS,
VFNMSUB213SS,
VFNMSUB231SS,
VFMADDSUB132PS,
VFMADDSUB132PD,
VFNMADD132SS,
VFNMADD213SS,
VFNMADD231SS,
VFMSUB132PS,
VFMSUB213PS,
VFMSUB231PS,
VFNMADD132PS,
VFNMADD213PS,
VFNMADD231PS,
VFNMSUB132PS,
VFNMSUB213PS,
VFNMSUB231PS,
VFMSUB132SD,
VFMSUB213SD,
VFMSUB231SD,
VFNMADD132SD,
VFNMADD213SD,
VFNMADD231SD,
VFNMSUB132SD,
VFNMSUB213SD,
VFNMSUB231SD,
VFMADDSUB213PS,
VFMADDSUB213PD,
VFMADDSUB231PS,
VFMADDSUB231PD,
VPADDB,
VPADDW,
VPADDD,
VPADDQ,
VPSUBB,
VPSUBW,
VPSUBD,
VPSUBQ,
VPMULLD,
VPMULUDQ,
VPMADDWD,
VPAVGB,
VPAVGW,
VPMINUB,
VPMINSW,
VPMAXUB,
VPMAXSW,
VPMINSB,
VPMINSD,
VPMINUW,
VPMINUD,
VPMAXSB,
VPMAXSD,
VPMAXUW,
VPMAXUD,
VPADDD_Z,
VPADDD_Z_MASK,
VPMULLQ_Z,
VPMULLQ_Z_MASK,
VPADDB_Z,
VPADDW_Z,
VPADDQ_Z,
VPSUBD_Z,
VPSUBQ_Z,
VPMULLD_Z,
VADDPS_Z,
VADDPD_Z,
VMULPS_Z,
VMULPD_Z,
VDIVPS_Z,
VDIVPD_Z,
VMINPS_Z,
VMINPD_Z,
VMAXPS_Z,
VMAXPD_Z,
VADDPS_Z_RND,
VADDPD_Z_RND,
VMULPS_Z_RND,
VMULPD_Z_RND,
VDIVPS_Z_RND,
VDIVPD_Z_RND,
VCVTDQ2PS_Z,
VCVTPS2DQ_Z,
VCVTTPS2DQ_Z,
VCVTDQ2PD_Z,
VCVTPD2DQ_Z,
VCVTTPD2DQ_Z,
VCVTPS2PD_Z,
VCVTPD2PS_Z,
VPROLVD_Z,
VPROLVQ_Z,
VPRORVD_Z,
VPRORVQ_Z,
VPABSQ_Z,
VPMAXSQ_Z,
VPMINSQ_Z,
VPMAXUQ_Z,
VPMINUQ_Z,
VPABSD_Z,
VPMAXSD_Z,
VPMINSD_Z,
VPMAXUD_Z,
VPMINUD_Z,
VPERMQ_Z,
VPERMPD_Z,
VSHUFF32X4_Z,
VSHUFF64X2_Z,
VSHUFI32X4_Z,
VSHUFI64X2_Z,
VALIGND_Z,
VALIGNQ_Z,
VUNPCKLPS_Z,
VUNPCKHPS_Z,
VUNPCKLPD_Z,
VUNPCKHPD_Z,
VMOVDQA32_Z,
VMOVDQA64_Z,
VMOVDQU32_Z,
VMOVDQU64_Z,
VMOVDQA32_Z_MASK,
VMOVDQA64_Z_MASK,
VMOVDQU32_Z_MASK,
VMOVDQU64_Z_MASK,
VPADDB_Z_MASK,
VPADDW_Z_MASK,
VPSUBB_Z,
VPSUBW_Z,
VPMULLW_Z,
VPMULHW_Z,
VPMULHUW_Z,
VPMINSB_Z,
VPMAXSB_Z,
VPMINUB_Z,
VPMAXUB_Z,
VPMINSW_Z,
VPMAXSW_Z,
VPMINUW_Z,
VPMAXUW_Z,
VPSLLVW_Z,
VPSRLVW_Z,
VPSRAVW_Z,
VPABSB_Z,
VPABSW_Z,
VPOPCNTB_Z,
VPOPCNTW_Z,
VANDPS_Z,
VANDPD_Z,
VANDNPS_Z,
VANDNPD_Z,
VORPS_Z,
VORPD_Z,
VXORPS_Z,
VXORPD_Z,
VPMULLQ_DQ_Z,
VPANDD_Z,
VPANDQ_Z,
VPANDND_Z,
VPANDNQ_Z,
VPORD_Z,
VPORQ_Z,
VPXORD_Z,
VPXORQ_Z,
KADDW_Z,
KANDW_Z,
KANDNW_Z,
KNOTW_Z,
KORW_Z,
KXNORW_Z,
KXORW_Z,
KSHIFTLW_Z,
KSHIFTRW_Z,
KUNPCKBW_Z,
VADDSS_Z,
VADDSD_Z,
VMULSS_Z,
VMULSD_Z,
VDIVSS_Z,
VDIVSD_Z,
VMINSS_Z,
VMINSD_Z,
VMAXSS_Z,
VMAXSD_Z,
VCOMPRESSPS_Z,
VCOMPRESSPD_Z,
VEXPANDPS_Z,
VEXPANDPD_Z,
VPCOMPRESSD_Z,
VPCOMPRESSQ_Z,
VPEXPANDD_Z,
VPEXPANDQ_Z,
VPGATHERDD_Z,
VPGATHERDQ_Z,
VPGATHERQD_Z,
VPGATHERQQ_Z,
VPSCATTERDD_Z,
VPSCATTERDQ_Z,
VPSCATTERQD_Z,
VPSCATTERQQ_Z,
VPBROADCASTD_Z,
VPBROADCASTQ_Z,
VBROADCASTSS_Z,
VBROADCASTSD_Z,
VCMPPS_Z,
VCMPPD_Z,
VCMPD_Z,
VCMPQ_Z,
VPCMPEQB_Z,
VPCMPEQW_Z,
VPCMPGTB_Z,
VPCMPGTW_Z,
VPCMPEQQ_Z,
VPCMPGTQ_Z,
VMOVDQU8_Z,
VMOVDQU16_Z,
VP2INTERSECTD,
VP2INTERSECTQ,
VADDPH_Z,
VMULPH_Z,
VDIVPH_Z,
VSUBPH_Z,
VMINPH_Z,
VMAXPH_Z,
VSQRTPH_Z,
VRNDSCALEPH_Z,
VGETMANTPH_Z,
VGETEXPPH_Z,
VSCALEFPH_Z,
VCVTPH2W_Z,
VCVTW2PH_Z,
VCVTPH2UW_Z,
VCVTUW2PH_Z,
VFMADD132PH_Z,
VFMADD213PH_Z,
VFMADD231PH_Z,
VFMSUB132PH_Z,
VFMSUB213PH_Z,
VFMSUB231PH_Z,
VCMPPH_Z,
VCVTNE2PS2BF16_Z,
VCVTNEEBF162PS_Z,
VCVTNEOBF162PS_Z,
VDPBF16PS_Z,
TDPBSSD_Z,
TDPBSUD_Z,
TDPBUSD_Z,
TDPBUUD_Z,
TDPBF16PS_Z,
TDPFP16PS_Z,
TILELOADD_Z,
TILESTORED_Z,
TILECONFIG,
TILERELEASE,
TILEZERO_Z,
VPCLMULQDQ_Z,
ROUNDPS,
ROUNDPD,
AESENC,
AESENCLAST,
AESDEC,
AESDECLAST,
AESIMC,
AESKEYGENASSIST,
PCLMULQDQ,
SHA1RNDS4,
SHA1NEXTE,
SHA1MSG1,
SHA1MSG2,
SHA256RNDS2,
SHA256MSG1,
SHA256MSG2,
PCMPESTRI,
PCMPESTRM,
PCMPISTRI,
PCMPISTRM,
CRC32B,
CRC32W,
CRC32D,
CRC32Q,
POPCNT16,
POPCNT32,
POPCNT64,
LZCNT16,
LZCNT32,
LZCNT64,
TZCNT16,
TZCNT32,
TZCNT64,
BMI_ANDN,
BMI_BEXTR,
BMI_BLSI,
BMI_BLSMSK,
BMI_BLSR,
BMI_TZCNT,
BMI2_BZHI,
BMI2_MULX,
BMI2_PDEP,
BMI2_PEXT,
BMI2_RORX,
BMI2_SARX,
BMI2_SHLX,
BMI2_SHRX,
ADCX,
ADOX,
CLFLUSHOPT,
CLWB,
PREFETCHW,
PREFETCHWT1,
RDFSBASE,
RDGSBASE,
WRFSBASE,
WRGSBASE,
CLFLUSH,
LFENCE,
MFENCE,
SFENCE,
PAUSE,
PREFETCHT0,
PREFETCHT1,
PREFETCHT2,
PREFETCHNTA,
MOVNTI,
MOVNTDQ,
MOVNTDQA,
MOVNTPD,
MOVNTPS,
RDPKRU,
WRPKRU,
PCOMMIT,
RDRAND16,
RDRAND32,
RDRAND64,
RDSEED16,
RDSEED32,
RDSEED64,
PREFETCHIT0,
PREFETCHIT1,
WRMSRNS,
RDMSRLIST,
WRMSRLIST,
CLDEMOTE,
MOVDIRI,
MOVDIR64B,
ENQCMD,
ENQCMDS,
SERIALIZE,
XSUSLDTRK,
XRESLDTRK,
CMPCCXADD,
AADD,
AAND,
AOR,
AXOR,
VGF2P8AFFINEQB,
VGF2P8AFFINEINVQB,
VGF2P8MULB,
VAESENC,
VAESENCLAST,
VAESDEC,
VAESDECLAST,
VPCLMULQDQ,
VPDPBUSD,
VPDPBUSDS,
VPDPWSSD,
VPDPWSSDS,
VPMADD52LUQ,
VPMADD52HUQ,
VBCSTNEBF162PS,
VBCSTNESH2PS,
VCVTNEEPH2PS,
VCVTPH2PS,
VCVTPS2PH,
FLD,
FST,
FSTP,
FILD,
FIST,
FISTP,
FBLD,
FBSTP,
FXCH,
FCOM,
FCOMP,
FCOMPP,
FUCOM,
FUCOMP,
FUCOMPP,
FTST,
FXAM,
FADD_ST0_ST,
FADD_ST_ST0,
FADDP,
FSUB_ST0_ST,
FSUB_ST_ST0,
FSUBP,
FSUBR_ST0_ST,
FSUBR_ST_ST0,
FSUBRP,
FMUL_ST0_ST,
FMUL_ST_ST0,
FMULP,
FDIV_ST0_ST,
FDIV_ST_ST0,
FDIVP,
FDIVR_ST0_ST,
FDIVR_ST_ST0,
FDIVRP,
FADD_MEM,
FSUB_MEM,
FSUBR_MEM,
FMUL_MEM,
FDIV_MEM,
FDIVR_MEM,
FCHS,
FABS,
FSQRT,
FRNDINT,
FSCALE,
FPREM,
FPREM1,
FXTRACT,
FSIN,
FCOS,
FSINCOS,
FPTAN,
FPATAN,
F2XM1,
FYL2X,
FYL2XP1,
FLDCW,
FSTCW,
FNSTCW,
FLDENV,
FSTENV,
FNSTENV,
FRSTOR,
FSAVE,
FNSAVE,
FNCLEX,
FINIT,
FNINIT,
FFREE,
FDECSTP,
FINCSTP,
MMX_MOVD,
MMX_MOVQ,
MMX_MOVD_TO_MEM,
MMX_MOVQ_TO_MEM,
MMX_PADDB,
MMX_PADDW,
MMX_PADDD,
MMX_PADDQ,
MMX_PADDSB,
MMX_PADDSW,
MMX_PADDUSB,
MMX_PADDUSW,
MMX_PSUBB,
MMX_PSUBW,
MMX_PSUBD,
MMX_PSUBQ,
MMX_PSUBSB,
MMX_PSUBSW,
MMX_PSUBUSB,
MMX_PSUBUSW,
MMX_PMULLW,
MMX_PMULHW,
MMX_PMULHUW,
MMX_PMADDWD,
MMX_PCMPEQB,
MMX_PCMPEQW,
MMX_PCMPEQD,
MMX_PCMPGTB,
MMX_PCMPGTW,
MMX_PCMPGTD,
MMX_PACKSSWB,
MMX_PACKSSDW,
MMX_PACKUSWB,
MMX_PUNPCKLBW,
MMX_PUNPCKHBW,
MMX_PUNPCKLWD,
MMX_PUNPCKHWD,
MMX_PUNPCKLDQ,
MMX_PUNPCKHDQ,
MMX_PSLLW,
MMX_PSLLD,
MMX_PSLLQ,
MMX_PSRLW,
MMX_PSRLD,
MMX_PSRLQ,
MMX_PSRAW,
MMX_PSRAD,
MMX_PAND,
MMX_PANDN,
MMX_POR,
MMX_PXOR,
MMX_EMMS,
AMD_PAVGUSB,
AMD_PFADD,
AMD_PFSUB,
AMD_PFSUBR,
AMD_PFMUL,
AMD_PFACC,
AMD_PFCMPGE,
AMD_PFCMPGT,
AMD_PFCMPEQ,
AMD_PFMIN,
AMD_PFMAX,
AMD_PI2FD,
AMD_PF2ID,
AMD_PFNACC,
AMD_PFPNACC,
AMD_PSWAPD,
AMD_PFRCP,
AMD_PFRCPIT1,
AMD_PFRCPIT2,
AMD_PFRSQRT,
AMD_PFRSQIT1,
AMD_FEMMS,
MONITORX_AMD,
MWAITX_AMD,
PREFETCH_RESERVED,
PREFETCH_EXCLUSIVE,
PREFETCH_MODIFIED,
CLFLUSHOPT_64,
PHI,
FRAME_SETUP,
FRAME_DESTROY,
BUNDLE,
BUNDLE_INSIDE,
EH_LABEL,
LANDINGPAD,
CATCHPAD,
CLEANUPPAD,
PATCHPOINT,
PATCHABLE_OP,
PATCHABLE_FUNCTION_ENTER,
PATCHABLE_RET,
PATCHABLE_TAIL_CALL,
STACKMAP,
GC_LABEL,
DBG_VALUE,
DBG_LABEL,
DBG_INSTR_REF,
JMP1,
JMP2,
JMP4,
RET1,
RET2,
ENTER,
LEAVE,
PUSHFS,
PUSHGS,
POPFS,
POPGS,
BOUND,
CMPXCHG,
CMPXCHG8B,
CMPXCHG16B,
XADD,
INSB,
INSW,
INSD,
OUTSB,
OUTSW,
OUTSD,
LODSD,
STOSD,
SCASD,
REP_MOVSB,
REP_MOVSW,
REP_MOVSD,
REP_STOSB,
REP_STOSW,
REP_STOSD,
REPE_CMPSB,
REPE_SCASB,
REPNE_CMPSB,
REPNE_SCASB,
MOVAPS,
MOVUPS,
MOVDQU,
LOCK_ADD,
LOCK_AND,
LOCK_DEC,
LOCK_INC,
LOCK_OR,
LOCK_SUB,
LOCK_XCHG,
LOCK_XOR,
PADDB,
PADDW,
PADDD,
PSUBB,
PSUBW,
PSUBD,
PMULLW,
PACKSSDW,
PACKSSWB,
PACKUSWB,
PAND,
PMOVSXBW,
PMOVSXBD,
PMOVSXBQ,
PMOVSXWD,
PMOVSXWQ,
PMOVSXDQ,
PMOVZXBW,
PMOVZXBD,
PMOVZXBQ,
PMOVZXWD,
PMOVZXWQ,
PMOVZXDQ,
VMOVSS,
VMOVSD,
VCVTSI2SS,
VCVTSS2SI,
VCOMISS,
VUCOMISS,
VMOVAPS,
VMOVUPS,
VANDPD,
VORPD,
VXORPD,
VADDPSZ,
VADDPDZ,
VMULPSZ,
VMULPDZ,
VGATHERDPD,
VSCATTERDPD,
VPERMDZ,
VPERMW,
VPEXPANDD,
VPCOMPRESSD,
VPMOVSXBW,
VPMOVSXBD,
VPMOVSXBQ,
VPMOVSXWD,
VPMOVSXWQ,
VPMOVSXDQ,
VPMOVZXBW,
VPMOVZXBD,
VPMOVZXBQ,
VPMOVZXWD,
VPMOVZXWQ,
VPMOVZXDQ,
VPACKSSDW,
VPACKSSWB,
VPACKUSDW,
VPACKUSWB,
VPMOVWB,
VPMOVDW,
VPMOVQW,
VPMOVQD,
VPMOVDB,
VPMOVQB,
VPMOVSWB,
VPMOVSDW,
VPMOVSQD,
VPMOVSQW,
VPMOVSQB,
VPMOVSDB,
VPMOVUSWB,
VPMOVUSDW,
VPMOVUSQD,
VPMOVUSQW,
VPMOVUSQB,
VPMOVUSDB,
CALL64pcrel32,
CALL32pcrel32,
PUSH64r,
PUSH32r,
POP64r,
POP32r,
MOV64rr,
MOV32rr,
MOV16rr,
MOV8rr,
MOV32ri,
LEA64r,
LEA32r,
INC64r,
INC32r,
DEC64r,
DEC32r,
DIV64r,
DIV32r,
IDIV64r,
IDIV32r,
SHL64rCL,
SHL32rCL,
SHR64rCL,
SHR32rCL,
SAR64rCL,
SAR32rCL,
MOVDQA,
ENDBR32,
ENDBR64,
RDSSPD,
RDSSPQ,
INCSSPD,
INCSSPQ,
SAVEPREVSSP,
RSTORSSP,
SETSSBSY,
CLRSSBSY,
WRSSD,
WRSSQ,
WRUSSD,
WRUSSQ,
LOADIWKEY,
AESENC128KL,
AESDEC128KL,
AESENC256KL,
AESDEC256KL,
AESENCWIDE128KL,
AESDECWIDE128KL,
ENCODEKEY128,
ENCODEKEY256,
SENDUIP,
UIRET,
TESTUI,
CLUI,
STUI,
ERETS,
ERETU,
LKGS,
HRESET,
WBNOINVD,
TPAUSE,
UMONITOR,
UMWAIT,
GF2P8AFFINEINVQB,
GF2P8AFFINEQB,
GF2P8MULB,
PTWRITE,
RDMSR,
WRMSR,
}
impl X86Opcode {
pub fn as_u32(self) -> u32 {
self as u32
}
pub fn is_cmov(self) -> bool {
matches!(
self,
X86Opcode::CMOVO
| X86Opcode::CMOVNO
| X86Opcode::CMOVB
| X86Opcode::CMOVAE
| X86Opcode::CMOVE
| X86Opcode::CMOVNE
| X86Opcode::CMOVBE
| X86Opcode::CMOVA
| X86Opcode::CMOVS
| X86Opcode::CMOVNS
| X86Opcode::CMOVP
| X86Opcode::CMOVNP
| X86Opcode::CMOVL
| X86Opcode::CMOVGE
| X86Opcode::CMOVLE
| X86Opcode::CMOVG
)
}
pub fn is_jcc(self) -> bool {
matches!(
self,
X86Opcode::JO
| X86Opcode::JNO
| X86Opcode::JB
| X86Opcode::JAE
| X86Opcode::JE
| X86Opcode::JNE
| X86Opcode::JBE
| X86Opcode::JA
| X86Opcode::JS
| X86Opcode::JNS
| X86Opcode::JP
| X86Opcode::JNP
| X86Opcode::JL
| X86Opcode::JGE
| X86Opcode::JLE
| X86Opcode::JG
)
}
pub fn is_setcc(self) -> bool {
matches!(
self,
X86Opcode::SETO
| X86Opcode::SETNO
| X86Opcode::SETB
| X86Opcode::SETAE
| X86Opcode::SETE
| X86Opcode::SETNE
| X86Opcode::SETBE
| X86Opcode::SETA
| X86Opcode::SETS
| X86Opcode::SETNS
| X86Opcode::SETP
| X86Opcode::SETNP
| X86Opcode::SETL
| X86Opcode::SETGE
| X86Opcode::SETLE
| X86Opcode::SETG
)
}
pub fn is_x87_fp(self) -> bool {
matches!(
self,
X86Opcode::FLD
| X86Opcode::FST
| X86Opcode::FSTP
| X86Opcode::FILD
| X86Opcode::FIST
| X86Opcode::FISTP
| X86Opcode::FBLD
| X86Opcode::FBSTP
| X86Opcode::FXCH
| X86Opcode::FCOM
| X86Opcode::FCOMP
| X86Opcode::FCOMPP
| X86Opcode::FUCOM
| X86Opcode::FUCOMP
| X86Opcode::FUCOMPP
| X86Opcode::FTST
| X86Opcode::FXAM
| X86Opcode::FADD_ST0_ST
| X86Opcode::FADD_ST_ST0
| X86Opcode::FADDP
| X86Opcode::FSUB_ST0_ST
| X86Opcode::FSUB_ST_ST0
| X86Opcode::FSUBP
| X86Opcode::FSUBR_ST0_ST
| X86Opcode::FSUBR_ST_ST0
| X86Opcode::FSUBRP
| X86Opcode::FMUL_ST0_ST
| X86Opcode::FMUL_ST_ST0
| X86Opcode::FMULP
| X86Opcode::FDIV_ST0_ST
| X86Opcode::FDIV_ST_ST0
| X86Opcode::FDIVP
| X86Opcode::FDIVR_ST0_ST
| X86Opcode::FDIVR_ST_ST0
| X86Opcode::FDIVRP
| X86Opcode::FADD_MEM
| X86Opcode::FSUB_MEM
| X86Opcode::FSUBR_MEM
| X86Opcode::FMUL_MEM
| X86Opcode::FDIV_MEM
| X86Opcode::FDIVR_MEM
| X86Opcode::FCHS
| X86Opcode::FABS
| X86Opcode::FSQRT
| X86Opcode::FRNDINT
| X86Opcode::FSCALE
| X86Opcode::FPREM
| X86Opcode::FPREM1
| X86Opcode::FXTRACT
| X86Opcode::FSIN
| X86Opcode::FCOS
| X86Opcode::FSINCOS
| X86Opcode::FPTAN
| X86Opcode::FPATAN
| X86Opcode::F2XM1
| X86Opcode::FYL2X
| X86Opcode::FYL2XP1
| X86Opcode::FLDCW
| X86Opcode::FSTCW
| X86Opcode::FNSTCW
| X86Opcode::FLDENV
| X86Opcode::FSTENV
| X86Opcode::FNSTENV
| X86Opcode::FRSTOR
| X86Opcode::FSAVE
| X86Opcode::FNSAVE
| X86Opcode::FNCLEX
| X86Opcode::FINIT
| X86Opcode::FNINIT
| X86Opcode::FFREE
| X86Opcode::FDECSTP
| X86Opcode::FINCSTP
)
}
pub fn is_mmx(self) -> bool {
matches!(
self,
X86Opcode::MMX_MOVD
| X86Opcode::MMX_MOVQ
| X86Opcode::MMX_MOVD_TO_MEM
| X86Opcode::MMX_MOVQ_TO_MEM
| X86Opcode::MMX_PADDB
| X86Opcode::MMX_PADDW
| X86Opcode::MMX_PADDD
| X86Opcode::MMX_PADDQ
| X86Opcode::MMX_PADDSB
| X86Opcode::MMX_PADDSW
| X86Opcode::MMX_PADDUSB
| X86Opcode::MMX_PADDUSW
| X86Opcode::MMX_PSUBB
| X86Opcode::MMX_PSUBW
| X86Opcode::MMX_PSUBD
| X86Opcode::MMX_PSUBQ
| X86Opcode::MMX_PSUBSB
| X86Opcode::MMX_PSUBSW
| X86Opcode::MMX_PSUBUSB
| X86Opcode::MMX_PSUBUSW
| X86Opcode::MMX_PMULLW
| X86Opcode::MMX_PMULHW
| X86Opcode::MMX_PMULHUW
| X86Opcode::MMX_PMADDWD
| X86Opcode::MMX_PCMPEQB
| X86Opcode::MMX_PCMPEQW
| X86Opcode::MMX_PCMPEQD
| X86Opcode::MMX_PCMPGTB
| X86Opcode::MMX_PCMPGTW
| X86Opcode::MMX_PCMPGTD
| X86Opcode::MMX_PACKSSWB
| X86Opcode::MMX_PACKSSDW
| X86Opcode::MMX_PACKUSWB
| X86Opcode::MMX_PUNPCKLBW
| X86Opcode::MMX_PUNPCKHBW
| X86Opcode::MMX_PUNPCKLWD
| X86Opcode::MMX_PUNPCKHWD
| X86Opcode::MMX_PUNPCKLDQ
| X86Opcode::MMX_PUNPCKHDQ
| X86Opcode::MMX_PSLLW
| X86Opcode::MMX_PSLLD
| X86Opcode::MMX_PSLLQ
| X86Opcode::MMX_PSRLW
| X86Opcode::MMX_PSRLD
| X86Opcode::MMX_PSRLQ
| X86Opcode::MMX_PSRAW
| X86Opcode::MMX_PSRAD
| X86Opcode::MMX_PAND
| X86Opcode::MMX_PANDN
| X86Opcode::MMX_POR
| X86Opcode::MMX_PXOR
| X86Opcode::MMX_EMMS
)
}
pub fn is_3dnow(self) -> bool {
matches!(
self,
X86Opcode::AMD_PAVGUSB
| X86Opcode::AMD_PFADD
| X86Opcode::AMD_PFSUB
| X86Opcode::AMD_PFSUBR
| X86Opcode::AMD_PFMUL
| X86Opcode::AMD_PFACC
| X86Opcode::AMD_PFCMPGE
| X86Opcode::AMD_PFCMPGT
| X86Opcode::AMD_PFCMPEQ
| X86Opcode::AMD_PFMIN
| X86Opcode::AMD_PFMAX
| X86Opcode::AMD_PI2FD
| X86Opcode::AMD_PF2ID
| X86Opcode::AMD_PFNACC
| X86Opcode::AMD_PFPNACC
| X86Opcode::AMD_PSWAPD
| X86Opcode::AMD_PFRCP
| X86Opcode::AMD_PFRCPIT1
| X86Opcode::AMD_PFRCPIT2
| X86Opcode::AMD_PFRSQRT
| X86Opcode::AMD_PFRSQIT1
| X86Opcode::AMD_FEMMS
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum OperandType {
Reg8,
Reg16,
Reg32,
Reg64,
Reg,
Imm8,
Imm16,
Imm32,
Imm64,
Mem8,
Mem16,
Mem32,
Mem64,
Mem80,
Mem128,
Mem256,
Mem512,
XmmReg,
YmmReg,
ZmmReg,
VK,
SegReg,
CtrlReg,
DebugReg,
Label,
}
impl OperandType {
pub fn is_register(&self) -> bool {
matches!(
self,
OperandType::Reg8
| OperandType::Reg16
| OperandType::Reg32
| OperandType::Reg64
| OperandType::Reg
| OperandType::XmmReg
| OperandType::YmmReg
| OperandType::ZmmReg
| OperandType::VK
| OperandType::SegReg
| OperandType::CtrlReg
| OperandType::DebugReg
)
}
pub fn is_memory(&self) -> bool {
matches!(
self,
OperandType::Mem8
| OperandType::Mem16
| OperandType::Mem32
| OperandType::Mem64
| OperandType::Mem80
| OperandType::Mem128
| OperandType::Mem256
| OperandType::Mem512
)
}
pub fn is_immediate(&self) -> bool {
matches!(
self,
OperandType::Imm8 | OperandType::Imm16 | OperandType::Imm32 | OperandType::Imm64
)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum X86Operand {
Reg(u16),
Imm(i64),
Mem(X86MemOperand),
Label(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct X86MemOperand {
pub base: u16,
pub index: u16,
pub scale: u8,
pub displacement: i32,
pub segment: u16,
}
impl X86MemOperand {
pub fn base(base: u16) -> Self {
X86MemOperand {
base,
index: 0,
scale: 0,
displacement: 0,
segment: 0,
}
}
pub fn base_disp(base: u16, displacement: i32) -> Self {
X86MemOperand {
base,
index: 0,
scale: 0,
displacement,
segment: 0,
}
}
pub fn base_index_scale(base: u16, index: u16, scale: u8) -> Self {
X86MemOperand {
base,
index,
scale,
displacement: 0,
segment: 0,
}
}
pub fn full(base: u16, index: u16, scale: u8, displacement: i32) -> Self {
X86MemOperand {
base,
index,
scale,
displacement,
segment: 0,
}
}
pub fn is_rip_relative(&self) -> bool {
self.base == RIP_ID
}
}
const RIP_ID: u16 = 255;
#[derive(Debug, Clone, Copy)]
pub struct X86SchedInfo {
pub latency: u8,
pub throughput: f32,
pub micro_ops: u8,
pub port_usage: u8,
}
impl X86SchedInfo {
pub const fn new(latency: u8, throughput: f32, micro_ops: u8, port_usage: u8) -> Self {
X86SchedInfo {
latency,
throughput,
micro_ops,
port_usage,
}
}
pub const SIMPLE_ALU: X86SchedInfo = X86SchedInfo::new(1, 0.25, 1, 0xFF);
pub const LOAD: X86SchedInfo = X86SchedInfo::new(5, 0.5, 1, 0x0C);
pub const STORE: X86SchedInfo = X86SchedInfo::new(1, 1.0, 2, 0x1C);
pub const IMUL: X86SchedInfo = X86SchedInfo::new(3, 1.0, 1, 0x01);
pub const IDIV: X86SchedInfo = X86SchedInfo::new(26, 6.0, 36, 0x01);
}
#[derive(Debug, Clone)]
pub struct X86InstrDesc {
pub opcode: X86Opcode,
pub mnemonic: &'static str,
pub intel_mnemonic: &'static str,
pub num_operands: u8,
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_bitcast: 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,
pub operand_types: &'static [OperandType],
pub implicit_defs: &'static [u16],
pub implicit_uses: &'static [u16],
pub scheduling_info: Option<X86SchedInfo>,
}
#[derive(Debug, Clone)]
pub struct X86InstrInfo {
descriptors: HashMap<X86Opcode, X86InstrDesc>,
by_mnemonic: HashMap<String, X86Opcode>,
}
impl X86InstrInfo {
pub fn new() -> Self {
let mut info = X86InstrInfo {
descriptors: HashMap::new(),
by_mnemonic: HashMap::new(),
};
info.init_descriptors();
info
}
fn init_descriptors(&mut self) {
self.add(InstrBuilder::new(X86Opcode::NOP, "nop", "nop", 0).build());
self.add(
InstrBuilder::new(X86Opcode::NOP1, "nop", "nop", 1)
.operands(&[OperandType::Mem8])
.may_load()
.may_store()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::NOP2, "nopw", "nop", 1)
.operands(&[OperandType::Mem16])
.may_load()
.may_store()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::NOP3, "nopl", "nop", 1)
.operands(&[OperandType::Mem32])
.may_load()
.may_store()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::NOP4, "nopw", "nop", 1)
.operands(&[OperandType::Mem16])
.may_load()
.may_store()
.build(),
);
self.add(InstrBuilder::new(X86Opcode::NOP5, "nop", "nop", 0).build());
self.add(InstrBuilder::new(X86Opcode::NOP6, "nop", "nop", 0).build());
self.add(InstrBuilder::new(X86Opcode::NOP7, "nop", "nop", 0).build());
self.add(InstrBuilder::new(X86Opcode::NOP8, "nop", "nop", 0).build());
self.add(InstrBuilder::new(X86Opcode::NOP9, "nop", "nop", 0).build());
self.add(
InstrBuilder::new(X86Opcode::MOV, "movq", "mov", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_move_immediate()
.is_commutative()
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVSX, "movsx", "movsx", 2)
.operands(&[OperandType::Reg64, OperandType::Reg32])
.is_move_immediate()
.is_convert()
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVZX, "movzx", "movzx", 2)
.operands(&[OperandType::Reg64, OperandType::Reg32])
.is_move_immediate()
.is_convert()
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVABS, "movabsq", "mov", 2)
.operands(&[OperandType::Reg64, OperandType::Imm64])
.is_move_immediate()
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LEA, "leaq", "lea", 2)
.operands(&[OperandType::Reg64, OperandType::Mem64])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XCHG, "xchgq", "xchg", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.may_load()
.may_store()
.is_commutative()
.sched(X86SchedInfo::new(2, 1.0, 2, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PUSH, "pushq", "push", 1)
.operands(&[OperandType::Reg64])
.has_side_effects()
.may_store()
.has_side_effects()
.implicit_defs(&[RSP_CONST])
.implicit_uses(&[RSP_CONST])
.sched(X86SchedInfo::STORE)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::POP, "popq", "pop", 1)
.operands(&[OperandType::Reg64])
.has_side_effects()
.may_load()
.implicit_defs(&[RSP_CONST])
.implicit_uses(&[RSP_CONST])
.sched(X86SchedInfo::LOAD)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PUSHF, "pushfq", "pushf", 0)
.has_side_effects()
.may_store()
.implicit_defs(&[RSP_CONST])
.implicit_uses(&[RSP_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::POPF, "popfq", "popf", 0)
.has_side_effects()
.may_load()
.implicit_defs(&[RSP_CONST])
.implicit_uses(&[RSP_CONST])
.build(),
);
self.add_cmov(X86Opcode::CMOVO, "cmovoq");
self.add_cmov(X86Opcode::CMOVNO, "cmovnoq");
self.add_cmov(X86Opcode::CMOVB, "cmovbq");
self.add_cmov(X86Opcode::CMOVAE, "cmovaeq");
self.add_cmov(X86Opcode::CMOVE, "cmoveq");
self.add_cmov(X86Opcode::CMOVNE, "cmovneq");
self.add_cmov(X86Opcode::CMOVBE, "cmovbeq");
self.add_cmov(X86Opcode::CMOVA, "cmovaq");
self.add_cmov(X86Opcode::CMOVS, "cmovsq");
self.add_cmov(X86Opcode::CMOVNS, "cmovnsq");
self.add_cmov(X86Opcode::CMOVP, "cmovpq");
self.add_cmov(X86Opcode::CMOVNP, "cmovnpq");
self.add_cmov(X86Opcode::CMOVL, "cmovlq");
self.add_cmov(X86Opcode::CMOVGE, "cmovgeq");
self.add_cmov(X86Opcode::CMOVLE, "cmovleq");
self.add_cmov(X86Opcode::CMOVG, "cmovgq");
self.add(
InstrBuilder::new(X86Opcode::ADD, "addq", "add", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_commutative()
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ADC, "adcq", "adc", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_commutative()
.implicit_uses(&[FLAGS_CONST])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SUB, "subq", "sub", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SBB, "sbbq", "sbb", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_uses(&[FLAGS_CONST])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MUL, "mulq", "mul", 1)
.operands(&[OperandType::Reg64])
.implicit_uses(&[RAX_CONST])
.implicit_defs(&[RAX_CONST, RDX_CONST, FLAGS_CONST])
.sched(X86SchedInfo::IMUL)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::IMUL, "imulq", "imul", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_commutative()
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::IMUL)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::DIV, "divq", "div", 1)
.operands(&[OperandType::Reg64])
.implicit_uses(&[RAX_CONST, RDX_CONST])
.implicit_defs(&[RAX_CONST, RDX_CONST, FLAGS_CONST])
.sched(X86SchedInfo::IDIV)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::IDIV, "idivq", "idiv", 1)
.operands(&[OperandType::Reg64])
.implicit_uses(&[RAX_CONST, RDX_CONST])
.implicit_defs(&[RAX_CONST, RDX_CONST, FLAGS_CONST])
.sched(X86SchedInfo::IDIV)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::INC, "incq", "inc", 1)
.operands(&[OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::DEC, "decq", "dec", 1)
.operands(&[OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::NEG, "negq", "neg", 1)
.operands(&[OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::AND, "andq", "and", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_commutative()
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::OR, "orq", "or", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_commutative()
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XOR, "xorq", "xor", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_commutative()
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::NOT, "notq", "not", 1)
.operands(&[OperandType::Reg64])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::TEST, "testq", "test", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_commutative()
.is_compare()
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHL, "shlq", "shl", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHR, "shrq", "shr", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SAR, "sarq", "sar", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ROL, "rolq", "rol", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ROR, "rorq", "ror", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RCL, "rclq", "rcl", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_uses(&[FLAGS_CONST])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(3, 2.0, 7, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RCR, "rcrq", "rcr", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_uses(&[FLAGS_CONST])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(3, 2.0, 7, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHLD, "shldq", "shld", 3)
.operands(&[OperandType::Reg64, OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(3, 2.0, 4, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHRD, "shrdq", "shrd", 3)
.operands(&[OperandType::Reg64, OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(3, 2.0, 4, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::JMP, "jmp", "jmp", 1)
.operands(&[OperandType::Label])
.is_terminator()
.is_branch()
.build(),
);
self.add_jcc(X86Opcode::JO, "jo");
self.add_jcc(X86Opcode::JNO, "jno");
self.add_jcc(X86Opcode::JB, "jb");
self.add_jcc(X86Opcode::JAE, "jae");
self.add_jcc(X86Opcode::JE, "je");
self.add_jcc(X86Opcode::JNE, "jne");
self.add_jcc(X86Opcode::JBE, "jbe");
self.add_jcc(X86Opcode::JA, "ja");
self.add_jcc(X86Opcode::JS, "js");
self.add_jcc(X86Opcode::JNS, "jns");
self.add_jcc(X86Opcode::JP, "jp");
self.add_jcc(X86Opcode::JNP, "jnp");
self.add_jcc(X86Opcode::JL, "jl");
self.add_jcc(X86Opcode::JGE, "jge");
self.add_jcc(X86Opcode::JLE, "jle");
self.add_jcc(X86Opcode::JG, "jg");
self.add(
InstrBuilder::new(X86Opcode::CALL, "callq", "call", 1)
.operands(&[OperandType::Label])
.is_terminator()
.is_call()
.has_side_effects()
.may_store()
.implicit_defs(&[RSP_CONST])
.implicit_uses(&[RSP_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RET, "retq", "ret", 0)
.is_terminator()
.is_return()
.has_side_effects()
.implicit_uses(&[RSP_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LOOP, "loop", "loop", 1)
.operands(&[OperandType::Label])
.is_terminator()
.is_branch()
.implicit_uses(&[RCX_CONST])
.implicit_defs(&[RCX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LOOPE, "loope", "loope", 1)
.operands(&[OperandType::Label])
.is_terminator()
.is_branch()
.implicit_uses(&[RCX_CONST, FLAGS_CONST])
.implicit_defs(&[RCX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LOOPNE, "loopne", "loopne", 1)
.operands(&[OperandType::Label])
.is_terminator()
.is_branch()
.implicit_uses(&[RCX_CONST, FLAGS_CONST])
.implicit_defs(&[RCX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::INT, "int", "int", 1)
.operands(&[OperandType::Imm8])
.is_terminator()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::INT3, "int3", "int3", 0)
.is_terminator()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::UD2, "ud2", "ud2", 0)
.is_terminator()
.has_side_effects()
.build(),
);
self.add_setcc(X86Opcode::SETO, "seto");
self.add_setcc(X86Opcode::SETNO, "setno");
self.add_setcc(X86Opcode::SETB, "setb");
self.add_setcc(X86Opcode::SETAE, "setae");
self.add_setcc(X86Opcode::SETE, "sete");
self.add_setcc(X86Opcode::SETNE, "setne");
self.add_setcc(X86Opcode::SETBE, "setbe");
self.add_setcc(X86Opcode::SETA, "seta");
self.add_setcc(X86Opcode::SETS, "sets");
self.add_setcc(X86Opcode::SETNS, "setns");
self.add_setcc(X86Opcode::SETP, "setp");
self.add_setcc(X86Opcode::SETNP, "setnp");
self.add_setcc(X86Opcode::SETL, "setl");
self.add_setcc(X86Opcode::SETGE, "setge");
self.add_setcc(X86Opcode::SETLE, "setle");
self.add_setcc(X86Opcode::SETG, "setg");
self.add(
InstrBuilder::new(X86Opcode::CMP, "cmpq", "cmp", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_compare()
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add_string_op(X86Opcode::MOVSB, "movsb", true, false);
self.add_string_op(X86Opcode::MOVSW, "movsw", true, false);
self.add_string_op(X86Opcode::MOVSD_STR, "movsd", true, false);
self.add_string_op(X86Opcode::MOVSQ, "movsq", true, false);
self.add_string_op(X86Opcode::CMPSB, "cmpsb", false, true);
self.add_string_op(X86Opcode::CMPSW, "cmpsw", false, true);
self.add_string_op(X86Opcode::CMPSD_STR, "cmpsd", false, true);
self.add_string_op(X86Opcode::CMPSQ, "cmpsq", false, true);
self.add_string_op(X86Opcode::STOSB, "stosb", true, false);
self.add_string_op(X86Opcode::STOSW, "stosw", true, false);
self.add_string_op(X86Opcode::STOSD_STR, "stosd", true, false);
self.add_string_op(X86Opcode::STOSQ, "stosq", true, false);
self.add_string_op(X86Opcode::LODSB, "lodsb", false, true);
self.add_string_op(X86Opcode::LODSW, "lodsw", false, true);
self.add_string_op(X86Opcode::LODSD_STR, "lodsd", false, true);
self.add_string_op(X86Opcode::LODSQ, "lodsq", false, true);
self.add_string_op(X86Opcode::SCASB, "scasb", false, true);
self.add_string_op(X86Opcode::SCASW, "scasw", false, true);
self.add_string_op(X86Opcode::SCASD_STR, "scasd", false, true);
self.add_string_op(X86Opcode::SCASQ, "scasq", false, true);
self.add(
InstrBuilder::new(X86Opcode::REP, "rep", "rep", 0)
.has_side_effects()
.implicit_uses(&[RCX_CONST])
.implicit_defs(&[RCX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::REPE, "repe", "repe", 0)
.has_side_effects()
.implicit_uses(&[RCX_CONST, FLAGS_CONST])
.implicit_defs(&[RCX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::REPNE, "repne", "repne", 0)
.has_side_effects()
.implicit_uses(&[RCX_CONST, FLAGS_CONST])
.implicit_defs(&[RCX_CONST])
.build(),
);
self.add_sse_binop(X86Opcode::MOVSS, "movss", false);
self.add_sse_binop(X86Opcode::MOVSD, "movsd", false);
self.add_sse_binop(X86Opcode::ADDSS, "addss", true);
self.add_sse_binop(X86Opcode::ADDSD, "addsd", true);
self.add_sse_binop(X86Opcode::SUBSS, "subss", false);
self.add_sse_binop(X86Opcode::SUBSD, "subsd", false);
self.add_sse_binop(X86Opcode::MULSS, "mulss", true);
self.add_sse_binop(X86Opcode::MULSD, "mulsd", true);
self.add_sse_binop(X86Opcode::DIVSS, "divss", false);
self.add_sse_binop(X86Opcode::DIVSD, "divsd", false);
self.add_sse_unop(X86Opcode::SQRTSS, "sqrtss");
self.add_sse_unop(X86Opcode::SQRTSD, "sqrtsd");
self.add_sse_binop(X86Opcode::MINSS, "minss", true);
self.add_sse_binop(X86Opcode::MINSD, "minsd", true);
self.add_sse_binop(X86Opcode::MAXSS, "maxss", true);
self.add_sse_binop(X86Opcode::MAXSD, "maxsd", true);
self.add(
InstrBuilder::new(X86Opcode::CMPSS, "cmpss", "cmpss", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.is_compare()
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CMPSD, "cmpsd", "cmpsd", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.is_compare()
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CVTSI2SS, "cvtsi2ss", "cvtsi2ss", 2)
.operands(&[OperandType::XmmReg, OperandType::Reg32])
.is_convert()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CVTSI2SD, "cvtsi2sd", "cvtsi2sd", 2)
.operands(&[OperandType::XmmReg, OperandType::Reg32])
.is_convert()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CVTSS2SI, "cvtss2si", "cvtss2si", 2)
.operands(&[OperandType::Reg32, OperandType::XmmReg])
.is_convert()
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CVTSD2SI, "cvtsd2si", "cvtsd2si", 2)
.operands(&[OperandType::Reg32, OperandType::XmmReg])
.is_convert()
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CVTTSS2SI, "cvttss2si", "cvttss2si", 2)
.operands(&[OperandType::Reg32, OperandType::XmmReg])
.is_convert()
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CVTTSD2SI, "cvttsd2si", "cvttsd2si", 2)
.operands(&[OperandType::Reg32, OperandType::XmmReg])
.is_convert()
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ANDPS, "andps", "andps", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.33, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ANDNPS, "andnps", "andnps", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.33, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ORPS, "orps", "orps", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.33, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XORPS, "xorps", "xorps", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.33, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ADDSUBPS, "addsubps", "addsubps", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ADDSUBPD, "addsubpd", "addsubpd", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::HADDPS, "haddps", "haddps", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(5, 2.0, 2, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::HADDPD, "haddpd", "haddpd", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(5, 2.0, 2, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::HSUBPS, "hsubps", "hsubps", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(5, 2.0, 2, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::HSUBPD, "hsubpd", "hsubpd", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(5, 2.0, 2, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVSLDUP, "movsldup", "movsldup", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x0C))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVSHDUP, "movshdup", "movshdup", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x0C))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVDDUP, "movddup", "movddup", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x0C))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PHADDW, "phaddw", "phaddw", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PHADDD, "phaddd", "phaddd", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PHADDSW, "phaddsw", "phaddsw", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMADDUBSW, "pmaddubsw", "pmaddubsw", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(5, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PHSUBW, "phsubw", "phsubw", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PHSUBD, "phsubd", "phsubd", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PHSUBSW, "phsubsw", "phsubsw", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PSIGNB, "psignb", "psignb", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PSIGNW, "psignw", "psignw", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PSIGND, "psignd", "psignd", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PABSB, "pabsb", "pabsb", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PABSW, "pabsw", "pabsw", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PABSD, "pabsd", "pabsd", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BLENDPS, "blendps", "blendps", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BLENDPD, "blendpd", "blendpd", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BLENDVPS, "blendvps", "blendvps", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.implicit_uses(&[XMM0_CONST])
.sched(X86SchedInfo::new(2, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BLENDVPD, "blendvpd", "blendvpd", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.implicit_uses(&[XMM0_CONST])
.sched(X86SchedInfo::new(2, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::DPPS, "dpps", "dpps", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(9, 2.0, 2, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::DPPD, "dppd", "dppd", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(9, 2.0, 2, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::EXTRACTPS, "extractps", "extractps", 3)
.operands(&[OperandType::Reg32, OperandType::XmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::INSERTPS, "insertps", "insertps", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(1, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMULLD, "pmulld", "pmulld", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(5, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMULDQ, "pmuldq", "pmuldq", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(5, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMINSB, "pminsb", "pminsb", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMINSD, "pminsd", "pminsd", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMINUW, "pminuw", "pminuw", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMINUD, "pminud", "pminud", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMAXSB, "pmaxsb", "pmaxsb", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMAXSD, "pmaxsd", "pmaxsd", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMAXUW, "pmaxuw", "pmaxuw", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PMAXUD, "pmaxud", "pmaxud", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PACKUSDW, "packusdw", "packusdw", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PCMPEQQ, "pcmpeqq", "pcmpeqq", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CRC32, "crc32q", "crc32", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add_avx_binop(X86Opcode::VADDPS, "vaddps", true);
self.add_avx_binop(X86Opcode::VADDPD, "vaddpd", true);
self.add_avx_binop(X86Opcode::VADDSS, "vaddss", true);
self.add_avx_binop(X86Opcode::VADDSD, "vaddsd", true);
self.add_avx_binop(X86Opcode::VSUBPS, "vsubps", false);
self.add_avx_binop(X86Opcode::VSUBPD, "vsubpd", false);
self.add_avx_binop(X86Opcode::VMULPS, "vmulps", true);
self.add_avx_binop(X86Opcode::VMULPD, "vmulpd", true);
self.add_avx_binop(X86Opcode::VDIVPS, "vdivps", false);
self.add_avx_binop(X86Opcode::VDIVPD, "vdivpd", false);
self.add_avx_binop(X86Opcode::VANDPS, "vandps", true);
self.add_avx_binop(X86Opcode::VANDNPS, "vandnps", false);
self.add_avx_binop(X86Opcode::VORPS, "vorps", true);
self.add_avx_binop(X86Opcode::VXORPS, "vxorps", true);
self.add(
InstrBuilder::new(X86Opcode::VBROADCASTSS, "vbroadcastss", "vbroadcastss", 2)
.operands(&[OperandType::YmmReg, OperandType::XmmReg])
.may_load()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VBROADCASTSD, "vbroadcastsd", "vbroadcastsd", 2)
.operands(&[OperandType::YmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPERMILPS, "vpermilps", "vpermilps", 3)
.operands(&[OperandType::YmmReg, OperandType::YmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPERM2F128, "vperm2f128", "vperm2f128", 3)
.operands(&[
OperandType::YmmReg,
OperandType::YmmReg,
OperandType::YmmReg,
OperandType::Imm8,
])
.num_operands(4)
.sched(X86SchedInfo::new(3, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VZEROALL, "vzeroall", "vzeroall", 0)
.has_side_effects()
.implicit_defs(&[
YMM0_CONST,
YMM1_CONST,
YMM2_CONST,
YMM3_CONST,
YMM4_CONST,
YMM5_CONST,
YMM6_CONST,
YMM7_CONST,
YMM8_CONST,
YMM9_CONST,
YMM10_CONST,
YMM11_CONST,
YMM12_CONST,
YMM13_CONST,
YMM14_CONST,
YMM15_CONST,
])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VZEROUPPER, "vzeroupper", "vzeroupper", 0)
.has_side_effects()
.implicit_defs(&[
YMM0_CONST,
YMM1_CONST,
YMM2_CONST,
YMM3_CONST,
YMM4_CONST,
YMM5_CONST,
YMM6_CONST,
YMM7_CONST,
YMM8_CONST,
YMM9_CONST,
YMM10_CONST,
YMM11_CONST,
YMM12_CONST,
YMM13_CONST,
YMM14_CONST,
YMM15_CONST,
])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPBROADCASTB, "vpbroadcastb", "vpbroadcastb", 2)
.operands(&[OperandType::YmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPBROADCASTW, "vpbroadcastw", "vpbroadcastw", 2)
.operands(&[OperandType::YmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPBROADCASTD, "vpbroadcastd", "vpbroadcastd", 2)
.operands(&[OperandType::YmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPBROADCASTQ, "vpbroadcastq", "vpbroadcastq", 2)
.operands(&[OperandType::YmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPERMQ, "vpermq", "vpermq", 3)
.operands(&[OperandType::YmmReg, OperandType::YmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPERMPD, "vpermpd", "vpermpd", 3)
.operands(&[OperandType::YmmReg, OperandType::YmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPGATHERDD, "vpgatherdd", "vpgatherdd", 2)
.operands(&[OperandType::XmmReg, OperandType::Mem32])
.may_load()
.has_side_effects()
.sched(X86SchedInfo::new(5, 4.0, 4, 0x0C))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPGATHERDQ, "vpgatherdq", "vpgatherdq", 2)
.operands(&[OperandType::XmmReg, OperandType::Mem64])
.may_load()
.has_side_effects()
.sched(X86SchedInfo::new(5, 2.0, 2, 0x0C))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPGATHERQD, "vpgatherqd", "vpgatherqd", 2)
.operands(&[OperandType::XmmReg, OperandType::Mem32])
.may_load()
.has_side_effects()
.sched(X86SchedInfo::new(7, 4.0, 6, 0x0C))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPGATHERQQ, "vpgatherqq", "vpgatherqq", 2)
.operands(&[OperandType::YmmReg, OperandType::Mem64])
.may_load()
.has_side_effects()
.sched(X86SchedInfo::new(5, 2.0, 2, 0x0C))
.build(),
);
self.add_fma3(X86Opcode::VFMADD132PD, "vfmadd132pd");
self.add_fma3(X86Opcode::VFMADD213PD, "vfmadd213pd");
self.add_fma3(X86Opcode::VFMADD231PD, "vfmadd231pd");
self.add_fma3(X86Opcode::VFMSUB132PD, "vfmsub132pd");
self.add_fma3(X86Opcode::VFMSUB213PD, "vfmsub213pd");
self.add_fma3(X86Opcode::VFMSUB231PD, "vfmsub231pd");
self.add_fma3(X86Opcode::VFNMADD132PD, "vfnmadd132pd");
self.add_fma3(X86Opcode::VFNMADD213PD, "vfnmadd213pd");
self.add_fma3(X86Opcode::VFNMADD231PD, "vfnmadd231pd");
self.add_fma3(X86Opcode::VFNMSUB132PD, "vfnmsub132pd");
self.add_fma3(X86Opcode::VFNMSUB213PD, "vfnmsub213pd");
self.add_fma3(X86Opcode::VFNMSUB231PD, "vfnmsub231pd");
self.add_fma3(X86Opcode::VFMADD132PS, "vfmadd132ps");
self.add_fma3(X86Opcode::VFMADD213PS, "vfmadd213ps");
self.add_fma3(X86Opcode::VFMADD231PS, "vfmadd231ps");
self.add_fma3(X86Opcode::VFMADD132SS, "vfmadd132ss");
self.add_fma3(X86Opcode::VFMADD213SS, "vfmadd213ss");
self.add_fma3(X86Opcode::VFMADD231SS, "vfmadd231ss");
self.add_fma3(X86Opcode::VFMADD132SD, "vfmadd132sd");
self.add_fma3(X86Opcode::VFMADD213SD, "vfmadd213sd");
self.add_fma3(X86Opcode::VFMADD231SD, "vfmadd231sd");
self.add(
InstrBuilder::new(X86Opcode::ANDN, "andnq", "andn", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BEXTR, "bextrq", "bextr", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::new(2, 1.0, 2, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BLSI, "blsiq", "blsi", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BLSMSK, "blsmskq", "blsmsk", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BLSR, "blsrq", "blsr", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BZHI, "bzhiq", "bzhi", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MULX, "mulxq", "mulx", 3)
.operands(&[OperandType::Reg64, OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PDEP, "pdepq", "pdep", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PEXT, "pextq", "pext", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RORX, "rorxq", "rorx", 3)
.operands(&[OperandType::Reg64, OperandType::Reg64, OperandType::Imm8])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SARX, "sarxq", "sarx", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHLX, "shlxq", "shlx", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHRX, "shrxq", "shrx", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::TZCNT, "tzcntq", "tzcnt", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LZCNT, "lzcntq", "lzcnt", 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.implicit_defs(&[FLAGS_CONST])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SYSCALL, "syscall", "syscall", 0)
.is_terminator()
.has_side_effects()
.implicit_uses(&[
RAX_CONST, RDI_CONST, RSI_CONST, RDX_CONST, R10_CONST, R8_CONST, R9_CONST,
])
.implicit_defs(&[RAX_CONST, RCX_CONST, R11_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SYSRET, "sysretq", "sysret", 0)
.is_terminator()
.has_side_effects()
.implicit_uses(&[RAX_CONST, RCX_CONST, R11_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SYSENTER, "sysenter", "sysenter", 0)
.is_terminator()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SYSEXIT, "sysexit", "sysexit", 0)
.is_terminator()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BNDMK, "bndmk", "bndmk", 2)
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BNDCL, "bndcl", "bndcl", 2)
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BNDCU, "bndcu", "bndcu", 2)
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BNDCN, "bndcn", "bndcn", 2)
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BNDMOV, "bndmov", "bndmov", 2)
.may_load()
.may_store()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BNDLDX, "bndldx", "bndldx", 2)
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::BNDSTX, "bndstx", "bndstx", 2)
.may_store()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CLAC, "clac", "clac", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::STAC, "stac", "stac", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ENCLS, "encls", "encls", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ENCLU, "enclu", "enclu", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ENCLV, "enclv", "enclv", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::GETSEC, "getsec", "getsec", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::INVEPT, "invept", "invept", 2)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::INVVPID, "invvpid", "invvpid", 2)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::INVPCID, "invpcid", "invpcid", 2)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMFUNC, "vmfunc", "vmfunc", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMCALL, "vmcall", "vmcall", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMLAUNCH, "vmlaunch", "vmlaunch", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMRESUME, "vmresume", "vmresume", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMXOFF, "vmxoff", "vmxoff", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMXON, "vmxon", "vmxon", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMCLEAR, "vmclear", "vmclear", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMPTRLD, "vmptrld", "vmptrld", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMPTRST, "vmptrst", "vmptrst", 1)
.has_side_effects()
.may_store()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMREAD, "vmread", "vmread", 2)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VMWRITE, "vmwrite", "vmwrite", 2)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MONITOR, "monitor", "monitor", 3)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MWAIT, "mwait", "mwait", 2)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MWAITX, "mwaitx", "mwaitx", 3)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MONITORX, "monitorx", "monitorx", 3)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDPID, "rdpid", "rdpid", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDRAND, "rdrand", "rdrand", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDSEED, "rdseed", "rdseed", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDTSC, "rdtsc", "rdtsc", 0)
.has_side_effects()
.implicit_defs(&[RAX_CONST, RDX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDTSCP, "rdtscp", "rdtscp", 0)
.has_side_effects()
.implicit_defs(&[RAX_CONST, RDX_CONST, RCX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDPMC, "rdpmc", "rdpmc", 0)
.has_side_effects()
.implicit_defs(&[RAX_CONST, RDX_CONST])
.implicit_uses(&[RCX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SWAPGS, "swapgs", "swapgs", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::UD0, "ud0", "ud0", 2)
.has_side_effects()
.is_terminator()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::UD1, "ud1", "ud1", 2)
.has_side_effects()
.is_terminator()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VERR, "verr", "verr", 1)
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VERW, "verw", "verw", 1)
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LAR, "lar", "lar", 2)
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LSL, "lsl", "lsl", 2)
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SGDT, "sgdt", "sgdt", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SIDT, "sidt", "sidt", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SLDT, "sldt", "sldt", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::STR, "str", "str", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LGDT, "lgdt", "lgdt", 1)
.may_load()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LIDT, "lidt", "lidt", 1)
.may_load()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LLDT, "lldt", "lldt", 1)
.may_load()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LTR, "ltr", "ltr", 1)
.may_load()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XABORT, "xabort", "xabort", 1)
.is_terminator()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XBEGIN, "xbegin", "xbegin", 1)
.is_branch()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XEND, "xend", "xend", 0)
.is_terminator()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XTEST, "xtest", "xtest", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XGETBV, "xgetbv", "xgetbv", 0)
.has_side_effects()
.implicit_uses(&[RCX_CONST])
.implicit_defs(&[RAX_CONST, RDX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XSETBV, "xsetbv", "xsetbv", 0)
.has_side_effects()
.implicit_uses(&[RCX_CONST, RAX_CONST, RDX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XRSTOR, "xrstor", "xrstor", 1)
.may_load()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XRSTORS, "xrstors", "xrstors", 1)
.may_load()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XSAVE, "xsave", "xsave", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XSAVEC, "xsavec", "xsavec", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XSAVEOPT, "xsaveopt", "xsaveopt", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XSAVES, "xsaves", "xsaves", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XRSTORS64, "xrstors64", "xrstors64", 1)
.may_load()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XSAVE64, "xsave64", "xsave64", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XSAVEC64, "xsavec64", "xsavec64", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XSAVEOPT64, "xsaveopt64", "xsaveopt64", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XSAVES64, "xsaves64", "xsaves64", 1)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDPRU, "rdpru", "rdpru", 0)
.has_side_effects()
.implicit_defs(&[RAX_CONST, RDX_CONST])
.implicit_uses(&[RCX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDFSBASE, "rdfsbase", "rdfsbase", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDGSBASE, "rdgsbase", "rdgsbase", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::WRFSBASE, "wrfsbase", "wrfsbase", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::WRGSBASE, "wrgsbase", "wrgsbase", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CLFLUSH, "clflush", "clflush", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CLFLUSHOPT, "clflushopt", "clflushopt", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CLWB, "clwb", "clwb", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CLDEMOTE, "cldemote", "cldemote", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::LFENCE, "lfence", "lfence", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MFENCE, "mfence", "mfence", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SFENCE, "sfence", "sfence", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PAUSE, "pause", "pause", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PREFETCHT0, "prefetcht0", "prefetcht0", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PREFETCHT1, "prefetcht1", "prefetcht1", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PREFETCHT2, "prefetcht2", "prefetcht2", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PREFETCHNTA, "prefetchnta", "prefetchnta", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PREFETCHW, "prefetchw", "prefetchw", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PREFETCHWT1, "prefetchwt1", "prefetchwt1", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVNTI, "movnti", "movnti", 2)
.may_store()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVNTDQ, "movntdq", "movntdq", 2)
.may_store()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVNTDQA, "movntdqa", "movntdqa", 2)
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVNTPD, "movntpd", "movntpd", 2)
.may_store()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVNTPS, "movntps", "movntps", 2)
.may_store()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDPKRU, "rdpkru", "rdpkru", 0)
.has_side_effects()
.implicit_uses(&[RCX_CONST])
.implicit_defs(&[RAX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::WRPKRU, "wrpkru", "wrpkru", 0)
.has_side_effects()
.implicit_uses(&[RAX_CONST, RCX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PCOMMIT, "pcommit", "pcommit", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::AESENC, "aesenc", "aesenc", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::AESENCLAST, "aesenclast", "aesenclast", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::AESDEC, "aesdec", "aesdec", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::AESDECLAST, "aesdeclast", "aesdeclast", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::AESIMC, "aesimc", "aesimc", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(
X86Opcode::AESKEYGENASSIST,
"aeskeygenassist",
"aeskeygenassist",
3,
)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(6, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PCLMULQDQ, "pclmulqdq", "pclmulqdq", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(5, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHA1RNDS4, "sha1rnds4", "sha1rnds4", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.sched(X86SchedInfo::new(5, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHA1NEXTE, "sha1nexte", "sha1nexte", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(2, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHA1MSG1, "sha1msg1", "sha1msg1", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(2, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHA1MSG2, "sha1msg2", "sha1msg2", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(2, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHA256RNDS2, "sha256rnds2", "sha256rnds2", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.implicit_uses(&[XMM0_CONST])
.sched(X86SchedInfo::new(5, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHA256MSG1, "sha256msg1", "sha256msg1", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(2, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SHA256MSG2, "sha256msg2", "sha256msg2", 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(2, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDRAND16, "rdrandw", "rdrandw", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDRAND32, "rdrandl", "rdrandl", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDRAND64, "rdrandq", "rdrandq", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDSEED16, "rdseedw", "rdseedw", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDSEED32, "rdseedl", "rdseedl", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDSEED64, "rdseedq", "rdseedq", 1)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PREFETCHIT0, "prefetchit0", "prefetchit0", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::PREFETCHIT1, "prefetchit1", "prefetchit1", 1)
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::WRMSRNS, "wrmsrns", "wrmsrns", 0)
.has_side_effects()
.implicit_uses(&[RCX_CONST, RAX_CONST, RDX_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::RDMSRLIST, "rdmsrlist", "rdmsrlist", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::WRMSRLIST, "wrmsrlist", "wrmsrlist", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVDIRI, "movdiri", "movdiri", 2)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MOVDIR64B, "movdir64b", "movdir64b", 2)
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ENQCMD, "enqcmd", "enqcmd", 2)
.may_load()
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::ENQCMDS, "enqcmds", "enqcmds", 2)
.may_load()
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::SERIALIZE, "serialize", "serialize", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XSUSLDTRK, "xsusldtrk", "xsusldtrk", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::XRESLDTRK, "xresldtrk", "xresldtrk", 0)
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::CMPCCXADD, "cmpccxadd", "cmpccxadd", 3)
.may_load()
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::AADD, "aadd", "aadd", 2)
.may_load()
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::AAND, "aand", "aand", 2)
.may_load()
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::AOR, "aor", "aor", 2)
.may_load()
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::AXOR, "axor", "axor", 2)
.may_load()
.may_store()
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(
X86Opcode::VGF2P8AFFINEQB,
"vgf2p8affineqb",
"vgf2p8affineqb",
3,
)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(5, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(
X86Opcode::VGF2P8AFFINEINVQB,
"vgf2p8affineinvqb",
"vgf2p8affineinvqb",
3,
)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(5, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VGF2P8MULB, "vgf2p8mulb", "vgf2p8mulb", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(3, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VAESENC, "vaesenc", "vaesenc", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VAESENCLAST, "vaesenclast", "vaesenclast", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VAESDEC, "vaesdec", "vaesdec", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VAESDECLAST, "vaesdeclast", "vaesdeclast", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPCLMULQDQ, "vpclmulqdq", "vpclmulqdq", 4)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::Imm8,
])
.is_three_address()
.sched(X86SchedInfo::new(5, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPDPBUSD, "vpdpbusd", "vpdpbusd", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPDPBUSDS, "vpdpbusds", "vpdpbusds", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPDPWSSD, "vpdpwssd", "vpdpwssd", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPDPWSSDS, "vpdpwssds", "vpdpwssds", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 0.5, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPMADD52LUQ, "vpmadd52luq", "vpmadd52luq", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VPMADD52HUQ, "vpmadd52huq", "vpmadd52huq", 3)
.operands(&[
OperandType::XmmReg,
OperandType::XmmReg,
OperandType::XmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(
X86Opcode::VBCSTNEBF162PS,
"vbcstnebf162ps",
"vbcstnebf162ps",
2,
)
.is_convert()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VBCSTNESH2PS, "vbcstnesh2ps", "vbcstnesh2ps", 2)
.is_convert()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VCVTNEEPH2PS, "vcvtneeph2ps", "vcvtneeph2ps", 2)
.is_convert()
.sched(X86SchedInfo::new(4, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VCVTPH2PS, "vcvtph2ps", "vcvtph2ps", 2)
.is_convert()
.sched(X86SchedInfo::new(3, 1.0, 1, 0x03))
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::VCVTPS2PH, "vcvtps2ph", "vcvtps2ph", 3)
.operands(&[OperandType::XmmReg, OperandType::XmmReg, OperandType::Imm8])
.is_convert()
.sched(X86SchedInfo::new(3, 1.0, 1, 0x03))
.build(),
);
self.add_x87(X86Opcode::FLD, "fld", 1, &[OperandType::Mem32], true, false);
self.add_x87_mem(X86Opcode::FST, "fst", 1, false, true);
self.add_x87_mem(X86Opcode::FSTP, "fstp", 1, false, true);
self.add_x87(
X86Opcode::FILD,
"fild",
1,
&[OperandType::Mem32],
true,
false,
);
self.add_x87(
X86Opcode::FIST,
"fist",
1,
&[OperandType::Mem32],
false,
true,
);
self.add_x87(
X86Opcode::FISTP,
"fistp",
1,
&[OperandType::Mem64],
false,
true,
);
self.add_x87(
X86Opcode::FBLD,
"fbld",
1,
&[OperandType::Mem80],
true,
false,
);
self.add_x87(
X86Opcode::FBSTP,
"fbstp",
1,
&[OperandType::Mem80],
false,
true,
);
self.add_x87(X86Opcode::FXCH, "fxch", 1, &[], false, false);
self.add_x87(
X86Opcode::FCOM,
"fcom",
1,
&[OperandType::Mem32],
true,
false,
);
self.add_x87(
X86Opcode::FCOMP,
"fcomp",
1,
&[OperandType::Mem32],
true,
false,
);
self.add(
InstrBuilder::new(X86Opcode::FCOMPP, "fcompp", "fcompp", 0)
.has_side_effects()
.implicit_uses(&[ST0_CONST, ST1_CONST])
.implicit_defs(&[FPFLAGS_CONST])
.build(),
);
self.add_x87(X86Opcode::FUCOM, "fucom", 1, &[], false, false);
self.add_x87(X86Opcode::FUCOMP, "fucomp", 1, &[], false, false);
self.add(
InstrBuilder::new(X86Opcode::FUCOMPP, "fucompp", "fucompp", 0)
.has_side_effects()
.implicit_uses(&[ST0_CONST, ST1_CONST])
.implicit_defs(&[FPFLAGS_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::FTST, "ftst", "ftst", 0)
.has_side_effects()
.implicit_uses(&[ST0_CONST])
.implicit_defs(&[FPFLAGS_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::FXAM, "fxam", "fxam", 0)
.has_side_effects()
.implicit_uses(&[ST0_CONST])
.implicit_defs(&[FPFLAGS_CONST])
.build(),
);
self.add_x87_arith(X86Opcode::FADD_ST0_ST, "fadd");
self.add_x87_arith(X86Opcode::FADD_ST_ST0, "fadd");
self.add_x87_arith(X86Opcode::FADDP, "faddp");
self.add_x87_arith(X86Opcode::FSUB_ST0_ST, "fsub");
self.add_x87_arith(X86Opcode::FSUB_ST_ST0, "fsub");
self.add_x87_arith(X86Opcode::FSUBP, "fsubp");
self.add_x87_arith(X86Opcode::FSUBR_ST0_ST, "fsubr");
self.add_x87_arith(X86Opcode::FSUBR_ST_ST0, "fsubr");
self.add_x87_arith(X86Opcode::FSUBRP, "fsubrp");
self.add_x87_arith(X86Opcode::FMUL_ST0_ST, "fmul");
self.add_x87_arith(X86Opcode::FMUL_ST_ST0, "fmul");
self.add_x87_arith(X86Opcode::FMULP, "fmulp");
self.add_x87_arith(X86Opcode::FDIV_ST0_ST, "fdiv");
self.add_x87_arith(X86Opcode::FDIV_ST_ST0, "fdiv");
self.add_x87_arith(X86Opcode::FDIVP, "fdivp");
self.add_x87_arith(X86Opcode::FDIVR_ST0_ST, "fdivr");
self.add_x87_arith(X86Opcode::FDIVR_ST_ST0, "fdivr");
self.add_x87_arith(X86Opcode::FDIVRP, "fdivrp");
self.add_x87_mem(X86Opcode::FADD_MEM, "fadds", 1, true, false);
self.add_x87_mem(X86Opcode::FSUB_MEM, "fsubs", 1, true, false);
self.add_x87_mem(X86Opcode::FSUBR_MEM, "fsubrs", 1, true, false);
self.add_x87_mem(X86Opcode::FMUL_MEM, "fmuls", 1, true, false);
self.add_x87_mem(X86Opcode::FDIV_MEM, "fdivs", 1, true, false);
self.add_x87_mem(X86Opcode::FDIVR_MEM, "fdivrs", 1, true, false);
self.add_x87_unary(X86Opcode::FCHS, "fchs");
self.add_x87_unary(X86Opcode::FABS, "fabs");
self.add_x87_unary(X86Opcode::FSQRT, "fsqrt");
self.add_x87_unary(X86Opcode::FRNDINT, "frndint");
self.add_x87_unary(X86Opcode::FSCALE, "fscale");
self.add_x87_unary(X86Opcode::FPREM, "fprem");
self.add_x87_unary(X86Opcode::FPREM1, "fprem1");
self.add_x87_unary(X86Opcode::FXTRACT, "fxtract");
self.add_x87_unary(X86Opcode::FSIN, "fsin");
self.add_x87_unary(X86Opcode::FCOS, "fcos");
self.add_x87_unary(X86Opcode::FSINCOS, "fsincos");
self.add_x87_unary(X86Opcode::FPTAN, "fptan");
self.add_x87_unary(X86Opcode::FPATAN, "fpatan");
self.add_x87_unary(X86Opcode::F2XM1, "f2xm1");
self.add_x87_unary(X86Opcode::FYL2X, "fyl2x");
self.add_x87_unary(X86Opcode::FYL2XP1, "fyl2xp1");
self.add_x87_env(X86Opcode::FLDCW, "fldcw", &[]);
self.add_x87_env(X86Opcode::FSTCW, "fstcw", &[FNSTCW_CONST]);
self.add_x87_env(X86Opcode::FNSTCW, "fnstcw", &[FNSTCW_CONST]);
self.add_x87_env(X86Opcode::FLDENV, "fldenv", &[]);
self.add_x87_env(X86Opcode::FSTENV, "fstenv", &[FNSTCW_CONST]);
self.add_x87_env(X86Opcode::FNSTENV, "fnstenv", &[FNSTCW_CONST]);
self.add_x87_env(X86Opcode::FRSTOR, "frstor", &[]);
self.add_x87_env(X86Opcode::FSAVE, "fsave", &[]);
self.add_x87_env(X86Opcode::FNSAVE, "fnsave", &[]);
self.add(
InstrBuilder::new(X86Opcode::FNCLEX, "fnclex", "fnclex", 0)
.has_side_effects()
.implicit_defs(&[FPFLAGS_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::FINIT, "finit", "finit", 0)
.has_side_effects()
.implicit_defs(&[FPFLAGS_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::FNINIT, "fninit", "fninit", 0)
.has_side_effects()
.implicit_defs(&[FPFLAGS_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::FFREE, "ffree", "ffree", 1)
.operands(&[])
.has_side_effects()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::FDECSTP, "fdecstp", "fdecstp", 0)
.has_side_effects()
.implicit_defs(&[TOPSW_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::FINCSTP, "fincstp", "fincstp", 0)
.has_side_effects()
.implicit_defs(&[TOPSW_CONST])
.build(),
);
self.add_mmx(
X86Opcode::MMX_MOVD,
"movd",
2,
&[OperandType::Reg64, OperandType::Reg32],
);
self.add_mmx(
X86Opcode::MMX_MOVQ,
"movq",
2,
&[OperandType::Reg64, OperandType::Reg64],
);
self.add_mmx_mem(X86Opcode::MMX_MOVD_TO_MEM, "movd", false, true);
self.add_mmx_mem(X86Opcode::MMX_MOVQ_TO_MEM, "movq", false, true);
self.add_mmx_binop(X86Opcode::MMX_PADDB, "paddb");
self.add_mmx_binop(X86Opcode::MMX_PADDW, "paddw");
self.add_mmx_binop(X86Opcode::MMX_PADDD, "paddd");
self.add_mmx_binop(X86Opcode::MMX_PADDQ, "paddq");
self.add_mmx_binop(X86Opcode::MMX_PADDSB, "paddsb");
self.add_mmx_binop(X86Opcode::MMX_PADDSW, "paddsw");
self.add_mmx_binop(X86Opcode::MMX_PADDUSB, "paddusb");
self.add_mmx_binop(X86Opcode::MMX_PADDUSW, "paddusw");
self.add_mmx_binop(X86Opcode::MMX_PSUBB, "psubb");
self.add_mmx_binop(X86Opcode::MMX_PSUBW, "psubw");
self.add_mmx_binop(X86Opcode::MMX_PSUBD, "psubd");
self.add_mmx_binop(X86Opcode::MMX_PSUBQ, "psubq");
self.add_mmx_binop(X86Opcode::MMX_PSUBSB, "psubsb");
self.add_mmx_binop(X86Opcode::MMX_PSUBSW, "psubsw");
self.add_mmx_binop(X86Opcode::MMX_PSUBUSB, "psubusb");
self.add_mmx_binop(X86Opcode::MMX_PSUBUSW, "psubusw");
self.add_mmx_binop(X86Opcode::MMX_PMULLW, "pmullw");
self.add_mmx_binop(X86Opcode::MMX_PMULHW, "pmulhw");
self.add_mmx_binop(X86Opcode::MMX_PMULHUW, "pmulhuw");
self.add_mmx_binop(X86Opcode::MMX_PMADDWD, "pmaddwd");
self.add_mmx_binop(X86Opcode::MMX_PCMPEQB, "pcmpeqb");
self.add_mmx_binop(X86Opcode::MMX_PCMPEQW, "pcmpeqw");
self.add_mmx_binop(X86Opcode::MMX_PCMPEQD, "pcmpeqd");
self.add_mmx_binop(X86Opcode::MMX_PCMPGTB, "pcmpgtb");
self.add_mmx_binop(X86Opcode::MMX_PCMPGTW, "pcmpgtw");
self.add_mmx_binop(X86Opcode::MMX_PCMPGTD, "pcmpgtd");
self.add_mmx_binop(X86Opcode::MMX_PACKSSWB, "packsswb");
self.add_mmx_binop(X86Opcode::MMX_PACKSSDW, "packssdw");
self.add_mmx_binop(X86Opcode::MMX_PACKUSWB, "packuswb");
self.add_mmx_binop(X86Opcode::MMX_PUNPCKLBW, "punpcklbw");
self.add_mmx_binop(X86Opcode::MMX_PUNPCKHBW, "punpckhbw");
self.add_mmx_binop(X86Opcode::MMX_PUNPCKLWD, "punpcklwd");
self.add_mmx_binop(X86Opcode::MMX_PUNPCKHWD, "punpckhwd");
self.add_mmx_binop(X86Opcode::MMX_PUNPCKLDQ, "punpckldq");
self.add_mmx_binop(X86Opcode::MMX_PUNPCKHDQ, "punpckhdq");
self.add_mmx_binop(X86Opcode::MMX_PSLLW, "psllw");
self.add_mmx_binop(X86Opcode::MMX_PSLLD, "pslld");
self.add_mmx_binop(X86Opcode::MMX_PSLLQ, "psllq");
self.add_mmx_binop(X86Opcode::MMX_PSRLW, "psrlw");
self.add_mmx_binop(X86Opcode::MMX_PSRLD, "psrld");
self.add_mmx_binop(X86Opcode::MMX_PSRLQ, "psrlq");
self.add_mmx_binop(X86Opcode::MMX_PSRAW, "psraw");
self.add_mmx_binop(X86Opcode::MMX_PSRAD, "psrad");
self.add_mmx_binop(X86Opcode::MMX_PAND, "pand");
self.add_mmx_binop(X86Opcode::MMX_PANDN, "pandn");
self.add_mmx_binop(X86Opcode::MMX_POR, "por");
self.add_mmx_binop(X86Opcode::MMX_PXOR, "pxor");
self.add(
InstrBuilder::new(X86Opcode::MMX_EMMS, "emms", "emms", 0)
.has_side_effects()
.implicit_defs(&[FPFLAGS_CONST])
.build(),
);
self.add_3dnow_binop(X86Opcode::AMD_PAVGUSB, "pavgusb");
self.add_3dnow_binop(X86Opcode::AMD_PFADD, "pfadd");
self.add_3dnow_binop(X86Opcode::AMD_PFSUB, "pfsub");
self.add_3dnow_binop(X86Opcode::AMD_PFSUBR, "pfsubr");
self.add_3dnow_binop(X86Opcode::AMD_PFMUL, "pfmul");
self.add_3dnow_binop(X86Opcode::AMD_PFACC, "pfacc");
self.add_3dnow_binop(X86Opcode::AMD_PFCMPGE, "pfcmpge");
self.add_3dnow_binop(X86Opcode::AMD_PFCMPGT, "pfcmpgt");
self.add_3dnow_binop(X86Opcode::AMD_PFCMPEQ, "pfcmpeq");
self.add_3dnow_binop(X86Opcode::AMD_PFMIN, "pfmin");
self.add_3dnow_binop(X86Opcode::AMD_PFMAX, "pfmax");
self.add_3dnow_binop(X86Opcode::AMD_PI2FD, "pi2fd");
self.add_3dnow_binop(X86Opcode::AMD_PF2ID, "pf2id");
self.add_3dnow_binop(X86Opcode::AMD_PFNACC, "pfnacc");
self.add_3dnow_binop(X86Opcode::AMD_PFPNACC, "pfpnacc");
self.add_3dnow_binop(X86Opcode::AMD_PSWAPD, "pswapd");
self.add_3dnow_binop(X86Opcode::AMD_PFRCP, "pfrcp");
self.add_3dnow_binop(X86Opcode::AMD_PFRCPIT1, "pfrcpit1");
self.add_3dnow_binop(X86Opcode::AMD_PFRCPIT2, "pfrcpit2");
self.add_3dnow_binop(X86Opcode::AMD_PFRSQRT, "pfrsqrt");
self.add_3dnow_binop(X86Opcode::AMD_PFRSQIT1, "pfrsqit1");
self.add(
InstrBuilder::new(X86Opcode::AMD_FEMMS, "femms", "femms", 0)
.has_side_effects()
.implicit_defs(&[FPFLAGS_CONST])
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MONITORX_AMD, "monitorx", "monitorx", 3)
.operands(&[OperandType::Reg64, OperandType::Reg32, OperandType::Reg32])
.has_side_effects()
.may_load()
.build(),
);
self.add(
InstrBuilder::new(X86Opcode::MWAITX_AMD, "mwaitx", "mwaitx", 3)
.operands(&[OperandType::Reg32, OperandType::Reg32, OperandType::Imm32])
.has_side_effects()
.build(),
);
self.add_prefetch(X86Opcode::PREFETCH_RESERVED, "prefetchreserved");
self.add_prefetch(X86Opcode::PREFETCH_EXCLUSIVE, "prefetchexclusive");
self.add_prefetch(X86Opcode::PREFETCH_MODIFIED, "prefetchmodified");
self.add(
InstrBuilder::new(X86Opcode::CLFLUSHOPT_64, "clflushopt", "clflushopt", 1)
.operands(&[OperandType::Mem64])
.has_side_effects()
.may_load()
.may_store()
.build(),
);
}
fn add(&mut self, desc: X86InstrDesc) {
let mnemonic = desc.mnemonic.to_string();
let intel = desc.intel_mnemonic.to_string();
let intel_differs = intel != mnemonic;
self.by_mnemonic.insert(mnemonic, desc.opcode);
if intel_differs {
self.by_mnemonic.insert(intel, desc.opcode);
}
self.descriptors.insert(desc.opcode, desc);
}
fn add_cmov(&mut self, opcode: X86Opcode, mnemonic: &'static str) {
let intel = &mnemonic[..mnemonic.len() - 1]; self.add(
InstrBuilder::new(opcode, mnemonic, intel, 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_move_immediate()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x03))
.build(),
);
}
fn add_jcc(&mut self, opcode: X86Opcode, mnemonic: &'static str) {
self.add(
InstrBuilder::new(opcode, mnemonic, mnemonic, 1)
.operands(&[OperandType::Label])
.is_terminator()
.is_branch()
.implicit_uses(&[FLAGS_CONST])
.build(),
);
}
fn add_setcc(&mut self, opcode: X86Opcode, mnemonic: &'static str) {
self.add(
InstrBuilder::new(opcode, mnemonic, mnemonic, 1)
.operands(&[OperandType::Reg8])
.implicit_uses(&[FLAGS_CONST])
.sched(X86SchedInfo::SIMPLE_ALU)
.build(),
);
}
fn add_string_op(
&mut self,
opcode: X86Opcode,
mnemonic: &'static str,
stores: bool,
loads: bool,
) {
let mut b = InstrBuilder::new(opcode, mnemonic, mnemonic, 0)
.has_side_effects()
.implicit_uses(&[RSI_CONST, RDI_CONST, RCX_CONST])
.implicit_defs(&[RSI_CONST, RDI_CONST, RCX_CONST]);
if stores {
b = b.may_store();
}
if loads {
b = b.may_load();
}
self.add(b.build());
}
fn add_sse_binop(&mut self, opcode: X86Opcode, mnemonic: &'static str, commutative: bool) {
let mut b = InstrBuilder::new(opcode, mnemonic, mnemonic, 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01));
if commutative {
b = b.is_commutative();
}
self.add(b.build());
}
fn add_sse_unop(&mut self, opcode: X86Opcode, mnemonic: &'static str) {
self.add(
InstrBuilder::new(opcode, mnemonic, mnemonic, 2)
.operands(&[OperandType::XmmReg, OperandType::XmmReg])
.sched(X86SchedInfo::new(4, 1.0, 1, 0x01))
.build(),
);
}
fn add_avx_binop(&mut self, opcode: X86Opcode, mnemonic: &'static str, commutative: bool) {
let mut b = InstrBuilder::new(opcode, mnemonic, mnemonic, 3)
.operands(&[
OperandType::YmmReg,
OperandType::YmmReg,
OperandType::YmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(3, 0.5, 1, 0x03));
if commutative {
b = b.is_commutative();
}
self.add(b.build());
}
fn add_fma3(&mut self, opcode: X86Opcode, mnemonic: &'static str) {
self.add(
InstrBuilder::new(opcode, mnemonic, mnemonic, 3)
.operands(&[
OperandType::YmmReg,
OperandType::YmmReg,
OperandType::YmmReg,
])
.is_three_address()
.sched(X86SchedInfo::new(4, 0.5, 1, 0x03))
.build(),
);
}
fn add_x87(
&mut self,
opcode: X86Opcode,
mnemonic: &'static str,
num_operands: u8,
operand_types: &'static [OperandType],
may_load: bool,
may_store: bool,
) {
let mut b = InstrBuilder::new(opcode, mnemonic, mnemonic, num_operands)
.has_side_effects()
.implicit_uses(&[ST0_CONST])
.implicit_defs(&[ST0_CONST, FPFLAGS_CONST])
.sched(X86SchedInfo::new(6, 1.0, 2, 0x01));
if !operand_types.is_empty() {
b = b.operands(operand_types);
}
if may_load {
b = b.may_load();
}
if may_store {
b = b.may_store();
}
self.add(b.build());
}
fn add_x87_mem(
&mut self,
opcode: X86Opcode,
mnemonic: &'static str,
num_operands: u8,
may_load: bool,
may_store: bool,
) {
let mut b = InstrBuilder::new(opcode, mnemonic, mnemonic, num_operands)
.operands(&[OperandType::Mem32])
.has_side_effects()
.implicit_uses(&[ST0_CONST])
.implicit_defs(&[ST0_CONST, FPFLAGS_CONST])
.sched(X86SchedInfo::new(6, 1.0, 2, 0x01));
if may_load {
b = b.may_load();
}
if may_store {
b = b.may_store();
}
self.add(b.build());
}
fn add_x87_arith(&mut self, opcode: X86Opcode, mnemonic: &'static str) {
self.add(
InstrBuilder::new(opcode, mnemonic, mnemonic, 2)
.has_side_effects()
.implicit_uses(&[ST0_CONST, ST1_CONST])
.implicit_defs(&[ST0_CONST, ST1_CONST, FPFLAGS_CONST])
.sched(X86SchedInfo::new(3, 1.0, 1, 0x01))
.build(),
);
}
fn add_x87_unary(&mut self, opcode: X86Opcode, mnemonic: &'static str) {
self.add(
InstrBuilder::new(opcode, mnemonic, mnemonic, 0)
.has_side_effects()
.implicit_uses(&[ST0_CONST])
.implicit_defs(&[ST0_CONST, FPFLAGS_CONST])
.sched(X86SchedInfo::new(8, 2.0, 5, 0x01))
.build(),
);
}
fn add_x87_env(&mut self, opcode: X86Opcode, mnemonic: &'static str, defs: &'static [u16]) {
let mut b = InstrBuilder::new(opcode, mnemonic, mnemonic, 1)
.operands(&[OperandType::Mem16])
.has_side_effects()
.may_load()
.may_store()
.sched(X86SchedInfo::new(10, 3.0, 6, 0x01));
if !defs.is_empty() {
b = b.implicit_defs(defs);
}
self.add(b.build());
}
fn add_mmx(
&mut self,
opcode: X86Opcode,
mnemonic: &'static str,
num_operands: u8,
operand_types: &'static [OperandType],
) {
self.add(
InstrBuilder::new(opcode, mnemonic, mnemonic, num_operands)
.operands(operand_types)
.implicit_uses(&[MM0_CONST])
.implicit_defs(&[MM0_CONST])
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
}
fn add_mmx_mem(
&mut self,
opcode: X86Opcode,
mnemonic: &'static str,
may_load: bool,
may_store: bool,
) {
let mut b = InstrBuilder::new(opcode, mnemonic, mnemonic, 2)
.operands(&[OperandType::Mem64, OperandType::Reg64])
.has_side_effects();
if may_load {
b = b.may_load();
}
if may_store {
b = b.may_store();
}
self.add(b.build());
}
fn add_mmx_binop(&mut self, opcode: X86Opcode, mnemonic: &'static str) {
self.add(
InstrBuilder::new(opcode, mnemonic, mnemonic, 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_commutative()
.sched(X86SchedInfo::new(1, 0.5, 1, 0x01))
.build(),
);
}
fn add_3dnow_binop(&mut self, opcode: X86Opcode, mnemonic: &'static str) {
self.add(
InstrBuilder::new(opcode, mnemonic, mnemonic, 2)
.operands(&[OperandType::Reg64, OperandType::Reg64])
.is_commutative()
.sched(X86SchedInfo::new(2, 1.0, 1, 0x01))
.build(),
);
}
fn add_prefetch(&mut self, opcode: X86Opcode, mnemonic: &'static str) {
self.add(
InstrBuilder::new(opcode, mnemonic, mnemonic, 1)
.operands(&[OperandType::Mem8])
.has_side_effects()
.may_load()
.build(),
);
}
pub fn get(&self, opcode: X86Opcode) -> &X86InstrDesc {
self.descriptors
.get(&opcode)
.unwrap_or_else(|| panic!("No descriptor for opcode {:?}", opcode))
}
pub fn get_mnemonic(&self, opcode: X86Opcode) -> &str {
self.get(opcode).mnemonic
}
pub fn get_intel_mnemonic(&self, opcode: X86Opcode) -> &str {
self.get(opcode).intel_mnemonic
}
pub fn get_num_operands(&self, opcode: X86Opcode) -> u8 {
self.get(opcode).num_operands
}
pub fn is_terminator(&self, opcode: X86Opcode) -> bool {
self.get(opcode).is_terminator
}
pub fn is_branch(&self, opcode: X86Opcode) -> bool {
self.get(opcode).is_branch
}
pub fn is_call(&self, opcode: X86Opcode) -> bool {
self.get(opcode).is_call
}
pub fn is_return(&self, opcode: X86Opcode) -> bool {
self.get(opcode).is_return
}
pub fn is_commutative(&self, opcode: X86Opcode) -> bool {
self.get(opcode).is_commutative
}
pub fn is_compare(&self, opcode: X86Opcode) -> bool {
self.get(opcode).is_compare
}
pub fn may_load(&self, opcode: X86Opcode) -> bool {
self.get(opcode).may_load
}
pub fn may_store(&self, opcode: X86Opcode) -> bool {
self.get(opcode).may_store
}
pub fn has_side_effects(&self, opcode: X86Opcode) -> bool {
self.get(opcode).has_side_effects
}
pub fn is_three_address(&self, opcode: X86Opcode) -> bool {
self.get(opcode).is_three_address
}
pub fn get_implicit_defs(&self, opcode: X86Opcode) -> &[u16] {
self.get(opcode).implicit_defs
}
pub fn get_implicit_uses(&self, opcode: X86Opcode) -> &[u16] {
self.get(opcode).implicit_uses
}
pub fn find_by_mnemonic(&self, name: &str) -> Option<X86Opcode> {
self.by_mnemonic.get(name).copied()
}
pub fn is_convert(&self, opcode: X86Opcode) -> bool {
self.get(opcode).is_convert
}
pub fn is_bitcast(&self, opcode: X86Opcode) -> bool {
self.get(opcode).is_bitcast
}
pub fn get_scheduling_info(&self, opcode: X86Opcode) -> Option<X86SchedInfo> {
self.get(opcode).scheduling_info
}
}
impl Default for X86InstrInfo {
fn default() -> Self {
X86InstrInfo::new()
}
}
struct InstrBuilder {
desc: X86InstrDesc,
}
impl InstrBuilder {
fn new(
opcode: X86Opcode,
mnemonic: &'static str,
intel_mnemonic: &'static str,
num_operands: u8,
) -> Self {
InstrBuilder {
desc: X86InstrDesc {
opcode,
mnemonic,
intel_mnemonic,
num_operands,
is_terminator: false,
is_branch: false,
is_call: false,
is_return: false,
is_compare: false,
is_move_immediate: false,
is_bitcast: false,
is_convert: false,
has_side_effects: false,
may_load: false,
may_store: false,
is_commutative: false,
is_three_address: false,
operand_types: &[],
implicit_defs: &[],
implicit_uses: &[],
scheduling_info: None,
},
}
}
fn operands(mut self, types: &'static [OperandType]) -> Self {
self.desc.operand_types = types;
self
}
fn num_operands(mut self, n: u8) -> Self {
self.desc.num_operands = n;
self
}
fn is_terminator(mut self) -> Self {
self.desc.is_terminator = true;
self
}
fn is_branch(mut self) -> Self {
self.desc.is_branch = true;
self
}
fn is_call(mut self) -> Self {
self.desc.is_call = true;
self
}
fn is_return(mut self) -> Self {
self.desc.is_return = true;
self
}
fn is_compare(mut self) -> Self {
self.desc.is_compare = true;
self
}
fn is_move_immediate(mut self) -> Self {
self.desc.is_move_immediate = true;
self
}
fn is_bitcast(mut self) -> Self {
self.desc.is_bitcast = true;
self
}
fn is_convert(mut self) -> Self {
self.desc.is_convert = true;
self
}
fn has_side_effects(mut self) -> Self {
self.desc.has_side_effects = true;
self
}
fn may_load(mut self) -> Self {
self.desc.may_load = true;
self
}
fn may_store(mut self) -> Self {
self.desc.may_store = true;
self
}
fn is_commutative(mut self) -> Self {
self.desc.is_commutative = true;
self
}
fn is_three_address(mut self) -> Self {
self.desc.is_three_address = true;
self
}
fn implicit_defs(mut self, defs: &'static [u16]) -> Self {
self.desc.implicit_defs = defs;
self
}
fn implicit_uses(mut self, uses: &'static [u16]) -> Self {
self.desc.implicit_uses = uses;
self
}
fn sched(mut self, info: X86SchedInfo) -> Self {
self.desc.scheduling_info = Some(info);
self
}
fn build(self) -> X86InstrDesc {
self.desc
}
}
const RAX_CONST: u16 = 0;
const RCX_CONST: u16 = 1;
const RDX_CONST: u16 = 2;
pub(crate) const RSP_CONST: u16 = 4;
pub(crate) const RBP_CONST: u16 = 5;
const RSI_CONST: u16 = 6;
const RDI_CONST: u16 = 7;
const R8_CONST: u16 = 8;
const R9_CONST: u16 = 9;
const R10_CONST: u16 = 10;
const R11_CONST: u16 = 11;
const FLAGS_CONST: u16 = 200;
const XMM0_CONST: u16 = 98;
const YMM0_CONST: u16 = 130;
const YMM1_CONST: u16 = 131;
const YMM2_CONST: u16 = 132;
const YMM3_CONST: u16 = 133;
const YMM4_CONST: u16 = 134;
const YMM5_CONST: u16 = 135;
const YMM6_CONST: u16 = 136;
const YMM7_CONST: u16 = 137;
const YMM8_CONST: u16 = 138;
const YMM9_CONST: u16 = 139;
const YMM10_CONST: u16 = 140;
const YMM11_CONST: u16 = 141;
const YMM12_CONST: u16 = 142;
const YMM13_CONST: u16 = 143;
const YMM14_CONST: u16 = 144;
const YMM15_CONST: u16 = 145;
const ST0_CONST: u16 = 210;
const ST1_CONST: u16 = 211;
const FPFLAGS_CONST: u16 = 212;
const FPSW_CONST: u16 = 213;
const FPCW_CONST: u16 = 214;
const FNSTCW_CONST: u16 = 215;
const TOPSW_CONST: u16 = 216;
const MM0_CONST: u16 = 220;
const MM1_CONST: u16 = 221;
const MM2_CONST: u16 = 222;
const MM3_CONST: u16 = 223;
const MM4_CONST: u16 = 224;
const MM5_CONST: u16 = 225;
const MM6_CONST: u16 = 226;
const MM7_CONST: u16 = 227;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_opcode_backward_compat() {
assert_eq!(X86Opcode::NOP as u32, 0);
assert_eq!(X86Opcode::MOV as u32, 1);
assert_eq!(X86Opcode::ADD as u32, 2);
assert_eq!(X86Opcode::SUB as u32, 3);
assert_eq!(X86Opcode::MUL as u32, 4);
assert_eq!(X86Opcode::DIV as u32, 5);
assert_eq!(X86Opcode::AND as u32, 6);
assert_eq!(X86Opcode::OR as u32, 7);
assert_eq!(X86Opcode::XOR as u32, 8);
assert_eq!(X86Opcode::SHL as u32, 9);
assert_eq!(X86Opcode::SHR as u32, 10);
assert_eq!(X86Opcode::PUSH as u32, 11);
assert_eq!(X86Opcode::POP as u32, 12);
assert_eq!(X86Opcode::CALL as u32, 13);
assert_eq!(X86Opcode::RET as u32, 14);
assert_eq!(X86Opcode::JMP as u32, 15);
assert_eq!(X86Opcode::JE as u32, 16);
assert_eq!(X86Opcode::JNE as u32, 17);
assert_eq!(X86Opcode::CMP as u32, 18);
assert_eq!(X86Opcode::LEA as u32, 19);
assert_eq!(X86Opcode::INC as u32, 20);
assert_eq!(X86Opcode::DEC as u32, 21);
assert_eq!(X86Opcode::NOT as u32, 22);
assert_eq!(X86Opcode::NEG as u32, 23);
}
#[test]
fn test_is_cmov() {
assert!(X86Opcode::CMOVO.is_cmov());
assert!(X86Opcode::CMOVE.is_cmov());
assert!(X86Opcode::CMOVG.is_cmov());
assert!(X86Opcode::CMOVL.is_cmov());
assert!(!X86Opcode::MOV.is_cmov());
assert!(!X86Opcode::ADD.is_cmov());
}
#[test]
fn test_is_jcc() {
assert!(X86Opcode::JE.is_jcc());
assert!(X86Opcode::JNE.is_jcc());
assert!(X86Opcode::JG.is_jcc());
assert!(X86Opcode::JL.is_jcc());
assert!(!X86Opcode::JMP.is_jcc());
assert!(!X86Opcode::CALL.is_jcc());
}
#[test]
fn test_is_setcc() {
assert!(X86Opcode::SETE.is_setcc());
assert!(X86Opcode::SETNE.is_setcc());
assert!(X86Opcode::SETG.is_setcc());
assert!(!X86Opcode::NOP.is_setcc());
assert!(!X86Opcode::MOV.is_setcc());
}
#[test]
fn test_opcode_count_at_least_200() {
let last = X86Opcode::NOP9 as u32;
assert!(
last >= 200,
"Expected at least 200 opcode variants, got max value {}",
last
);
}
#[test]
fn test_mem_operand_base() {
let mem = X86MemOperand::base(RBP_CONST);
assert_eq!(mem.base, RBP_CONST);
assert_eq!(mem.index, 0);
assert_eq!(mem.scale, 0);
assert_eq!(mem.displacement, 0);
assert_eq!(mem.segment, 0);
}
#[test]
fn test_mem_operand_base_disp() {
let mem = X86MemOperand::base_disp(RBP_CONST, -16);
assert_eq!(mem.base, RBP_CONST);
assert_eq!(mem.index, 0);
assert_eq!(mem.displacement, -16);
}
#[test]
fn test_mem_operand_full() {
let mem = X86MemOperand::full(RBX_CONST, RSI_CONST, 4, 8);
assert_eq!(mem.base, RBX_CONST);
assert_eq!(mem.index, RSI_CONST);
assert_eq!(mem.scale, 4);
assert_eq!(mem.displacement, 8);
}
const RBX_CONST: u16 = 3;
const RSI_CONST_LOCAL: u16 = RSI_CONST;
#[test]
fn test_mem_operand_base_index_scale() {
let mem = X86MemOperand::base_index_scale(RAX_CONST, RSI_CONST_LOCAL, 2);
assert_eq!(mem.base, RAX_CONST);
assert_eq!(mem.index, RSI_CONST_LOCAL);
assert_eq!(mem.scale, 2);
assert_eq!(mem.displacement, 0);
}
#[test]
fn test_mem_rip_relative() {
let mem = X86MemOperand {
base: 255, index: 0,
scale: 0,
displacement: 0,
segment: 0,
};
assert!(mem.is_rip_relative());
}
#[test]
fn test_operand_type_is_register() {
assert!(OperandType::Reg64.is_register());
assert!(OperandType::Reg32.is_register());
assert!(OperandType::XmmReg.is_register());
assert!(OperandType::YmmReg.is_register());
assert!(!OperandType::Mem64.is_register());
assert!(!OperandType::Imm32.is_register());
assert!(!OperandType::Label.is_register());
}
#[test]
fn test_operand_type_is_memory() {
assert!(OperandType::Mem8.is_memory());
assert!(OperandType::Mem64.is_memory());
assert!(OperandType::Mem80.is_memory());
assert!(!OperandType::Reg64.is_memory());
assert!(!OperandType::Imm32.is_memory());
}
#[test]
fn test_operand_type_is_immediate() {
assert!(OperandType::Imm8.is_immediate());
assert!(OperandType::Imm16.is_immediate());
assert!(OperandType::Imm32.is_immediate());
assert!(OperandType::Imm64.is_immediate());
assert!(!OperandType::Reg64.is_immediate());
assert!(!OperandType::Mem64.is_immediate());
}
#[test]
fn test_instr_info_get() {
let info = X86InstrInfo::new();
let desc = info.get(X86Opcode::ADD);
assert_eq!(desc.mnemonic, "addq");
assert_eq!(desc.intel_mnemonic, "add");
assert_eq!(desc.num_operands, 2);
assert!(desc.is_commutative);
}
#[test]
fn test_instr_info_get_mnemonic() {
let info = X86InstrInfo::new();
assert_eq!(info.get_mnemonic(X86Opcode::SUB), "subq");
assert_eq!(info.get_mnemonic(X86Opcode::RET), "retq");
assert_eq!(info.get_mnemonic(X86Opcode::NOP), "nop");
}
#[test]
fn test_instr_info_get_intel_mnemonic() {
let info = X86InstrInfo::new();
assert_eq!(info.get_intel_mnemonic(X86Opcode::ADD), "add");
assert_eq!(info.get_intel_mnemonic(X86Opcode::MOV), "mov");
assert_eq!(info.get_intel_mnemonic(X86Opcode::JMP), "jmp");
}
#[test]
fn test_instr_info_get_num_operands() {
let info = X86InstrInfo::new();
assert_eq!(info.get_num_operands(X86Opcode::NOP), 0);
assert_eq!(info.get_num_operands(X86Opcode::PUSH), 1);
assert_eq!(info.get_num_operands(X86Opcode::ADD), 2);
assert_eq!(info.get_num_operands(X86Opcode::SHLD), 3);
}
#[test]
fn test_instr_info_is_terminator() {
let info = X86InstrInfo::new();
assert!(info.is_terminator(X86Opcode::RET));
assert!(info.is_terminator(X86Opcode::JMP));
assert!(info.is_terminator(X86Opcode::JE));
assert!(info.is_terminator(X86Opcode::CALL));
assert!(!info.is_terminator(X86Opcode::ADD));
assert!(!info.is_terminator(X86Opcode::NOP));
}
#[test]
fn test_instr_info_is_branch() {
let info = X86InstrInfo::new();
assert!(info.is_branch(X86Opcode::JMP));
assert!(info.is_branch(X86Opcode::JE));
assert!(info.is_branch(X86Opcode::JNE));
assert!(!info.is_branch(X86Opcode::RET));
assert!(!info.is_branch(X86Opcode::ADD));
}
#[test]
fn test_instr_info_is_call() {
let info = X86InstrInfo::new();
assert!(info.is_call(X86Opcode::CALL));
assert!(!info.is_call(X86Opcode::JMP));
assert!(!info.is_call(X86Opcode::RET));
}
#[test]
fn test_instr_info_is_return() {
let info = X86InstrInfo::new();
assert!(info.is_return(X86Opcode::RET));
assert!(!info.is_return(X86Opcode::CALL));
}
#[test]
fn test_instr_info_is_commutative() {
let info = X86InstrInfo::new();
assert!(info.is_commutative(X86Opcode::ADD));
assert!(info.is_commutative(X86Opcode::AND));
assert!(info.is_commutative(X86Opcode::OR));
assert!(info.is_commutative(X86Opcode::XOR));
assert!(info.is_commutative(X86Opcode::IMUL));
assert!(!info.is_commutative(X86Opcode::SUB));
assert!(!info.is_commutative(X86Opcode::DIV));
assert!(!info.is_commutative(X86Opcode::MUL));
}
#[test]
fn test_instr_info_is_compare() {
let info = X86InstrInfo::new();
assert!(info.is_compare(X86Opcode::CMP));
assert!(info.is_compare(X86Opcode::TEST));
assert!(!info.is_compare(X86Opcode::ADD));
assert!(!info.is_compare(X86Opcode::MOV));
}
#[test]
fn test_instr_info_may_load() {
let info = X86InstrInfo::new();
assert!(info.may_load(X86Opcode::POP));
assert!(info.may_load(X86Opcode::VBROADCASTSS));
assert!(!info.may_load(X86Opcode::ADD));
assert!(!info.may_load(X86Opcode::NOP));
}
#[test]
fn test_instr_info_may_store() {
let info = X86InstrInfo::new();
assert!(info.may_store(X86Opcode::PUSH));
assert!(info.may_store(X86Opcode::CALL));
assert!(!info.may_store(X86Opcode::ADD));
assert!(!info.may_store(X86Opcode::MOV));
}
#[test]
fn test_instr_info_has_side_effects() {
let info = X86InstrInfo::new();
assert!(info.has_side_effects(X86Opcode::CALL));
assert!(info.has_side_effects(X86Opcode::PUSH));
assert!(info.has_side_effects(X86Opcode::SYSCALL));
assert!(!info.has_side_effects(X86Opcode::ADD));
assert!(!info.has_side_effects(X86Opcode::MOV));
}
#[test]
fn test_instr_info_is_three_address() {
let info = X86InstrInfo::new();
assert!(info.is_three_address(X86Opcode::VADDPS));
assert!(info.is_three_address(X86Opcode::VFMADD132PD));
assert!(!info.is_three_address(X86Opcode::ADD));
assert!(!info.is_three_address(X86Opcode::MOV));
}
#[test]
fn test_instr_info_find_by_mnemonic() {
let info = X86InstrInfo::new();
assert_eq!(info.find_by_mnemonic("addq"), Some(X86Opcode::ADD));
assert_eq!(info.find_by_mnemonic("add"), Some(X86Opcode::ADD));
assert_eq!(info.find_by_mnemonic("retq"), Some(X86Opcode::RET));
assert_eq!(info.find_by_mnemonic("callq"), Some(X86Opcode::CALL));
assert_eq!(info.find_by_mnemonic("nonexistent"), None);
}
#[test]
fn test_instr_info_find_by_mnemonic_jumps() {
let info = X86InstrInfo::new();
assert_eq!(info.find_by_mnemonic("je"), Some(X86Opcode::JE));
assert_eq!(info.find_by_mnemonic("jne"), Some(X86Opcode::JNE));
assert_eq!(info.find_by_mnemonic("jg"), Some(X86Opcode::JG));
assert_eq!(info.find_by_mnemonic("jmp"), Some(X86Opcode::JMP));
}
#[test]
fn test_instr_info_find_by_mnemonic_sse() {
let info = X86InstrInfo::new();
assert_eq!(info.find_by_mnemonic("addss"), Some(X86Opcode::ADDSS));
assert_eq!(info.find_by_mnemonic("mulsd"), Some(X86Opcode::MULSD));
assert_eq!(info.find_by_mnemonic("andps"), Some(X86Opcode::ANDPS));
}
#[test]
fn test_instr_info_implicit_defs() {
let info = X86InstrInfo::new();
let defs = info.get_implicit_defs(X86Opcode::MUL);
assert!(defs.contains(&RAX_CONST));
assert!(defs.contains(&RDX_CONST));
}
#[test]
fn test_instr_info_implicit_uses() {
let info = X86InstrInfo::new();
let uses = info.get_implicit_uses(X86Opcode::DIV);
assert!(uses.contains(&RAX_CONST));
assert!(uses.contains(&RDX_CONST));
}
#[test]
fn test_instr_info_scheduling() {
let info = X86InstrInfo::new();
let sched = info.get_scheduling_info(X86Opcode::ADD);
assert!(sched.is_some());
let s = sched.unwrap();
assert_eq!(s.latency, 1);
assert!(s.throughput < 1.0);
}
#[test]
fn test_instr_info_is_convert() {
let info = X86InstrInfo::new();
assert!(info.is_convert(X86Opcode::CVTSI2SS));
assert!(info.is_convert(X86Opcode::CVTSD2SI));
assert!(!info.is_convert(X86Opcode::ADD));
assert!(!info.is_convert(X86Opcode::MOV));
}
#[test]
fn test_instr_info_all_cmov() {
let info = X86InstrInfo::new();
let cmovs = [
X86Opcode::CMOVO,
X86Opcode::CMOVNO,
X86Opcode::CMOVB,
X86Opcode::CMOVAE,
X86Opcode::CMOVE,
X86Opcode::CMOVNE,
X86Opcode::CMOVBE,
X86Opcode::CMOVA,
X86Opcode::CMOVS,
X86Opcode::CMOVNS,
X86Opcode::CMOVP,
X86Opcode::CMOVNP,
X86Opcode::CMOVL,
X86Opcode::CMOVGE,
X86Opcode::CMOVLE,
X86Opcode::CMOVG,
];
for &op in &cmovs {
assert!(
info.get(op).is_move_immediate,
"CMOV {:?} should be move_immediate",
op
);
}
}
#[test]
fn test_instr_info_all_jcc() {
let info = X86InstrInfo::new();
let jccs = [
X86Opcode::JO,
X86Opcode::JNO,
X86Opcode::JB,
X86Opcode::JAE,
X86Opcode::JE,
X86Opcode::JNE,
X86Opcode::JBE,
X86Opcode::JA,
X86Opcode::JS,
X86Opcode::JNS,
X86Opcode::JP,
X86Opcode::JNP,
X86Opcode::JL,
X86Opcode::JGE,
X86Opcode::JLE,
X86Opcode::JG,
];
for &op in &jccs {
let d = info.get(op);
assert!(d.is_terminator, "JCC {:?} should be terminator", op);
assert!(d.is_branch, "JCC {:?} should be branch", op);
}
}
#[test]
fn test_instr_info_all_setcc() {
let info = X86InstrInfo::new();
let setccs = [
X86Opcode::SETO,
X86Opcode::SETNO,
X86Opcode::SETB,
X86Opcode::SETAE,
X86Opcode::SETE,
X86Opcode::SETNE,
X86Opcode::SETBE,
X86Opcode::SETA,
X86Opcode::SETS,
X86Opcode::SETNS,
X86Opcode::SETP,
X86Opcode::SETNP,
X86Opcode::SETL,
X86Opcode::SETGE,
X86Opcode::SETLE,
X86Opcode::SETG,
];
for &op in &setccs {
let d = info.get(op);
assert_eq!(d.num_operands, 1, "SETcc {:?} should have 1 operand", op);
}
}
#[test]
fn test_x86_sched_info_constants() {
assert_eq!(X86SchedInfo::SIMPLE_ALU.latency, 1);
assert_eq!(X86SchedInfo::LOAD.latency, 5);
assert_eq!(X86SchedInfo::STORE.micro_ops, 2);
assert_eq!(X86SchedInfo::IMUL.latency, 3);
assert!(X86SchedInfo::IDIV.latency > 20);
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum X86InstrKind {
ALU,
Compare,
Move,
Stack,
Branch,
Call,
Return,
Float,
Vector,
Other,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct X86InstrFlags {
pub has_def: bool,
pub defs_flags: bool,
pub uses_flags: bool,
pub is_compare: bool,
pub is_call: bool,
pub is_branch: bool,
pub is_return: bool,
}