X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fi386-dis.c;h=fb7574704e8f9cbc9b9bdf56fb03a0a735e22703;hb=047cd301d40288d13e44f3322541ac28ebe06078;hp=5f4aed566d696545708e86d6097f76a008e2eb32;hpb=6f2750feaf2827ef8a1a0a5b2f90c1e9a6cabbd1;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 5f4aed566d..fb7574704e 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -258,7 +258,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define Edw { OP_E, dw_mode } #define Edqd { OP_E, dqd_mode } #define Eq { OP_E, q_mode } -#define indirEv { OP_indirE, stack_v_mode } +#define indirEv { OP_indirE, indir_v_mode } #define indirEp { OP_indirE, f_mode } #define stackEv { OP_E, stack_v_mode } #define Em { OP_E, m_mode } @@ -561,6 +561,8 @@ enum /* 4- or 6-byte pointer operand */ f_mode, const_1_mode, + /* v_mode for indirect branch opcodes. */ + indir_v_mode, /* v_mode for stack-related opcodes. */ stack_v_mode, /* non-quad operand size depends on prefixes */ @@ -982,6 +984,8 @@ enum PREFIX_0FAE_REG_1, PREFIX_0FAE_REG_2, PREFIX_0FAE_REG_3, + PREFIX_MOD_0_0FAE_REG_4, + PREFIX_MOD_3_0FAE_REG_4, PREFIX_0FAE_REG_6, PREFIX_0FAE_REG_7, PREFIX_RM_0_0FAE_REG_7, @@ -2483,6 +2487,9 @@ struct dis386 { 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 + has no operand size prefix for AMD64 ISA, behave as 'P' + otherwise 2 upper case letter macros: "XY" => print 'x' or 'y' if suffix_always is true or no register @@ -3531,9 +3538,9 @@ static const struct dis386 reg_table[][8] = { { { "incQ", { Evh1 }, 0 }, { "decQ", { Evh1 }, 0 }, - { "call{T|}", { indirEv, BND }, 0 }, + { "call{&|}", { indirEv, BND }, 0 }, { MOD_TABLE (MOD_FF_REG_3) }, - { "jmp{T|}", { indirEv, BND }, 0 }, + { "jmp{&|}", { indirEv, BND }, 0 }, { MOD_TABLE (MOD_FF_REG_5) }, { "pushU", { stackEv }, 0 }, { Bad_Opcode }, @@ -4061,6 +4068,18 @@ static const struct dis386 prefix_table[][4] = { { "wrgsbase", { Ev }, 0 }, }, + /* PREFIX_MOD_0_0FAE_REG_4 */ + { + { "xsave", { FXSAVE }, 0 }, + { "ptwrite%LQ", { Edq }, 0 }, + }, + + /* PREFIX_MOD_3_0FAE_REG_4 */ + { + { Bad_Opcode }, + { "ptwrite%LQ", { Edq }, 0 }, + }, + /* PREFIX_0FAE_REG_6 */ { { "xsaveopt", { FXSAVE }, 0 }, @@ -4132,7 +4151,7 @@ static const struct dis386 prefix_table[][4] = { /* PREFIX_MOD_3_0FC7_REG_7 */ { { "rdseed", { Ev }, 0 }, - { Bad_Opcode }, + { "rdpid", { Em }, 0 }, { "rdseed", { Ev }, 0 }, }, @@ -11864,7 +11883,8 @@ static const struct dis386 mod_table[][2] = { }, { /* MOD_0FAE_REG_4 */ - { "xsave", { FXSAVE }, 0 }, + { PREFIX_TABLE (PREFIX_MOD_0_0FAE_REG_4) }, + { PREFIX_TABLE (PREFIX_MOD_3_0FAE_REG_4) }, }, { /* MOD_0FAE_REG_5 */ @@ -13327,6 +13347,13 @@ print_insn (bfd_vma pc, disassemble_info *info) p++; } + if (address_mode == mode_64bit && sizeof (bfd_vma) < 8) + { + (*info->fprintf_func) (info->stream, + _("64-bit address is disabled")); + return -1; + } + if (intel_syntax) { names64 = intel_names64; @@ -13644,7 +13671,7 @@ print_insn (bfd_vma pc, disassemble_info *info) if (op_index[i] != -1 && op_riprel[i]) { (*info->fprintf_func) (info->stream, " # "); - (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep + (*info->print_address_func) ((bfd_vma) (start_pc + (codep - start_codep) + op_address[op_index[i]]), info); break; } @@ -14289,6 +14316,15 @@ case_L: if (!(rex & REX_W)) used_prefixes |= (prefixes & PREFIX_DATA); break; + case '&': + if (!intel_syntax + && address_mode == mode_64bit + && isa64 == intel64) + { + *obufp++ = 'q'; + break; + } + /* Fall through. */ case 'T': if (!intel_syntax && address_mode == mode_64bit @@ -14809,6 +14845,12 @@ intel_operand_size (int bytemode, int sizeflag) case dqw_swap_mode: oappend ("WORD PTR "); break; + case indir_v_mode: + if (address_mode == mode_64bit && isa64 == intel64) + { + oappend ("QWORD PTR "); + break; + } case stack_v_mode: if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W))) { @@ -15186,6 +15228,12 @@ OP_E_register (int bytemode, int sizeflag) case bnd_mode: names = names_bnd; break; + case indir_v_mode: + if (address_mode == mode_64bit && isa64 == intel64) + { + names = names64; + break; + } case stack_v_mode: if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W))) { @@ -16158,7 +16206,7 @@ OP_J (int bytemode, int sizeflag) the displacement is added! */ mask = 0xffff; if ((prefixes & PREFIX_DATA) == 0) - segment = ((start_pc + codep - start_codep) + segment = ((start_pc + (codep - start_codep)) & ~((bfd_vma) 0xffff)); } if (address_mode != mode_64bit