X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=opcodes%2Fi386-dis.c;h=8e0a9500903082b1c65ff178ef23102fdd3a0c86;hb=b9915cbc7d3ac2b9cd136248defbf9538b9a9bcf;hp=c73e964b5469b6f43c6a54f2a3227ad37dd71960;hpb=1d67fe3b6e696fccb902d9919b9e58b7299a3205;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index c73e964b54..8e0a950090 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -124,6 +124,7 @@ static void OP_Vex_2src_1 (int, int); static void OP_Vex_2src_2 (int, int); static void MOVBE_Fixup (int, int); +static void MOVSXD_Fixup (int, int); static void OP_Mask (int, int); @@ -400,11 +401,9 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define EXxmm_mw { OP_EX, xmm_mw_mode } #define EXxmm_md { OP_EX, xmm_md_mode } #define EXxmm_mq { OP_EX, xmm_mq_mode } -#define EXxmm_mdq { OP_EX, xmm_mdq_mode } #define EXxmmdw { OP_EX, xmmdw_mode } #define EXxmmqd { OP_EX, xmmqd_mode } #define EXymmq { OP_EX, ymmq_mode } -#define EXVexWdq { OP_EX, vex_w_dq_mode } #define EXVexWdqScalar { OP_EX, vex_scalar_w_dq_mode } #define EXEvexXGscat { OP_EX, evex_x_gscat_mode } #define EXEvexXNoBcst { OP_EX, evex_x_nobcst_mode } @@ -537,9 +536,6 @@ enum xmm_md_mode, /* XMM register or quad word memory operand */ xmm_mq_mode, - /* XMM register or double/quad word memory operand, depending on - VEX.W. */ - xmm_mdq_mode, /* 16-byte XMM, word, double word or quad word operand. */ xmmdw_mode, /* 16-byte XMM, double word, quad word operand or xmm word operand. */ @@ -556,6 +552,7 @@ enum a_mode, cond_jump_mode, loop_jcxz_mode, + movsxd_mode, v_bnd_mode, /* like v_bnd_mode in 32bit, no RIP-rel in 64bit mode. */ v_bndmk_mode, @@ -593,14 +590,12 @@ enum vex128_mode, /* 256bit vex mode */ vex256_mode, - /* operand size depends on the VEX.W bit. */ - vex_w_dq_mode, - /* Similar to vex_w_dq_mode, with VSIB dword indices. */ + /* Operand size depends on the VEX.W bit, with VSIB dword indices. */ vex_vsib_d_w_dq_mode, /* Similar to vex_vsib_d_w_dq_mode, with smaller memory. */ vex_vsib_d_w_d_mode, - /* Similar to vex_w_dq_mode, with VSIB qword indices. */ + /* Operand size depends on the VEX.W bit, with VSIB qword indices. */ vex_vsib_q_w_dq_mode, /* Similar to vex_vsib_q_w_dq_mode, with smaller memory. */ vex_vsib_q_w_d_mode, @@ -621,7 +616,7 @@ enum q_scalar_swap_mode, /* like vex_mode, ignore vector length. */ vex_scalar_mode, - /* like vex_w_dq_mode, ignore vector length. */ + /* Operand size depends on the VEX.W bit, ignore vector length. */ vex_scalar_w_dq_mode, /* Static rounding. */ @@ -1762,6 +1757,8 @@ enum X86_64_6F, X86_64_82, X86_64_9A, + X86_64_C2, + X86_64_C3, X86_64_C4, X86_64_C5, X86_64_CE, @@ -2334,8 +2331,8 @@ struct dis386 { 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise '!' => change condition from true to false or from false to true. '%' => add 1 upper case letter to the macro. - '^' => print 'w' or 'l' depending on operand size prefix or - suffix_always is true (lcall/ljmp). + '^' => print 'w', 'l', or 'q' (Intel64 ISA only) depending on operand size + prefix or suffix_always is true (lcall/ljmp). '@' => print 'q' for Intel64 ISA, 'w' or 'q' for AMD64 ISA depending on operand size prefix. '&' => print 'q' in 64bit mode for Intel64 ISA or if instruction @@ -2584,8 +2581,8 @@ static const struct dis386 dis386[] = { /* c0 */ { REG_TABLE (REG_C0) }, { REG_TABLE (REG_C1) }, - { "retT", { Iw, BND }, 0 }, - { "retT", { BND }, 0 }, + { X86_64_TABLE (X86_64_C2) }, + { X86_64_TABLE (X86_64_C3) }, { X86_64_TABLE (X86_64_C4) }, { X86_64_TABLE (X86_64_C5) }, { REG_TABLE (REG_C6) }, @@ -6873,7 +6870,7 @@ static const struct dis386 x86_64_table[][2] = { /* X86_64_63 */ { { "arpl", { Ew, Gw }, 0 }, - { "movs{lq|xd}", { Gv, Ed }, 0 }, + { "movs", { { OP_G, movsxd_mode }, { MOVSXD_Fixup, movsxd_mode } }, 0 }, }, /* X86_64_6D */ @@ -6899,6 +6896,18 @@ static const struct dis386 x86_64_table[][2] = { { "Jcall{T|}", { Ap }, 0 }, }, + /* X86_64_C2 */ + { + { "retP", { Iw, BND }, 0 }, + { "ret@", { Iw, BND }, 0 }, + }, + + /* X86_64_C3 */ + { + { "retP", { BND }, 0 }, + { "ret@", { BND }, 0 }, + }, + /* X86_64_C4 */ { { MOD_TABLE (MOD_C4_32BIT) }, @@ -13287,6 +13296,12 @@ case_S: case '^': if (intel_syntax) break; + if (isa64 == intel64 && (rex & REX_W)) + { + USED_REX (REX_W); + *obufp++ = 'q'; + break; + } if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS)) { if (sizeflag & DFLAG) @@ -13536,6 +13551,13 @@ intel_operand_size (int bytemode, int sizeflag) oappend ("DWORD PTR "); used_prefixes |= (prefixes & PREFIX_DATA); break; + case movsxd_mode: + if (!(sizeflag & DFLAG) && isa64 == intel64) + oappend ("WORD PTR "); + else + oappend ("DWORD PTR "); + used_prefixes |= (prefixes & PREFIX_DATA); + break; case d_mode: case d_scalar_mode: case d_scalar_swap_mode: @@ -13751,8 +13773,6 @@ intel_operand_size (int bytemode, int sizeflag) case o_mode: oappend ("OWORD PTR "); break; - case xmm_mdq_mode: - case vex_w_dq_mode: case vex_scalar_w_dq_mode: if (!need_vex) abort (); @@ -13921,6 +13941,13 @@ OP_E_register (int bytemode, int sizeflag) used_prefixes |= (prefixes & PREFIX_DATA); } break; + case movsxd_mode: + if (!(sizeflag & DFLAG) && isa64 == intel64) + names = names16; + else + names = names32; + used_prefixes |= (prefixes & PREFIX_DATA); + break; case va_mode: names = (address_mode == mode_64bit ? names64 : names32); @@ -13990,12 +14017,12 @@ OP_E_memory (int bytemode, int sizeflag) break; } /* fall through */ + case vex_scalar_w_dq_mode: case vex_vsib_d_w_dq_mode: case vex_vsib_d_w_d_mode: case vex_vsib_q_w_dq_mode: case vex_vsib_q_w_d_mode: case evex_x_gscat_mode: - case xmm_mdq_mode: shift = vex.w ? 3 : 2; break; case x_mode: @@ -14492,12 +14519,14 @@ OP_G (int bytemode, int sizeflag) case dqb_mode: case dqd_mode: case dqw_mode: + case movsxd_mode: USED_REX (REX_W); if (rex & REX_W) oappend (names64[modrm.reg + add]); else { - if ((sizeflag & DFLAG) || bytemode != v_mode) + if ((sizeflag & DFLAG) + || (bytemode != v_mode && bytemode != movsxd_mode)) oappend (names32[modrm.reg + add]); else oappend (names16[modrm.reg + add]); @@ -15339,7 +15368,6 @@ OP_EX (int bytemode, int sizeflag) && bytemode != xmm_mw_mode && bytemode != xmm_md_mode && bytemode != xmm_mq_mode - && bytemode != xmm_mdq_mode && bytemode != xmmq_mode && bytemode != evex_half_bcst_xmmq_mode && bytemode != ymm_mode @@ -16563,6 +16591,45 @@ skip: OP_M (bytemode, sizeflag); } +static void +MOVSXD_Fixup (int bytemode, int sizeflag) +{ + /* Add proper suffix to "movsxd". */ + char *p = mnemonicendp; + + switch (bytemode) + { + case movsxd_mode: + if (intel_syntax) + { + *p++ = 'x'; + *p++ = 'd'; + goto skip; + } + + USED_REX (REX_W); + if (rex & REX_W) + { + *p++ = 'l'; + *p++ = 'q'; + } + else + { + *p++ = 'x'; + *p++ = 'd'; + } + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + break; + } + +skip: + mnemonicendp = p; + *p = '\0'; + OP_E (bytemode, sizeflag); +} + static void OP_LWPCB_E (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) {