+ {
+ /* MOD_VEX_0F71_REG_4 */
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_VEX_0F71_REG_4) },
+ },
+ {
+ /* MOD_VEX_0F71_REG_6 */
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_VEX_0F71_REG_6) },
+ },
+ {
+ /* MOD_VEX_0F72_REG_2 */
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_VEX_0F72_REG_2) },
+ },
+ {
+ /* MOD_VEX_0F72_REG_4 */
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_VEX_0F72_REG_4) },
+ },
+ {
+ /* MOD_VEX_0F72_REG_6 */
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_VEX_0F72_REG_6) },
+ },
+ {
+ /* MOD_VEX_0F73_REG_2 */
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_VEX_0F73_REG_2) },
+ },
+ {
+ /* MOD_VEX_0F73_REG_3 */
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_VEX_0F73_REG_3) },
+ },
+ {
+ /* MOD_VEX_0F73_REG_6 */
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_VEX_0F73_REG_6) },
+ },
+ {
+ /* MOD_VEX_0F73_REG_7 */
+ { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_VEX_0F73_REG_7) },
+ },
+ {
+ /* MOD_VEX_W_0_0F91_P_0_LEN_0 */
+ { "kmovw", { Ew, MaskG }, 0 },
+ { Bad_Opcode },
+ },
+ {
+ /* MOD_VEX_W_0_0F91_P_0_LEN_0 */
+ { "kmovq", { Eq, MaskG }, 0 },
+ { Bad_Opcode },
+ },
+ {
+ /* MOD_VEX_W_0_0F91_P_2_LEN_0 */
+ { "kmovb", { Eb, MaskG }, 0 },
+ { Bad_Opcode },
+ },
+ {
+ /* MOD_VEX_W_0_0F91_P_2_LEN_0 */
+ { "kmovd", { Ed, MaskG }, 0 },
+ { Bad_Opcode },
+ },
+ {
+ /* MOD_VEX_W_0_0F92_P_0_LEN_0 */
+ { Bad_Opcode },
+ { "kmovw", { MaskG, Rdq }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F92_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kmovb", { MaskG, Rdq }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F92_P_3_LEN_0 */
+ { Bad_Opcode },
+ { "kmovd", { MaskG, Rdq }, 0 },
+ },
+ {
+ /* MOD_VEX_W_1_0F92_P_3_LEN_0 */
+ { Bad_Opcode },
+ { "kmovq", { MaskG, Rdq }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F93_P_0_LEN_0 */
+ { Bad_Opcode },
+ { "kmovw", { Gdq, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F93_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kmovb", { Gdq, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F93_P_3_LEN_0 */
+ { Bad_Opcode },
+ { "kmovd", { Gdq, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_1_0F93_P_3_LEN_0 */
+ { Bad_Opcode },
+ { "kmovq", { Gdq, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F98_P_0_LEN_0 */
+ { Bad_Opcode },
+ { "kortestw", { MaskG, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_1_0F98_P_0_LEN_0 */
+ { Bad_Opcode },
+ { "kortestq", { MaskG, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F98_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kortestb", { MaskG, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_1_0F98_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kortestd", { MaskG, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F99_P_0_LEN_0 */
+ { Bad_Opcode },
+ { "ktestw", { MaskG, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_1_0F99_P_0_LEN_0 */
+ { Bad_Opcode },
+ { "ktestq", { MaskG, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F99_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "ktestb", { MaskG, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_W_1_0F99_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "ktestd", { MaskG, MaskR }, 0 },
+ },
+ {
+ /* MOD_VEX_0FAE_REG_2 */
+ { VEX_LEN_TABLE (VEX_LEN_0FAE_R_2_M_0) },
+ },
+ {
+ /* MOD_VEX_0FAE_REG_3 */
+ { VEX_LEN_TABLE (VEX_LEN_0FAE_R_3_M_0) },
+ },
+ {
+ /* MOD_VEX_0FD7_PREFIX_2 */
+ { Bad_Opcode },
+ { VEX_W_TABLE (VEX_W_0FD7_P_2_M_1) },
+ },
+ {
+ /* MOD_VEX_0FE7_PREFIX_2 */
+ { VEX_W_TABLE (VEX_W_0FE7_P_2_M_0) },
+ },
+ {
+ /* MOD_VEX_0FF0_PREFIX_3 */
+ { VEX_W_TABLE (VEX_W_0FF0_P_3_M_0) },
+ },
+ {
+ /* MOD_VEX_0F381A_PREFIX_2 */
+ { VEX_LEN_TABLE (VEX_LEN_0F381A_P_2_M_0) },
+ },
+ {
+ /* MOD_VEX_0F382A_PREFIX_2 */
+ { VEX_W_TABLE (VEX_W_0F382A_P_2_M_0) },
+ },
+ {
+ /* MOD_VEX_0F382C_PREFIX_2 */
+ { VEX_W_TABLE (VEX_W_0F382C_P_2_M_0) },
+ },
+ {
+ /* MOD_VEX_0F382D_PREFIX_2 */
+ { VEX_W_TABLE (VEX_W_0F382D_P_2_M_0) },
+ },
+ {
+ /* MOD_VEX_0F382E_PREFIX_2 */
+ { VEX_W_TABLE (VEX_W_0F382E_P_2_M_0) },
+ },
+ {
+ /* MOD_VEX_0F382F_PREFIX_2 */
+ { VEX_W_TABLE (VEX_W_0F382F_P_2_M_0) },
+ },
+ {
+ /* MOD_VEX_0F385A_PREFIX_2 */
+ { VEX_LEN_TABLE (VEX_LEN_0F385A_P_2_M_0) },
+ },
+ {
+ /* MOD_VEX_0F388C_PREFIX_2 */
+ { "vpmaskmov%LW", { XM, Vex, Mx }, 0 },
+ },
+ {
+ /* MOD_VEX_0F388E_PREFIX_2 */
+ { "vpmaskmov%LW", { Mx, Vex, XM }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F3A30_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kshiftrb", { MaskG, MaskR, Ib }, 0 },
+ },
+ {
+ /* MOD_VEX_W_1_0F3A30_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kshiftrw", { MaskG, MaskR, Ib }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F3A31_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kshiftrd", { MaskG, MaskR, Ib }, 0 },
+ },
+ {
+ /* MOD_VEX_W_1_0F3A31_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kshiftrq", { MaskG, MaskR, Ib }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F3A32_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kshiftlb", { MaskG, MaskR, Ib }, 0 },
+ },
+ {
+ /* MOD_VEX_W_1_0F3A32_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kshiftlw", { MaskG, MaskR, Ib }, 0 },
+ },
+ {
+ /* MOD_VEX_W_0_0F3A33_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kshiftld", { MaskG, MaskR, Ib }, 0 },
+ },
+ {
+ /* MOD_VEX_W_1_0F3A33_P_2_LEN_0 */
+ { Bad_Opcode },
+ { "kshiftlq", { MaskG, MaskR, Ib }, 0 },
+ },
+#define NEED_MOD_TABLE
+#include "i386-dis-evex.h"
+#undef NEED_MOD_TABLE
+};
+
+static const struct dis386 rm_table[][8] = {
+ {
+ /* RM_C6_REG_7 */
+ { "xabort", { Skip_MODRM, Ib }, 0 },
+ },
+ {
+ /* RM_C7_REG_7 */
+ { "xbeginT", { Skip_MODRM, Jv }, 0 },
+ },
+ {
+ /* RM_0F01_REG_0 */
+ { Bad_Opcode },
+ { "vmcall", { Skip_MODRM }, 0 },
+ { "vmlaunch", { Skip_MODRM }, 0 },
+ { "vmresume", { Skip_MODRM }, 0 },
+ { "vmxoff", { Skip_MODRM }, 0 },
+ },
+ {
+ /* RM_0F01_REG_1 */
+ { "monitor", { { OP_Monitor, 0 } }, 0 },
+ { "mwait", { { OP_Mwait, 0 } }, 0 },
+ { "clac", { Skip_MODRM }, 0 },
+ { "stac", { Skip_MODRM }, 0 },
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { "encls", { Skip_MODRM }, 0 },
+ },
+ {
+ /* RM_0F01_REG_2 */
+ { "xgetbv", { Skip_MODRM }, 0 },
+ { "xsetbv", { Skip_MODRM }, 0 },
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { "vmfunc", { Skip_MODRM }, 0 },
+ { "xend", { Skip_MODRM }, 0 },
+ { "xtest", { Skip_MODRM }, 0 },
+ { "enclu", { Skip_MODRM }, 0 },
+ },
+ {
+ /* RM_0F01_REG_3 */
+ { "vmrun", { Skip_MODRM }, 0 },
+ { "vmmcall", { Skip_MODRM }, 0 },
+ { "vmload", { Skip_MODRM }, 0 },
+ { "vmsave", { Skip_MODRM }, 0 },
+ { "stgi", { Skip_MODRM }, 0 },
+ { "clgi", { Skip_MODRM }, 0 },
+ { "skinit", { Skip_MODRM }, 0 },
+ { "invlpga", { Skip_MODRM }, 0 },
+ },
+ {
+ /* RM_0F01_REG_5 */
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { "rdpkru", { Skip_MODRM }, 0 },
+ { "wrpkru", { Skip_MODRM }, 0 },
+ },
+ {
+ /* RM_0F01_REG_7 */
+ { "swapgs", { Skip_MODRM }, 0 },
+ { "rdtscp", { Skip_MODRM }, 0 },
+ { "monitorx", { { OP_Monitor, 0 } }, 0 },
+ { "mwaitx", { { OP_Mwaitx, 0 } }, 0 },
+ { "clzero", { Skip_MODRM }, 0 },
+ },
+ {
+ /* RM_0FAE_REG_5 */
+ { "lfence", { Skip_MODRM }, 0 },
+ },
+ {
+ /* RM_0FAE_REG_6 */
+ { "mfence", { Skip_MODRM }, 0 },
+ },
+ {
+ /* RM_0FAE_REG_7 */
+ { PREFIX_TABLE (PREFIX_RM_0_0FAE_REG_7) },
+ },
+};
+
+#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
+
+/* We use the high bit to indicate different name for the same
+ prefix. */
+#define REP_PREFIX (0xf3 | 0x100)
+#define XACQUIRE_PREFIX (0xf2 | 0x200)
+#define XRELEASE_PREFIX (0xf3 | 0x400)
+#define BND_PREFIX (0xf2 | 0x400)
+
+static int
+ckprefix (void)
+{
+ int newrex, i, length;
+ rex = 0;
+ rex_ignored = 0;
+ prefixes = 0;
+ used_prefixes = 0;
+ rex_used = 0;
+ last_lock_prefix = -1;
+ last_repz_prefix = -1;
+ last_repnz_prefix = -1;
+ last_data_prefix = -1;
+ last_addr_prefix = -1;
+ last_rex_prefix = -1;
+ last_seg_prefix = -1;
+ fwait_prefix = -1;
+ active_seg_prefix = 0;
+ for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
+ all_prefixes[i] = 0;
+ i = 0;
+ length = 0;
+ /* The maximum instruction length is 15bytes. */
+ while (length < MAX_CODE_LENGTH - 1)
+ {
+ FETCH_DATA (the_info, codep + 1);
+ newrex = 0;
+ switch (*codep)
+ {
+ /* REX prefixes family. */
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f:
+ if (address_mode == mode_64bit)
+ newrex = *codep;
+ else
+ return 1;
+ last_rex_prefix = i;
+ break;
+ case 0xf3:
+ prefixes |= PREFIX_REPZ;
+ last_repz_prefix = i;
+ break;
+ case 0xf2:
+ prefixes |= PREFIX_REPNZ;
+ last_repnz_prefix = i;
+ break;
+ case 0xf0:
+ prefixes |= PREFIX_LOCK;
+ last_lock_prefix = i;
+ break;
+ case 0x2e:
+ prefixes |= PREFIX_CS;
+ last_seg_prefix = i;
+ active_seg_prefix = PREFIX_CS;
+ break;
+ case 0x36:
+ prefixes |= PREFIX_SS;
+ last_seg_prefix = i;
+ active_seg_prefix = PREFIX_SS;
+ break;
+ case 0x3e:
+ prefixes |= PREFIX_DS;
+ last_seg_prefix = i;
+ active_seg_prefix = PREFIX_DS;
+ break;
+ case 0x26:
+ prefixes |= PREFIX_ES;
+ last_seg_prefix = i;
+ active_seg_prefix = PREFIX_ES;
+ break;
+ case 0x64:
+ prefixes |= PREFIX_FS;
+ last_seg_prefix = i;
+ active_seg_prefix = PREFIX_FS;
+ break;
+ case 0x65:
+ prefixes |= PREFIX_GS;
+ last_seg_prefix = i;
+ active_seg_prefix = PREFIX_GS;
+ break;