Skip to content

Instantly share code, notes, and snippets.

@progschj
Created January 20, 2014 10:19
Show Gist options
  • Save progschj/8517847 to your computer and use it in GitHub Desktop.
Save progschj/8517847 to your computer and use it in GitHub Desktop.
WiP x64 instruction encoding
typedef enum mnemonic_enum_t {
UNKNOWN=0,
ADC=1,
ADD,
AND,
BSF,
BSR,
BSWAP,
BT,
BTC,
BTR,
BTS,
CALL,
CBW,
CWDE,
CDQE,
CWD,
CDQ,
CQO,
CLC,
CLD,
CLFLUSH,
CMC,
CMOVO,
CMOVNO,
CMOVB,
CMOVC,
CMOVNAE,
CMOVNB,
CMOVNC,
CMOVAE,
CMOVZ,
CMOVE,
CMOVNZ,
CMOVNE,
CMOVBE,
CMOVNA,
CMOVNBE,
CMOVA,
CMOVS,
CMOVNS,
CMOVP,
CMOVPE,
CMOVNP,
CMOVPO,
CMOVL,
CMOVNGE,
CMOVNL,
CMOVGE,
CMOVLE,
CMOVNG,
CMOVNLE,
CMOVG,
CMP,
CMPSB,
CMPSW,
CMPSD,
CMPSQ,
CMPXCHG,
/*
CMPXCHG8B,
CMPXCHG16B,
*/
CPUID,
DEC,
DIV,
ENTER,
IDIV,
IMUL,
INC,
INT,
INTO,
JO,
JNO,
JB,
JC,
JNAE,
JNB,
JNC,
JAE,
JZ,
JE,
JNZ,
JNE,
JBE,
JNA,
JNBE,
JA,
JS,
JNS,
JP,
JPE,
JNP,
JPO,
JL,
JNGE,
JNL,
JGE,
JLE,
JNG,
JNLE,
JG,
JRCXZ,
JMP,
LAHF,
LEA,
LEAVE,
LFENCE,
LODSB,
LODSW,
LODSD,
LODSQ,
LOOP,
LOOPE,
LOOPZ,
LOOPNE,
LOOPNZ,
LZCNT,
MFENCE,
MOV,
MOVBE,
MOVD,
MOVQ = MOVD,
MOVMSKPD,
MOVMSKPS,
MOVNTI,
MOVSB,
MOVSW,
MOVSD,
MOVSQ,
MOVSX,
MOVSXD,
MOVZX,
MUL,
NEG,
NOP,
NOT,
OR,
PAUSE,
POP,
POPCNT,
POPF,
PREFETCH,
PREFETCHW,
PREFETCHNTA,
PREFETCH0,
PREFETCH1,
PREFETCH2,
PUSH,
PUSHF,
RCL,
RCR,
RET,
ROL,
ROR,
SAHF,
SAL,
SHL = SAL,
SAR,
SBB,
SCASB,
SCASW,
SCASD,
SCASQ,
SETO,
SETNO,
SETB,
SETC,
SETNAE,
SETNB,
SETNC,
SETAE,
SETZ,
SETE,
SETNZ,
SETNE,
SETBE,
SETNA,
SETNBE,
SETA,
SETS,
SETNS,
SETP,
SETPE,
SETNP,
SETPO,
SETL,
SETNGE,
SETNL,
SETGE,
SETLE,
SETNG,
SETNLE,
SETG,
SFENCE,
SHLD,
SHR,
SHRD,
STC,
STD,
STOSB,
STOSW,
STOSD,
STOSQ,
SUB,
TEST,
TZCNT,
XADD,
XCHG,
XLAT,
XOR,
RDTSC,
ADDPD,
ADDPS,
ADDSD,
ADDSS,
ADDSUBPD,
ADDSUBPS,
ANDNPD,
ANDNPS,
ANDPD,
ANDPS,
BLENDPD,
BLENDPS,
BLENDVPD,
BLENDVPS,
CMPPD,
CMPPS,
//CMPSD, //this already exists
CMPSS,
COMISD,
COMISS,
CVTDQ2PD,
CVTDQ2PS,
CVTPD2DQ,
CVTPD2PS,
CVTPS2DQ,
CVTPS2PD,
CVTSD2SI,
CVTSD2SS,
CVTSI2SD,
CVTSI2SS,
CVTSS2SD,
CVTSS2SI,
CVTTPD2DQ,
CVTTPS2DQ,
CVTTSD2SI,
CVTTSS2SI,
DIVPD,
DIVPS,
DIVSD,
DIVSS,
DPPD,
DPPS,
EXTRACTPS,
EXTRQ,
HADDPD,
HADDPS,
HSUBPD,
HSUBPS,
INSERTPS,
INSERTQ,
LDDQU,
LDMXCSR,
MASKMOVDQU,
MAXPD,
MAXPS,
MAXSD,
MAXSS,
MINPD,
MINPS,
MINSD,
MINSS,
MOVAPD,
MOVAPS,
MOVDDUP,
MOVDQA,
MOVDQU,
MOVHLPS,
MOVHPD,
MOVHPS,
MOVLHPS,
MOVLPD,
MOVLPS,
MOVNTDQ,
MOVNTDQA,
MOVNTPD,
MOVNTPS,
MOVNTSD,
MOVNTSS,
MOVSHDUP,
MOVSLDUP,
MOVSS,
MOVUPD,
MOVUPS,
MPSADBW,
MULPD,
MULPS,
MULSD,
MULSS,
ORPD,
ORPS,
PABSB,
PABSW,
PABSD,
PACKSSDW,
PACKSSWB,
PACKUSDW,
PACKUSWB,
PADDB,
PADDW,
PADDD,
PADDQ,
PADDSB,
PADDSW,
PADDUSB,
PADDUSW,
PALIGNR,
PAND,
PANDN,
PAVGB,
PAVGW,
PBLENDVB,
PBLENDW,
PCLMULQDQ,
PCMPEQB,
PCMPEQD,
PCMPEQW,
PCMPEQQ,
PCMPESTRI,
PCMPESTRM,
PCMPGTB,
PCMPGTD,
PCMPGTW,
PCMPGTQ,
PCMPISTRI,
PCMPISTRM,
PEXTRB,
PEXTRW,
PEXTRD,
PEXTRQ,
PHADDD,
PHADDSW,
PHADDW,
PHMINPOSUW,
PHSUBD,
PHSUBSW,
PHSUBW,
PINSRB,
PINSRW,
PINSRD,
PINSRQ,
PMADDUBSW,
PMADDWD,
PMAXSB,
PMAXSD,
PMAXSW,
PMAXSUB,
PMAXSUD,
PMAXSUW,
PMINSB,
PMINSD,
PMINSW,
PMINUB,
PMINUD,
PMINUW,
PMOVMSKB,
PMOVSXBD,
PMOVSXBQ,
PMOVSXBW,
PMOVSXDQ,
PMOVSXWD,
PMOVSXWQ,
PMOVZXBD,
PMOVZXBQ,
PMOVZXBW,
PMOVZXDQ,
PMOVZXWD,
PMOVZXWQ,
PMULDQ,
PMULHRSW,
PMULHUW,
PMULHW,
PMULLD,
PMULLW,
PMULUDQ,
POR,
PSADBW,
PSHUFB,
PSHUFD,
PSHUFLW,
PSIGNB,
PSIGND,
PSIGNW,
PSLLD,
PSLLDQ,
PSLLQ,
PSLLW,
PSRAD,
PSRAW,
PSRLD,
PSRLDQ,
PSRLQ,
PSRLW,
PSUBB,
PSUBD,
PSUBW,
PSUBQ,
PSUBSW,
PSUBUSB,
PSUBUSW,
PTEST,
PUNPCKHBW,
PUNPCKHDQ,
PUNPCKHQDQ,
PUNPCKHWD,
PUNPCKLBW,
PUNPCKLDQ,
PUNPCKLQDQ,
PUNPCKLWD,
PXOR,
RCPPS,
RCPSS,
ROUNDPD,
ROUNDPS,
ROUNDSD,
ROUNDSS,
RSQRTPS,
RSQRTSS,
SHUFPD,
SHUFPS,
SQRTPD,
SQRTPS,
SQRTSD,
SQRTSS,
SUBPD,
SUBPS,
SUBSD,
SUBSS,
UCOMISD,
UCOMISS,
MAX_MNEMONIC
} mnemonic_t;
typedef struct opcode_info_t {
mnemonic_t mnemonic;
optype_t operand1;
optype_t operand2;
optype_t operand3;
optype_t opcode;
unsigned char modrm;
unsigned char norex;
} opcode_info;
opcode_info instructions[] = {
{ADC, EXACT_AL, IMM8, 0, 0x14, ' ', 0},
{ADC, EXACT_AX, IMM16, 0, 0x15, ' ', 0},
{ADC, EXACT_EAX, IMM32, 0, 0x15, ' ', 0},
{ADC, EXACT_RAX, IMM32, 0, 0x15, ' ', 0},
{ADC, RM8, IMM8, 0, 0x80, '2', 0},
{ADC, RM16, IMM16, 0, 0x81, '2', 0},
{ADC, RM32, IMM32, 0, 0x81, '2', 0},
{ADC, RM64, IMM32, 0, 0x81, '2', 0},
{ADC, RM16, IMM8, 0, 0x83, '2', 0},
{ADC, RM32, IMM8, 0, 0x83, '2', 0},
{ADC, RM64, IMM8, 0, 0x83, '2', 0},
{ADC, REG8, RM8, 0, 0x12, 'r', 0},
{ADC, REG16, RM16, 0, 0x13, 'r', 0},
{ADC, REG32, RM32, 0, 0x13, 'r', 0},
{ADC, REG64, RM64, 0, 0x13, 'r', 0},
{ADC, RM8, REG8, 0, 0x10, 'r', 0},
{ADC, RM16, REG16, 0, 0x11, 'r', 0},
{ADC, RM32, REG32, 0, 0x11, 'r', 0},
{ADC, RM64, REG64, 0, 0x11, 'r', 0},
{ADD, EXACT_AL, IMM8, 0, 0x04, ' ', 0},
{ADD, EXACT_AX, IMM16, 0, 0x05, ' ', 0},
{ADD, EXACT_EAX, IMM32, 0, 0x05, ' ', 0},
{ADD, EXACT_RAX, IMM32, 0, 0x05, ' ', 0},
{ADD, RM8, IMM8, 0, 0x80, '0', 0},
{ADD, RM16, IMM16, 0, 0x81, '0', 0},
{ADD, RM32, IMM32, 0, 0x81, '0', 0},
{ADD, RM64, IMM32, 0, 0x81, '0', 0},
{ADD, RM16, IMM8, 0, 0x83, '0', 0},
{ADD, RM32, IMM8, 0, 0x83, '0', 0},
{ADD, RM64, IMM8, 0, 0x83, '0', 0},
{ADD, REG8, RM8, 0, 0x02, 'r', 0},
{ADD, REG16, RM16, 0, 0x03, 'r', 0},
{ADD, REG32, RM32, 0, 0x03, 'r', 0},
{ADD, REG64, RM64, 0, 0x03, 'r', 0},
{ADD, RM8, REG8, 0, 0x00, 'r', 0},
{ADD, RM16, REG16, 0, 0x01, 'r', 0},
{ADD, RM32, REG32, 0, 0x01, 'r', 0},
{ADD, RM64, REG64, 0, 0x01, 'r', 0},
{AND, EXACT_AL, IMM8, 0, 0x24, ' ', 0},
{AND, EXACT_AX, IMM16, 0, 0x25, ' ', 0},
{AND, EXACT_EAX, IMM32, 0, 0x25, ' ', 0},
{AND, EXACT_RAX, IMM32, 0, 0x25, ' ', 0},
{AND, RM8, IMM8, 0, 0x80, '4', 0},
{AND, RM16, IMM16, 0, 0x81, '4', 0},
{AND, RM32, IMM32, 0, 0x81, '4', 0},
{AND, RM64, IMM32, 0, 0x81, '4', 0},
{AND, RM16, IMM8, 0, 0x83, '4', 0},
{AND, RM32, IMM8, 0, 0x83, '4', 0},
{AND, RM64, IMM8, 0, 0x83, '4', 0},
{AND, REG8, RM8, 0, 0x22, 'r', 0},
{AND, REG16, RM16, 0, 0x23, 'r', 0},
{AND, REG32, RM32, 0, 0x23, 'r', 0},
{AND, REG64, RM64, 0, 0x23, 'r', 0},
{AND, RM8, REG8, 0, 0x20, 'r', 0},
{AND, RM16, REG16, 0, 0x21, 'r', 0},
{AND, RM32, REG32, 0, 0x21, 'r', 0},
{AND, RM64, REG64, 0, 0x21, 'r', 0},
{BSF, REG16, RM16, 0, 0xBC0F, 'r', 0},
{BSF, REG32, RM32, 0, 0xBC0F, 'r', 0},
{BSF, REG64, RM64, 0, 0xBC0F, 'r', 0},
{BSR, REG16, RM16, 0, 0xBD0F, 'r', 0},
{BSR, REG32, RM32, 0, 0xBD0F, 'r', 0},
{BSR, REG64, RM64, 0, 0xBD0F, 'r', 0},
{BSWAP, REG32, 0, 0, 0xC80F, '+', 0},
{BSWAP, REG64, 0, 0, 0xC80F, '+', 0},
{BT, RM16, REG16, 0, 0xA30F, 'r', 0},
{BT, RM32, REG32, 0, 0xA30F, 'r', 0},
{BT, RM64, REG64, 0, 0xA30F, 'r', 0},
{BT, RM16, IMM8, 0, 0xBA0F, '4', 0},
{BT, RM32, IMM8, 0, 0xBA0F, '4', 0},
{BT, RM64, IMM8, 0, 0xBA0F, '4', 0},
{BTC, RM16, REG16, 0, 0xBB0F, 'r', 0},
{BTC, RM32, REG32, 0, 0xBB0F, 'r', 0},
{BTC, RM64, REG64, 0, 0xBB0F, 'r', 0},
{BTC, RM16, IMM8, 0, 0xBA0F, '7', 0},
{BTC, RM32, IMM8, 0, 0xBA0F, '7', 0},
{BTC, RM64, IMM8, 0, 0xBA0F, '7', 0},
{BTR, RM16, REG16, 0, 0xB30F, 'r', 0},
{BTR, RM32, REG32, 0, 0xB30F, 'r', 0},
{BTR, RM64, REG64, 0, 0xB30F, 'r', 0},
{BTR, RM16, IMM8, 0, 0xBA0F, '6', 0},
{BTR, RM32, IMM8, 0, 0xBA0F, '6', 0},
{BTR, RM64, IMM8, 0, 0xBA0F, '6', 0},
{BTS, RM16, REG16, 0, 0xAB0F, 'r', 0},
{BTS, RM32, REG32, 0, 0xAB0F, 'r', 0},
{BTS, RM64, REG64, 0, 0xAB0F, 'r', 0},
{BTS, RM16, IMM8, 0, 0xBA0F, '5', 0},
{BTS, RM32, IMM8, 0, 0xBA0F, '5', 0},
{BTS, RM64, IMM8, 0, 0xBA0F, '5', 0},
{CALL, REL16OFF, 0, 0, 0xE8, ' ', 0},
{CALL, REL32OFF, 0, 0, 0xE8, ' ', 0},
{CALL, RM16, 0, 0, 0xFF, '2', NO_REX},
{CALL, RM64, 0, 0, 0xFF, '2', NO_REX},
{CBW, 0, 0, 0, 0x9866, ' ', 0},
{CWDE, 0, 0, 0, 0x98, ' ', 0},
{CDQE, 0, 0, 0, 0x9848, ' ', 0},
{CWD, 0, 0, 0, 0x9966, ' ', 0},
{CDQ, 0, 0, 0, 0x99, ' ', 0},
{CQO, 0, 0, 0, 0x9948, ' ', 0},
{CLC, 0, 0, 0, 0xF8, ' ', 0},
{CLD, 0, 0, 0, 0xFC, ' ', 0},
{CLFLUSH, MEM8, 0, 0, 0xAE0F, '7', 0},
{CMC, 0, 0, 0, 0xF5, ' ', 0},
{CMOVO, REG16, RM16, 0, 0x400F, 'r', 0},
{CMOVO, REG32, RM32, 0, 0x400F, 'r', 0},
{CMOVO, REG64, RM64, 0, 0x400F, 'r', 0},
{CMOVNO, REG16, RM16, 0, 0x410F, 'r', 0},
{CMOVNO, REG32, RM32, 0, 0x410F, 'r', 0},
{CMOVNO, REG64, RM64, 0, 0x410F, 'r', 0},
{CMOVB, REG16, RM16, 0, 0x420F, 'r', 0},
{CMOVB, REG32, RM32, 0, 0x420F, 'r', 0},
{CMOVB, REG64, RM64, 0, 0x420F, 'r', 0},
{CMOVC, REG16, RM16, 0, 0x420F, 'r', 0},
{CMOVC, REG32, RM32, 0, 0x420F, 'r', 0},
{CMOVC, REG64, RM64, 0, 0x420F, 'r', 0},
{CMOVNAE, REG16, RM16, 0, 0x420F, 'r', 0},
{CMOVNAE, REG32, RM32, 0, 0x420F, 'r', 0},
{CMOVNAE, REG64, RM64, 0, 0x420F, 'r', 0},
{CMOVNB, REG16, RM16, 0, 0x430F, 'r', 0},
{CMOVNB, REG32, RM32, 0, 0x430F, 'r', 0},
{CMOVNB, REG64, RM64, 0, 0x430F, 'r', 0},
{CMOVNC, REG16, RM16, 0, 0x430F, 'r', 0},
{CMOVNC, REG32, RM32, 0, 0x430F, 'r', 0},
{CMOVNC, REG64, RM64, 0, 0x430F, 'r', 0},
{CMOVAE, REG16, RM16, 0, 0x430F, 'r', 0},
{CMOVAE, REG32, RM32, 0, 0x430F, 'r', 0},
{CMOVAE, REG64, RM64, 0, 0x430F, 'r', 0},
{CMOVZ, REG16, RM16, 0, 0x440F, 'r', 0},
{CMOVZ, REG32, RM32, 0, 0x440F, 'r', 0},
{CMOVZ, REG64, RM64, 0, 0x440F, 'r', 0},
{CMOVE, REG16, RM16, 0, 0x440F, 'r', 0},
{CMOVE, REG32, RM32, 0, 0x440F, 'r', 0},
{CMOVE, REG64, RM64, 0, 0x440F, 'r', 0},
{CMOVNZ, REG16, RM16, 0, 0x450F, 'r', 0},
{CMOVNZ, REG32, RM32, 0, 0x450F, 'r', 0},
{CMOVNZ, REG64, RM64, 0, 0x450F, 'r', 0},
{CMOVNE, REG16, RM16, 0, 0x450F, 'r', 0},
{CMOVNE, REG32, RM32, 0, 0x450F, 'r', 0},
{CMOVNE, REG64, RM64, 0, 0x450F, 'r', 0},
{CMOVBE, REG16, RM16, 0, 0x460F, 'r', 0},
{CMOVBE, REG32, RM32, 0, 0x460F, 'r', 0},
{CMOVBE, REG64, RM64, 0, 0x460F, 'r', 0},
{CMOVNA, REG16, RM16, 0, 0x460F, 'r', 0},
{CMOVNA, REG32, RM32, 0, 0x460F, 'r', 0},
{CMOVNA, REG64, RM64, 0, 0x460F, 'r', 0},
{CMOVNBE, REG16, RM16, 0, 0x470F, 'r', 0},
{CMOVNBE, REG32, RM32, 0, 0x470F, 'r', 0},
{CMOVNBE, REG64, RM64, 0, 0x470F, 'r', 0},
{CMOVA, REG16, RM16, 0, 0x470F, 'r', 0},
{CMOVA, REG32, RM32, 0, 0x470F, 'r', 0},
{CMOVA, REG64, RM64, 0, 0x470F, 'r', 0},
{CMOVS, REG16, RM16, 0, 0x480F, 'r', 0},
{CMOVS, REG32, RM32, 0, 0x480F, 'r', 0},
{CMOVS, REG64, RM64, 0, 0x480F, 'r', 0},
{CMOVNS, REG16, RM16, 0, 0x490F, 'r', 0},
{CMOVNS, REG32, RM32, 0, 0x490F, 'r', 0},
{CMOVNS, REG64, RM64, 0, 0x490F, 'r', 0},
{CMOVP, REG16, RM16, 0, 0x4A0F, 'r', 0},
{CMOVP, REG32, RM32, 0, 0x4A0F, 'r', 0},
{CMOVP, REG64, RM64, 0, 0x4A0F, 'r', 0},
{CMOVPE, REG16, RM16, 0, 0x4A0F, 'r', 0},
{CMOVPE, REG32, RM32, 0, 0x4A0F, 'r', 0},
{CMOVPE, REG64, RM64, 0, 0x4A0F, 'r', 0},
{CMOVNP, REG16, RM16, 0, 0x4B0F, 'r', 0},
{CMOVNP, REG32, RM32, 0, 0x4B0F, 'r', 0},
{CMOVNP, REG64, RM64, 0, 0x4B0F, 'r', 0},
{CMOVPO, REG16, RM16, 0, 0x4B0F, 'r', 0},
{CMOVPO, REG32, RM32, 0, 0x4B0F, 'r', 0},
{CMOVPO, REG64, RM64, 0, 0x4B0F, 'r', 0},
{CMOVL, REG16, RM16, 0, 0x4C0F, 'r', 0},
{CMOVL, REG32, RM32, 0, 0x4C0F, 'r', 0},
{CMOVL, REG64, RM64, 0, 0x4C0F, 'r', 0},
{CMOVNGE, REG16, RM16, 0, 0x4C0F, 'r', 0},
{CMOVNGE, REG32, RM32, 0, 0x4C0F, 'r', 0},
{CMOVNGE, REG64, RM64, 0, 0x4C0F, 'r', 0},
{CMOVNL, REG16, RM16, 0, 0x4D0F, 'r', 0},
{CMOVNL, REG32, RM32, 0, 0x4D0F, 'r', 0},
{CMOVNL, REG64, RM64, 0, 0x4D0F, 'r', 0},
{CMOVGE, REG16, RM16, 0, 0x4D0F, 'r', 0},
{CMOVGE, REG32, RM32, 0, 0x4D0F, 'r', 0},
{CMOVGE, REG64, RM64, 0, 0x4D0F, 'r', 0},
{CMOVLE, REG16, RM16, 0, 0x4E0F, 'r', 0},
{CMOVLE, REG32, RM32, 0, 0x4E0F, 'r', 0},
{CMOVLE, REG64, RM64, 0, 0x4E0F, 'r', 0},
{CMOVNG, REG16, RM16, 0, 0x4E0F, 'r', 0},
{CMOVNG, REG32, RM32, 0, 0x4E0F, 'r', 0},
{CMOVNG, REG64, RM64, 0, 0x4E0F, 'r', 0},
{CMOVNLE, REG16, RM16, 0, 0x4F0F, 'r', 0},
{CMOVNLE, REG32, RM32, 0, 0x4F0F, 'r', 0},
{CMOVNLE, REG64, RM64, 0, 0x4F0F, 'r', 0},
{CMOVG, REG16, RM16, 0, 0x4F0F, 'r', 0},
{CMOVG, REG32, RM32, 0, 0x4F0F, 'r', 0},
{CMOVG, REG64, RM64, 0, 0x4F0F, 'r', 0},
{CMP, EXACT_AL, IMM8, 0, 0x3C, ' ', 0},
{CMP, EXACT_AX, IMM16, 0, 0x3D, ' ', 0},
{CMP, EXACT_EAX, IMM32, 0, 0x3D, ' ', 0},
{CMP, EXACT_RAX, IMM32, 0, 0x3D, ' ', 0},
{CMP, RM8, IMM8, 0, 0x80, '7', 0},
{CMP, RM16, IMM16, 0, 0x81, '7', 0},
{CMP, RM32, IMM32, 0, 0x81, '7', 0},
{CMP, RM64, IMM32, 0, 0x81, '7', 0},
{CMP, RM16, IMM8, 0, 0x83, '7', 0},
{CMP, RM32, IMM8, 0, 0x83, '7', 0},
{CMP, RM64, IMM8, 0, 0x83, '7', 0},
{CMP, REG8, RM8, 0, 0x3A, 'r', 0},
{CMP, REG16, RM16, 0, 0x3B, 'r', 0},
{CMP, REG32, RM32, 0, 0x3B, 'r', 0},
{CMP, REG64, RM64, 0, 0x3B, 'r', 0},
{CMP, RM8, REG8, 0, 0x38, 'r', 0},
{CMP, RM16, REG16, 0, 0x39, 'r', 0},
{CMP, RM32, REG32, 0, 0x39, 'r', 0},
{CMP, RM64, REG64, 0, 0x39, 'r', 0},
{CMPSB, 0, 0, 0, 0xA6, ' ', 0},
{CMPSW, 0, 0, 0, 0xA766, ' ', 0},
{CMPSD, 0, 0, 0, 0xA7, ' ', 0},
{CMPSQ, 0, 0, 0, 0xA748, ' ', 0},
{CMPXCHG, RM8, REG8, 0, 0xB00F, 'r', 0},
{CMPXCHG, RM16, REG16, 0, 0xB10F, 'r', 0},
{CMPXCHG, RM32, REG32, 0, 0xB10F, 'r', 0},
{CMPXCHG, RM64, REG64, 0, 0xB10F, 'r', 0},
/*
{CMPXCHG8B, MEM64, 0, 0, 0xC70F, '1', 0},
{CMPXCHG16B, MEM128, 0, 0, 0xC70F, '1', 0},
*/
{CPUID, 0, 0, 0, 0xA20F, ' ', 0},
{DEC, RM8, 0, 0, 0xFE, '1', 0},
{DEC, RM16, 0, 0, 0xFF, '1', 0},
{DEC, RM32, 0, 0, 0xFF, '1', 0},
{DEC, RM64, 0, 0, 0xFF, '1', 0},
{DIV, RM8, 0, 0, 0xF6, '6', 0},
{DIV, RM16, 0, 0, 0xF7, '6', 0},
{DIV, RM32, 0, 0, 0xF7, '6', 0},
{DIV, RM64, 0, 0, 0xF7, '6', 0},
{ENTER, IMM16, IMM8, 0, 0xC8, ' ', 0},
{IDIV, RM8, 0, 0, 0xF6, '7', 0},
{IDIV, RM16, 0, 0, 0xF7, '7', 0},
{IDIV, RM32, 0, 0, 0xF7, '7', 0},
{IDIV, RM64, 0, 0, 0xF7, '7', 0},
{IMUL, RM8, 0, 0, 0xF6, '5', 0},
{IMUL, RM16, 0, 0, 0xF7, '5', 0},
{IMUL, RM32, 0, 0, 0xF7, '5', 0},
{IMUL, RM64, 0, 0, 0xF7, '5', 0},
{IMUL, REG16, RM16, 0, 0xAF0F, 'r', 0},
{IMUL, REG32, RM32, 0, 0xAF0F, 'r', 0},
{IMUL, REG64, RM64, 0, 0xAF0F, 'r', 0},
{IMUL, REG16, RM16, IMM8, 0x6B, 'r', 0},
{IMUL, REG32, RM32, IMM8, 0x6B, 'r', 0},
{IMUL, REG64, RM64, IMM8, 0x6B, 'r', 0},
{IMUL, REG16, RM16, IMM16, 0x69, 'r', 0},
{IMUL, REG32, RM32, IMM32, 0x69, 'r', 0},
{IMUL, REG64, RM64, IMM32, 0x69, 'r', 0},
{INC, RM8, 0, 0, 0xFE, '0', 0},
{INC, RM16, 0, 0, 0xFF, '0', 0},
{INC, RM32, 0, 0, 0xFF, '0', 0},
{INC, RM64, 0, 0, 0xFF, '0', 0},
{INT, IMM8, 0, 0, 0xCD, ' ', 0},
{INTO, 0, 0, 0, 0xCE, ' ', 0},
{JO, REL16OFF, 0, 0, 0x800F, ' ', 0},
{JO, REL32OFF, 0, 0, 0x800F, ' ', 0},
{JNO, REL16OFF, 0, 0, 0x810F, ' ', 0},
{JNO, REL32OFF, 0, 0, 0x810F, ' ', 0},
{JB, REL16OFF, 0, 0, 0x820F, ' ', 0},
{JB, REL32OFF, 0, 0, 0x820F, ' ', 0},
{JC, REL16OFF, 0, 0, 0x820F, ' ', 0},
{JC, REL32OFF, 0, 0, 0x820F, ' ', 0},
{JNAE, REL16OFF, 0, 0, 0x820F, ' ', 0},
{JNAE, REL32OFF, 0, 0, 0x820F, ' ', 0},
{JNB, REL16OFF, 0, 0, 0x830F, ' ', 0},
{JNB, REL32OFF, 0, 0, 0x830F, ' ', 0},
{JNC, REL16OFF, 0, 0, 0x830F, ' ', 0},
{JNC, REL32OFF, 0, 0, 0x830F, ' ', 0},
{JAE, REL16OFF, 0, 0, 0x830F, ' ', 0},
{JAE, REL32OFF, 0, 0, 0x830F, ' ', 0},
{JZ, REL16OFF, 0, 0, 0x840F, ' ', 0},
{JZ, REL32OFF, 0, 0, 0x840F, ' ', 0},
{JE, REL16OFF, 0, 0, 0x840F, ' ', 0},
{JE, REL32OFF, 0, 0, 0x840F, ' ', 0},
{JNZ, REL16OFF, 0, 0, 0x850F, ' ', 0},
{JNZ, REL32OFF, 0, 0, 0x850F, ' ', 0},
{JNE, REL16OFF, 0, 0, 0x850F, ' ', 0},
{JNE, REL32OFF, 0, 0, 0x850F, ' ', 0},
{JBE, REL16OFF, 0, 0, 0x860F, ' ', 0},
{JBE, REL32OFF, 0, 0, 0x860F, ' ', 0},
{JNA, REL16OFF, 0, 0, 0x860F, ' ', 0},
{JNA, REL32OFF, 0, 0, 0x860F, ' ', 0},
{JNBE, REL16OFF, 0, 0, 0x870F, ' ', 0},
{JNBE, REL32OFF, 0, 0, 0x870F, ' ', 0},
{JA, REL16OFF, 0, 0, 0x870F, ' ', 0},
{JA, REL32OFF, 0, 0, 0x870F, ' ', 0},
{JS, REL16OFF, 0, 0, 0x880F, ' ', 0},
{JS, REL32OFF, 0, 0, 0x880F, ' ', 0},
{JNS, REL16OFF, 0, 0, 0x890F, ' ', 0},
{JNS, REL32OFF, 0, 0, 0x890F, ' ', 0},
{JP, REL16OFF, 0, 0, 0x8A0F, ' ', 0},
{JP, REL32OFF, 0, 0, 0x8A0F, ' ', 0},
{JPE, REL16OFF, 0, 0, 0x8A0F, ' ', 0},
{JPE, REL32OFF, 0, 0, 0x8A0F, ' ', 0},
{JNP, REL16OFF, 0, 0, 0x8B0F, ' ', 0},
{JNP, REL32OFF, 0, 0, 0x8B0F, ' ', 0},
{JPO, REL16OFF, 0, 0, 0x8B0F, ' ', 0},
{JPO, REL32OFF, 0, 0, 0x8B0F, ' ', 0},
{JL, REL16OFF, 0, 0, 0x8C0F, ' ', 0},
{JL, REL32OFF, 0, 0, 0x8C0F, ' ', 0},
{JNGE, REL16OFF, 0, 0, 0x8C0F, ' ', 0},
{JNGE, REL32OFF, 0, 0, 0x8C0F, ' ', 0},
{JNL, REL16OFF, 0, 0, 0x8D0F, ' ', 0},
{JNL, REL32OFF, 0, 0, 0x8D0F, ' ', 0},
{JGE, REL16OFF, 0, 0, 0x8D0F, ' ', 0},
{JGE, REL32OFF, 0, 0, 0x8D0F, ' ', 0},
{JLE, REL16OFF, 0, 0, 0x8E0F, ' ', 0},
{JLE, REL32OFF, 0, 0, 0x8E0F, ' ', 0},
{JNG, REL16OFF, 0, 0, 0x8E0F, ' ', 0},
{JNG, REL32OFF, 0, 0, 0x8E0F, ' ', 0},
{JNLE, REL16OFF, 0, 0, 0x8F0F, ' ', 0},
{JNLE, REL32OFF, 0, 0, 0x8F0F, ' ', 0},
{JG, REL16OFF, 0, 0, 0x8F0F, ' ', 0},
{JG, REL32OFF, 0, 0, 0x8F0F, ' ', 0},
{JO, REL8OFF, 0, 0, 0x70, ' ', 0},
{JNO, REL8OFF, 0, 0, 0x71, ' ', 0},
{JB, REL8OFF, 0, 0, 0x72, ' ', 0},
{JC, REL8OFF, 0, 0, 0x72, ' ', 0},
{JNAE, REL8OFF, 0, 0, 0x72, ' ', 0},
{JNB, REL8OFF, 0, 0, 0x73, ' ', 0},
{JNC, REL8OFF, 0, 0, 0x73, ' ', 0},
{JAE, REL8OFF, 0, 0, 0x73, ' ', 0},
{JZ, REL8OFF, 0, 0, 0x74, ' ', 0},
{JE, REL8OFF, 0, 0, 0x74, ' ', 0},
{JNZ, REL8OFF, 0, 0, 0x75, ' ', 0},
{JNE, REL8OFF, 0, 0, 0x75, ' ', 0},
{JBE, REL8OFF, 0, 0, 0x76, ' ', 0},
{JNA, REL8OFF, 0, 0, 0x76, ' ', 0},
{JNBE, REL8OFF, 0, 0, 0x77, ' ', 0},
{JA, REL8OFF, 0, 0, 0x77, ' ', 0},
{JS, REL8OFF, 0, 0, 0x78, ' ', 0},
{JNS, REL8OFF, 0, 0, 0x79, ' ', 0},
{JP, REL8OFF, 0, 0, 0x7A, ' ', 0},
{JPE, REL8OFF, 0, 0, 0x7A, ' ', 0},
{JNP, REL8OFF, 0, 0, 0x7B, ' ', 0},
{JPO, REL8OFF, 0, 0, 0x7B, ' ', 0},
{JL, REL8OFF, 0, 0, 0x7C, ' ', 0},
{JNGE, REL8OFF, 0, 0, 0x7C, ' ', 0},
{JNL, REL8OFF, 0, 0, 0x7D, ' ', 0},
{JGE, REL8OFF, 0, 0, 0x7D, ' ', 0},
{JLE, REL8OFF, 0, 0, 0x7E, ' ', 0},
{JNG, REL8OFF, 0, 0, 0x7E, ' ', 0},
{JNLE, REL8OFF, 0, 0, 0x7F, ' ', 0},
{JG, REL8OFF, 0, 0, 0x7F, ' ', 0},
{JRCXZ, REL8OFF, 0, 0, 0xE3, ' ', 0},
{JMP, REL8OFF, 0, 0, 0xEB, ' ', 0},
{JMP, REL16OFF, 0, 0, 0xE9, ' ', 0},
{JMP, REL32OFF, 0, 0, 0xE9, ' ', 0},
{JMP, RM16, 0, 0, 0xFF, '4', NO_REX},
{JMP, RM32, 0, 0, 0xFF, '4', NO_REX},
{JMP, RM64, 0, 0, 0xFF, '4', NO_REX},
{LAHF, 0, 0, 0, 0x9F, ' ', 0},
{LEA, REG16, MEM16, 0, 0x8D, 'r', 0},
{LEA, REG32, MEM32, 0, 0x8D, 'r', 0},
{LEA, REG64, MEM64, 0, 0x8D, 'r', 0},
{LEAVE, 0, 0, 0, 0xC9, ' ', 0},
{LFENCE, 0, 0, 0, 0xE8AE0F, ' ', 0},
{LODSB, 0, 0, 0, 0xAC, ' ', 0},
{LODSW, 0, 0, 0, 0xAD66, ' ', 0},
{LODSD, 0, 0, 0, 0xAD, ' ', 0},
{LODSQ, 0, 0, 0, 0xAD48, ' ', 0},
{LOOP, REL8OFF, 0, 0, 0xE2, ' ', 0},
{LOOPE, REL8OFF, 0, 0, 0xE1, ' ', 0},
{LOOPZ, REL8OFF, 0, 0, 0xE1, ' ', 0},
{LOOPNE, REL8OFF, 0, 0, 0xE0, ' ', 0},
{LOOPNZ, REL8OFF, 0, 0, 0xE0, ' ', 0},
{LZCNT, REG16, RM16, 0, 0xBD0FF3, 'r', 0},
{LZCNT, REG32, RM32, 0, 0xBD0FF3, 'r', 0},
{LZCNT, REG64, RM64, 0, 0xBD0FF3, 'r', 0},
{MFENCE, 0, 0, 0, 0xF0AE0F, ' ', 0},
{MOV, RM8, REG8, 0, 0x88, 'r', 0},
{MOV, RM16, REG16, 0, 0x89, 'r', 0},
{MOV, RM32, REG32, 0, 0x89, 'r', 0},
{MOV, RM64, REG64, 0, 0x89, 'r', 0},
{MOV, REG8, RM8, 0, 0x8A, 'r', 0},
{MOV, REG16, RM16, 0, 0x8B, 'r', 0},
{MOV, REG32, RM32, 0, 0x8B, 'r', 0},
{MOV, REG64, RM64, 0, 0x8B, 'r', 0},
{MOV, EXACT_AL, MOFFSET8, 0, 0xA0, ' ', 0},
{MOV, EXACT_AX, MOFFSET16, 0, 0xA1, ' ', 0},
{MOV, EXACT_EAX, MOFFSET32, 0, 0xA1, ' ', 0},
{MOV, EXACT_RAX, MOFFSET64, 0, 0xA1, ' ', 0},
{MOV, MOFFSET8, EXACT_AL, 0, 0xA2, ' ', 0},
{MOV, MOFFSET16, EXACT_AX, 0, 0xA3, ' ', 0},
{MOV, MOFFSET32, EXACT_EAX, 0, 0xA3, ' ', 0},
{MOV, MOFFSET64, EXACT_RAX, 0, 0xA3, ' ', 0},
{MOV, REG8, IMM8, 0, 0xB0, '+', 0},
{MOV, REG16, IMM16, 0, 0xB8, '+', 0},
{MOV, REG32, IMM32, 0, 0xB8, '+', 0},
{MOV, REG64, IMM64, 0, 0xB8, '+', 0},
{MOV, RM8, IMM8, 0, 0xC6, '0', 0},
{MOV, RM16, IMM16, 0, 0xC7, '0', 0},
{MOV, RM32, IMM32, 0, 0xC7, '0', 0},
{MOV, RM64, IMM32, 0, 0xC7, '0', 0},
{MOVBE, REG16, MEM16, 0, 0xF0380F, 'r', 0},
{MOVBE, REG32, MEM32, 0, 0xF0380F, 'r', 0},
{MOVBE, REG64, MEM64, 0, 0xF0380F, 'r', 0},
{MOVBE, MEM16, REG16, 0, 0xF1380F, 'r', 0},
{MOVBE, MEM32, REG32, 0, 0xF1380F, 'r', 0},
{MOVBE, MEM64, REG64, 0, 0xF1380F, 'r', 0},
{MOVD, XMM0, RM32, 0, 0x6E0F66, 'r', 0},
{MOVQ, XMM0, RM64, 0, 0x6E0F66, 'r', 0},
{MOVD, RM32, XMM0, 0, 0x7E0F66, 'r', 0},
{MOVQ, RM64, XMM0, 0, 0x7E0F66, 'r', 0},
{MOVMSKPD, REG32, XMM0, 0, 0x500F66, 'r', 0},
{MOVMSKPS, REG32, XMM0, 0, 0x500F, 'r', 0},
{MOVNTI, MEM32, REG32, 0, 0xC30F, 'r', 0},
{MOVNTI, MEM64, REG64, 0, 0xC30F, 'r', 0},
{MOVSB, 0, 0, 0, 0xA4, ' ', 0},
{MOVSW, 0, 0, 0, 0xA5, ' ', 0},
{MOVSD, 0, 0, 0, 0xA5, ' ', 0},
{MOVSQ, 0, 0, 0, 0xA5, ' ', 0},
{MOVSX, REG16, RM8, 0, 0xBE0F, 'r', 0},
{MOVSX, REG32, RM8, 0, 0xBE0F, 'r', 0},
{MOVSX, REG64, RM8, 0, 0xBE0F, 'r', 0},
//~ {MOVSX, REG32, RM16, 0, 0xBF0F, 'r', 0},
//~ {MOVSX, REG64, RM16, 0, 0xBF0F, 'r', 0},
{MOVSXD, REG64, RM32, 0, 0x63, 'r', 0},
{MOVZX, REG16, RM8, 0, 0xB60F, 'r', 0},
{MOVZX, REG32, RM8, 0, 0xB60F, 'r', 0},
{MOVZX, REG64, RM8, 0, 0xB60F, 'r', 0},
{MUL, RM8, 0, 0, 0xF6, '4', 0},
{MUL, RM16, 0, 0, 0xF7, '4', 0},
{MUL, RM32, 0, 0, 0xF7, '4', 0},
{MUL, RM64, 0, 0, 0xF7, '4', 0},
{MUL, RM64, 0, 0, 0xF7, '4', 0},
{NEG, RM8, 0, 0, 0xF6, '3', 0},
{NEG, RM16, 0, 0, 0xF7, '3', 0},
{NEG, RM32, 0, 0, 0xF7, '3', 0},
{NEG, RM64, 0, 0, 0xF7, '3', 0},
{NOP, 0, 0, 0, 0x90, ' ', 0},
{NOT, RM8, 0, 0, 0xF6, '2', 0},
{NOT, RM16, 0, 0, 0xF7, '2', 0},
{NOT, RM32, 0, 0, 0xF7, '2', 0},
{NOT, RM64, 0, 0, 0xF7, '2', 0},
{OR, EXACT_AL, IMM8, 0, 0x0C, ' ', 0},
{OR, EXACT_AX, IMM16, 0, 0x0D, ' ', 0},
{OR, EXACT_EAX, IMM32, 0, 0x0D, ' ', 0},
{OR, EXACT_RAX, IMM32, 0, 0x0D, ' ', 0},
{OR, RM8, IMM8, 0, 0x80, '1', 0},
{OR, RM16, IMM16, 0, 0x81, '1', 0},
{OR, RM32, IMM32, 0, 0x81, '1', 0},
{OR, RM64, IMM32, 0, 0x81, '1', 0},
{OR, RM16, IMM8, 0, 0x83, '1', 0},
{OR, RM32, IMM8, 0, 0x83, '1', 0},
{OR, RM64, IMM8, 0, 0x83, '1', 0},
{OR, REG8, RM8, 0, 0x0A, 'r', 0},
{OR, REG16, RM16, 0, 0x0B, 'r', 0},
{OR, REG32, RM32, 0, 0x0B, 'r', 0},
{OR, REG64, RM64, 0, 0x0B, 'r', 0},
{OR, RM8, REG8, 0, 0x08, 'r', 0},
{OR, RM16, REG16, 0, 0x09, 'r', 0},
{OR, RM32, REG32, 0, 0x09, 'r', 0},
{OR, RM64, REG64, 0, 0x09, 'r', 0},
{PAUSE, 0, 0, 0, 0x90F3, ' ', 0},
{POP, REG16, 0, 0, 0x58, '+', NO_REX},
{POP, REG64, 0, 0, 0x58, '+', NO_REX},
{POP, RM16, 0, 0, 0x8F, '0', NO_REX},
{POP, RM64, 0, 0, 0x8F, '0', NO_REX},
{POPCNT, REG16, RM16, 0, 0xB80FF3, 'r', 0},
{POPCNT, REG32, RM32, 0, 0xB80FF3, 'r', 0},
{POPCNT, REG64, RM64, 0, 0xB80FF3, 'r', 0},
{POPF, 0, 0, 0, 0x9D, ' ', 0},
{PREFETCH, MEM8, 0, 0, 0x0D0F, '0', 0},
{PREFETCHW, MEM8, 0, 0, 0x0D0F, '1', 0},
{PREFETCHNTA, MEM8, 0, 0, 0x180F, '0', 0},
{PREFETCH0, MEM8, 0, 0, 0x180F, '1', 0},
{PREFETCH1, MEM8, 0, 0, 0x180F, '2', 0},
{PREFETCH2, MEM8, 0, 0, 0x180F, '3', 0},
{PUSH, REG16, 0, 0, 0x50, '+', NO_REX},
{PUSH, REG64, 0, 0, 0x50, '+', NO_REX},
{PUSH, RM16, 0, 0, 0xFF, '6', NO_REX},
{PUSH, RM64, 0, 0, 0xFF, '6', NO_REX},
{PUSH, IMM8, 0, 0, 0x6A, ' ', NO_REX},
{PUSH, IMM16, 0, 0, 0x68, ' ', NO_REX},
{PUSH, IMM32, 0, 0, 0x68, ' ', NO_REX},
{PUSHF, 0, 0, 0, 0x9C, ' ', 0},
{RCL, RM8, 0, 0, 0xD0, '2', 0},
{RCL, RM8, 0, 0, 0xD2, '2', 0},
{RCL, RM8, IMM8, 0, 0xC0, '2', 0},
{RCL, RM16, 0, 0, 0xD1, '2', 0},
{RCL, RM16, 0, 0, 0xD3, '2', 0},
{RCL, RM16, IMM8, 0, 0xC1, '2', 0},
{RCL, RM32, 0, 0, 0xD1, '2', 0},
{RCL, RM32, 0, 0, 0xD3, '2', 0},
{RCL, RM32, IMM8, 0, 0xC1, '2', 0},
{RCL, RM64, 0, 0, 0xD1, '2', 0},
{RCL, RM64, 0, 0, 0xD3, '2', 0},
{RCL, RM64, IMM8, 0, 0xC1, '2', 0},
{RCR, RM8, 0, 0, 0xD0, '3', 0},
{RCR, RM8, 0, 0, 0xD2, '3', 0},
{RCR, RM8, IMM8, 0, 0xC0, '3', 0},
{RCR, RM16, 0, 0, 0xD1, '3', 0},
{RCR, RM16, 0, 0, 0xD3, '3', 0},
{RCR, RM16, IMM8, 0, 0xC1, '3', 0},
{RCR, RM32, 0, 0, 0xD1, '3', 0},
{RCR, RM32, 0, 0, 0xD3, '3', 0},
{RCR, RM32, IMM8, 0, 0xC1, '3', 0},
{RCR, RM64, 0, 0, 0xD1, '3', 0},
{RCR, RM64, 0, 0, 0xD3, '3', 0},
{RCR, RM64, IMM8, 0, 0xC1, '3', 0},
{RET, IMM16, 0, 0, 0xC2, ' ', 0},
{RET, 0, 0, 0, 0xC3, ' ', 0},
{ROL, RM8, 0, 0, 0xD0, '0', 0},
{ROL, RM8, 0, 0, 0xD2, '0', 0},
{ROL, RM8, IMM8, 0, 0xC0, '0', 0},
{ROL, RM16, 0, 0, 0xD1, '0', 0},
{ROL, RM16, 0, 0, 0xD3, '0', 0},
{ROL, RM16, IMM8, 0, 0xC1, '0', 0},
{ROL, RM32, 0, 0, 0xD1, '0', 0},
{ROL, RM32, 0, 0, 0xD3, '0', 0},
{ROL, RM32, IMM8, 0, 0xC1, '0', 0},
{ROL, RM64, 0, 0, 0xD1, '0', 0},
{ROL, RM64, 0, 0, 0xD3, '0', 0},
{ROL, RM64, IMM8, 0, 0xC1, '0', 0},
{ROR, RM8, 0, 0, 0xD0, '1', 0},
{ROR, RM8, 0, 0, 0xD2, '1', 0},
{ROR, RM8, IMM8, 0, 0xC0, '1', 0},
{ROR, RM16, 0, 0, 0xD1, '1', 0},
{ROR, RM16, 0, 0, 0xD3, '1', 0},
{ROR, RM16, IMM8, 0, 0xC1, '1', 0},
{ROR, RM32, 0, 0, 0xD1, '1', 0},
{ROR, RM32, 0, 0, 0xD3, '1', 0},
{ROR, RM32, IMM8, 0, 0xC1, '1', 0},
{ROR, RM64, 0, 0, 0xD1, '1', 0},
{ROR, RM64, 0, 0, 0xD3, '1', 0},
{ROR, RM64, IMM8, 0, 0xC1, '1', 0},
{SAHF, 0, 0, 0, 0x9E, ' ', 0},
{SHL, RM8, 0, 0, 0xD0, '4', 0},
{SHL, RM8, 0, 0, 0xD2, '4', 0},
{SHL, RM8, IMM8, 0, 0xC0, '4', 0},
{SHL, RM16, 0, 0, 0xD1, '4', 0},
{SHL, RM16, 0, 0, 0xD3, '4', 0},
{SHL, RM16, IMM8, 0, 0xC1, '4', 0},
{SHL, RM32, 0, 0, 0xD1, '4', 0},
{SHL, RM32, 0, 0, 0xD3, '4', 0},
{SHL, RM32, IMM8, 0, 0xC1, '4', 0},
{SHL, RM64, 0, 0, 0xD1, '4', 0},
{SHL, RM64, 0, 0, 0xD3, '4', 0},
{SHL, RM64, IMM8, 0, 0xC1, '4', 0},
{SAR, RM8, 0, 0, 0xD0, '7', 0},
{SAR, RM8, 0, 0, 0xD2, '7', 0},
{SAR, RM8, IMM8, 0, 0xC0, '7', 0},
{SAR, RM16, 0, 0, 0xD1, '7', 0},
{SAR, RM16, 0, 0, 0xD3, '7', 0},
{SAR, RM16, IMM8, 0, 0xC1, '7', 0},
{SAR, RM32, 0, 0, 0xD1, '7', 0},
{SAR, RM32, 0, 0, 0xD3, '7', 0},
{SAR, RM32, IMM8, 0, 0xC1, '7', 0},
{SAR, RM64, 0, 0, 0xD1, '7', 0},
{SAR, RM64, 0, 0, 0xD3, '7', 0},
{SAR, RM64, IMM8, 0, 0xC1, '7', 0},
{SBB, EXACT_AL, IMM8, 0, 0x1C, ' ', 0},
{SBB, EXACT_AX, IMM16, 0, 0x1D, ' ', 0},
{SBB, EXACT_EAX, IMM32, 0, 0x1D, ' ', 0},
{SBB, EXACT_RAX, IMM32, 0, 0x1D, ' ', 0},
{SBB, RM8, IMM8, 0, 0x80, '3', 0},
{SBB, RM16, IMM16, 0, 0x81, '3', 0},
{SBB, RM32, IMM32, 0, 0x81, '3', 0},
{SBB, RM64, IMM32, 0, 0x81, '3', 0},
{SBB, RM16, IMM8, 0, 0x83, '3', 0},
{SBB, RM32, IMM8, 0, 0x83, '3', 0},
{SBB, RM64, IMM8, 0, 0x83, '3', 0},
{SBB, REG8, RM8, 0, 0x1A, 'r', 0},
{SBB, REG16, RM16, 0, 0x1B, 'r', 0},
{SBB, REG32, RM32, 0, 0x1B, 'r', 0},
{SBB, REG64, RM64, 0, 0x1B, 'r', 0},
{SBB, RM8, REG8, 0, 0x18, 'r', 0},
{SBB, RM16, REG16, 0, 0x19, 'r', 0},
{SBB, RM32, REG32, 0, 0x19, 'r', 0},
{SBB, RM64, REG64, 0, 0x19, 'r', 0},
{SCASB, 0, 0, 0, 0xAE, ' ', 0},
{SCASW, 0, 0, 0, 0xAF66, ' ', 0},
{SCASD, 0, 0, 0, 0xAF, ' ', 0},
{SCASQ, 0, 0, 0, 0xAF48, ' ', 0},
{SETO, RM8, 0, 0, 0x900F, '0', 0},
{SETNO, RM8, 0, 0, 0x910F, '0', 0},
{SETB, RM8, 0, 0, 0x920F, '0', 0},
{SETC, RM8, 0, 0, 0x920F, '0', 0},
{SETNAE, RM8, 0, 0, 0x920F, '0', 0},
{SETNB, RM8, 0, 0, 0x930F, '0', 0},
{SETNC, RM8, 0, 0, 0x930F, '0', 0},
{SETAE, RM8, 0, 0, 0x930F, '0', 0},
{SETZ, RM8, 0, 0, 0x940F, '0', 0},
{SETE, RM8, 0, 0, 0x940F, '0', 0},
{SETNZ, RM8, 0, 0, 0x950F, '0', 0},
{SETNE, RM8, 0, 0, 0x950F, '0', 0},
{SETBE, RM8, 0, 0, 0x960F, '0', 0},
{SETNA, RM8, 0, 0, 0x960F, '0', 0},
{SETNBE, RM8, 0, 0, 0x970F, '0', 0},
{SETA, RM8, 0, 0, 0x970F, '0', 0},
{SETS, RM8, 0, 0, 0x980F, '0', 0},
{SETNS, RM8, 0, 0, 0x990F, '0', 0},
{SETP, RM8, 0, 0, 0x9A0F, '0', 0},
{SETPE, RM8, 0, 0, 0x9A0F, '0', 0},
{SETNP, RM8, 0, 0, 0x9B0F, '0', 0},
{SETPO, RM8, 0, 0, 0x9B0F, '0', 0},
{SETL, RM8, 0, 0, 0x9C0F, '0', 0},
{SETNGE, RM8, 0, 0, 0x9C0F, '0', 0},
{SETNL, RM8, 0, 0, 0x9D0F, '0', 0},
{SETGE, RM8, 0, 0, 0x9D0F, '0', 0},
{SETLE, RM8, 0, 0, 0x9E0F, '0', 0},
{SETNG, RM8, 0, 0, 0x9E0F, '0', 0},
{SETNLE, RM8, 0, 0, 0x9F0F, '0', 0},
{SETG, RM8, 0, 0, 0x9F0F, '0', 0},
{SFENCE, 0, 0, 0, 0xF8AE0F, ' ', 0},
{SHLD, RM16, REG16, IMM8, 0xA40F, 'r', 0},
{SHLD, RM16, REG16, 0, 0xA50F, 'r', 0},
{SHLD, RM32, REG32, IMM8, 0xA40F, 'r', 0},
{SHLD, RM32, REG32, 0, 0xA50F, 'r', 0},
{SHLD, RM64, REG64, IMM8, 0xA40F, 'r', 0},
{SHLD, RM64, REG64, 0, 0xA50F, 'r', 0},
{SHR, RM8, 0, 0, 0xD0, '5', 0},
{SHR, RM8, 0, 0, 0xD2, '5', 0},
{SHR, RM8, IMM8, 0, 0xC0, '5', 0},
{SHR, RM16, 0, 0, 0xD1, '5', 0},
{SHR, RM16, 0, 0, 0xD3, '5', 0},
{SHR, RM16, IMM8, 0, 0xC1, '5', 0},
{SHR, RM32, 0, 0, 0xD1, '5', 0},
{SHR, RM32, 0, 0, 0xD3, '5', 0},
{SHR, RM32, IMM8, 0, 0xC1, '5', 0},
{SHR, RM64, 0, 0, 0xD1, '5', 0},
{SHR, RM64, 0, 0, 0xD3, '5', 0},
{SHR, RM64, IMM8, 0, 0xC1, '5', 0},
{SHRD, RM16, REG16, IMM8, 0xAC0F, 'r', 0},
{SHRD, RM16, REG16, 0, 0xAD0F, 'r', 0},
{SHRD, RM32, REG32, IMM8, 0xAC0F, 'r', 0},
{SHRD, RM32, REG32, 0, 0xAD0F, 'r', 0},
{SHRD, RM64, REG64, IMM8, 0xAC0F, 'r', 0},
{SHRD, RM64, REG64, 0, 0xAD0F, 'r', 0},
{STC, 0, 0, 0, 0xF9, ' ', 0},
{STD, 0, 0, 0, 0xFD, ' ', 0},
{STOSB, 0, 0, 0, 0xAA, ' ', 0},
{STOSW, 0, 0, 0, 0xAB66, ' ', 0},
{STOSD, 0, 0, 0, 0xAB, ' ', 0},
{STOSQ, 0, 0, 0, 0xAB48, ' ', 0},
{SUB, EXACT_AL, IMM8, 0, 0x2C, ' ', 0},
{SUB, EXACT_AX, IMM16, 0, 0x2D, ' ', 0},
{SUB, EXACT_EAX, IMM32, 0, 0x2D, ' ', 0},
{SUB, EXACT_RAX, IMM32, 0, 0x2D, ' ', 0},
{SUB, RM8, IMM8, 0, 0x80, '5', 0},
{SUB, RM16, IMM16, 0, 0x81, '5', 0},
{SUB, RM32, IMM32, 0, 0x81, '5', 0},
{SUB, RM64, IMM32, 0, 0x81, '5', 0},
{SUB, RM16, IMM8, 0, 0x83, '5', 0},
{SUB, RM32, IMM8, 0, 0x83, '5', 0},
{SUB, RM64, IMM8, 0, 0x83, '5', 0},
{SUB, REG8, RM8, 0, 0x2A, 'r', 0},
{SUB, REG16, RM16, 0, 0x2B, 'r', 0},
{SUB, REG32, RM32, 0, 0x2B, 'r', 0},
{SUB, REG64, RM64, 0, 0x2B, 'r', 0},
{SUB, RM8, REG8, 0, 0x28, 'r', 0},
{SUB, RM16, REG16, 0, 0x29, 'r', 0},
{SUB, RM32, REG32, 0, 0x29, 'r', 0},
{SUB, RM64, REG64, 0, 0x29, 'r', 0},
{TEST, EXACT_AL, IMM8, 0, 0xA8, ' ', 0},
{TEST, EXACT_AX, IMM16, 0, 0xA9, ' ', 0},
{TEST, EXACT_EAX, IMM32, 0, 0xA9, ' ', 0},
{TEST, EXACT_RAX, IMM32, 0, 0xA9, ' ', 0},
{TEST, RM8, IMM8, 0, 0xF6, '0', 0},
{TEST, RM16, IMM16, 0, 0xF7, '0', 0},
{TEST, RM32, IMM32, 0, 0xF7, '0', 0},
{TEST, RM64, IMM32, 0, 0xF7, '0', 0},
{TEST, RM8, REG8, 0, 0x84, 'r', 0},
{TEST, RM16, REG16, 0, 0x85, 'r', 0},
{TEST, RM32, REG32, 0, 0x85, 'r', 0},
{TEST, RM64, REG32, 0, 0x85, 'r', 0},
{TZCNT, REG16, RM16, 0, 0xBC0FF3, 'r', 0},
{TZCNT, REG32, RM32, 0, 0xBC0FF3, 'r', 0},
{TZCNT, REG64, RM64, 0, 0xBC0FF3, 'r', 0},
{XADD, RM8, REG8, 0, 0xC00F, 'r', 0},
{XADD, RM16, REG16, 0, 0xC10F, 'r', 0},
{XADD, RM32, REG32, 0, 0xC10F, 'r', 0},
{XADD, RM64, REG64, 0, 0xC10F, 'r', 0},
{XCHG, EXACT_AX, REG16, 0, 0x90, '+', 0},
{XCHG, REG16, EXACT_AX, 0, 0x90, '+', 0},
{XCHG, EXACT_EAX, REG32, 0, 0x90, '+', 0},
{XCHG, REG32, EXACT_EAX, 0, 0x90, '+', 0},
{XCHG, EXACT_RAX, REG64, 0, 0x90, '+', 0},
{XCHG, REG64, EXACT_RAX, 0, 0x90, '+', 0},
{XCHG, RM8 , REG8 , 0, 0x86, 'r', 0},
{XCHG, RM16 , REG16, 0, 0x87, 'r', 0},
{XCHG, RM32 , REG32, 0, 0x87, 'r', 0},
{XCHG, RM64 , REG64, 0, 0x87, 'r', 0},
{XCHG, REG8 , RM8 , 0, 0x86, 'r', 0},
{XCHG, REG16 , RM16, 0, 0x87, 'r', 0},
{XCHG, REG32 , RM32, 0, 0x87, 'r', 0},
{XCHG, REG64 , RM64, 0, 0x87, 'r', 0},
{XLAT, 0, 0, 0, 0xD7, ' ', 0},
{XOR, EXACT_AL, IMM8, 0, 0x34, ' ', 0},
{XOR, EXACT_AX, IMM16, 0, 0x35, ' ', 0},
{XOR, EXACT_EAX, IMM32, 0, 0x35, ' ', 0},
{XOR, EXACT_RAX, IMM32, 0, 0x35, ' ', 0},
{XOR, RM8, IMM8, 0, 0x80, '6', 0},
{XOR, RM16, IMM16, 0, 0x81, '6', 0},
{XOR, RM32, IMM32, 0, 0x81, '6', 0},
{XOR, RM64, IMM32, 0, 0x81, '6', 0},
{XOR, RM16, IMM8, 0, 0x83, '6', 0},
{XOR, RM32, IMM8, 0, 0x83, '6', 0},
{XOR, RM64, IMM8, 0, 0x83, '6', 0},
{XOR, REG8, RM8, 0, 0x32, 'r', 0},
{XOR, REG16, RM16, 0, 0x33, 'r', 0},
{XOR, REG32, RM32, 0, 0x33, 'r', 0},
{XOR, REG64, RM64, 0, 0x33, 'r', 0},
{XOR, RM8, REG8, 0, 0x30, 'r', 0},
{XOR, RM16, REG16, 0, 0x31, 'r', 0},
{XOR, RM32, REG32, 0, 0x31, 'r', 0},
{XOR, RM64, REG64, 0, 0x31, 'r', 0},
{RDTSC, 0, 0, 0, 0x310F, ' ', 0},
{ADDPD, XMM0, RM128, 0, 0x580F66, 'r', 0},
{ADDPS, XMM0, RM128, 0, 0x580F, 'r', 0},
{ADDSD, XMM0, RM128, 0, 0x580FF2, 'r', 0},
{ADDSS, XMM0, RM128, 0, 0x580FF3, 'r', 0},
{ADDSUBPD, XMM0, RM128, 0, 0xD00F66, 'r', 0},
{ADDSUBPS, XMM0, RM128, 0, 0xD00FF2, 'r', 0},
{ANDNPD, XMM0, RM128, 0, 0x550F66, 'r', 0},
{ANDNPS, XMM0, RM128, 0, 0x550F, 'r', 0},
{ANDPD, XMM0, RM128, 0, 0x540F66, 'r', 0},
{ANDPS, XMM0, RM128, 0, 0x540F, 'r', 0},
{BLENDPD, XMM0, RM128, IMM8, 0x0D3A0F66u, 'r', 0},
{BLENDPS, XMM0, RM128, IMM8, 0x0C3A0F66u, 'r', 0},
{BLENDVPD, XMM0, RM128, 0, 0x15380F66, 'r', 0},
{BLENDVPS, XMM0, RM128, 0, 0x14380F66, 'r', 0},
{CMPPD, XMM0, RM128, IMM8, 0xC20F66, 'r', 0},
{CMPPS, XMM0, RM128, IMM8, 0xC20F, 'r', 0},
{CMPSD, XMM0, RM128, IMM8, 0xC20FF2, 'r', 0},
{CMPSS, XMM0, RM128, IMM8, 0xC20FF3, 'r', 0},
{COMISD, XMM0, RM128, 0, 0x2F0F66, 'r', 0},
{COMISS, XMM0, RM128, 0, 0x2F0F, 'r', 0},
{CVTDQ2PD, XMM0, RM128, 0, 0xE60FF3, 'r', 0},
{CVTDQ2PS, XMM0, RM128, 0, 0x5B0F, 'r', 0},
{CVTPD2DQ, XMM0, RM128, 0, 0xE60FF2, 'r', 0},
{CVTPD2PS, XMM0, RM128, 0, 0x5A0F66, 'r', 0},
{CVTPS2DQ, XMM0, RM128, 0, 0x5B0F66, 'r', 0},
{CVTPS2PD, XMM0, RM128, 0, 0x5A0F, 'r', 0},
{CVTSD2SI, REG32, RM128, 0, 0x2D0FF2, 'r', 0},
{CVTSD2SI, REG64, RM128, 0, 0x2D0FF2, 'r', 0},
{CVTSD2SS, XMM0, RM128, 0, 0x5A0FF2, 'r', 0},
{CVTSI2SD, XMM0, RM32, 0, 0x2A0FF2, 'r', 0},
{CVTSI2SD, XMM0, RM64, 0, 0x2A0FF2, 'r', 0},
{CVTSI2SS, XMM0, RM32, 0, 0x2A0FF3, 'r', 0},
{CVTSI2SS, XMM0, RM64, 0, 0x2A0FF3, 'r', 0},
{CVTSS2SD, XMM0, RM128, 0, 0x5A0FF3, 'r', 0},
{CVTSS2SI, REG32, RM128, 0, 0x2D0FF3, 'r', 0},
{CVTSS2SI, REG64, RM128, 0, 0x2D0FF3, 'r', 0},
{CVTTPD2DQ, XMM0, RM128, 0, 0xE60F66, 'r', 0},
{CVTTPS2DQ, XMM0, RM128, 0, 0x5B0FF3, 'r', 0},
{CVTTSD2SI, REG32, RM128, 0, 0x2C0FF2, 'r', 0},
{CVTTSD2SI, REG64, RM128, 0, 0x2C0FF2, 'r', 0},
{CVTTSS2SI, REG32, RM128, 0, 0x2C0FF3, 'r', 0},
{CVTTSS2SI, REG64, RM128, 0, 0x2C0FF3, 'r', 0},
{DIVPD, XMM0, RM128, 0, 0x5E0F66, 'r', 0},
{DIVPS, XMM0, RM128, 0, 0x5E0F, 'r', 0},
{DIVSD, XMM0, RM128, 0, 0x5E0FF2, 'r', 0},
{DIVSS, XMM0, RM128, 0, 0x5E0FF3, 'r', 0},
{DPPD, XMM0, RM128, IMM8, 0x413A0F66u, 'r', 0},
{DPPS, XMM0, RM128, IMM8, 0x403A0F66u, 'r', 0},
{EXTRACTPS, RM32, XMM0, IMM8, 0x173A0F66u, 'r', 0},
{EXTRQ, XMM0, IMM8, IMM8, 0x780F66, '0', 0},
{EXTRQ, XMM0, XMM0, 0, 0x790F66, 'r', 0},
{HADDPD, XMM0, RM128, 0, 0x7C0F66, 'r', 0},
{HADDPS, XMM0, RM128, 0, 0x7C0FF2, 'r', 0},
{HSUBPD, XMM0, RM128, 0, 0x7D0F66, 'r', 0},
{HSUBPS, XMM0, RM128, 0, 0x7D0FF2, 'r', 0},
{INSERTPS, XMM0, RM128, IMM8, 0x213A0F66u, 'r', 0},
{INSERTQ, XMM0, XMM0, IMM8, 0x780FF2, 'r', 0},
{INSERTQ, XMM0, XMM0, 0, 0x790FF2, 'r', 0},
{LDDQU, XMM0, RM128, 0, 0xF00FF2, 'r', 0},
{MASKMOVDQU, XMM0, XMM0, 0, 0xF70F66, 'r', 0},
{MAXPD, XMM0, RM128, 0, 0x5F0F66, 'r', 0},
{MAXPS, XMM0, RM128, 0, 0x5F0F, 'r', 0},
{MAXSD, XMM0, RM128, 0, 0x5F0FF2, 'r', 0},
{MAXSS, XMM0, RM128, 0, 0x5F0FF3, 'r', 0},
{MINPD, XMM0, RM128, 0, 0x5D0F66, 'r', 0},
{MINPS, XMM0, RM128, 0, 0x5D0F, 'r', 0},
{MINSD, XMM0, RM128, 0, 0x5D0FF2, 'r', 0},
{MINSS, XMM0, RM128, 0, 0x5D0FF3, 'r', 0},
{MOVAPD, XMM0, RM128, 0, 0x280F66, 'r', 0},
{MOVAPD, RM128, XMM0, 0, 0x290F66, 'r', 0},
{MOVAPS, XMM0, RM128, 0, 0x280F66, 'r', 0},
{MOVAPS, RM128, XMM0, 0, 0x290F66, 'r', 0},
{MOVDDUP, XMM0, RM128, 0, 0x120FF2, 'r', 0},
{MOVDQA, XMM0, RM128, 0, 0x6F0F66, 'r', 0},
{MOVDQA, RM128, XMM0, 0, 0x7F0F66, 'r', 0},
{MOVDQU, XMM0, RM128, 0, 0x6F0FF3, 'r', 0},
{MOVDQU, RM128, XMM0, 0, 0x7F0FF3, 'r', 0},
{MOVHLPS, XMM0, XMM0, 0, 0x120F, 'r', 0},
{MOVHPD, XMM0, MEM64, 0, 0x160F66, 'r', 0},
{MOVHPD, MEM64, XMM0, 0, 0x170F66, 'r', 0},
{MOVHPS, XMM0, MEM64, 0, 0x160F, 'r', 0},
{MOVHPS, MEM64, XMM0, 0, 0x170F, 'r', 0},
{MOVLHPS, XMM0, XMM0, 0, 0x160F, 'r', 0},
{MOVLPD, XMM0, MEM64, 0, 0x120F66, 'r', 0},
{MOVHPD, MEM64, XMM0, 0, 0x130F66, 'r', 0},
{MOVLPS, XMM0, MEM64, 0, 0x120F, 'r', 0},
{MOVLPS, MEM64, XMM0, 0, 0x130F, 'r', 0},
{MOVNTDQ, MEM128, XMM0, 0, 0xE70F66, 'r', 0},
{MOVNTDQA, MEM128, XMM0, 0, 0x2A380F66u, 'r', 0},
{MOVNTPD, MEM128, XMM0, 0, 0x2B0F66, 'r', 0},
{MOVNTPS, MEM128, XMM0, 0, 0x2B0F, 'r', 0},
{MOVNTSD, MEM128, XMM0, 0, 0x2B0FF2, 'r', 0},
{MOVNTSS, MEM128, XMM0, 0, 0x2B0FF3, 'r', 0},
{MOVSD, XMM0, RM128, 0, 0x100FF2, 'r', 0},
{MOVSD, RM128, XMM0, 0, 0x110FF2, 'r', 0},
{MOVSHDUP, XMM0, RM128, 0, 0x160FF3, 'r', 0},
{MOVSLDUP, XMM0, RM128, 0, 0x120FF3, 'r', 0},
{MOVSS, XMM0, RM128, 0, 0x100FF3, 'r', 0},
{MOVSS, RM128, XMM0, 0, 0x110FF3, 'r', 0},
{MOVUPD, XMM0, RM128, 0, 0x100F66, 'r', 0},
{MOVUPD, RM128, XMM0, 0, 0x110F66, 'r', 0},
{MOVUPS, XMM0, RM128, 0, 0x100F, 'r', 0},
{MOVUPS, RM128, XMM0, 0, 0x110F, 'r', 0},
{MPSADBW, XMM0, RM128, IMM8, 0x423A0F66u, 'r', 0},
{MULPD, XMM0, RM128, 0, 0x590F66, 'r', 0},
{MULPS, XMM0, RM128, 0, 0x590F, 'r', 0},
{MULSD, XMM0, RM128, 0, 0x590FF2, 'r', 0},
{MULSS, XMM0, RM128, 0, 0x590FF3, 'r', 0},
{ORPD, XMM0, RM128, 0, 0x560F66, 'r', 0},
{ORPS, XMM0, RM128, 0, 0x560F, 'r', 0},
{PABSB, XMM0, RM128, 0, 0x1C380F, 'r', 0},
{PABSW, XMM0, RM128, 0, 0x1D380F, 'r', 0},
{PABSD, XMM0, RM128, 0, 0x1E380F, 'r', 0},
{PACKSSDW, XMM0, RM128, 0, 0x6B0F66, 'r', 0},
{PACKSSWB, XMM0, RM128, 0, 0x630F66, 'r', 0},
{PACKUSDW, XMM0, RM128, 0, 0x2B380F66u, 'r', 0},
{PACKUSWB, XMM0, RM128, 0, 0x670F66, 'r', 0},
{PADDB, XMM0, RM128, 0, 0xFC0F66, 'r', 0},
{PADDW, XMM0, RM128, 0, 0xFD0F66, 'r', 0},
{PADDD, XMM0, RM128, 0, 0xFE0F66, 'r', 0},
{PADDQ, XMM0, RM128, 0, 0xD40F66, 'r', 0},
{PADDSB, XMM0, RM128, 0, 0xEC0F66, 'r', 0},
{PADDSW, XMM0, RM128, 0, 0xED0F66, 'r', 0},
{PADDUSB, XMM0, RM128, 0, 0xDC0F66, 'r', 0},
{PADDUSW, XMM0, RM128, 0, 0xDD0F66, 'r', 0},
{PALIGNR, XMM0, RM128, IMM8, 0x0F3A0F66u, 'r', 0},
{PAND, XMM0, RM128, 0, 0xDB0F66u, 'r', 0},
{PANDN, XMM0, RM128, 0, 0xDF0F66u, 'r', 0},
{PAVGB, XMM0, RM128, 0, 0xE00F66u, 'r', 0},
{PAVGW, XMM0, RM128, 0, 0xE30F66u, 'r', 0},
{PBLENDVB, XMM0, RM128, 0, 0x10380F66u, 'r', 0},
{PBLENDW, XMM0, RM128, IMM8, 0x0E3A0F66u, 'r', 0},
{PCLMULQDQ, XMM0, RM128, IMM8, 0x443A0F66u, 'r', 0},
{PCMPEQB, XMM0, RM128, 0, 0x740F66u, 'r', 0},
{PCMPEQD, XMM0, RM128, 0, 0x760F66u, 'r', 0},
{PCMPEQW, XMM0, RM128, 0, 0x750F66u, 'r', 0},
{PCMPEQQ, XMM0, RM128, 0, 0x29380F66u, 'r', 0},
{PCMPESTRI, XMM0, RM128, IMM8, 0x613A0F66u, 'r', 0},
{PCMPESTRM, XMM0, RM128, IMM8, 0x603A0F66u, 'r', 0},
{PCMPGTB, XMM0, RM128, 0, 0x640F66u, 'r', 0},
{PCMPGTD, XMM0, RM128, 0, 0x660F66u, 'r', 0},
{PCMPGTW, XMM0, RM128, 0, 0x650F66u, 'r', 0},
{PCMPGTQ, XMM0, RM128, 0, 0x37380F66u, 'r', 0},
{PCMPISTRI, XMM0, RM128, IMM8, 0x633A0F66u, 'r', 0},
{PCMPISTRM, XMM0, RM128, IMM8, 0x623A0F66u, 'r', 0},
{PEXTRB, RM8, XMM0, IMM8, 0x143A0F66u, 'r', 0},
{PEXTRW, RM16, XMM0, IMM8, 0x153A0F66u, 'r', 0},
{PEXTRD, RM32, XMM0, IMM8, 0x163A0F66u, 'r', 0},
{PEXTRQ, RM64, XMM0, IMM8, 0x163A0F66u, 'r', 0},
{PHADDD, XMM0, RM128, 0, 0x02380F66u, 'r', 0},
{PHADDSW, XMM0, RM128, 0, 0x03380F66u, 'r', 0},
{PHADDW, XMM0, RM128, 0, 0x01380F66u, 'r', 0},
{PHMINPOSUW, XMM0, RM128, 0, 0x41380F66u, 'r', 0},
{PHSUBD, XMM0, RM128, 0, 0x06380F66u, 'r', 0},
{PHSUBSW, XMM0, RM128, 0, 0x07380F66u, 'r', 0},
{PHSUBW, XMM0, RM128, 0, 0x05380F66u, 'r', 0},
{PINSRB, XMM0, RM8, IMM8, 0x203A0F66u, 'r', 0},
{PINSRW, XMM0, RM16, IMM8, 0xC40F66u, 'r', 0},
{PINSRD, XMM0, RM32, IMM8, 0x223A0F66u, 'r', 0},
{PINSRQ, XMM0, RM64, IMM8, 0x223A0F66u, 'r', 0},
{PMADDUBSW, XMM0, RM128, 0, 0x04380F66u, 'r', 0},
{PMADDWD, XMM0, RM128, 0, 0xF50F66u, 'r', 0},
{PMAXSB, XMM0, RM128, 0, 0x3C380F66u, 'r', 0},
{PMAXSD, XMM0, RM128, 0, 0x3D380F66u, 'r', 0},
{PMAXSW, XMM0, RM128, 0, 0xEE0F66u, 'r', 0},
{PMAXSUB, XMM0, RM128, 0, 0xDE0F66u, 'r', 0},
{PMAXSUD, XMM0, RM128, 0, 0x3F380F66u, 'r', 0},
{PMAXSUW, XMM0, RM128, 0, 0x3E0F66u, 'r', 0},
{PMINSB, XMM0, RM128, 0, 0x38380F66u, 'r', 0},
{PMINSD, XMM0, RM128, 0, 0x39380F66u, 'r', 0},
{PMINSW, XMM0, RM128, 0, 0xEA0F66u, 'r', 0},
{PMINUB, XMM0, RM128, 0, 0xDA0F66u, 'r', 0},
{PMINUD, XMM0, RM128, 0, 0x3B380F66u, 'r', 0},
{PMINUW, XMM0, RM128, 0, 0x3A380F66u, 'r', 0},
{PMOVMSKB, REG32, XMM0, 0, 0xD70F66u, 'r', 0},
{PMOVSXBD, XMM0, RM128, 0, 0x21380F66u, 'r', 0},
{PMOVSXBQ, XMM0, RM128, 0, 0x22380F66u, 'r', 0},
{PMOVSXBW, XMM0, RM128, 0, 0x20380F66u, 'r', 0},
{PMOVSXDQ, XMM0, RM128, 0, 0x25380F66u, 'r', 0},
{PMOVSXWD, XMM0, RM128, 0, 0x23380F66u, 'r', 0},
{PMOVSXWQ, XMM0, RM128, 0, 0x24380F66u, 'r', 0},
{PMOVZXBD, XMM0, RM128, 0, 0x31380F66u, 'r', 0},
{PMOVZXBQ, XMM0, RM128, 0, 0x32380F66u, 'r', 0},
{PMOVZXBW, XMM0, RM128, 0, 0x30380F66u, 'r', 0},
{PMOVZXDQ, XMM0, RM128, 0, 0x35380F66u, 'r', 0},
{PMOVZXWD, XMM0, RM128, 0, 0x33380F66u, 'r', 0},
{PMOVZXWQ, XMM0, RM128, 0, 0x34380F66u, 'r', 0},
{PMULDQ, XMM0, RM128, 0, 0x28380F66u, 'r', 0},
{PMULHRSW, XMM0, RM128, 0, 0x0B380F66u, 'r', 0},
{PMULHUW, XMM0, RM128, 0, 0xE40F66u, 'r', 0},
{PMULHW, XMM0, RM128, 0, 0xE50F66u, 'r', 0},
{PMULLD, XMM0, RM128, 0, 0x40380F66u, 'r', 0},
{PMULLW, XMM0, RM128, 0, 0xD50F66u, 'r', 0},
{PMULUDQ, XMM0, RM128, 0, 0xF40F66u, 'r', 0},
{POR, XMM0, RM128, 0, 0xEB0F66u, 'r', 0},
{PSADBW, XMM0, RM128, 0, 0xF60F66u, 'r', 0},
{PSHUFB, XMM0, RM128, 0, 0x00380F66u, 'r', 0},
{PSHUFD, XMM0, RM128, IMM8, 0x700F66u, 'r', 0},
{PSHUFD, XMM0, RM128, IMM8, 0x700F66u, 'r', 0},
{PSHUFLW, XMM0, RM128, IMM8, 0x700FF2u, 'r', 0},
{PSIGNB, XMM0, RM128, 0, 0x08380F66u, 'r', 0},
{PSIGND, XMM0, RM128, 0, 0x0A380F66u, 'r', 0},
{PSIGNW, XMM0, RM128, 0, 0x09380F66u, 'r', 0},
{PSLLD, XMM0, RM128, 0, 0xF20F66u, 'r', 0},
{PSLLD, XMM0, IMM8, 0, 0x720F66u, '6', 0},
{PSLLDQ, XMM0, IMM8, 0, 0x730F66u, '7', 0},
{PSLLQ, XMM0, RM128, 0, 0xF30F66u, 'r', 0},
{PSLLQ, XMM0, IMM8, 0, 0x730F66u, '6', 0},
{PSLLW, XMM0, RM128, 0, 0xF10F66u, 'r', 0},
{PSLLW, XMM0, IMM8, 0, 0x710F66u, '6', 0},
{PSRAD, XMM0, RM128, 0, 0xE20F66u, 'r', 0},
{PSRAD, XMM0, IMM8, 0, 0x720F66u, '4', 0},
{PSRAW, XMM0, RM128, 0, 0xE10F66u, 'r', 0},
{PSRAW, XMM0, IMM8, 0, 0x710F66u, '4', 0},
{PSRLD, XMM0, RM128, 0, 0xD20F66u, 'r', 0},
{PSRLD, XMM0, IMM8, 0, 0x720F66u, '2', 0},
{PSRLDQ, XMM0, IMM8, 0, 0x730F66u, '3', 0},
{PSRLQ, XMM0, RM128, 0, 0xD30F66u, 'r', 0},
{PSRLQ, XMM0, IMM8, 0, 0x730F66u, '2', 0},
{PSRLW, XMM0, RM128, 0, 0xD10F66u, 'r', 0},
{PSRLW, XMM0, IMM8, 0, 0x710F66u, '2', 0},
{PSUBB, XMM0, RM128, 0, 0xF80F66u, 'r', 0},
{PSUBD, XMM0, RM128, 0, 0xFA0F66u, 'r', 0},
{PSUBW, XMM0, RM128, 0, 0xF90F66u, 'r', 0},
{PSUBQ, XMM0, RM128, 0, 0xFB0F66u, 'r', 0},
{PSUBSW, XMM0, RM128, 0, 0xE90F66u, 'r', 0},
{PSUBUSB, XMM0, RM128, 0, 0xD80F66u, 'r', 0},
{PSUBUSW, XMM0, RM128, 0, 0xD90F66u, 'r', 0},
{PTEST, XMM0, RM128, 0, 0x17380F66u, 'r', 0},
{PUNPCKHBW, XMM0, RM128, 0, 0x680F66u, 'r', 0},
{PUNPCKHDQ, XMM0, RM128, 0, 0x6A0F66u, 'r', 0},
{PUNPCKHQDQ, XMM0, RM128, 0, 0x6D0F66u, 'r', 0},
{PUNPCKHWD, XMM0, RM128, 0, 0x690F66u, 'r', 0},
{PUNPCKLBW, XMM0, RM128, 0, 0x600F66u, 'r', 0},
{PUNPCKLDQ, XMM0, RM128, 0, 0x620F66u, 'r', 0},
{PUNPCKLQDQ, XMM0, RM128, 0, 0x6C0F66u, 'r', 0},
{PUNPCKLWD, XMM0, RM128, 0, 0x610F66u, 'r', 0},
{PXOR, XMM0, RM128, 0, 0xEF0F66u, 'r', 0},
{RCPPS, XMM0, RM128, 0, 0x530Fu, 'r', 0},
{RCPSS, XMM0, RM128, 0, 0x530FF3u, 'r', 0},
{ROUNDPD, XMM0, RM128, IMM8, 0x093A0F66u, 'r', 0},
{ROUNDPS, XMM0, RM128, IMM8, 0x083A0F66u, 'r', 0},
{ROUNDSD, XMM0, RM128, IMM8, 0x0B3A0F66u, 'r', 0},
{ROUNDSS, XMM0, RM128, IMM8, 0x0A3A0F66u, 'r', 0},
{RSQRTPS, XMM0, RM128, 0, 0x520Fu, 'r', 0},
{RSQRTSS, XMM0, RM128, 0, 0x520FF3u, 'r', 0},
{SHUFPD, XMM0, RM128, IMM8, 0xC60F66u, 'r', 0},
{SHUFPS, XMM0, RM128, IMM8, 0xC60Fu, 'r', 0},
{SQRTPD, XMM0, RM128, 0, 0x510F66u, 'r', 0},
{SQRTPS, XMM0, RM128, 0, 0x510Fu, 'r', 0},
{SQRTSD, XMM0, RM128, 0, 0x510FF2u, 'r', 0},
{SQRTSS, XMM0, RM128, 0, 0x510FF3u, 'r', 0},
{SUBPD, XMM0, RM128, 0, 0x5C0F66u, 'r', 0},
{SUBPS, XMM0, RM128, 0, 0x5C0Fu, 'r', 0},
{SUBSD, XMM0, RM128, 0, 0x5C0FF2u, 'r', 0},
{SUBSS, XMM0, RM128, 0, 0x5C0FF3u, 'r', 0},
{UCOMISD, XMM0, RM128, 0, 0x2E0F66u, 'r', 0},
{UCOMISS, XMM0, RM128, 0, 0x2E0Fu, 'r', 0},
{UNKNOWN, 0, 0, 0, 0, ' ', 0},
};
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <sys/mman.h>
typedef struct assembler_t {
uint8_t *buffer;
size_t position, size;
} assembler;
void assembler_init(assembler *as, size_t size) {
as->size = size;
as->position = 0;
as->buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
void assembler_finalize(assembler *as) {
mprotect(as->buffer, as->size, PROT_EXEC | PROT_READ);
}
void assembler_free(assembler *as) {
munmap(as->buffer, as->size);
}
int put_byte(assembler *as, uint8_t value) {
if(as->position<as->size) {
as->buffer[as->position++] = value;
return 1;
} else {
return 0;
}
}
uint8_t* get_pos_ptr(assembler *as) {
return as->buffer + as->position;
}
int put_word(assembler *as, uint16_t value) {
return put_byte(as, value&0xFFu) && put_byte(as, (value>>8u)&0xFFu);
}
int put_dword(assembler *as, uint32_t value) {
return put_byte(as, value&0xFFu) &&
put_byte(as, (value>>8u)&0xFFu) &&
put_byte(as, (value>>16u)&0xFFu) &&
put_byte(as, (value>>24u)&0xFFu);
}
int put_qword(assembler *as, uint64_t value) {
return put_byte(as, value&0xFFu) &&
put_byte(as, (value>>8u)&0xFFu) &&
put_byte(as, (value>>16u)&0xFFu) &&
put_byte(as, (value>>24u)&0xFFu) &&
put_byte(as, (value>>32u)&0xFFu) &&
put_byte(as, (value>>40u)&0xFFu) &&
put_byte(as, (value>>48u)&0xFFu) &&
put_byte(as, (value>>56u)&0xFFu);
}
typedef uint64_t optype_t;
typedef struct {
optype_t type;
union {
uint8_t immediate8;
uint16_t immediate16;
uint32_t immediate32;
uint64_t immediate64;
int8_t rel8off;
int16_t rel16off;
int32_t rel32off;
uint64_t moffset;
struct {
uint8_t size_override;
uint8_t rex;
uint8_t modrm;
uint8_t sib;
union {
int8_t disp8;
int32_t disp32;
} disp;
} memory;
} data;
uint8_t **position;
} opspec_t;
// type 3 bits
#define REG 0x01ull
#define MEM 0x02ull
#define RM 0x03ull
#define IMM 0x04ull
#define MOFFSET 0x05ull
#define RELOFF 0x06ull
#define RELOFF 0x06ull
// width 3 bits
#define BIT8 (0x01ull<<3ull)
#define BIT16 (0x02ull<<3ull)
#define BIT32 (0x03ull<<3ull)
#define BIT64 (0x04ull<<3ull)
#define BIT128 (0x05ull<<3ull)
#define BIT256 (0x06ull<<3ull)
// require exact register match
#define EXACT_FLAG (0x01ull<<7ull)
#define REG8 (REG | BIT8)
#define REG16 (REG | BIT16)
#define REG32 (REG | BIT32)
#define REG64 (REG | BIT64)
#define XMM0 (REG | BIT128)
#define YMM0 (REG | BIT256)
#define MEM8 (MEM | BIT8)
#define MEM16 (MEM | BIT16)
#define MEM32 (MEM | BIT32)
#define MEM64 (MEM | BIT64)
#define MEM128 (MEM | BIT128)
#define MEM256 (MEM | BIT256)
#define RM8 (RM | BIT8)
#define RM16 (RM | BIT16)
#define RM32 (RM | BIT32)
#define RM64 (RM | BIT64)
#define RM128 (RM | BIT128)
#define IMM8 (IMM | BIT8)
#define IMM16 (IMM | BIT16)
#define IMM32 (IMM | BIT32)
#define IMM64 (IMM | BIT64)
#define MOFFSET8 (MOFFSET | BIT8)
#define MOFFSET16 (MOFFSET | BIT16)
#define MOFFSET32 (MOFFSET | BIT32)
#define MOFFSET64 (MOFFSET | BIT64)
#define REL8OFF (RELOFF | BIT8)
#define REL16OFF (RELOFF | BIT16)
#define REL32OFF (RELOFF | BIT32)
#define REL64OFF (RELOFF | BIT64)
opspec_t make_reg(optype_t type) {
opspec_t result;
result.type = type;
result.position = NULL;
return result;
}
opspec_t IMMEDIATE8(uint8_t value) {
opspec_t result;
result.type = IMM8;
result.data.immediate8 = value;
result.position = NULL;
return result;
}
opspec_t IMMEDIATE16(uint16_t value) {
opspec_t result;
result.type = IMM16;
result.data.immediate16 = value;
result.position = NULL;
return result;
}
opspec_t IMMEDIATE32(uint32_t value) {
opspec_t result;
result.type = IMM32;
result.data.immediate32 = value;
result.position = NULL;
return result;
}
opspec_t IMMEDIATE64(uint64_t value) {
opspec_t result;
result.type = IMM64;
result.data.immediate64 = value;
result.position = NULL;
return result;
}
#define Rb(i) make_reg(REG8 | i<<16ull)
#define Rw(i) make_reg(REG16 | i<<16ull)
#define Rd(i) make_reg(REG32 | i<<16ull)
#define Rq(i) make_reg(REG64 | i<<16ull)
#define XMM(i) make_reg(XMM0 | i<<16ull)
#define RAX make_reg(REG64 | 0x00ull<<16ull)
#define RCX make_reg(REG64 | 0x01ull<<16ull)
#define RDX make_reg(REG64 | 0x02ull<<16ull)
#define RBX make_reg(REG64 | 0x03ull<<16ull)
#define RSP make_reg(REG64 | 0x04ull<<16ull)
#define RBP make_reg(REG64 | 0x05ull<<16ull)
#define RSI make_reg(REG64 | 0x06ull<<16ull)
#define RDI make_reg(REG64 | 0x07ull<<16ull)
#define EAX make_reg(REG32 | 0x00ull<<16ull)
#define ECX make_reg(REG32 | 0x01ull<<16ull)
#define EDX make_reg(REG32 | 0x02ull<<16ull)
#define EBX make_reg(REG32 | 0x03ull<<16ull)
#define ESP make_reg(REG32 | 0x04ull<<16ull)
#define EBP make_reg(REG32 | 0x05ull<<16ull)
#define ESI make_reg(REG32 | 0x06ull<<16ull)
#define EDI make_reg(REG32 | 0x07ull<<16ull)
#define AX make_reg(REG16 | 0x00ull<<16ull)
#define CX make_reg(REG16 | 0x01ull<<16ull)
#define DX make_reg(REG16 | 0x02ull<<16ull)
#define BX make_reg(REG16 | 0x03ull<<16ull)
#define SP make_reg(REG16 | 0x04ull<<16ull)
#define BP make_reg(REG16 | 0x05ull<<16ull)
#define SI make_reg(REG16 | 0x06ull<<16ull)
#define DI make_reg(REG16 | 0x07ull<<16ull)
#define AL make_reg(REG8 | 0x00ull<<16ull)
#define CL make_reg(REG8 | 0x01ull<<16ull)
#define DL make_reg(REG8 | 0x02ull<<16ull)
#define BL make_reg(REG8 | 0x03ull<<16ull)
#define AH make_reg(REG8 | 0x04ull<<16ull)
#define CH make_reg(REG8 | 0x05ull<<16ull)
#define DH make_reg(REG8 | 0x06ull<<16ull)
#define BH make_reg(REG8 | 0x07ull<<16ull)
#define EXACT_AL (REG8 | EXACT_FLAG)
#define EXACT_AX (REG16 | EXACT_FLAG)
#define EXACT_EAX (REG32 | EXACT_FLAG)
#define EXACT_RAX (REG64 | EXACT_FLAG)
#define OP_TYPE(op) (op & 7ull)
#define OP_WIDTH(op) (op & (7ull<<3ull))
#define OP_TYPE_WIDTH(op) (op & 63ull)
#define REGISTER_INDEX(op) (op >> 16ull)
#define IS_EXACT(op) (op & EXACT_FLAG)
#define NO_REX 0xFFu
opspec_t MEMORY_INDEX_impl(optype_t type, uint8_t scale, optype_t index, optype_t base, int32_t disp) {
opspec_t result;
optype_t regidx = REGISTER_INDEX(index);
optype_t regbase = REGISTER_INDEX(base);
scale = ((scale&10u)?1u:0u)+((scale&12u)?2u:0u);
result.type = type;
result.data.memory.size_override = OP_WIDTH(index)==BIT32?0x67u:0x00;
result.data.memory.rex = (regidx&8u) >> 2u | (regbase&8u) >> 3u;
result.data.memory.modrm = 0x04;
if((disp == (int8_t)disp && disp != 0) || (regidx&7u) == 5u) {
result.data.memory.disp.disp8 = disp;
result.data.memory.modrm |= 0x40u;
} else if(disp != 0) {
result.data.memory.disp.disp32 = disp;
result.data.memory.modrm |= 0x80u;
}
result.data.memory.sib = scale<<6u | (regidx&7u)<<3u | (regbase&7u);
result.position = NULL;
return result;
}
opspec_t MEMORY_INDEX(optype_t type, uint8_t scale, opspec_t index, opspec_t base, int32_t disp) {
return MEMORY_INDEX_impl(type, scale, index.type, base.type, disp);
}
opspec_t MEMORY(optype_t type, opspec_t reg, int32_t disp) {
opspec_t result;
optype_t regidx = REGISTER_INDEX(reg.type);
if(regidx == 4u) {
return MEMORY_INDEX_impl(type, 1, reg.type, reg.type, disp);
} else if(regidx == 12u) {
return MEMORY_INDEX_impl(type, 1, reg.type&(~0x80000ull), reg.type, disp);
} else if(reg.type == 0) {
result = MEMORY_INDEX_impl(type, 1, REG64 | 0x04ull<<16ull, REG64 | 0x05ull<<16ull, disp);
result.data.memory.modrm = 4u;
return result;
}
result.type = type;
result.data.memory.size_override = OP_WIDTH(reg.type)==BIT32?0x67u:0x00;
result.data.memory.rex = (regidx&8u) >> 3u;
result.data.memory.modrm = (regidx&7u);
if((disp == (int8_t)disp && disp != 0) || (regidx&7u) == 5u) {
result.data.memory.disp.disp8 = disp;
result.data.memory.modrm |= 0x40u;
} else if(disp != 0) {
result.data.memory.disp.disp32 = disp;
result.data.memory.modrm |= 0x80u;
}
result.data.memory.sib = 0u;
result.position = NULL;
return result;
}
opspec_t DISP(optype_t type, int32_t disp) {
opspec_t result;
result.type = type;
result.data.memory.rex = 0;
result.data.memory.modrm = 4u;
result.data.memory.sib = 4u<<3u | 5u;
result.data.memory.disp.disp32 = disp;
result.position = NULL;
return result;
}
opspec_t DISP_RIP(optype_t type, int32_t disp) {
opspec_t result;
result.type = type;
result.data.memory.rex = 0;
result.data.memory.modrm = 5u;
result.data.memory.sib = 0;
result.data.memory.disp.disp32 = disp;
result.position = NULL;
return result;
}
opspec_t MOFF(optype_t type, uint64_t offset) {
opspec_t result;
result.type = type;
result.data.moffset = offset;
result.position = NULL;
return result;
}
opspec_t REL8(int8_t offset) {
opspec_t result;
result.type = REL8OFF;
result.data.rel8off = offset;
result.position = NULL;
return result;
}
opspec_t REL16(int16_t offset) {
opspec_t result;
result.type = REL16OFF;
result.data.rel16off = offset;
result.position = NULL;
return result;
}
opspec_t REL32(int32_t offset) {
opspec_t result;
result.type = REL32OFF;
result.data.rel32off = offset;
result.position = NULL;
return result;
}
opspec_t REL(int32_t offset) {
if(offset == (int8_t)offset) {
return REL8(offset);
} else if(offset == (int16_t)offset) {
return REL16(offset);
} else {
return REL32(offset);
}
}
opspec_t MOFF8(uint64_t offset) {
return MOFF(MOFFSET8, offset);
}
opspec_t MOFF16(uint64_t offset) {
return MOFF(MOFFSET16, offset);
}
opspec_t MOFF32(uint64_t offset) {
return MOFF(MOFFSET32, offset);
}
opspec_t MOFF64(uint64_t offset) {
return MOFF(MOFFSET64, offset);
}
opspec_t MEMORY8(opspec_t reg, int32_t disp) {
return MEMORY(MEM8, reg, disp);
}
opspec_t MEMORY16(opspec_t reg, int32_t disp) {
return MEMORY(MEM16, reg, disp);
}
opspec_t MEMORY32(opspec_t reg, int32_t disp) {
return MEMORY(MEM32, reg, disp);
}
opspec_t MEMORY64(opspec_t reg, int32_t disp) {
return MEMORY(MEM64, reg, disp);
}
opspec_t MEMORY128(opspec_t reg, int32_t disp) {
return MEMORY(MEM128, reg, disp);
}
opspec_t MEMORY_INDEX8(uint8_t scale, opspec_t index, opspec_t base, int32_t disp) {
return MEMORY_INDEX(MEM8, scale, index, base, disp);
}
opspec_t MEMORY_INDEX16(uint8_t scale, opspec_t index, opspec_t base, int32_t disp) {
return MEMORY_INDEX(MEM16, scale, index, base, disp);
}
opspec_t MEMORY_INDEX32(uint8_t scale, opspec_t index, opspec_t base, int32_t disp) {
return MEMORY_INDEX(MEM32, scale, index, base, disp);
}
opspec_t MEMORY_INDEX64(uint8_t scale, opspec_t index, opspec_t base, int32_t disp) {
return MEMORY_INDEX(MEM64, scale, index, base, disp);
}
opspec_t MEMORY_INDEX128(uint8_t scale, opspec_t index, opspec_t base, int32_t disp) {
return MEMORY_INDEX(MEM128, scale, index, base, disp);
}
uint8_t calc_modrm_modrm(opspec_t op) {
if(OP_TYPE(op.type) == REG) {
return 0xC0u | (REGISTER_INDEX(op.type)&7u);
} else {
return op.data.memory.modrm;
}
}
uint8_t calc_modrm_reg(opspec_t op) {
return (REGISTER_INDEX(op.type)&7u) << 3u;
}
uint8_t calc_modrm_modrm_rex(opspec_t op) {
if((op.type == 0) || (op.type & IMM)) {
return 0u;
}
if(OP_TYPE(op.type) == REG) {
return (REGISTER_INDEX(op.type)&8u)>>3u;
} else {
return op.data.memory.rex;
}
}
uint8_t calc_modrm_reg_rex(opspec_t op) {
if((op.type == 0) || (op.type & IMM)) {
return 0u;
}
return (REGISTER_INDEX(op.type)&8u)>>1u;
}
#include "instruction_table.h"
int type_width_match(optype_t a, optype_t b) {
if(OP_WIDTH(a) != OP_WIDTH(b)) {
return 0;
}
if((a & IMM) || (b & IMM)) {
return a == b;
} else {
return OP_TYPE(a & b);
}
}
int operand_match(optype_t a, optype_t b) {
if(!(a && b)) {
return a == b;
}
if(type_width_match(a, b)) {
if(IS_EXACT(a) || IS_EXACT(b)) {
return REGISTER_INDEX(a) == REGISTER_INDEX(b);
}else {
return 1;
}
} else {
return 0;
}
}
int find_instruction(mnemonic_t mnemonic, opspec_t op1, opspec_t op2, opspec_t op3) {
for(int i = 0;instructions[i].mnemonic != UNKNOWN;++i) {
if(
instructions[i].mnemonic == mnemonic &&
operand_match(instructions[i].operand1, op1.type) &&
operand_match(instructions[i].operand2, op2.type) &&
operand_match(instructions[i].operand3, op3.type)
) {
return i;
}
}
return -1;
}
int put_immediate(assembler *as, opspec_t op) {
if(op.position) {
*op.position = get_pos_ptr(as);
}
if(op.type & IMM) {
switch(OP_TYPE_WIDTH(op.type)) {
case IMM8: return put_byte(as, op.data.immediate8);
case IMM16: return put_word(as, op.data.immediate16);
case IMM32: return put_dword(as, op.data.immediate32);
case IMM64: return put_qword(as, op.data.immediate64);
case MOFFSET8:
case MOFFSET16:
case MOFFSET32:
case MOFFSET64: return put_qword(as, op.data.moffset);
case REL8OFF: return put_byte(as, op.data.rel8off);
case REL16OFF: return put_word(as, op.data.rel16off);
case REL32OFF: return put_dword(as, op.data.rel32off);
default: return 0;
}
} else if((OP_TYPE(op.type) == MEM)) {
if(op.data.memory.modrm>>6u == 1u) {
put_byte(as, op.data.memory.disp.disp8);
} else if(op.data.memory.modrm>>6u == 2u) {
put_dword(as, op.data.memory.disp.disp32);
} else if(op.data.memory.modrm == 5 ||
(op.data.memory.modrm == 4 && op.data.memory.sib == (4u<<3u | 5u))) {
put_dword(as, op.data.memory.disp.disp32);
}
}
return 0;
}
int put_mandatory_prefixes(assembler *as, optype_t *opcode) {
for(;;) {
switch(*opcode&0xFFu) {
case 0x66u:
case 0x67u:
case 0xF3u:
case 0xF2u: break;
default: return 1;
}
if(!put_byte(as, *opcode)) return 0;
*opcode>>=8u;
}
}
int put_sib(assembler *as, opspec_t op) {
if(OP_TYPE(op.type) == MEM && (op.data.memory.modrm&7u) == 4u) {
if(!put_byte(as, op.data.memory.sib)) return 0;
}
return 1;
}
int put_opcode(assembler *as, optype_t opcode, optype_t addition) {
if((opcode&0xFFu) == 0x0Fu) {
if(!put_byte(as, opcode)) return 0;
opcode>>=8u;
if((opcode&0xFFu) == 0x0Fu || (opcode&0xFFu) == 0x38u || (opcode&0xFFu) == 0x3Au) {
if(!put_byte(as, opcode)) return 0;
opcode>>=8u;
}
}
if(!put_byte(as, opcode+addition)) return 0;
return 1;
}
int put_op_fun(assembler *as, mnemonic_t mnemonic, opspec_t op1, opspec_t op2, opspec_t op3, ...) {
int idx = find_instruction(mnemonic, op1, op2, op3);
// exit if no fitting instruction is found
if(idx<0) {
return 0;
}
// if the first two operands are a Register RM pair make sure RM
// is in operand 1
if((OP_TYPE(instructions[idx].operand1) == REG) && (OP_TYPE(instructions[idx].operand2) == RM)) {
opspec_t tmp = op1; op1 = op2; op2 = tmp;
}
optype_t opcode = instructions[idx].opcode;
// write out any mandatory prefixes included in the opcode
put_mandatory_prefixes(as, &opcode);
// 16bit operand size override
if(OP_WIDTH(op1.type)==BIT16 || OP_WIDTH(op2.type)==BIT16) {
put_byte(as, 0x66u);
}
if(OP_TYPE(op1.type)==MEM && op1.data.memory.size_override) {
put_byte(as, op1.data.memory.size_override);
}
uint8_t rex = 0;
if(instructions[idx].norex !=NO_REX && (OP_WIDTH(op1.type)==BIT64 || OP_WIDTH(op2.type)==BIT64)) {
rex |= 0x08u;
}
rex |= calc_modrm_modrm_rex(op1) | calc_modrm_reg_rex(op2);
if(rex) put_byte(as, 0x40u | rex);
switch(instructions[idx].modrm) {
case 'r':
put_opcode(as, opcode, 0);
put_byte(as, calc_modrm_modrm(op1) | calc_modrm_reg(op2));
put_sib(as, op1);
break;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
put_opcode(as, opcode, 0);
put_byte(as, calc_modrm_modrm(op1) | (instructions[idx].modrm-'0')<<3);
put_sib(as, op1);
break;
case '+':
put_opcode(as, opcode, REGISTER_INDEX(op1.type)&7u);
break;
case ' ':
put_opcode(as, opcode, 0);
break;
}
put_immediate(as, op1);
put_immediate(as, op2);
put_immediate(as, op3);
return 1;
}
#define put_op(...) put_op_fun(__VA_ARGS__,make_reg(0),make_reg(0),make_reg(0))
int main(void) {
assembler as;
assembler_init(&as, 4096);
put_op(&as, PUSH, RBP);
put_op(&as, PUSH, RBX);
put_op(&as, PUSH, Rq(11));
put_op(&as, PUSH, Rq(15));
put_op(&as, MOV, EAX, IMMEDIATE32(42));
put_op(&as, POP, Rq(15));
put_op(&as, POP, Rq(11));
put_op(&as, POP, RBX);
put_op(&as, POP, RBP);
put_op(&as, RET);
put_op(&as, CMPPD, XMM(1), MEMORY128(RAX, 0), IMMEDIATE8(0));
put_op(&as, CMPPS, XMM(1), MEMORY128(RAX, 0), IMMEDIATE8(0));
put_op(&as, CMPSD, XMM(1), MEMORY128(RAX, 0), IMMEDIATE8(0));
put_op(&as, CMPSS, XMM(1), MEMORY128(RAX, 0), IMMEDIATE8(0));
put_op(&as, COMISD, XMM(1), MEMORY128(RAX, 0));
put_op(&as, COMISS, XMM(1), MEMORY128(RAX, 0));
put_op(&as, BLENDPD, XMM(1), XMM(13), IMMEDIATE8(0));
put_op(&as, BLENDPS, XMM(1), XMM(13), IMMEDIATE8(0));
put_op(&as, CVTSD2SI, EAX, XMM(13));
put_op(&as, CVTSD2SI, RAX, XMM(13));
put_op(&as, CVTSI2SD, XMM(13), EAX);
put_op(&as, CVTSI2SD, XMM(13), RAX);
put_op(&as, DIVPS, XMM(13), XMM(9));
put_op(&as, EXTRACTPS, ECX, XMM(9), IMMEDIATE8(0));
put_op(&as, PACKSSDW, XMM(13), XMM(9));
put_op(&as, PACKSSWB, XMM(13), XMM(9));
put_op(&as, PACKUSDW, XMM(13), XMM(9));
put_op(&as, PACKUSWB, XMM(13), XMM(9));
put_op(&as, PADDB, XMM(13), XMM(9));
put_op(&as, PADDW, XMM(13), XMM(9));
put_op(&as, PADDD, XMM(13), XMM(9));
put_op(&as, PADDQ, XMM(13), XMM(9));
put_op(&as, PADDSB, XMM(13), XMM(9));
put_op(&as, PADDSW, XMM(13), XMM(9));
put_op(&as, PADDUSB, XMM(13), XMM(9));
put_op(&as, PADDUSW, XMM(13), XMM(9));
put_op(&as, PINSRB, XMM(9), AL, IMMEDIATE8(0));
put_op(&as, PINSRW, XMM(9), AX, IMMEDIATE8(0));
put_op(&as, PINSRD, XMM(9), EAX, IMMEDIATE8(0));
put_op(&as, PINSRQ, XMM(9), RAX, IMMEDIATE8(0));
put_op(&as, PSHUFB, XMM(9), XMM(10));
assembler_finalize(&as);
int (*func)() = (int(*)())as.buffer;
printf("%d\n", func());
FILE *fp = fopen("out.bin", "wb");
fwrite(as.buffer, 1, as.position, fp);
fclose(fp);
system("ndisasm -b 64 out.bin");
assembler_free(&as);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment