Add missing break statement for case elfcpp::R_X86_64_PLTOFF64.
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index 7d8a18c34cc2c4811617bcc8dc8c8cb71d9bc243..0e076060e0ed643696f5557b16ef0d8f7b5e94fe 100644 (file)
@@ -1,7 +1,5 @@
 /* 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, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright (C) 1988-2014 Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
 
@@ -429,7 +427,9 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define MaskVex { OP_VEX, mask_mode }
 
 #define MVexVSIBDWpX { OP_M, vex_vsib_d_w_dq_mode }
+#define MVexVSIBDQWpX { OP_M, vex_vsib_d_w_d_mode }
 #define MVexVSIBQWpX { OP_M, vex_vsib_q_w_dq_mode }
+#define MVexVSIBQDWpX { OP_M, vex_vsib_q_w_d_mode }
 
 /* Used handle "rep" prefix for string instructions.  */
 #define Xbr { REP_Fixup, eSI_reg }
@@ -558,8 +558,12 @@ enum
 
   /* Similar to vex_w_dq_mode, 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.  */
   vex_vsib_q_w_dq_mode,
+  /* Similar to vex_vsib_q_w_dq_mode, with smaller memory.  */
+  vex_vsib_q_w_d_mode,
 
   /* scalar, ignore vector length.  */
   scalar_mode,
@@ -715,6 +719,8 @@ enum
   MOD_8D = 0,
   MOD_C6_REG_7,
   MOD_C7_REG_7,
+  MOD_FF_REG_3,
+  MOD_FF_REG_5,
   MOD_0F01_REG_0,
   MOD_0F01_REG_1,
   MOD_0F01_REG_2,
@@ -767,6 +773,9 @@ enum
   MOD_0FB2,
   MOD_0FB4,
   MOD_0FB5,
+  MOD_0FC7_REG_3,
+  MOD_0FC7_REG_4,
+  MOD_0FC7_REG_5,
   MOD_0FC7_REG_6,
   MOD_0FC7_REG_7,
   MOD_0FD7,
@@ -882,6 +891,7 @@ enum
   PREFIX_0FAE_REG_1,
   PREFIX_0FAE_REG_2,
   PREFIX_0FAE_REG_3,
+  PREFIX_0FAE_REG_7,
   PREFIX_0FB8,
   PREFIX_0FBC,
   PREFIX_0FBD,
@@ -1469,8 +1479,6 @@ enum
   PREFIX_EVEX_0F3A39,
   PREFIX_EVEX_0F3A3A,
   PREFIX_EVEX_0F3A3B,
-  PREFIX_EVEX_0F3A3E,
-  PREFIX_EVEX_0F3A3F,
   PREFIX_EVEX_0F3A43,
   PREFIX_EVEX_0F3A54,
   PREFIX_EVEX_0F3A55,
@@ -3231,9 +3239,9 @@ static const struct dis386 reg_table[][8] = {
     { "incQ",  { Evh1 } },
     { "decQ",  { Evh1 } },
     { "call{T|}", { indirEv, BND } },
-    { "Jcall{T|}", { indirEp } },
+    { MOD_TABLE (MOD_FF_REG_3) },
     { "jmp{T|}", { indirEv, BND } },
-    { "Jjmp{T|}", { indirEp } },
+    { MOD_TABLE (MOD_FF_REG_5) },
     { "pushU", { stackEv } },
     { Bad_Opcode },
   },
@@ -3354,9 +3362,9 @@ static const struct dis386 reg_table[][8] = {
     { Bad_Opcode },
     { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } },
     { Bad_Opcode },
-    { Bad_Opcode },
-    { Bad_Opcode },
-    { Bad_Opcode },
+    { MOD_TABLE (MOD_0FC7_REG_3) },
+    { MOD_TABLE (MOD_0FC7_REG_4) },
+    { MOD_TABLE (MOD_0FC7_REG_5) },
     { MOD_TABLE (MOD_0FC7_REG_6) },
     { MOD_TABLE (MOD_0FC7_REG_7) },
   },
@@ -3759,6 +3767,13 @@ static const struct dis386 prefix_table[][4] = {
     { "wrgsbase", { Ev } },
   },
 
