/* Print i386 instructions for GDB, the GNU debugger.
- Copyright (C) 1988-2016 Free Software Foundation, Inc.
+ Copyright (C) 1988-2017 Free Software Foundation, Inc.
This file is part of the GNU opcodes library.
the Intel manual for details. */
#include "sysdep.h"
-#include "dis-asm.h"
+#include "disassemble.h"
#include "opintl.h"
#include "opcode/i386.h"
#include "libiberty.h"
static void BadOp (void);
static void REP_Fixup (int, int);
static void BND_Fixup (int, int);
+static void NOTRACK_Fixup (int, int);
static void HLE_Fixup1 (int, int);
static void HLE_Fixup2 (int, int);
static void HLE_Fixup3 (int, int);
static void XMM_Fixup (int, int);
static void CRC32_Fixup (int, int);
static void FXSAVE_Fixup (int, int);
+static void PCMPESTR_Fixup (int, int);
static void OP_LWPCB_E (int, int);
static void OP_LWP_E (int, int);
static void OP_Vex_2src_1 (int, int);
#define Ed { OP_E, d_mode }
#define Edq { OP_E, dq_mode }
#define Edqw { OP_E, dqw_mode }
-#define EdqwS { OP_E, dqw_swap_mode }
#define Edqb { OP_E, dqb_mode }
#define Edb { OP_E, db_mode }
#define Edw { OP_E, dw_mode }
#define Evh3 { HLE_Fixup3, v_mode }
#define BND { BND_Fixup, 0 }
+#define NOTRACK { NOTRACK_Fixup, 0 }
#define cond_jump_flag { NULL, cond_jump_mode }
#define loop_jcxz_flag { NULL, loop_jcxz_mode }
dq_mode,
/* registers like dq_mode, memory like w_mode. */
dqw_mode,
- dqw_swap_mode,
bnd_mode,
/* 4- or 6-byte pointer operand */
f_mode,
REG_0F01,
REG_0F0D,
REG_0F18,
+ REG_0F1E_MOD_3,
REG_0F71,
REG_0F72,
REG_0F73,
MOD_0F1A_PREFIX_0,
MOD_0F1B_PREFIX_0,
MOD_0F1B_PREFIX_1,
+ MOD_0F1E_PREFIX_1,
MOD_0F24,
MOD_0F26,
MOD_0F2B_PREFIX_0,
MOD_0FE7_PREFIX_2,
MOD_0FF0_PREFIX_3,
MOD_0F382A_PREFIX_2,
+ MOD_0F38F5_PREFIX_2,
+ MOD_0F38F6_PREFIX_0,
MOD_62_32BIT,
MOD_C4_32BIT,
MOD_C5_32BIT,
RM_0F01_REG_3,
RM_0F01_REG_5,
RM_0F01_REG_7,
+ RM_0F1E_MOD_3_REG_7,
RM_0FAE_REG_5,
RM_0FAE_REG_6,
RM_0FAE_REG_7
enum
{
PREFIX_90 = 0,
+ PREFIX_MOD_0_0F01_REG_5,
+ PREFIX_MOD_3_0F01_REG_5_RM_1,
+ PREFIX_MOD_3_0F01_REG_5_RM_2,
PREFIX_0F10,
PREFIX_0F11,
PREFIX_0F12,
PREFIX_0F16,
PREFIX_0F1A,
PREFIX_0F1B,
+ PREFIX_0F1E,
PREFIX_0F2A,
PREFIX_0F2B,
PREFIX_0F2C,
PREFIX_0FAE_REG_3,
PREFIX_MOD_0_0FAE_REG_4,
PREFIX_MOD_3_0FAE_REG_4,
+ PREFIX_MOD_0_0FAE_REG_5,
PREFIX_0FAE_REG_6,
PREFIX_0FAE_REG_7,
PREFIX_0FB8,
PREFIX_0F38DF,
PREFIX_0F38F0,
PREFIX_0F38F1,
+ PREFIX_0F38F5,
PREFIX_0F38F6,
PREFIX_0F3A08,
PREFIX_0F3A09,
PREFIX_EVEX_0F384F,
PREFIX_EVEX_0F3852,
PREFIX_EVEX_0F3853,
+ PREFIX_EVEX_0F3855,
PREFIX_EVEX_0F3858,
PREFIX_EVEX_0F3859,
PREFIX_EVEX_0F385A,
enum
{
THREE_BYTE_0F38 = 0,
- THREE_BYTE_0F3A,
- THREE_BYTE_0F7A
+ THREE_BYTE_0F3A
};
enum
VEX_W_0F3A4A_P_2,
VEX_W_0F3A4B_P_2,
VEX_W_0F3A4C_P_2,
- VEX_W_0F3A60_P_2,
- VEX_W_0F3A61_P_2,
VEX_W_0F3A62_P_2,
VEX_W_0F3A63_P_2,
VEX_W_0F3ADF_P_2,
EVEX_W_0F3839_P_1,
EVEX_W_0F383A_P_1,
EVEX_W_0F3840_P_2,
+ EVEX_W_0F3855_P_2,
EVEX_W_0F3858_P_2,
EVEX_W_0F3859_P_2,
EVEX_W_0F385A_P_2,
{ PREFIX_TABLE (PREFIX_0F1B) },
{ "nopQ", { Ev }, 0 },
{ "nopQ", { Ev }, 0 },
- { "nopQ", { Ev }, 0 },
+ { PREFIX_TABLE (PREFIX_0F1E) },
{ "nopQ", { Ev }, 0 },
/* 20 */
{ "movZ", { Rm, Cm }, 0 },
/* 78 */
{ PREFIX_TABLE (PREFIX_0F78) },
{ PREFIX_TABLE (PREFIX_0F79) },
- { THREE_BYTE_TABLE (THREE_BYTE_0F7A) },
+ { Bad_Opcode },
{ Bad_Opcode },
{ PREFIX_TABLE (PREFIX_0F7C) },
{ PREFIX_TABLE (PREFIX_0F7D) },
static int last_addr_prefix;
static int last_rex_prefix;
static int last_seg_prefix;
+static int last_active_prefix;
static int fwait_prefix;
/* The active segment register prefix. */
static int active_seg_prefix;
/* REG_F6 */
{
{ "testA", { Eb, Ib }, 0 },
- { Bad_Opcode },
+ { "testA", { Eb, Ib }, 0 },
{ "notA", { Ebh1 }, 0 },
{ "negA", { Ebh1 }, 0 },
{ "mulA", { Eb }, 0 }, /* Don't print the implicit %al register, */
/* REG_F7 */
{
{ "testQ", { Ev, Iv }, 0 },
- { Bad_Opcode },
+ { "testQ", { Ev, Iv }, 0 },
{ "notQ", { Evh1 }, 0 },
{ "negQ", { Evh1 }, 0 },
{ "mulQ", { Ev }, 0 }, /* Don't print the implicit register. */
{
{ "incQ", { Evh1 }, 0 },
{ "decQ", { Evh1 }, 0 },
- { "call{&|}", { indirEv, BND }, 0 },
+ { "call{&|}", { NOTRACK, indirEv, BND }, 0 },
{ MOD_TABLE (MOD_FF_REG_3) },
- { "jmp{&|}", { indirEv, BND }, 0 },
+ { "jmp{&|}", { NOTRACK, indirEv, BND }, 0 },
{ MOD_TABLE (MOD_FF_REG_5) },
{ "pushU", { stackEv }, 0 },
{ Bad_Opcode },
{ MOD_TABLE (MOD_0F18_REG_6) },
{ MOD_TABLE (MOD_0F18_REG_7) },
},
+ /* REG_0F1E_MOD_3 */
+ {
+ { "nopQ", { Ev }, 0 },
+ { "rdsspK", { Rdq }, PREFIX_OPCODE },
+ { "nopQ", { Ev }, 0 },
+ { "nopQ", { Ev }, 0 },
+ { "nopQ", { Ev }, 0 },
+ { "nopQ", { Ev }, 0 },
+ { "nopQ", { Ev }, 0 },
+ { RM_TABLE (RM_0F1E_MOD_3_REG_7) },
+ },
/* REG_0F71 */
{
{ Bad_Opcode },
{ NULL, { { NULL, 0 } }, PREFIX_IGNORED }
},
+ /* PREFIX_MOD_0_0F01_REG_5 */
+ {
+ { Bad_Opcode },
+ { "rstorssp", { Mq }, PREFIX_OPCODE },
+ },
+
+ /* PREFIX_MOD_3_0F01_REG_5_RM_1 */
+ {
+ { Bad_Opcode },
+ { "incsspK", { Skip_MODRM }, PREFIX_OPCODE },
+ },
+
+ /* PREFIX_MOD_3_0F01_REG_5_RM_2 */
+ {
+ { Bad_Opcode },
+ { "saveprevssp", { Skip_MODRM }, PREFIX_OPCODE },
+ },
+
/* PREFIX_0F10 */
{
{ "movups", { XM, EXx }, PREFIX_OPCODE },
{ "bndcn", { Gbnd, Ev_bnd }, 0 },
},
+ /* PREFIX_0F1E */
+ {
+ { "nopQ", { Ev }, PREFIX_OPCODE },
+ { MOD_TABLE (MOD_0F1E_PREFIX_1) },
+ { "nopQ", { Ev }, PREFIX_OPCODE },
+ { "nopQ", { Ev }, PREFIX_OPCODE },
+ },
+
/* PREFIX_0F2A */
{
{ "cvtpi2ps", { XM, EMCq }, PREFIX_OPCODE },
{ "ptwrite%LQ", { Edq }, 0 },
},
+ /* PREFIX_MOD_0_0FAE_REG_5 */
+ {
+ { "xrstor", { FXSAVE }, PREFIX_OPCODE },
+ { "setssbsy", { Mq }, PREFIX_OPCODE },
+ },
+
/* PREFIX_0FAE_REG_6 */
{
- { "xsaveopt", { FXSAVE }, 0 },
- { Bad_Opcode },
- { "clwb", { Mb }, 0 },
+ { "xsaveopt", { FXSAVE }, PREFIX_OPCODE },
+ { "clrssbsy", { Mq }, PREFIX_OPCODE },
+ { "clwb", { Mb }, PREFIX_OPCODE },
},
/* PREFIX_0FAE_REG_7 */
{ "crc32", { Gdq, { CRC32_Fixup, v_mode } }, PREFIX_OPCODE },
},
- /* PREFIX_0F38F6 */
+ /* PREFIX_0F38F5 */
{
{ Bad_Opcode },
+ { Bad_Opcode },
+ { MOD_TABLE (MOD_0F38F5_PREFIX_2) },
+ },
+
+ /* PREFIX_0F38F6 */
+ {
+ { MOD_TABLE (MOD_0F38F6_PREFIX_0) },
{ "adoxS", { Gdq, Edq}, PREFIX_OPCODE },
{ "adcxS", { Gdq, Edq}, PREFIX_OPCODE },
{ Bad_Opcode },
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "pcmpestrm", { XM, EXx, Ib }, PREFIX_OPCODE },
+ { "pcmpestrm", { XM, { PCMPESTR_Fixup, x_mode }, Ib }, PREFIX_OPCODE },
},
/* PREFIX_0F3A61 */
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "pcmpestri", { XM, EXx, Ib }, PREFIX_OPCODE },
+ { "pcmpestri", { XM, { PCMPESTR_Fixup, x_mode }, Ib }, PREFIX_OPCODE },
},
/* PREFIX_0F3A62 */
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
- { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_0F38F5) },
{ PREFIX_TABLE (PREFIX_0F38F6) },
{ Bad_Opcode },
/* f8 */
{ Bad_Opcode },
{ Bad_Opcode },
},
-
- /* THREE_BYTE_0F7A */
- {
- /* 00 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 08 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 10 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 18 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 20 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 28 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 30 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 38 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 40 */
- { Bad_Opcode },
- { "phaddbw", { XM, EXq }, PREFIX_OPCODE },
- { "phaddbd", { XM, EXq }, PREFIX_OPCODE },
- { "phaddbq", { XM, EXq }, PREFIX_OPCODE },
- { Bad_Opcode },
- { Bad_Opcode },
- { "phaddwd", { XM, EXq }, PREFIX_OPCODE },
- { "phaddwq", { XM, EXq }, PREFIX_OPCODE },
- /* 48 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { "phadddq", { XM, EXq }, PREFIX_OPCODE },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 50 */
- { Bad_Opcode },
- { "phaddubw", { XM, EXq }, PREFIX_OPCODE },
- { "phaddubd", { XM, EXq }, PREFIX_OPCODE },
- { "phaddubq", { XM, EXq }, PREFIX_OPCODE },
- { Bad_Opcode },
- { Bad_Opcode },
- { "phadduwd", { XM, EXq }, PREFIX_OPCODE },
- { "phadduwq", { XM, EXq }, PREFIX_OPCODE },
- /* 58 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { "phaddudq", { XM, EXq }, PREFIX_OPCODE },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 60 */
- { Bad_Opcode },
- { "phsubbw", { XM, EXq }, PREFIX_OPCODE },
- { "phsubbd", { XM, EXq }, PREFIX_OPCODE },
- { "phsubbq", { XM, EXq }, PREFIX_OPCODE },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 68 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 70 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 78 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 80 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 88 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 90 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* 98 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* a0 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* a8 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* b0 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* b8 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* c0 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* c8 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* d0 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* d8 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* e0 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* e8 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* f0 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- /* f8 */
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
- },
};
static const struct dis386 xop_table[][256] = {
/* VEX_LEN_0F3A60_P_2 */
{
- { VEX_W_TABLE (VEX_W_0F3A60_P_2) },
+ { "vpcmpestrm", { XM, { PCMPESTR_Fixup, x_mode }, Ib }, 0 },
},
/* VEX_LEN_0F3A61_P_2 */
{
- { VEX_W_TABLE (VEX_W_0F3A61_P_2) },
+ { "vpcmpestri", { XM, { PCMPESTR_Fixup, x_mode }, Ib }, 0 },
},
/* VEX_LEN_0F3A62_P_2 */
{ "vpblendvb", { XM, Vex, EXx, XMVexI4 }, 0 },
},
{
- /* VEX_W_0F3A60_P_2 */
- { "vpcmpestrm", { XM, EXx, Ib }, 0 },
- },
- {
- /* VEX_W_0F3A61_P_2 */
- { "vpcmpestri", { XM, EXx, Ib }, 0 },
- },
- {
/* VEX_W_0F3A62_P_2 */
{ "vpcmpistrm", { XM, EXx, Ib }, 0 },
},
},
{
/* MOD_0F01_REG_5 */
- { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_MOD_0_0F01_REG_5) },
{ RM_TABLE (RM_0F01_REG_5) },
},
{
{ "nopQ", { Ev }, 0 },
},
{
+ /* MOD_0F1E_PREFIX_1 */
+ { "nopQ", { Ev }, 0 },
+ { REG_TABLE (REG_0F1E_MOD_3) },
+ },
+ {
/* MOD_0F24 */
{ Bad_Opcode },
{ "movL", { Rd, Td }, 0 },
},
{
/* MOD_0FAE_REG_5 */
- { "xrstor", { FXSAVE }, 0 },
+ { PREFIX_TABLE (PREFIX_MOD_0_0FAE_REG_5) },
{ RM_TABLE (RM_0FAE_REG_5) },
},
{
{ "movntdqa", { XM, Mx }, 0 },
},
{
+ /* MOD_0F38F5_PREFIX_2 */
+ { "wrussK", { M, Gdq }, PREFIX_OPCODE },
+ },
+ {
+ /* MOD_0F38F6_PREFIX_0 */
+ { "wrssK", { M, Gdq }, PREFIX_OPCODE },
+ },
+ {
/* MOD_62_32BIT */
{ "bound{S|}", { Gv, Ma }, 0 },
{ EVEX_TABLE (EVEX_0F) },
{
/* RM_0F01_REG_5 */
{ Bad_Opcode },
- { Bad_Opcode },
- { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_MOD_3_0F01_REG_5_RM_1) },
+ { PREFIX_TABLE (PREFIX_MOD_3_0F01_REG_5_RM_2) },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ "clzero", { Skip_MODRM }, 0 },
},
{
+ /* RM_0F1E_MOD_3_REG_7 */
+ { "nopQ", { Ev }, 0 },
+ { "nopQ", { Ev }, 0 },
+ { "endbr64", { Skip_MODRM }, PREFIX_OPCODE },
+ { "endbr32", { Skip_MODRM }, PREFIX_OPCODE },
+ { "nopQ", { Ev }, 0 },
+ { "nopQ", { Ev }, 0 },
+ { "nopQ", { Ev }, 0 },
+ { "nopQ", { Ev }, 0 },
+ },
+ {
/* RM_0FAE_REG_5 */
{ "lfence", { Skip_MODRM }, 0 },
},
#define XACQUIRE_PREFIX (0xf2 | 0x200)
#define XRELEASE_PREFIX (0xf3 | 0x400)
#define BND_PREFIX (0xf2 | 0x400)
+#define NOTRACK_PREFIX (0x3e | 0x100)
static int
ckprefix (void)
last_addr_prefix = -1;
last_rex_prefix = -1;
last_seg_prefix = -1;
+ last_active_prefix = -1;
fwait_prefix = -1;
active_seg_prefix = 0;
for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
return 1;
}
if (*codep != FWAIT_OPCODE)
- all_prefixes[i++] = *codep;
+ {
+ last_active_prefix = i;
+ all_prefixes[i++] = *codep;
+ }
rex = newrex;
codep++;
length++;
return "xrelease";
case BND_PREFIX:
return "bnd";
+ case NOTRACK_PREFIX:
+ return "notrack";
default:
return NULL;
}
rex |= REX_W;
vex.register_specifier = (~(*codep >> 3)) & 0xf;
- if (address_mode != mode_64bit
- && vex.register_specifier > 0x7)
+ if (address_mode != mode_64bit)
{
- dp = &bad_opcode;
- return dp;
+ /* In 16/32-bit mode REX_B is silently ignored. */
+ rex &= ~REX_B;
+ if (vex.register_specifier > 0x7)
+ {
+ dp = &bad_opcode;
+ return dp;
+ }
}
vex.length = (*codep & 0x4) ? 256 : 128;
vindex = *codep++;
dp = &vex_table[vex_table_index][vindex];
end_codep = codep;
- /* There is no MODRM byte for VEX [82|77]. */
- if (vindex != 0x77 && vindex != 0x82)
+ /* There is no MODRM byte for VEX0F 77. */
+ if (vex_table_index != VEX_0F || vindex != 0x77)
{
FETCH_DATA (info, codep + 1);
modrm.mod = (*codep >> 6) & 3;
vindex = *codep++;
dp = &vex_table[dp->op[1].bytemode][vindex];
end_codep = codep;
- /* There is no MODRM byte for VEX [82|77]. */
- if (vindex != 0x77 && vindex != 0x82)
+ /* There is no MODRM byte for VEX 77. */
+ if (vindex != 0x77)
{
FETCH_DATA (info, codep + 1);
modrm.mod = (*codep >> 6) & 3;
case w_mode:
case dw_mode:
case dqw_mode:
- case dqw_swap_mode:
oappend ("WORD PTR ");
break;
case indir_v_mode:
if ((sizeflag & SUFFIX_ALWAYS)
&& (bytemode == b_swap_mode
- || bytemode == v_swap_mode
- || bytemode == dqw_swap_mode))
+ || bytemode == v_swap_mode))
swap_operand ();
switch (bytemode)
names = address_mode == mode_64bit ? names64 : names32;
break;
case bnd_mode:
+ if (reg > 0x3)
+ {
+ oappend ("(bad)");
+ return;
+ }
names = names_bnd;
break;
case indir_v_mode:
case dqb_mode:
case dqd_mode:
case dqw_mode:
- case dqw_swap_mode:
USED_REX (REX_W);
if (rex & REX_W)
names = names64;
{
case dqw_mode:
case dw_mode:
- case dqw_swap_mode:
shift = 1;
break;
case dqb_mode:
oappend (names64[modrm.reg + add]);
break;
case bnd_mode:
+ if (modrm.reg > 0x3)
+ {
+ oappend ("(bad)");
+ return;
+ }
oappend (names_bnd[modrm.reg]);
break;
case v_mode:
case dqb_mode:
case dqd_mode:
case dqw_mode:
- case dqw_swap_mode:
USED_REX (REX_W);
if (rex & REX_W)
oappend (names64[modrm.reg + add]);
if ((sizeflag & SUFFIX_ALWAYS)
&& (bytemode == x_swap_mode
|| bytemode == d_swap_mode
- || bytemode == dqw_swap_mode
|| bytemode == d_scalar_swap_mode
|| bytemode == q_swap_mode
|| bytemode == q_scalar_swap_mode))
all_prefixes[last_repnz_prefix] = BND_PREFIX;
}
+/* For NOTRACK-prefixed instructions, 0x3E prefix should be displayed as
+ "notrack". */
+
+static void
+NOTRACK_Fixup (int bytemode ATTRIBUTE_UNUSED,
+ int sizeflag ATTRIBUTE_UNUSED)
+{
+ if (active_seg_prefix == PREFIX_DS
+ && (address_mode != mode_64bit || last_data_prefix < 0))
+ {
+ /* NOTRACK prefix is only valid on indirect branch instructions
+ and it must be the last prefix before REX prefix and opcode.
+ NB: DATA prefix is unsupported for Intel64. */
+ if (last_active_prefix >= 0)
+ {
+ int notrack_prefix = last_active_prefix;
+ if (last_rex_prefix == last_active_prefix)
+ notrack_prefix--;
+ if (all_prefixes[notrack_prefix] != NOTRACK_PREFIX_OPCODE)
+ return;
+ }
+ active_seg_prefix = 0;
+ all_prefixes[last_seg_prefix] = NOTRACK_PREFIX;
+ }
+}
+
/* Similar to OP_E. But the 0xf2/0xf3 prefixes should be displayed as
"xacquire"/"xrelease" for memory operand if there is a LOCK prefix.
*/
OP_M (bytemode, sizeflag);
}
+static void
+PCMPESTR_Fixup (int bytemode, int sizeflag)
+{
+ /* Add proper suffix to "{,v}pcmpestr{i,m}". */
+ if (!intel_syntax)
+ {
+ char *p = mnemonicendp;
+
+ USED_REX (REX_W);
+ if (rex & REX_W)
+ *p++ = 'q';
+ else if (sizeflag & SUFFIX_ALWAYS)
+ *p++ = 'l';
+
+ *p = '\0';
+ mnemonicendp = p;
+ }
+
+ OP_EX (bytemode, sizeflag);
+}
+
/* Display the destination register operand for instructions with
VEX. */
names = names_mask;
break;
default:
- abort ();
+ /* See PR binutils/20893 for a reproducer. */
+ oappend ("(bad)");
return;
}
break;