X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fi386-dis.c;h=b35dbc046ee0dda4db472230a07a186ecf786e70;hb=76800cba595efc3fe95a446c2d664e42ae4ee869;hp=1518a1df5eb80df9f4dd3c0750d8ef60d42f62de;hpb=9889cbb14ebea4b281408afcfd94ad6646ab370a;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 1518a1df5e..b35dbc046e 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -1,5 +1,5 @@ /* 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. @@ -33,7 +33,7 @@ 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" @@ -110,6 +110,7 @@ static void CMP_Fixup (int, int); 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); @@ -117,6 +118,7 @@ static void CMPXCHG8B_Fixup (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); @@ -252,7 +254,6 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #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 } @@ -473,6 +474,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #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 } @@ -556,7 +558,6 @@ enum 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, @@ -706,7 +707,7 @@ enum { REG_80 = 0, REG_81, - REG_82, + REG_83, REG_8F, REG_C0, REG_C1, @@ -724,6 +725,7 @@ enum REG_0F01, REG_0F0D, REG_0F18, + REG_0F1E_MOD_3, REG_0F71, REG_0F72, REG_0F73, @@ -777,6 +779,7 @@ enum MOD_0F1A_PREFIX_0, MOD_0F1B_PREFIX_0, MOD_0F1B_PREFIX_1, + MOD_0F1E_PREFIX_1, MOD_0F24, MOD_0F26, MOD_0F2B_PREFIX_0, @@ -815,6 +818,8 @@ enum 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, @@ -934,6 +939,7 @@ enum 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 @@ -942,12 +948,16 @@ enum 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, @@ -986,9 +996,9 @@ enum 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_RM_0_0FAE_REG_7, PREFIX_0FB8, PREFIX_0FBC, PREFIX_0FBD, @@ -1050,6 +1060,7 @@ enum PREFIX_0F38DF, PREFIX_0F38F0, PREFIX_0F38F1, + PREFIX_0F38F5, PREFIX_0F38F6, PREFIX_0F3A08, PREFIX_0F3A09, @@ -1549,6 +1560,9 @@ enum PREFIX_EVEX_0F384D, PREFIX_EVEX_0F384E, PREFIX_EVEX_0F384F, + PREFIX_EVEX_0F3852, + PREFIX_EVEX_0F3853, + PREFIX_EVEX_0F3855, PREFIX_EVEX_0F3858, PREFIX_EVEX_0F3859, PREFIX_EVEX_0F385A, @@ -1693,6 +1707,7 @@ enum X86_64_63, X86_64_6D, X86_64_6F, + X86_64_82, X86_64_9A, X86_64_C4, X86_64_C5, @@ -1711,8 +1726,7 @@ enum enum { THREE_BYTE_0F38 = 0, - THREE_BYTE_0F3A, - THREE_BYTE_0F7A + THREE_BYTE_0F3A }; enum @@ -2191,8 +2205,6 @@ 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, @@ -2378,6 +2390,7 @@ enum 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, @@ -2661,8 +2674,8 @@ static const struct dis386 dis386[] = { /* 80 */ { REG_TABLE (REG_80) }, { REG_TABLE (REG_81) }, - { Bad_Opcode }, - { REG_TABLE (REG_82) }, + { X86_64_TABLE (X86_64_82) }, + { REG_TABLE (REG_83) }, { "testB", { Eb, Gb }, 0 }, { "testS", { Ev, Gv }, 0 }, { "xchgB", { Ebh2, Gb }, 0 }, @@ -2839,7 +2852,7 @@ static const struct dis386 dis386_twobyte[] = { { 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 }, @@ -2943,7 +2956,7 @@ static const struct dis386 dis386_twobyte[] = { /* 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) }, @@ -3156,6 +3169,7 @@ static int last_data_prefix; 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; @@ -3399,7 +3413,7 @@ static const struct dis386 reg_table[][8] = { { "xorQ", { Evh1, Iv }, 0 }, { "cmpQ", { Ev, Iv }, 0 }, }, - /* REG_82 */ + /* REG_83 */ { { "addQ", { Evh1, sIb }, 0 }, { "orQ", { Evh1, sIb }, 0 }, @@ -3510,7 +3524,7 @@ static const struct dis386 reg_table[][8] = { /* 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, */ @@ -3521,7 +3535,7 @@ static const struct dis386 reg_table[][8] = { /* 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. */ @@ -3538,9 +3552,9 @@ static const struct dis386 reg_table[][8] = { { { "incQ", { Evh1 }, 0 }, { "decQ", { Evh1 }, 0 }, - { "call{&|}", { indirEv, BND }, 0 }, + { "call{&|}", { indirEv, NOTRACK, BND }, 0 }, { MOD_TABLE (MOD_FF_REG_3) }, - { "jmp{&|}", { indirEv, BND }, 0 }, + { "jmp{&|}", { indirEv, NOTRACK, BND }, 0 }, { MOD_TABLE (MOD_FF_REG_5) }, { "pushU", { stackEv }, 0 }, { Bad_Opcode }, @@ -3589,6 +3603,17 @@ static const struct dis386 reg_table[][8] = { { 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 }, @@ -3758,6 +3783,24 @@ static const struct dis386 prefix_table[][4] = { { 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 }, + { "savessp", { Skip_MODRM }, PREFIX_OPCODE }, + }, + /* PREFIX_0F10 */ { { "movups", { XM, EXx }, PREFIX_OPCODE }, @@ -3805,6 +3848,14 @@ static const struct dis386 prefix_table[][4] = { { "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 }, @@ -4080,11 +4131,17 @@ static const struct dis386 prefix_table[][4] = { { "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 */ @@ -4094,13 +4151,6 @@ static const struct dis386 prefix_table[][4] = { { "clflushopt", { Mb }, 0 }, }, - /* PREFIX_RM_0_0FAE_REG_7 */ - { - { "sfence", { Skip_MODRM }, 0 }, - { Bad_Opcode }, - { "pcommit", { Skip_MODRM }, 0 }, - }, - /* PREFIX_0FB8 */ { { Bad_Opcode }, @@ -4520,9 +4570,16 @@ static const struct dis386 prefix_table[][4] = { { "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 }, @@ -4658,14 +4715,14 @@ static const struct dis386 prefix_table[][4] = { { { 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 */ @@ -6893,6 +6950,12 @@ static const struct dis386 x86_64_table[][2] = { { "outs{G|}", { indirDXr, Xz }, 0 }, }, + /* X86_64_82 */ + { + /* Opcode 0x82 is an alias of of opcode 0x80 in 32-bit mode. */ + { REG_TABLE (REG_80) }, + }, + /* X86_64_9A */ { { "Jcall{T|}", { Ap }, 0 }, @@ -7247,7 +7310,7 @@ static const struct dis386 three_byte_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, - { Bad_Opcode }, + { PREFIX_TABLE (PREFIX_0F38F5) }, { PREFIX_TABLE (PREFIX_0F38F6) }, { Bad_Opcode }, /* f8 */ @@ -7551,298 +7614,6 @@ static const struct dis386 three_byte_table[][256] = { { 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] = { @@ -10290,12 +10061,12 @@ static const struct dis386 vex_len_table[][2] = { /* 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 */ @@ -11637,14 +11408,6 @@ static const struct dis386 vex_w_table[][2] = { /* VEX_W_0F3A4C_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 }, @@ -11707,7 +11470,7 @@ static const struct dis386 mod_table[][2] = { }, { /* MOD_0F01_REG_5 */ - { Bad_Opcode }, + { PREFIX_TABLE (PREFIX_MOD_0_0F01_REG_5) }, { RM_TABLE (RM_0F01_REG_5) }, }, { @@ -11780,6 +11543,11 @@ static const struct dis386 mod_table[][2] = { { "bndmk", { Gbnd, Ev_bnd }, 0 }, { "nopQ", { Ev }, 0 }, }, + { + /* MOD_0F1E_PREFIX_1 */ + { "nopQ", { Ev }, 0 }, + { REG_TABLE (REG_0F1E_MOD_3) }, + }, { /* MOD_0F24 */ { Bad_Opcode }, @@ -11888,7 +11656,7 @@ static const struct dis386 mod_table[][2] = { }, { /* MOD_0FAE_REG_5 */ - { "xrstor", { FXSAVE }, 0 }, + { PREFIX_TABLE (PREFIX_MOD_0_0FAE_REG_5) }, { RM_TABLE (RM_0FAE_REG_5) }, }, { @@ -11956,6 +11724,14 @@ static const struct dis386 mod_table[][2] = { /* MOD_0F382A_PREFIX_2 */ { "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 }, @@ -12458,8 +12234,8 @@ static const struct dis386 rm_table[][8] = { { /* 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 }, @@ -12474,6 +12250,17 @@ static const struct dis386 rm_table[][8] = { { "mwaitx", { { OP_Mwaitx, 0 } }, 0 }, { "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 }, @@ -12484,7 +12271,8 @@ static const struct dis386 rm_table[][8] = { }, { /* RM_0FAE_REG_7 */ - { PREFIX_TABLE (PREFIX_RM_0_0FAE_REG_7) }, + { "sfence", { Skip_MODRM }, 0 }, + }, }; @@ -12496,6 +12284,7 @@ static const struct dis386 rm_table[][8] = { #define XACQUIRE_PREFIX (0xf2 | 0x200) #define XRELEASE_PREFIX (0xf3 | 0x400) #define BND_PREFIX (0xf2 | 0x400) +#define NOTRACK_PREFIX (0x3e | 0x100) static int ckprefix (void) @@ -12513,6 +12302,7 @@ 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++) @@ -12625,7 +12415,10 @@ ckprefix (void) return 1; } if (*codep != FWAIT_OPCODE) - all_prefixes[i++] = *codep; + { + last_active_prefix = i; + all_prefixes[i++] = *codep; + } rex = newrex; codep++; length++; @@ -12714,6 +12507,8 @@ prefix_name (int pref, int sizeflag) return "xrelease"; case BND_PREFIX: return "bnd"; + case NOTRACK_PREFIX: + return "notrack"; default: return NULL; } @@ -12963,11 +12758,15 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info) 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; @@ -13058,8 +12857,8 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info) 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; @@ -13101,8 +12900,8 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info) 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; @@ -13828,15 +13627,15 @@ static const unsigned char float_mem_mode[] = { #define ST { OP_ST, 0 } #define STi { OP_STi, 0 } -#define FGRPd9_2 NULL, { { NULL, 0 } }, 0 -#define FGRPd9_4 NULL, { { NULL, 1 } }, 0 -#define FGRPd9_5 NULL, { { NULL, 2 } }, 0 -#define FGRPd9_6 NULL, { { NULL, 3 } }, 0 -#define FGRPd9_7 NULL, { { NULL, 4 } }, 0 -#define FGRPda_5 NULL, { { NULL, 5 } }, 0 -#define FGRPdb_4 NULL, { { NULL, 6 } }, 0 -#define FGRPde_3 NULL, { { NULL, 7 } }, 0 -#define FGRPdf_4 NULL, { { NULL, 8 } }, 0 +#define FGRPd9_2 NULL, { { NULL, 1 } }, 0 +#define FGRPd9_4 NULL, { { NULL, 2 } }, 0 +#define FGRPd9_5 NULL, { { NULL, 3 } }, 0 +#define FGRPd9_6 NULL, { { NULL, 4 } }, 0 +#define FGRPd9_7 NULL, { { NULL, 5 } }, 0 +#define FGRPda_5 NULL, { { NULL, 6 } }, 0 +#define FGRPdb_4 NULL, { { NULL, 7 } }, 0 +#define FGRPde_3 NULL, { { NULL, 8 } }, 0 +#define FGRPdf_4 NULL, { { NULL, 9 } }, 0 static const struct dis386 float_reg[][8] = { /* d8 */ @@ -13930,48 +13729,53 @@ static const struct dis386 float_reg[][8] = { }; static char *fgrps[][8] = { - /* d9_2 0 */ + /* Bad opcode 0 */ + { + "(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", + }, + + /* d9_2 1 */ { "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", }, - /* d9_4 1 */ + /* d9_4 2 */ { "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", }, - /* d9_5 2 */ + /* d9_5 3 */ { "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", }, - /* d9_6 3 */ + /* d9_6 4 */ { "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", }, - /* d9_7 4 */ + /* d9_7 5 */ { "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", }, - /* da_5 5 */ + /* da_5 6 */ { "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", }, - /* db_4 6 */ + /* db_4 7 */ { "fNeni(8087 only)","fNdisi(8087 only)","fNclex","fNinit", "fNsetpm(287 only)","frstpm(287 only)","(bad)","(bad)", }, - /* de_3 7 */ + /* de_3 8 */ { "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", }, - /* df_4 8 */ + /* df_4 9 */ { "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", }, @@ -14838,7 +14642,6 @@ intel_operand_size (int bytemode, int sizeflag) case w_mode: case dw_mode: case dqw_mode: - case dqw_swap_mode: oappend ("WORD PTR "); break; case indir_v_mode: @@ -15193,8 +14996,7 @@ OP_E_register (int bytemode, int sizeflag) if ((sizeflag & SUFFIX_ALWAYS) && (bytemode == b_swap_mode - || bytemode == v_swap_mode - || bytemode == dqw_swap_mode)) + || bytemode == v_swap_mode)) swap_operand (); switch (bytemode) @@ -15246,7 +15048,6 @@ OP_E_register (int bytemode, int sizeflag) case dqb_mode: case dqd_mode: case dqw_mode: - case dqw_swap_mode: USED_REX (REX_W); if (rex & REX_W) names = names64; @@ -15302,7 +15103,6 @@ OP_E_memory (int bytemode, int sizeflag) { case dqw_mode: case dw_mode: - case dqw_swap_mode: shift = 1; break; case dqb_mode: @@ -15776,7 +15576,6 @@ OP_G (int bytemode, int sizeflag) 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]); @@ -16631,7 +16430,6 @@ OP_EX (int bytemode, int sizeflag) 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)) @@ -17001,6 +16799,34 @@ BND_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 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 (modrm.mod == 3 + && active_seg_prefix == PREFIX_DS + && (address_mode != mode_64bit || last_data_prefix < 0)) + { + /* NOTRACK prefix is only valid on register 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. */ @@ -17185,6 +17011,27 @@ FXSAVE_Fixup (int bytemode, int sizeflag) 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. */ @@ -17265,7 +17112,8 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED) names = names_mask; break; default: - abort (); + /* See PR binutils/20893 for a reproducer. */ + oappend ("(bad)"); return; } break;