+  /* PREFIX_0FAE_REG_7 */
+  {
+    { "clflush",       { Mb } },
+    { Bad_Opcode },
+    { "clflushopt",    { Mb } },
+  },
+
   /* PREFIX_0FB8 */
   {
     { Bad_Opcode },
@@ -11051,6 +11066,14 @@ static const struct dis386 mod_table[][2] = {
     { Bad_Opcode },
     { RM_TABLE (RM_C7_REG_7) },
   },
+  {
+    /* MOD_FF_REG_3 */
+    { "Jcall{T|}", { indirEp } },
+  },
+  {
+    /* MOD_FF_REG_5 */
+    { "Jjmp{T|}", { indirEp } },
+  },
   {
     /* MOD_0F01_REG_0 */
     { X86_64_TABLE (X86_64_0F01_REG_0) },
@@ -11278,7 +11301,7 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_0FAE_REG_7 */
-    { "clflush",       { Mb } },
+    { PREFIX_TABLE (PREFIX_0FAE_REG_7) },
     { RM_TABLE (RM_0FAE_REG_7) },
   },
   {
@@ -11293,6 +11316,18 @@ static const struct dis386 mod_table[][2] = {
     /* MOD_0FB5 */
     { "lgsS",          { Gv, Mp } },
   },
+  {
+    /* MOD_0FC7_REG_3 */
+    { "xrstors",               { FXSAVE } },
+  },
+  {
+    /* MOD_0FC7_REG_4 */
+    { "xsavec",                { FXSAVE } },
+  },
+  {
+    /* MOD_0FC7_REG_5 */
+    { "xsaves",                { FXSAVE } },
+  },
   {
     /* MOD_0FC7_REG_6 */
     { PREFIX_TABLE (PREFIX_0FC7_REG_6) },
@@ -11497,6 +11532,10 @@ static const struct dis386 rm_table[][8] = {
     { "mwait",         { { OP_Mwait, 0 } } },
     { "clac",          { Skip_MODRM } },
     { "stac",          { Skip_MODRM } },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { "encls",         { Skip_MODRM } },
   },
   {
     /* RM_0F01_REG_2 */
@@ -11507,7 +11546,7 @@ static const struct dis386 rm_table[][8] = {
     { "vmfunc",                { Skip_MODRM } },
     { "xend",          { Skip_MODRM } },
     { "xtest",         { Skip_MODRM } },
-    { Bad_Opcode },
+    { "enclu",         { Skip_MODRM } },
   },
   {
     /* RM_0F01_REG_3 */
@@ -12637,7 +12676,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
     }
 
   /* Check if the REX prefix is used.  */
-  if (rex_ignored == 0 && (rex ^ rex_used) == 0)
+  if (rex_ignored == 0 && (rex ^ rex_used) == 0 && last_rex_prefix >= 0)
     all_prefixes[last_rex_prefix] = 0;
 
   /* Check if the SEG prefix is used.  */
@@ -13097,17 +13136,25 @@ dofloat (int sizeflag)
     }
 }
 
+/* Like oappend (below), but S is a string starting with '%'.
+   In Intel syntax, the '%' is elided.  */
+static void
+oappend_maybe_intel (const char *s)
+{
+  oappend (s + intel_syntax);
+}
+
 static void
 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
 {
-  oappend ("%st" + intel_syntax);
+  oappend_maybe_intel ("%st");
 }
 
 static void
 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
 {
   sprintf (scratchbuf, "%%st(%d)", modrm.rm);
-  oappend (scratchbuf + intel_syntax);
+  oappend_maybe_intel (scratchbuf);
 }
 
 /* Capital letters in template are macros.  */
@@ -13631,32 +13678,32 @@ append_seg (void)
   if (prefixes & PREFIX_CS)
     {
       used_prefixes |= PREFIX_CS;
-      oappend ("%cs:" + intel_syntax);
+      oappend_maybe_intel ("%cs:");
     }
   if (prefixes & PREFIX_DS)
     {
       used_prefixes |= PREFIX_DS;
-      oappend ("%ds:" + intel_syntax);
+      oappend_maybe_intel ("%ds:");
     }
   if (prefixes & PREFIX_SS)
     {
       used_prefixes |= PREFIX_SS;
-      oappend ("%ss:" + intel_syntax);
+      oappend_maybe_intel ("%ss:");
     }
   if (prefixes & PREFIX_ES)
     {
       used_prefixes |= PREFIX_ES;
-      oappend ("%es:" + intel_syntax);
+      oappend_maybe_intel ("%es:");
     }
   if (prefixes & PREFIX_FS)
     {
       used_prefixes |= PREFIX_FS;
-      oappend ("%fs:" + intel_syntax);
+      oappend_maybe_intel ("%fs:");
     }
   if (prefixes & PREFIX_GS)
     {
       used_prefixes |= PREFIX_GS;
-      oappend ("%gs:" + intel_syntax);
+      oappend_maybe_intel ("%gs:");
     }
 }
 
@@ -13802,7 +13849,6 @@ intel_operand_size (int bytemode, int sizeflag)
        }
       /* FALLTHRU */
     case v_mode:
