PR binutils/12523
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index f83ac78cfb7dce47b537c00fd56de9222a7dfae4..9834098ea552a1d975fc334dd3ea9a7d4223be04 100644 (file)
@@ -1,6 +1,6 @@
 /* Print i386 instructions for GDB, the GNU debugger.
    Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
@@ -252,6 +252,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Rm { OP_R, m_mode }
 #define Ib { OP_I, b_mode }
 #define sIb { OP_sI, b_mode }  /* sign extened byte */
+#define sIbT { OP_sI, b_T_mode } /* sign extened byte like 'T' */
 #define Iv { OP_I, v_mode }
 #define sIv { OP_sI, v_mode } 
 #define Iq { OP_I, q_mode }
@@ -282,7 +283,6 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define RMrSI { OP_REG, rSI_reg }
 #define RMrDI { OP_REG, rDI_reg }
 #define RMAL { OP_REG, al_reg }
-#define RMAL { OP_REG, al_reg }
 #define RMCL { OP_REG, cl_reg }
 #define RMDL { OP_REG, dl_reg }
 #define RMBL { OP_REG, bl_reg }
@@ -371,6 +371,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define VexScalar { OP_VEX, vex_scalar_mode }
 #define Vex128 { OP_VEX, vex128_mode }
 #define Vex256 { OP_VEX, vex256_mode }
+#define VexGdq { OP_VEX, dq_mode }
 #define VexI4 { VEXI4_Fixup, 0}
 #define EXdVex { OP_EX_Vex, d_mode }
 #define EXdVexS { OP_EX_Vex, d_swap_mode }
@@ -414,6 +415,8 @@ enum
   b_mode = 1,
   /* byte operand with operand swapped */
   b_swap_mode,
+  /* byte operand, sign extend like 'T' suffix */
+  b_T_mode,
   /* operand size depends on prefixes */
   v_mode,
   /* operand size depends on prefixes with operand swapped */
@@ -599,8 +602,11 @@ enum
   REG_VEX_0F72,
   REG_VEX_0F73,
   REG_VEX_0FAE,
+  REG_VEX_0F38F3,
   REG_XOP_LWPCB,
-  REG_XOP_LWP
+  REG_XOP_LWP,
+  REG_XOP_TBM_01,
+  REG_XOP_TBM_02
 };
 
 enum
@@ -747,6 +753,7 @@ enum
   PREFIX_0FAE_REG_2,
   PREFIX_0FAE_REG_3,
   PREFIX_0FB8,
+  PREFIX_0FBC,
   PREFIX_0FBD,
   PREFIX_0FC2,
   PREFIX_0FC3,
@@ -1015,6 +1022,11 @@ enum
   PREFIX_VEX_0F38DD,
   PREFIX_VEX_0F38DE,
   PREFIX_VEX_0F38DF,
+  PREFIX_VEX_0F38F2,
+  PREFIX_VEX_0F38F3_REG_1,
+  PREFIX_VEX_0F38F3_REG_2,
+  PREFIX_VEX_0F38F3_REG_3,
+  PREFIX_VEX_0F38F7,
   PREFIX_VEX_0F3A04,
   PREFIX_VEX_0F3A05,
   PREFIX_VEX_0F3A06,
@@ -1298,6 +1310,11 @@ enum
   VEX_LEN_0F38DD_P_2,
   VEX_LEN_0F38DE_P_2,
   VEX_LEN_0F38DF_P_2,
+  VEX_LEN_0F38F2_P_0,
+  VEX_LEN_0F38F3_R_1_P_0,
+  VEX_LEN_0F38F3_R_2_P_0,
+  VEX_LEN_0F38F3_R_3_P_0,
+  VEX_LEN_0F38F7_P_0,
   VEX_LEN_0F3A06_P_2,
   VEX_LEN_0F3A0A_P_2,
   VEX_LEN_0F3A0B_P_2,
