PR binutils/12523
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index 2ee8e577a5e893f71b72d781a974ef9a2fa48f6a..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,7 +252,9 @@ 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 }
 #define Iv64 { OP_I64, v_mode }
 #define Iw { OP_I, w_mode }
@@ -281,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 }
@@ -370,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 }
@@ -413,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 */
@@ -598,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
@@ -746,6 +753,7 @@ enum
   PREFIX_0FAE_REG_2,
   PREFIX_0FAE_REG_3,
   PREFIX_0FB8,
+  PREFIX_0FBC,
   PREFIX_0FBD,
   PREFIX_0FC2,
   PREFIX_0FC3,
@@ -1014,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,
@@ -1297,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,
@@ -1773,9 +1791,9 @@ static const struct dis386 dis386[] = {
   { Bad_Opcode },      /* op size prefix */
   { Bad_Opcode },      /* adr size prefix */
   /* 68 */
-  { "pushT",           { Iq } },
+  { "pushT",           { sIv } },
   { "imulS",           { Gv, Ev, Iv } },
-  { "pushT",           { sIb } },
+  { "pushT",           { sIbT } },
   { "imulS",           { Gv, Ev, sIb } },
   { "ins{b|}",         { Ybr, indirDX } },
   { X86_64_TABLE (X86_64_6D) },
@@ -2158,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 ! */
@@ -2591,10 +2609,10 @@ static const struct dis386 reg_table[][8] = {
   {
     { "incQ",  { Ev } },
     { "decQ",  { Ev } },
-    { "callT", { indirEv } },
-    { "JcallT",        { indirEp } },
-    { "jmpT",  { indirEv } },
-    { "JjmpT", { indirEp } },
+    { "call{T|}", { indirEv } },
+    { "Jcall{T|}", { indirEp } },
+    { "jmp{T|}", { indirEv } },
+    { "Jjmp{T|}", { indirEp } },
     { "pushU", { stackEv } },
     { Bad_Opcode },
   },
@@ -2749,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 } } },
@@ -2759,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] = {
@@ -3069,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 } },
@@ -4968,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 },
@@ -5359,37 +5437,37 @@ static const struct dis386 prefix_table[][4] = {
 static const struct dis386 x86_64_table[][2] = {
   /* X86_64_06 */
   {
-    { "push{T|}", { es } },
+    { "pushP", { es } },
   },
 
   /* X86_64_07 */
   {
-    { "pop{T|}", { es } },
+    { "popP", { es } },
   },
 
   /* X86_64_0D */
   {
-    { "push{T|}", { cs } },
+    { "pushP", { cs } },
   },
 
   /* X86_64_16 */
   {
-    { "push{T|}", { ss } },
+    { "pushP", { ss } },
   },
 
   /* X86_64_17 */
   {
-    { "pop{T|}", { ss } },
+    { "popP", { ss } },
   },
 
   /* X86_64_1E */
   {
-    { "push{T|}", { ds } },
+    { "pushP", { ds } },
   },
 
   /* X86_64_1F */
   {
-    { "pop{T|}", { ds } },
+    { "popP", { ds } },
   },
 
   /* X86_64_27 */
@@ -5414,12 +5492,12 @@ static const struct dis386 x86_64_table[][2] = {
 
   /* X86_64_60 */
   {
-    { "pusha{P|}", { XX } },
+    { "pushaP", { XX } },
   },
 
   /* X86_64_61 */
   {
-    { "popa{P|}", { XX } },
+    { "popaP", { XX } },
   },
 
   /* X86_64_62 */
@@ -5469,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 */
@@ -6407,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 },
@@ -6681,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 },
@@ -6989,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 },
@@ -7828,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 },
@@ -9033,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 },
@@ -11330,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;
@@ -11339,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)
@@ -11594,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)
     {
@@ -12335,9 +12443,9 @@ case_L:
            used_prefixes |= (prefixes & PREFIX_DATA);
          break;
        case 'T':
-         if (intel_syntax)
-           break;
-         if (address_mode == mode_64bit && (sizeflag & DFLAG))
+         if (!intel_syntax
+             && address_mode == mode_64bit
+             && (sizeflag & DFLAG))
            {
              *obufp++ = 'q';
              break;
@@ -12345,7 +12453,16 @@ case_L:
          /* Fall through.  */
        case 'P':
          if (intel_syntax)
-           break;
+           {
+             if ((rex & REX_W) == 0
+                 && (prefixes & PREFIX_DATA))
+               {
+                 if ((sizeflag & DFLAG) == 0)
+                   *obufp++ = 'w';
+                  used_prefixes |= (prefixes & PREFIX_DATA);
+               }
+             break;
+           }
          if ((prefixes & PREFIX_DATA)
              || (rex & REX_W)
              || (sizeflag & SUFFIX_ALWAYS))
@@ -13617,34 +13734,38 @@ 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;
-      break;
-    case v_mode:
-      USED_REX (REX_W);
-      if (rex & REX_W)
-       op = get32s ();
-      else
+      if (bytemode == b_T_mode)
        {
-         if (sizeflag & DFLAG)
+         if (address_mode != mode_64bit
+             || !(sizeflag & DFLAG))
            {
-             op = get32s ();
-           }
-         else
+             if (sizeflag & DFLAG)
+               op &= 0xffffffff;
+             else
+               op &= 0xffff;
+         }
+       }
+      else
+       {
+         if (!(rex & REX_W))
            {
-             op = get16 ();
-             if ((op & 0x8000) != 0)
-               op -= 0x10000;
+             if (sizeflag & DFLAG)
+               op &= 0xffffffff;
+             else
+               op &= 0xffff;
            }
-         used_prefixes |= (prefixes & PREFIX_DATA);
        }
       break;
-    case w_mode:
-      op = get16 ();
-      if ((op & 0x8000) != 0)
-       op -= 0x10000;
+    case v_mode:
+      if (sizeflag & DFLAG)
+       op = get32s ();
+      else
+       op = get16 ();
       break;
     default:
       oappend (INTERNAL_DISASSEMBLER_ERROR);
@@ -13696,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);
@@ -14531,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.031319 seconds and 4 git commands to generate.