-    case v_bnd_mode:
     case v_swap_mode:
     case dq_mode:
       USED_REX (REX_W);
@@ -14074,6 +14120,14 @@ intel_operand_size (int bytemode, int sizeflag)
          oappend ("ZMMWORD PTR ");
        }
       break;
+    case vex_vsib_q_w_d_mode:
+    case vex_vsib_d_w_d_mode:
+      if (!need_vex || !vex.evex || vex.length != 512)
+       abort ();
+
+      oappend ("YMMWORD PTR ");
+
+      break;
     case mask_mode:
       if (!need_vex)
        abort ();
@@ -14084,6 +14138,7 @@ intel_operand_size (int bytemode, int sizeflag)
        abort ();
       oappend ("WORD PTR ");
       break;
+    case v_bnd_mode:
     default:
       break;
     }
@@ -14123,6 +14178,7 @@ OP_E_register (int bytemode, int sizeflag)
       names = names64;
       break;
     case m_mode:
+    case v_bnd_mode:
       names = address_mode == mode_64bit ? names64 : names32;
       break;
     case bnd_mode:
@@ -14137,7 +14193,6 @@ OP_E_register (int bytemode, int sizeflag)
       bytemode = v_mode;
       /* FALLTHRU */
     case v_mode:
-    case v_bnd_mode:
     case v_swap_mode:
     case dq_mode:
     case dqb_mode:
@@ -14190,13 +14245,13 @@ OP_E_memory (int bytemode, int sizeflag)
       switch (bytemode)
        {
        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 vex_vsib_q_w_dq_mode:
-         shift = 3;
-         break;
        case x_mode:
        case evex_half_bcst_xmmq_mode:
          if (vex.b)
@@ -14311,7 +14366,9 @@ OP_E_memory (int bytemode, int sizeflag)
          switch (bytemode)
            {
            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:
              if (!need_vex)
                abort ();
              if (vex.evex)
@@ -14327,13 +14384,17 @@ OP_E_memory (int bytemode, int sizeflag)
                  indexes64 = indexes32 = names_xmm;
                  break;
                case 256:
-                 if (!vex.w || bytemode == vex_vsib_q_w_dq_mode)
+                 if (!vex.w
+                     || bytemode == vex_vsib_q_w_dq_mode
+                     || bytemode == vex_vsib_q_w_d_mode)
                    indexes64 = indexes32 = names_ymm;
                  else
                    indexes64 = indexes32 = names_xmm;
                  break;
                case 512:
-                 if (!vex.w || bytemode == vex_vsib_q_w_dq_mode)
+                 if (!vex.w
+                     || bytemode == vex_vsib_q_w_dq_mode
+                     || bytemode == vex_vsib_q_w_d_mode)
                    indexes64 = indexes32 = names_zmm;
                  else
                    indexes64 = indexes32 = names_ymm;
@@ -14906,7 +14967,7 @@ OP_I (int bytemode, int sizeflag)
   op &= mask;
   scratchbuf[0] = '$';
   print_operand_value (scratchbuf + 1, 1, op);
-  oappend (scratchbuf + intel_syntax);
+  oappend_maybe_intel (scratchbuf);
   scratchbuf[0] = '\0';
 }
 
@@ -14960,7 +15021,7 @@ OP_I64 (int bytemode, int sizeflag)
   op &= mask;
   scratchbuf[0] = '$';
   print_operand_value (scratchbuf + 1, 1, op);
-  oappend (scratchbuf + intel_syntax);
+  oappend_maybe_intel (scratchbuf);
   scratchbuf[0] = '\0';
 }
 
