X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fi386-dis.c;h=fb7574704e8f9cbc9b9bdf56fb03a0a735e22703;hb=d50c751e00b5336b4604b92271ab84615fdb0d27;hp=76ecb5a78bb94cab935faf7565625060625aa7db;hpb=f24bcbaa5a6e30556e2da20bfd78e7823741475a;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 76ecb5a78b..fb7574704e 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-2015 Free Software Foundation, Inc. + Copyright (C) 1988-2016 Free Software Foundation, Inc. This file is part of the GNU opcodes library. @@ -102,6 +102,7 @@ static void VPCMP_Fixup (int, int); static void OP_0f07 (int, int); static void OP_Monitor (int, int); static void OP_Mwait (int, int); +static void OP_Mwaitx (int, int); static void NOP_Fixup1 (int, int); static void NOP_Fixup2 (int, int); static void OP_3DNowSuffix (int, int); @@ -222,12 +223,6 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) } /* Possible values for prefix requirement. */ -#define PREFIX_UD_SHIFT 8 -#define PREFIX_UD_REPZ (PREFIX_REPZ << PREFIX_UD_SHIFT) -#define PREFIX_UD_REPNZ (PREFIX_REPNZ << PREFIX_UD_SHIFT) -#define PREFIX_UD_DATA (PREFIX_DATA << PREFIX_UD_SHIFT) -#define PREFIX_UD_ADDR (PREFIX_ADDR << PREFIX_UD_SHIFT) -#define PREFIX_UD_LOCK (PREFIX_LOCK << PREFIX_UD_SHIFT) #define PREFIX_IGNORED_SHIFT 16 #define PREFIX_IGNORED_REPZ (PREFIX_REPZ << PREFIX_IGNORED_SHIFT) #define PREFIX_IGNORED_REPNZ (PREFIX_REPNZ << PREFIX_IGNORED_SHIFT) @@ -263,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 } @@ -566,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 */ @@ -763,6 +760,7 @@ enum MOD_0F01_REG_1, MOD_0F01_REG_2, MOD_0F01_REG_3, + MOD_0F01_REG_5, MOD_0F01_REG_7, MOD_0F12_PREFIX_0, MOD_0F13, @@ -807,6 +805,7 @@ enum MOD_0FB2, MOD_0FB4, MOD_0FB5, + MOD_0FC3, MOD_0FC7_REG_3, MOD_0FC7_REG_4, MOD_0FC7_REG_5, @@ -824,6 +823,37 @@ enum MOD_VEX_0F16_PREFIX_0, MOD_VEX_0F17, MOD_VEX_0F2B, + MOD_VEX_W_0_0F41_P_0_LEN_1, + MOD_VEX_W_1_0F41_P_0_LEN_1, + MOD_VEX_W_0_0F41_P_2_LEN_1, + MOD_VEX_W_1_0F41_P_2_LEN_1, + MOD_VEX_W_0_0F42_P_0_LEN_1, + MOD_VEX_W_1_0F42_P_0_LEN_1, + MOD_VEX_W_0_0F42_P_2_LEN_1, + MOD_VEX_W_1_0F42_P_2_LEN_1, + MOD_VEX_W_0_0F44_P_0_LEN_1, + MOD_VEX_W_1_0F44_P_0_LEN_1, + MOD_VEX_W_0_0F44_P_2_LEN_1, + MOD_VEX_W_1_0F44_P_2_LEN_1, + MOD_VEX_W_0_0F45_P_0_LEN_1, + MOD_VEX_W_1_0F45_P_0_LEN_1, + MOD_VEX_W_0_0F45_P_2_LEN_1, + MOD_VEX_W_1_0F45_P_2_LEN_1, + MOD_VEX_W_0_0F46_P_0_LEN_1, + MOD_VEX_W_1_0F46_P_0_LEN_1, + MOD_VEX_W_0_0F46_P_2_LEN_1, + MOD_VEX_W_1_0F46_P_2_LEN_1, + MOD_VEX_W_0_0F47_P_0_LEN_1, + MOD_VEX_W_1_0F47_P_0_LEN_1, + MOD_VEX_W_0_0F47_P_2_LEN_1, + MOD_VEX_W_1_0F47_P_2_LEN_1, + MOD_VEX_W_0_0F4A_P_0_LEN_1, + MOD_VEX_W_1_0F4A_P_0_LEN_1, + MOD_VEX_W_0_0F4A_P_2_LEN_1, + MOD_VEX_W_1_0F4A_P_2_LEN_1, + MOD_VEX_W_0_0F4B_P_0_LEN_1, + MOD_VEX_W_1_0F4B_P_0_LEN_1, + MOD_VEX_W_0_0F4B_P_2_LEN_1, MOD_VEX_0F50, MOD_VEX_0F71_REG_2, MOD_VEX_0F71_REG_4, @@ -835,6 +865,26 @@ enum MOD_VEX_0F73_REG_3, MOD_VEX_0F73_REG_6, MOD_VEX_0F73_REG_7, + MOD_VEX_W_0_0F91_P_0_LEN_0, + MOD_VEX_W_1_0F91_P_0_LEN_0, + MOD_VEX_W_0_0F91_P_2_LEN_0, + MOD_VEX_W_1_0F91_P_2_LEN_0, + MOD_VEX_W_0_0F92_P_0_LEN_0, + MOD_VEX_W_0_0F92_P_2_LEN_0, + MOD_VEX_W_0_0F92_P_3_LEN_0, + MOD_VEX_W_1_0F92_P_3_LEN_0, + MOD_VEX_W_0_0F93_P_0_LEN_0, + MOD_VEX_W_0_0F93_P_2_LEN_0, + MOD_VEX_W_0_0F93_P_3_LEN_0, + MOD_VEX_W_1_0F93_P_3_LEN_0, + MOD_VEX_W_0_0F98_P_0_LEN_0, + MOD_VEX_W_1_0F98_P_0_LEN_0, + MOD_VEX_W_0_0F98_P_2_LEN_0, + MOD_VEX_W_1_0F98_P_2_LEN_0, + MOD_VEX_W_0_0F99_P_0_LEN_0, + MOD_VEX_W_1_0F99_P_0_LEN_0, + MOD_VEX_W_0_0F99_P_2_LEN_0, + MOD_VEX_W_1_0F99_P_2_LEN_0, MOD_VEX_0FAE_REG_2, MOD_VEX_0FAE_REG_3, MOD_VEX_0FD7_PREFIX_2, @@ -849,6 +899,14 @@ enum MOD_VEX_0F385A_PREFIX_2, MOD_VEX_0F388C_PREFIX_2, MOD_VEX_0F388E_PREFIX_2, + MOD_VEX_W_0_0F3A30_P_2_LEN_0, + MOD_VEX_W_1_0F3A30_P_2_LEN_0, + MOD_VEX_W_0_0F3A31_P_2_LEN_0, + MOD_VEX_W_1_0F3A31_P_2_LEN_0, + MOD_VEX_W_0_0F3A32_P_2_LEN_0, + MOD_VEX_W_1_0F3A32_P_2_LEN_0, + MOD_VEX_W_0_0F3A33_P_2_LEN_0, + MOD_VEX_W_1_0F3A33_P_2_LEN_0, MOD_EVEX_0F10_PREFIX_1, MOD_EVEX_0F10_PREFIX_3, @@ -874,6 +932,7 @@ enum RM_0F01_REG_1, RM_0F01_REG_2, RM_0F01_REG_3, + RM_0F01_REG_5, RM_0F01_REG_7, RM_0FAE_REG_5, RM_0FAE_REG_6, @@ -925,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, @@ -932,7 +993,7 @@ enum PREFIX_0FBC, PREFIX_0FBD, PREFIX_0FC2, - PREFIX_0FC3, + PREFIX_MOD_0_0FC3, PREFIX_MOD_0_0FC7_REG_6, PREFIX_MOD_3_0FC7_REG_6, PREFIX_MOD_3_0FC7_REG_7, @@ -1638,6 +1699,8 @@ enum X86_64_CE, X86_64_D4, X86_64_D5, + X86_64_E8, + X86_64_E9, X86_64_EA, X86_64_0F01_REG_0, X86_64_0F01_REG_1, @@ -2407,9 +2470,12 @@ struct dis386 { is true 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode) 'S' => print 'w', 'l' or 'q' if suffix_always is true - 'T' => print 'q' in 64bit mode and behave as 'P' otherwise - 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise - 'V' => print 'q' in 64bit mode and behave as 'S' otherwise + 'T' => print 'q' in 64bit mode if instruction has no operand size + prefix and behave as 'P' otherwise + 'U' => print 'q' in 64bit mode if instruction has no operand size + prefix and behave as 'Q' otherwise + 'V' => print 'q' in 64bit mode if instruction has no operand size + prefix and behave as 'S' otherwise 'W' => print 'b', 'w' or 'l' ('d' in Intel mode) 'X' => print 's', 'd' depending on data16 prefix (for XMM) 'Y' => 'q' if instruction has an REX 64bit overwrite prefix and @@ -2417,10 +2483,19 @@ 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 '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 no register operands or suffix_always - is true. + "XY" => print 'x' or 'y' if suffix_always is true or no register + operands and no broadcast. + "XZ" => print 'x', 'y', or 'z' if suffix_always is true or no + register operands and no broadcast. "XW" => print 's', 'd' depending on the VEX.W bit (for FMA) "LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand or suffix_always is true @@ -2701,8 +2776,8 @@ static const struct dis386 dis386[] = { { "outB", { Ib, AL }, 0 }, { "outG", { Ib, zAX }, 0 }, /* e8 */ - { "callT", { Jv, BND }, 0 }, - { "jmpT", { Jv, BND }, 0 }, + { X86_64_TABLE (X86_64_E8) }, + { X86_64_TABLE (X86_64_E9) }, { X86_64_TABLE (X86_64_EA) }, { "jmp", { Jb, BND }, 0 }, { "inB", { AL, indirDX }, 0 }, @@ -2950,7 +3025,7 @@ static const struct dis386 dis386_twobyte[] = { { "xaddB", { Ebh1, Gb }, 0 }, { "xaddS", { Evh1, Gv }, 0 }, { PREFIX_TABLE (PREFIX_0FC2) }, - { PREFIX_TABLE (PREFIX_0FC3) }, + { MOD_TABLE (MOD_0FC3) }, { "pinsrw", { MX, Edqw, Ib }, PREFIX_OPCODE }, { "pextrw", { Gdq, MS, Ib }, PREFIX_OPCODE }, { "shufpX", { XM, EXx, Ib }, PREFIX_OPCODE }, @@ -3082,8 +3157,6 @@ static int last_addr_prefix; static int last_rex_prefix; static int last_seg_prefix; static int fwait_prefix; -/* The PREFIX_REPZ/PREFIX_REPNZ/PREFIX_DATA prefix is mandatory. */ -static int prefix_requirement; /* The active segment register prefix. */ static int active_seg_prefix; #define MAX_CODE_LENGTH 15 @@ -3465,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 }, @@ -3490,7 +3563,7 @@ static const struct dis386 reg_table[][8] = { { MOD_TABLE (MOD_0F01_REG_2) }, { MOD_TABLE (MOD_0F01_REG_3) }, { "smswD", { Sv }, 0 }, - { Bad_Opcode }, + { MOD_TABLE (MOD_0F01_REG_5) }, { "lmsw", { Ew }, 0 }, { MOD_TABLE (MOD_0F01_REG_7) }, }, @@ -3995,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 }, @@ -4044,9 +4129,9 @@ static const struct dis386 prefix_table[][4] = { { "cmpsd", { XM, EXq, CMP }, PREFIX_OPCODE }, }, - /* PREFIX_0FC3 */ + /* PREFIX_MOD_0_0FC3 */ { - { "movntiS", { Ma, Gv }, PREFIX_OPCODE }, + { "movntiS", { Ev, Gv }, PREFIX_OPCODE }, }, /* PREFIX_MOD_0_0FC7_REG_6 */ @@ -4066,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 }, }, @@ -6840,6 +6925,18 @@ static const struct dis386 x86_64_table[][2] = { { "aad", { Ib }, 0 }, }, + /* X86_64_E8 */ + { + { "callP", { Jv, BND }, 0 }, + { "call@", { Jv, BND }, 0 } + }, + + /* X86_64_E9 */ + { + { "jmpP", { Jv, BND }, 0 }, + { "jmp@", { Jv, BND }, 0 } + }, + /* X86_64_EA */ { { "Jjmp{T|}", { Ap }, 0 }, @@ -10429,82 +10526,82 @@ static const struct dis386 vex_w_table[][2] = { }, { /* VEX_W_0F41_P_0_LEN_1 */ - { "kandw", { MaskG, MaskVex, MaskR }, 0 }, - { "kandq", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F41_P_0_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F41_P_0_LEN_1) }, }, { /* VEX_W_0F41_P_2_LEN_1 */ - { "kandb", { MaskG, MaskVex, MaskR }, 0 }, - { "kandd", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F41_P_2_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F41_P_2_LEN_1) } }, { /* VEX_W_0F42_P_0_LEN_1 */ - { "kandnw", { MaskG, MaskVex, MaskR }, 0 }, - { "kandnq", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F42_P_0_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F42_P_0_LEN_1) }, }, { /* VEX_W_0F42_P_2_LEN_1 */ - { "kandnb", { MaskG, MaskVex, MaskR }, 0 }, - { "kandnd", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F42_P_2_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F42_P_2_LEN_1) }, }, { /* VEX_W_0F44_P_0_LEN_0 */ - { "knotw", { MaskG, MaskR }, 0 }, - { "knotq", { MaskG, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F44_P_0_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F44_P_0_LEN_1) }, }, { /* VEX_W_0F44_P_2_LEN_0 */ - { "knotb", { MaskG, MaskR }, 0 }, - { "knotd", { MaskG, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F44_P_2_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F44_P_2_LEN_1) }, }, { /* VEX_W_0F45_P_0_LEN_1 */ - { "korw", { MaskG, MaskVex, MaskR }, 0 }, - { "korq", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F45_P_0_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F45_P_0_LEN_1) }, }, { /* VEX_W_0F45_P_2_LEN_1 */ - { "korb", { MaskG, MaskVex, MaskR }, 0 }, - { "kord", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F45_P_2_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F45_P_2_LEN_1) }, }, { /* VEX_W_0F46_P_0_LEN_1 */ - { "kxnorw", { MaskG, MaskVex, MaskR }, 0 }, - { "kxnorq", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F46_P_0_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F46_P_0_LEN_1) }, }, { /* VEX_W_0F46_P_2_LEN_1 */ - { "kxnorb", { MaskG, MaskVex, MaskR }, 0 }, - { "kxnord", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F46_P_2_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F46_P_2_LEN_1) }, }, { /* VEX_W_0F47_P_0_LEN_1 */ - { "kxorw", { MaskG, MaskVex, MaskR }, 0 }, - { "kxorq", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F47_P_0_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F47_P_0_LEN_1) }, }, { /* VEX_W_0F47_P_2_LEN_1 */ - { "kxorb", { MaskG, MaskVex, MaskR }, 0 }, - { "kxord", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F47_P_2_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F47_P_2_LEN_1) }, }, { /* VEX_W_0F4A_P_0_LEN_1 */ - { "kaddw", { MaskG, MaskVex, MaskR }, 0 }, - { "kaddq", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F4A_P_0_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F4A_P_0_LEN_1) }, }, { /* VEX_W_0F4A_P_2_LEN_1 */ - { "kaddb", { MaskG, MaskVex, MaskR }, 0 }, - { "kaddd", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F4A_P_2_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F4A_P_2_LEN_1) }, }, { /* VEX_W_0F4B_P_0_LEN_1 */ - { "kunpckwd", { MaskG, MaskVex, MaskR }, 0 }, - { "kunpckdq", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F4B_P_0_LEN_1) }, + { MOD_TABLE (MOD_VEX_W_1_0F4B_P_0_LEN_1) }, }, { /* VEX_W_0F4B_P_2_LEN_1 */ - { "kunpckbw", { MaskG, MaskVex, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F4B_P_2_LEN_1) }, }, { /* VEX_W_0F50_M_0 */ @@ -10834,59 +10931,59 @@ static const struct dis386 vex_w_table[][2] = { }, { /* VEX_W_0F91_P_0_LEN_0 */ - { "kmovw", { Ew, MaskG }, 0 }, - { "kmovq", { Eq, MaskG }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F91_P_0_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F91_P_0_LEN_0) }, }, { /* VEX_W_0F91_P_2_LEN_0 */ - { "kmovb", { Eb, MaskG }, 0 }, - { "kmovd", { Ed, MaskG }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F91_P_2_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F91_P_2_LEN_0) }, }, { /* VEX_W_0F92_P_0_LEN_0 */ - { "kmovw", { MaskG, Rdq }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F92_P_0_LEN_0) }, }, { /* VEX_W_0F92_P_2_LEN_0 */ - { "kmovb", { MaskG, Rdq }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F92_P_2_LEN_0) }, }, { /* VEX_W_0F92_P_3_LEN_0 */ - { "kmovd", { MaskG, Rdq }, 0 }, - { "kmovq", { MaskG, Rdq }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F92_P_3_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F92_P_3_LEN_0) }, }, { /* VEX_W_0F93_P_0_LEN_0 */ - { "kmovw", { Gdq, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F93_P_0_LEN_0) }, }, { /* VEX_W_0F93_P_2_LEN_0 */ - { "kmovb", { Gdq, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F93_P_2_LEN_0) }, }, { /* VEX_W_0F93_P_3_LEN_0 */ - { "kmovd", { Gdq, MaskR }, 0 }, - { "kmovq", { Gdq, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F93_P_3_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F93_P_3_LEN_0) }, }, { /* VEX_W_0F98_P_0_LEN_0 */ - { "kortestw", { MaskG, MaskR }, 0 }, - { "kortestq", { MaskG, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F98_P_0_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F98_P_0_LEN_0) }, }, { /* VEX_W_0F98_P_2_LEN_0 */ - { "kortestb", { MaskG, MaskR }, 0 }, - { "kortestd", { MaskG, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F98_P_2_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F98_P_2_LEN_0) }, }, { /* VEX_W_0F99_P_0_LEN_0 */ - { "ktestw", { MaskG, MaskR }, 0 }, - { "ktestq", { MaskG, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F99_P_0_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F99_P_0_LEN_0) }, }, { /* VEX_W_0F99_P_2_LEN_0 */ - { "ktestb", { MaskG, MaskR }, 0 }, - { "ktestd", { MaskG, MaskR }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F99_P_2_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F99_P_2_LEN_0) }, }, { /* VEX_W_0FAE_R_2_M_0 */ @@ -11472,23 +11569,23 @@ static const struct dis386 vex_w_table[][2] = { }, { /* VEX_W_0F3A30_P_2_LEN_0 */ - { "kshiftrb", { MaskG, MaskR, Ib }, 0 }, - { "kshiftrw", { MaskG, MaskR, Ib }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F3A30_P_2_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F3A30_P_2_LEN_0) }, }, { /* VEX_W_0F3A31_P_2_LEN_0 */ - { "kshiftrd", { MaskG, MaskR, Ib }, 0 }, - { "kshiftrq", { MaskG, MaskR, Ib }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F3A31_P_2_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F3A31_P_2_LEN_0) }, }, { /* VEX_W_0F3A32_P_2_LEN_0 */ - { "kshiftlb", { MaskG, MaskR, Ib }, 0 }, - { "kshiftlw", { MaskG, MaskR, Ib }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F3A32_P_2_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F3A32_P_2_LEN_0) }, }, { /* VEX_W_0F3A33_P_2_LEN_0 */ - { "kshiftld", { MaskG, MaskR, Ib }, 0 }, - { "kshiftlq", { MaskG, MaskR, Ib }, 0 }, + { MOD_TABLE (MOD_VEX_W_0_0F3A33_P_2_LEN_0) }, + { MOD_TABLE (MOD_VEX_W_1_0F3A33_P_2_LEN_0) }, }, { /* VEX_W_0F3A38_P_2 */ @@ -11582,11 +11679,11 @@ static const struct dis386 mod_table[][2] = { }, { /* MOD_FF_REG_3 */ - { "Jcall{T|}", { indirEp }, 0 }, + { "Jcall^", { indirEp }, 0 }, }, { /* MOD_FF_REG_5 */ - { "Jjmp{T|}", { indirEp }, 0 }, + { "Jjmp^", { indirEp }, 0 }, }, { /* MOD_0F01_REG_0 */ @@ -11608,6 +11705,11 @@ static const struct dis386 mod_table[][2] = { { X86_64_TABLE (X86_64_0F01_REG_3) }, { RM_TABLE (RM_0F01_REG_3) }, }, + { + /* MOD_0F01_REG_5 */ + { Bad_Opcode }, + { RM_TABLE (RM_0F01_REG_5) }, + }, { /* MOD_0F01_REG_7 */ { "invlpg", { Mb }, 0 }, @@ -11781,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 */ @@ -11810,9 +11913,13 @@ static const struct dis386 mod_table[][2] = { /* MOD_0FB5 */ { "lgsS", { Gv, Mp }, 0 }, }, + { + /* MOD_0FC3 */ + { PREFIX_TABLE (PREFIX_MOD_0_0FC3) }, + }, { /* MOD_0FC7_REG_3 */ - { "xrstors", { FXSAVE }, 0 }, + { "xrstors", { FXSAVE }, 0 }, }, { /* MOD_0FC7_REG_4 */ @@ -11886,6 +11993,161 @@ static const struct dis386 mod_table[][2] = { /* MOD_VEX_0F2B */ { VEX_W_TABLE (VEX_W_0F2B_M_0) }, }, + { + /* MOD_VEX_W_0_0F41_P_0_LEN_1 */ + { Bad_Opcode }, + { "kandw", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F41_P_0_LEN_1 */ + { Bad_Opcode }, + { "kandq", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F41_P_2_LEN_1 */ + { Bad_Opcode }, + { "kandb", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F41_P_2_LEN_1 */ + { Bad_Opcode }, + { "kandd", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F42_P_0_LEN_1 */ + { Bad_Opcode }, + { "kandnw", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F42_P_0_LEN_1 */ + { Bad_Opcode }, + { "kandnq", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F42_P_2_LEN_1 */ + { Bad_Opcode }, + { "kandnb", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F42_P_2_LEN_1 */ + { Bad_Opcode }, + { "kandnd", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F44_P_0_LEN_0 */ + { Bad_Opcode }, + { "knotw", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F44_P_0_LEN_0 */ + { Bad_Opcode }, + { "knotq", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F44_P_2_LEN_0 */ + { Bad_Opcode }, + { "knotb", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F44_P_2_LEN_0 */ + { Bad_Opcode }, + { "knotd", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F45_P_0_LEN_1 */ + { Bad_Opcode }, + { "korw", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F45_P_0_LEN_1 */ + { Bad_Opcode }, + { "korq", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F45_P_2_LEN_1 */ + { Bad_Opcode }, + { "korb", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F45_P_2_LEN_1 */ + { Bad_Opcode }, + { "kord", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F46_P_0_LEN_1 */ + { Bad_Opcode }, + { "kxnorw", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F46_P_0_LEN_1 */ + { Bad_Opcode }, + { "kxnorq", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F46_P_2_LEN_1 */ + { Bad_Opcode }, + { "kxnorb", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F46_P_2_LEN_1 */ + { Bad_Opcode }, + { "kxnord", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F47_P_0_LEN_1 */ + { Bad_Opcode }, + { "kxorw", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F47_P_0_LEN_1 */ + { Bad_Opcode }, + { "kxorq", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F47_P_2_LEN_1 */ + { Bad_Opcode }, + { "kxorb", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F47_P_2_LEN_1 */ + { Bad_Opcode }, + { "kxord", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F4A_P_0_LEN_1 */ + { Bad_Opcode }, + { "kaddw", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F4A_P_0_LEN_1 */ + { Bad_Opcode }, + { "kaddq", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F4A_P_2_LEN_1 */ + { Bad_Opcode }, + { "kaddb", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F4A_P_2_LEN_1 */ + { Bad_Opcode }, + { "kaddd", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F4B_P_0_LEN_1 */ + { Bad_Opcode }, + { "kunpckwd", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F4B_P_0_LEN_1 */ + { Bad_Opcode }, + { "kunpckdq", { MaskG, MaskVex, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F4B_P_2_LEN_1 */ + { Bad_Opcode }, + { "kunpckbw", { MaskG, MaskVex, MaskR }, 0 }, + }, { /* MOD_VEX_0F50 */ { Bad_Opcode }, @@ -11941,6 +12203,106 @@ static const struct dis386 mod_table[][2] = { { Bad_Opcode }, { PREFIX_TABLE (PREFIX_VEX_0F73_REG_7) }, }, + { + /* MOD_VEX_W_0_0F91_P_0_LEN_0 */ + { "kmovw", { Ew, MaskG }, 0 }, + { Bad_Opcode }, + }, + { + /* MOD_VEX_W_0_0F91_P_0_LEN_0 */ + { "kmovq", { Eq, MaskG }, 0 }, + { Bad_Opcode }, + }, + { + /* MOD_VEX_W_0_0F91_P_2_LEN_0 */ + { "kmovb", { Eb, MaskG }, 0 }, + { Bad_Opcode }, + }, + { + /* MOD_VEX_W_0_0F91_P_2_LEN_0 */ + { "kmovd", { Ed, MaskG }, 0 }, + { Bad_Opcode }, + }, + { + /* MOD_VEX_W_0_0F92_P_0_LEN_0 */ + { Bad_Opcode }, + { "kmovw", { MaskG, Rdq }, 0 }, + }, + { + /* MOD_VEX_W_0_0F92_P_2_LEN_0 */ + { Bad_Opcode }, + { "kmovb", { MaskG, Rdq }, 0 }, + }, + { + /* MOD_VEX_W_0_0F92_P_3_LEN_0 */ + { Bad_Opcode }, + { "kmovd", { MaskG, Rdq }, 0 }, + }, + { + /* MOD_VEX_W_1_0F92_P_3_LEN_0 */ + { Bad_Opcode }, + { "kmovq", { MaskG, Rdq }, 0 }, + }, + { + /* MOD_VEX_W_0_0F93_P_0_LEN_0 */ + { Bad_Opcode }, + { "kmovw", { Gdq, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F93_P_2_LEN_0 */ + { Bad_Opcode }, + { "kmovb", { Gdq, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F93_P_3_LEN_0 */ + { Bad_Opcode }, + { "kmovd", { Gdq, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F93_P_3_LEN_0 */ + { Bad_Opcode }, + { "kmovq", { Gdq, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F98_P_0_LEN_0 */ + { Bad_Opcode }, + { "kortestw", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F98_P_0_LEN_0 */ + { Bad_Opcode }, + { "kortestq", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F98_P_2_LEN_0 */ + { Bad_Opcode }, + { "kortestb", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F98_P_2_LEN_0 */ + { Bad_Opcode }, + { "kortestd", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F99_P_0_LEN_0 */ + { Bad_Opcode }, + { "ktestw", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F99_P_0_LEN_0 */ + { Bad_Opcode }, + { "ktestq", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_0_0F99_P_2_LEN_0 */ + { Bad_Opcode }, + { "ktestb", { MaskG, MaskR }, 0 }, + }, + { + /* MOD_VEX_W_1_0F99_P_2_LEN_0 */ + { Bad_Opcode }, + { "ktestd", { MaskG, MaskR }, 0 }, + }, { /* MOD_VEX_0FAE_REG_2 */ { VEX_LEN_TABLE (VEX_LEN_0FAE_R_2_M_0) }, @@ -11998,6 +12360,46 @@ static const struct dis386 mod_table[][2] = { /* MOD_VEX_0F388E_PREFIX_2 */ { "vpmaskmov%LW", { Mx, Vex, XM }, 0 }, }, + { + /* MOD_VEX_W_0_0F3A30_P_2_LEN_0 */ + { Bad_Opcode }, + { "kshiftrb", { MaskG, MaskR, Ib }, 0 }, + }, + { + /* MOD_VEX_W_1_0F3A30_P_2_LEN_0 */ + { Bad_Opcode }, + { "kshiftrw", { MaskG, MaskR, Ib }, 0 }, + }, + { + /* MOD_VEX_W_0_0F3A31_P_2_LEN_0 */ + { Bad_Opcode }, + { "kshiftrd", { MaskG, MaskR, Ib }, 0 }, + }, + { + /* MOD_VEX_W_1_0F3A31_P_2_LEN_0 */ + { Bad_Opcode }, + { "kshiftrq", { MaskG, MaskR, Ib }, 0 }, + }, + { + /* MOD_VEX_W_0_0F3A32_P_2_LEN_0 */ + { Bad_Opcode }, + { "kshiftlb", { MaskG, MaskR, Ib }, 0 }, + }, + { + /* MOD_VEX_W_1_0F3A32_P_2_LEN_0 */ + { Bad_Opcode }, + { "kshiftlw", { MaskG, MaskR, Ib }, 0 }, + }, + { + /* MOD_VEX_W_0_0F3A33_P_2_LEN_0 */ + { Bad_Opcode }, + { "kshiftld", { MaskG, MaskR, Ib }, 0 }, + }, + { + /* MOD_VEX_W_1_0F3A33_P_2_LEN_0 */ + { Bad_Opcode }, + { "kshiftlq", { MaskG, MaskR, Ib }, 0 }, + }, #define NEED_MOD_TABLE #include "i386-dis-evex.h" #undef NEED_MOD_TABLE @@ -12053,12 +12455,23 @@ static const struct dis386 rm_table[][8] = { { "skinit", { Skip_MODRM }, 0 }, { "invlpga", { Skip_MODRM }, 0 }, }, + { + /* RM_0F01_REG_5 */ + { Bad_Opcode }, + { Bad_Opcode }, + { Bad_Opcode }, + { Bad_Opcode }, + { Bad_Opcode }, + { Bad_Opcode }, + { "rdpkru", { Skip_MODRM }, 0 }, + { "wrpkru", { Skip_MODRM }, 0 }, + }, { /* RM_0F01_REG_7 */ { "swapgs", { Skip_MODRM }, 0 }, { "rdtscp", { Skip_MODRM }, 0 }, - { Bad_Opcode }, - { Bad_Opcode }, + { "monitorx", { { OP_Monitor, 0 } }, 0 }, + { "mwaitx", { { OP_Mwaitx, 0 } }, 0 }, { "clzero", { Skip_MODRM }, 0 }, }, { @@ -12329,6 +12742,14 @@ static char close_char; static char separator_char; static char scale_char; +enum x86_64_isa +{ + amd64 = 0, + intel64 +}; + +static enum x86_64_isa isa64; + /* Here for backwards compatibility. When gdb stops using print_insn_i386_att and print_insn_i386_intel these functions can disappear, and print_insn_i386 be merged into print_insn. */ @@ -12378,6 +12799,8 @@ with the -M switch (multiple options should be separated by commas):\n")); fprintf (stream, _(" data32 Assume 32bit data size\n")); fprintf (stream, _(" data16 Assume 16bit data size\n")); fprintf (stream, _(" suffix Always display instruction suffix in AT&T syntax\n")); + fprintf (stream, _(" amd64 Display instruction in AMD64 ISA\n")); + fprintf (stream, _(" intel64 Display instruction in Intel64 ISA\n")); } /* Bad opcode. */ @@ -12861,7 +13284,11 @@ print_insn (bfd_vma pc, disassemble_info *info) for (p = info->disassembler_options; p != NULL; ) { - if (CONST_STRNEQ (p, "x86-64")) + if (CONST_STRNEQ (p, "amd64")) + isa64 = amd64; + else if (CONST_STRNEQ (p, "intel64")) + isa64 = intel64; + else if (CONST_STRNEQ (p, "x86-64")) { address_mode = mode_64bit; priv.orig_sizeflag = AFLAG | DFLAG; @@ -12920,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; @@ -13049,18 +13483,18 @@ print_insn (bfd_vma pc, disassemble_info *info) if (*codep == 0x0f) { unsigned char threebyte; - FETCH_DATA (info, codep + 2); - threebyte = *++codep; + + codep++; + FETCH_DATA (info, codep + 1); + threebyte = *codep; dp = &dis386_twobyte[threebyte]; need_modrm = twobyte_has_modrm[*codep]; - prefix_requirement = dp->prefix_requirement; codep++; } else { dp = &dis386[*codep]; need_modrm = onebyte_has_modrm[*codep]; - prefix_requirement = 0; codep++; } @@ -13160,7 +13594,7 @@ print_insn (bfd_vma pc, disassemble_info *info) used by putop and MMX/SSE operand and may be overriden by the PREFIX_REPZ/PREFIX_REPNZ fix, we check the PREFIX_DATA prefix separately. */ - if (prefix_requirement == PREFIX_OPCODE + if (dp->prefix_requirement == PREFIX_OPCODE && dp != &bad_opcode && (((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) != 0 @@ -13197,6 +13631,13 @@ print_insn (bfd_vma pc, disassemble_info *info) for (i = 0; i < MAX_OPERANDS; ++i) op_txt[i] = op_out[i]; + if (intel_syntax && dp && dp->op[2].rtn == OP_Rounding + && dp->op[3].rtn == OP_E && dp->op[4].rtn == NULL) + { + op_txt[2] = op_out[3]; + op_txt[3] = op_out[2]; + } + for (i = 0; i < (MAX_OPERANDS >> 1); ++i) { op_ad = op_index[i]; @@ -13230,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; } @@ -13805,6 +14246,34 @@ case_B: *obufp++ = 'd'; break; case 'Z': + if (l != 0 || len != 1) + { + if (l != 1 || len != 2 || last[0] != 'X') + { + SAVE_LAST (*p); + break; + } + if (!need_vex || !vex.evex) + abort (); + if (intel_syntax + || ((modrm.mod == 3 || vex.b) && !(sizeflag & SUFFIX_ALWAYS))) + break; + switch (vex.length) + { + case 128: + *obufp++ = 'x'; + break; + case 256: + *obufp++ = 'y'; + break; + case 512: + *obufp++ = 'z'; + break; + default: + abort (); + } + break; + } if (intel_syntax) break; if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS)) @@ -13847,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 @@ -14103,7 +14581,7 @@ case_S: if (!need_vex) abort (); if (intel_syntax - || (modrm.mod == 3 && !(sizeflag & SUFFIX_ALWAYS))) + || ((modrm.mod == 3 || vex.b) && !(sizeflag & SUFFIX_ALWAYS))) break; switch (vex.length) { @@ -14113,8 +14591,10 @@ case_S: case 256: *obufp++ = 'y'; break; + case 512: + if (!vex.evex) default: - abort (); + abort (); } } break; @@ -14155,6 +14635,32 @@ case_S: *obufp++ = vex.w ? 'q': 'd'; } break; + case '^': + if (intel_syntax) + break; + if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS)) + { + if (sizeflag & DFLAG) + *obufp++ = 'l'; + else + *obufp++ = 'w'; + used_prefixes |= (prefixes & PREFIX_DATA); + } + break; + case '@': + if (intel_syntax) + break; + if (address_mode == mode_64bit + && (isa64 == intel64 + || ((sizeflag & DFLAG) || (rex & REX_W)))) + *obufp++ = 'q'; + else if ((prefixes & PREFIX_DATA)) + { + if (!(sizeflag & DFLAG)) + *obufp++ = 'w'; + used_prefixes |= (prefixes & PREFIX_DATA); + } + break; } alt = 0; } @@ -14339,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))) { @@ -14716,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))) { @@ -15296,11 +15814,11 @@ get64 (void) a = *codep++ & 0xff; a |= (*codep++ & 0xff) << 8; a |= (*codep++ & 0xff) << 16; - a |= (*codep++ & 0xff) << 24; + a |= (*codep++ & 0xffu) << 24; b = *codep++ & 0xff; b |= (*codep++ & 0xff) << 8; b |= (*codep++ & 0xff) << 16; - b |= (*codep++ & 0xff) << 24; + b |= (*codep++ & 0xffu) << 24; x = a + ((bfd_vma) b << 32); #else abort (); @@ -15671,8 +16189,11 @@ OP_J (int bytemode, int sizeflag) disp -= 0x100; break; case v_mode: - USED_REX (REX_W); - if ((sizeflag & DFLAG) || (rex & REX_W)) + if (isa64 == amd64) + USED_REX (REX_W); + if ((sizeflag & DFLAG) + || (address_mode == mode_64bit + && (isa64 != amd64 || (rex & REX_W)))) disp = get32s (); else { @@ -15685,10 +16206,11 @@ 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 (!(rex & REX_W)) + if (address_mode != mode_64bit + || (isa64 == amd64 && !(rex & REX_W))) used_prefixes |= (prefixes & PREFIX_DATA); break; default: @@ -16357,6 +16879,25 @@ CMP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) } } +static void +OP_Mwaitx (int bytemode ATTRIBUTE_UNUSED, + int sizeflag ATTRIBUTE_UNUSED) +{ + /* mwaitx %eax,%ecx,%ebx */ + if (!intel_syntax) + { + const char **names = (address_mode == mode_64bit + ? names64 : names32); + strcpy (op_out[0], names[0]); + strcpy (op_out[1], names[1]); + strcpy (op_out[2], names[3]); + two_source_ops = 1; + } + /* Skip mod/rm byte. */ + MODRM_CHECK; + codep++; +} + static void OP_Mwait (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)