X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fi386-dis.c;h=930569e0f73a2544d317e4542a0fe5d9dd54e4cd;hb=e90426589d7c783b7e458162baaac1431fc33bd5;hp=98950e20f070dbf5e6eb95024f4363e1beae874b;hpb=aa178437393fd97f706c3f8bdf60ab2cc53a8cb4;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 98950e20f0..930569e0f7 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -273,6 +273,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define Mo { OP_M, o_mode } #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */ #define Mq { OP_M, q_mode } +#define Mv_bnd { OP_M, v_bndmk_mode } #define Mx { OP_M, x_mode } #define Mxmm { OP_M, xmm_mode } #define Gb { OP_G, b_mode } @@ -281,6 +282,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define Gd { OP_G, d_mode } #define Gdq { OP_G, dq_mode } #define Gm { OP_G, m_mode } +#define Gva { OP_G, va_mode } #define Gw { OP_G, w_mode } #define Rd { OP_R, d_mode } #define Rdq { OP_R, dq_mode } @@ -560,6 +562,8 @@ enum cond_jump_mode, loop_jcxz_mode, v_bnd_mode, + /* like v_bnd_mode in 32bit, no RIP-rel in 64bit mode. */ + v_bndmk_mode, /* operand size depends on REX prefixes. */ dq_mode, /* registers like dq_mode, memory like w_mode. */ @@ -835,6 +839,8 @@ enum MOD_0F382A_PREFIX_2, MOD_0F38F5_PREFIX_2, MOD_0F38F6_PREFIX_0, + MOD_0F38F8_PREFIX_2, + MOD_0F38F9_PREFIX_0, MOD_62_32BIT, MOD_C4_32BIT, MOD_C5_32BIT, @@ -1081,6 +1087,8 @@ enum PREFIX_0F38F1, PREFIX_0F38F5, PREFIX_0F38F6, + PREFIX_0F38F8, + PREFIX_0F38F9, PREFIX_0F3A08, PREFIX_0F3A09, PREFIX_0F3A0A, @@ -4680,6 +4688,18 @@ static const struct dis386 prefix_table[][4] = { { Bad_Opcode }, }, + /* PREFIX_0F38F8 */ + { + { Bad_Opcode }, + { Bad_Opcode }, + { MOD_TABLE (MOD_0F38F8_PREFIX_2) }, + }, + + /* PREFIX_0F38F9 */ + { + { MOD_TABLE (MOD_0F38F9_PREFIX_0) }, + }, + /* PREFIX_0F3A08 */ { { Bad_Opcode }, @@ -7444,8 +7464,8 @@ static const struct dis386 three_byte_table[][256] = { { PREFIX_TABLE (PREFIX_0F38F6) }, { Bad_Opcode }, /* f8 */ - { Bad_Opcode }, - { Bad_Opcode }, + { PREFIX_TABLE (PREFIX_0F38F8) }, + { PREFIX_TABLE (PREFIX_0F38F9) }, { Bad_Opcode }, { Bad_Opcode }, { Bad_Opcode }, @@ -11629,17 +11649,17 @@ static const struct dis386 mod_table[][2] = { }, { /* MOD_0F1A_PREFIX_0 */ - { "bndldx", { Gbnd, Ev_bnd }, 0 }, + { "bndldx", { Gbnd, Mv_bnd }, 0 }, { "nopQ", { Ev }, 0 }, }, { /* MOD_0F1B_PREFIX_0 */ - { "bndstx", { Ev_bnd, Gbnd }, 0 }, + { "bndstx", { Mv_bnd, Gbnd }, 0 }, { "nopQ", { Ev }, 0 }, }, { /* MOD_0F1B_PREFIX_1 */ - { "bndmk", { Gbnd, Ev_bnd }, 0 }, + { "bndmk", { Gbnd, Mv_bnd }, 0 }, { "nopQ", { Ev }, 0 }, }, { @@ -11836,6 +11856,14 @@ static const struct dis386 mod_table[][2] = { /* MOD_0F38F6_PREFIX_0 */ { "wrssK", { M, Gdq }, PREFIX_OPCODE }, }, + { + /* MOD_0F38F8_PREFIX_2 */ + { "movdir64b", { Gva, M }, PREFIX_OPCODE }, + }, + { + /* MOD_0F38F9_PREFIX_0 */ + { "movdiri", { Em, Gv }, PREFIX_OPCODE }, + }, { /* MOD_62_32BIT */ { "bound{S|}", { Gv, Ma }, 0 }, @@ -15058,6 +15086,7 @@ intel_operand_size (int bytemode, int sizeflag) oappend ("WORD PTR "); break; case v_bnd_mode: + case v_bndmk_mode: default: break; } @@ -15312,11 +15341,13 @@ OP_E_memory (int bytemode, int sizeflag) int havebase; int haveindex; int needindex; + int needaddr32; int base, rbase; int vindex = 0; int scale = 0; int addr32flag = !((sizeflag & AFLAG) || bytemode == v_bnd_mode + || bytemode == v_bndmk_mode || bytemode == bnd_mode || bytemode == bnd_swap_mode); const char **indexes64 = names64; @@ -15393,6 +15424,11 @@ OP_E_memory (int bytemode, int sizeflag) if (address_mode == mode_64bit && !havesib) riprel = 1; disp = get32s (); + if (riprel && bytemode == v_bndmk_mode) + { + oappend ("(bad)"); + return; + } } break; case 1: @@ -15408,12 +15444,27 @@ OP_E_memory (int bytemode, int sizeflag) break; } - /* In 32bit mode, we need index register to tell [offset] from - [eiz*1 + offset]. */ - needindex = (havesib - && !havebase - && !haveindex - && address_mode == mode_32bit); + needindex = 0; + needaddr32 = 0; + if (havesib + && !havebase + && !haveindex + && address_mode != mode_16bit) + { + if (address_mode == mode_64bit) + { + /* Display eiz instead of addr32. */ + needindex = addr32flag; + needaddr32 = 1; + } + else + { + /* In 32-bit mode, we need index register to tell [offset] + from [eiz*1 + offset]. */ + needindex = 1; + } + } + havedisp = (havebase || needindex || (havesib && (haveindex || scale != 0))); @@ -15433,8 +15484,9 @@ OP_E_memory (int bytemode, int sizeflag) } } - if ((havebase || haveindex || riprel) + if ((havebase || haveindex || needaddr32 || riprel) && (bytemode != v_bnd_mode) + && (bytemode != v_bndmk_mode) && (bytemode != bnd_mode) && (bytemode != bnd_swap_mode)) used_prefixes |= PREFIX_ADDR; @@ -15652,6 +15704,7 @@ static void OP_G (int bytemode, int sizeflag) { int add = 0; + const char **names; USED_REX (REX_R); if (rex & REX_R) add += 8; @@ -15700,6 +15753,24 @@ OP_G (int bytemode, int sizeflag) used_prefixes |= (prefixes & PREFIX_DATA); } break; + case va_mode: + names = (address_mode == mode_64bit + ? names64 : names32); + if (!(prefixes & PREFIX_ADDR)) + { + if (address_mode == mode_16bit) + names = names16; + } + else + { + /* Remove "addr16/addr32". */ + all_prefixes[last_addr_prefix] = 0; + names = (address_mode != mode_32bit + ? names32 : names16); + used_prefixes |= PREFIX_ADDR; + } + oappend (names[modrm.reg + add]); + break; case m_mode: if (address_mode == mode_64bit) oappend (names64[modrm.reg + add]);