@@ -15014,7 +15075,7 @@ OP_sI (int bytemode, int sizeflag)
 
   scratchbuf[0] = '$';
   print_operand_value (scratchbuf + 1, 1, op);
-  oappend (scratchbuf + intel_syntax);
+  oappend_maybe_intel (scratchbuf);
 }
 
 static void
@@ -15196,7 +15257,7 @@ OP_ESreg (int code, int sizeflag)
          intel_operand_size (b_mode, sizeflag);
        }
     }
-  oappend ("%es:" + intel_syntax);
+  oappend_maybe_intel ("%es:");
   ptr_reg (code, sizeflag);
 }
 
@@ -15249,7 +15310,7 @@ OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
   else
     add = 0;
   sprintf (scratchbuf, "%%cr%d", modrm.reg + add);
-  oappend (scratchbuf + intel_syntax);
+  oappend_maybe_intel (scratchbuf);
 }
 
 static void
@@ -15272,7 +15333,7 @@ static void
 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
 {
   sprintf (scratchbuf, "%%tr%d", modrm.reg);
-  oappend (scratchbuf + intel_syntax);
+  oappend_maybe_intel (scratchbuf);
 }
 
 static void
@@ -15331,7 +15392,9 @@ OP_XMM (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
          names = names_xmm;
          break;
        case 256:
-         if (vex.w || bytemode != vex_vsib_q_w_dq_mode)
+         if (vex.w
+             || (bytemode != vex_vsib_q_w_dq_mode
+                 && bytemode != vex_vsib_q_w_d_mode))
            names = names_ymm;
          else
            names = names_xmm;
@@ -15717,7 +15780,7 @@ CMP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
       /* We have a reserved extension byte.  Output it directly.  */
       scratchbuf[0] = '$';
       print_operand_value (scratchbuf + 1, 1, cmp_type);
-      oappend (scratchbuf + intel_syntax);
+      oappend_maybe_intel (scratchbuf);
       scratchbuf[0] = '\0';
     }
 }
@@ -16037,6 +16100,7 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
        case vex_mode:
        case vex128_mode:
        case vex_vsib_q_w_dq_mode:
+       case vex_vsib_q_w_d_mode:
          names = names_xmm;
          break;
        case dq_mode:
@@ -16061,6 +16125,7 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
          names = names_ymm;
          break;
        case vex_vsib_q_w_dq_mode:
+       case vex_vsib_q_w_d_mode:
          names = vex.w ? names_ymm : names_xmm;
          break;
        case mask_mode:
@@ -16242,7 +16307,7 @@ OP_EX_VexImmW (int bytemode, int sizeflag)
       /* Output the imm8 directly.  */
       scratchbuf[0] = '$';
       print_operand_value (scratchbuf + 1, 1, vex_imm8 & 0xf);
-      oappend (scratchbuf + intel_syntax);
+      oappend_maybe_intel (scratchbuf);
       scratchbuf[0] = '\0';
       codep++;
     }
@@ -16471,7 +16536,7 @@ VCMP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
       /* We have a reserved extension byte.  Output it directly.  */
       scratchbuf[0] = '$';
       print_operand_value (scratchbuf + 1, 1, cmp_type);
-      oappend (scratchbuf + intel_syntax);
+      oappend_maybe_intel (scratchbuf);
       scratchbuf[0] = '\0';
     }
 }
@@ -16518,7 +16583,7 @@ VPCMP_Fixup (int bytemode ATTRIBUTE_UNUSED,
       /* We have a reserved extension byte.  Output it directly.  */
       scratchbuf[0] = '$';
       print_operand_value (scratchbuf + 1, 1, cmp_type);
-      oappend (scratchbuf + intel_syntax);
+      oappend_maybe_intel (scratchbuf);
       scratchbuf[0] = '\0';
     }
 }
@@ -16566,7 +16631,7 @@ PCLMUL_Fixup (int bytemode ATTRIBUTE_UNUSED,
       /* We have a reserved extension byte.  Output it directly.  */
       scratchbuf[0] = '$';
       print_operand_value (scratchbuf + 1, 1, pclmul_type);
-      oappend (scratchbuf + intel_syntax);
+      oappend_maybe_intel (scratchbuf);
       scratchbuf[0] = '\0';
     }
 }
This page took 0.030371 seconds and 4 git commands to generate.