@@ -1776,7 +1793,7 @@ static const struct dis386 dis386[] = {
   /* 68 */
   { "pushT",           { sIv } },
   { "imulS",           { Gv, Ev, Iv } },
-  { "pushT",           { sIb } },
+  { "pushT",           { sIbT } },
   { "imulS",           { Gv, Ev, sIb } },
   { "ins{b|}",         { Ybr, indirDX } },
   { X86_64_TABLE (X86_64_6D) },
@@ -2159,7 +2176,7 @@ static const struct dis386 dis386_twobyte[] = {
   { "ud1",             { XX } },
   { REG_TABLE (REG_0FBA) },
   { "btcS",            { Ev, Gv } },
-  { "bsfS",            { Gv, Ev } },
+  { PREFIX_TABLE (PREFIX_0FBC) },
   { PREFIX_TABLE (PREFIX_0FBD) },
   { "movs{bR|x}",      { Gv, Eb } },
   { "movs{wR|x}",      { Gv, Ew } }, /* yes, there really is movsww ! */
@@ -2750,6 +2767,13 @@ static const struct dis386 reg_table[][8] = {
     { MOD_TABLE (MOD_VEX_0FAE_REG_2) },
     { MOD_TABLE (MOD_VEX_0FAE_REG_3) },
   },
+  /* REG_VEX_0F38F3 */
+  {
+    { Bad_Opcode },
+    { PREFIX_TABLE (PREFIX_VEX_0F38F3_REG_1) },
+    { PREFIX_TABLE (PREFIX_VEX_0F38F3_REG_2) },
+    { PREFIX_TABLE (PREFIX_VEX_0F38F3_REG_3) },
+  },
   /* REG_XOP_LWPCB */
   {
     { "llwpcb", { { OP_LWPCB_E, 0 } } },
@@ -2760,6 +2784,27 @@ static const struct dis386 reg_table[][8] = {
     { "lwpins", { { OP_LWP_E, 0 }, Ed, Iq } },
     { "lwpval",        { { OP_LWP_E, 0 }, Ed, Iq } },
   },
+  /* REG_XOP_TBM_01 */
+  {
+    { Bad_Opcode },
+    { "blcfill",       { { OP_LWP_E, 0 }, Ev } },
+    { "blsfill",       { { OP_LWP_E, 0 }, Ev } },
+    { "blcs",  { { OP_LWP_E, 0 }, Ev } },
+    { "tzmsk", { { OP_LWP_E, 0 }, Ev } },
+    { "blcic", { { OP_LWP_E, 0 }, Ev } },
+    { "blsic", { { OP_LWP_E, 0 }, Ev } },
+    { "t1mskc",        { { OP_LWP_E, 0 }, Ev } },
+  },
+  /* REG_XOP_TBM_02 */
+  {
+    { Bad_Opcode },
+    { "blcmsk",        { { OP_LWP_E, 0 }, Ev } },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { "blci",  { { OP_LWP_E, 0 }, Ev } },
+  },
 };
 
 static const struct dis386 prefix_table[][4] = {
@@ -3070,6 +3115,13 @@ static const struct dis386 prefix_table[][4] = {
     { "popcntS", { Gv, Ev } },
   },
 
+  /* PREFIX_0FBC */
+  {
+    { "bsfS",  { Gv, Ev } },
+    { "tzcntS",        { Gv, Ev } },
+    { "bsfS",  { Gv, Ev } },
+  },
+
   /* PREFIX_0FBD */
   {
     { "bsrS",  { Gv, Ev } },
@@ -4969,6 +5021,31 @@ static const struct dis386 prefix_table[][4] = {
     { VEX_LEN_TABLE (VEX_LEN_0F38DF_P_2) },
   },
 
+  /* PREFIX_VEX_0F38F2 */
+  {
+    { VEX_LEN_TABLE (VEX_LEN_0F38F2_P_0) },
+  },
+
+  /* PREFIX_VEX_0F38F3_REG_1 */
+  {
+    { VEX_LEN_TABLE (VEX_LEN_0F38F3_R_1_P_0) },
+  },
+
+  /* PREFIX_VEX_0F38F3_REG_2 */
+  {
+    { VEX_LEN_TABLE (VEX_LEN_0F38F3_R_2_P_0) },
+  },
+
+  /* PREFIX_VEX_0F38F3_REG_3 */
+  {
+    { VEX_LEN_TABLE (VEX_LEN_0F38F3_R_3_P_0) },
+  },
+
+  /* PREFIX_VEX_0F38F7 */
+  {
+    { VEX_LEN_TABLE (VEX_LEN_0F38F7_P_0) },
+  },
+
   /* PREFIX_VEX_0F3A04 */
   {
     { Bad_Opcode },
@@ -5470,12 +5547,12 @@ static const struct dis386 x86_64_table[][2] = {
 
   /* X86_64_D4 */
   {
-    { "aam", { sIb } },
+    { "aam", { Ib } },
   },
 
   /* X86_64_D5 */
   {
-    { "aad", { sIb } },
+    { "aad", { Ib } },
   },
 
   /* X86_64_EA */
@@ -6408,7 +6485,7 @@ static const struct dis386 xop_table[][256] = {
     { Bad_Opcode },
     { Bad_Opcode },
     /* 10 */
-    { Bad_Opcode },
+    { "bextr", { Gv, Ev, Iq } },
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
@@ -6682,8 +6759,8 @@ static const struct dis386 xop_table[][256] = {
   {
     /* 00 */
     { Bad_Opcode },
-    { Bad_Opcode },
-    { Bad_Opcode },
+    { REG_TABLE (REG_XOP_TBM_01) },
+    { REG_TABLE (REG_XOP_TBM_02) },
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
@@ -6990,7 +7067,7 @@ static const struct dis386 xop_table[][256] = {
     { Bad_Opcode },
     { Bad_Opcode },
     /* 10 */
-    { Bad_Opcode },
+    { "bextr", { Gv, Ev, Iq } },
     { Bad_Opcode },
     { REG_TABLE (REG_XOP_LWP) },
     { Bad_Opcode },
@@ -7829,12 +7906,12 @@ static const struct dis386 vex_table[][256] = {
     /* f0 */
     { Bad_Opcode },
     { Bad_Opcode },
+    { PREFIX_TABLE (PREFIX_VEX_0F38F2) },
+    { REG_TABLE (REG_VEX_0F38F3) },
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
-    { Bad_Opcode },
-    { Bad_Opcode },
-    { Bad_Opcode },
+    { PREFIX_TABLE (PREFIX_VEX_0F38F7) },
     /* f8 */
     { Bad_Opcode },
     { Bad_Opcode },
@@ -9034,6 +9111,31 @@ static const struct dis386 vex_len_table[][2] = {
     { VEX_W_TABLE (VEX_W_0F38DF_P_2) },
   },
 
+  /* VEX_LEN_0F38F2_P_0 */
+  {
+    { "andnS",         { Gdq, VexGdq, Edq } },
+  },
+
+  /* VEX_LEN_0F38F3_R_1_P_0 */
+  {
+    { "blsrS",         { VexGdq, Edq } },
+  },
+
+  /* VEX_LEN_0F38F3_R_2_P_0 */
+  {
+    { "blsmskS",       { VexGdq, Edq } },
+  },
+
+  /* VEX_LEN_0F38F3_R_3_P_0 */
+  {
+    { "blsiS",         { VexGdq, Edq } },
+  },
+
+  /* VEX_LEN_0F38F7_P_0 */
+  {
+    { "bextrS",                { Gdq, Edq, VexGdq } },
+  },
+
   /* VEX_LEN_0F3A06_P_2 */
   {
     { Bad_Opcode },
@@ -11331,6 +11433,8 @@ print_insn (bfd_vma pc, disassemble_info *info)
 
   if (info->mach == bfd_mach_x86_64_intel_syntax
       || info->mach == bfd_mach_x86_64
+      || info->mach == bfd_mach_x64_32_intel_syntax
+      || info->mach == bfd_mach_x64_32
       || info->mach == bfd_mach_l1om
       || info->mach == bfd_mach_l1om_intel_syntax)
     address_mode = mode_64bit;
@@ -11340,13 +11444,16 @@ print_insn (bfd_vma pc, disassemble_info *info)
   if (intel_syntax == (char) -1)
     intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
                    || info->mach == bfd_mach_x86_64_intel_syntax
+                   || info->mach == bfd_mach_x64_32_intel_syntax
                    || info->mach == bfd_mach_l1om_intel_syntax);
 
   if (info->mach == bfd_mach_i386_i386
       || info->mach == bfd_mach_x86_64
+      || info->mach == bfd_mach_x64_32
       || info->mach == bfd_mach_l1om
       || info->mach == bfd_mach_i386_i386_intel_syntax
       || info->mach == bfd_mach_x86_64_intel_syntax
+      || info->mach == bfd_mach_x64_32_intel_syntax
       || info->mach == bfd_mach_l1om_intel_syntax)
     priv.orig_sizeflag = AFLAG | DFLAG;
   else if (info->mach == bfd_mach_i386_i8086)
@@ -11595,9 +11702,9 @@ print_insn (bfd_vma pc, disassemble_info *info)
       modrm.rm = *codep & 7;
     }
 
-   need_vex = 0;
-   need_vex_reg = 0;
-   vex_w_done = 0;
+  need_vex = 0;
+  need_vex_reg = 0;
+  vex_w_done = 0;
 
   if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
     {
@@ -13627,10 +13734,32 @@ OP_sI (int bytemode, int sizeflag)
   switch (bytemode)
     {
     case b_mode:
+    case b_T_mode:
       FETCH_DATA (the_info, codep + 1);
       op = *codep++;
       if ((op & 0x80) != 0)
        op -= 0x100;
+      if (bytemode == b_T_mode)
+       {
+         if (address_mode != mode_64bit
+             || !(sizeflag & DFLAG))
+           {
+             if (sizeflag & DFLAG)
+               op &= 0xffffffff;
+             else
+               op &= 0xffff;
+         }
+       }
+      else
+       {
+         if (!(rex & REX_W))
+           {
+             if (sizeflag & DFLAG)
+               op &= 0xffffffff;
+             else
+               op &= 0xffff;
+           }
+       }
       break;
     case v_mode:
       if (sizeflag & DFLAG)
@@ -13688,7 +13817,7 @@ OP_J (int bytemode, int sizeflag)
       oappend (INTERNAL_DISASSEMBLER_ERROR);
       return;
     }
-  disp = ((start_pc + codep - start_codep + disp) & mask) | segment;
+  disp = ((start_pc + (codep - start_codep) + disp) & mask) | segment;
   set_op (disp, 0);
   print_operand_value (scratchbuf, 1, disp);
   oappend (scratchbuf);
@@ -14523,13 +14652,18 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
        {
        case vex_mode:
        case vex128_mode:
+         names = names_xmm;
+         break;
+       case dq_mode:
+         if (vex.w)
+           names = names64;
+         else
+           names = names32;
          break;
        default:
          abort ();
          return;
        }
-
-      names = names_xmm;
       break;
     case 256:
       switch (bytemode)
This page took 0.029151 seconds and 4 git commands to generate.