gas/testsuite/
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index 8c04ccfbfda60e4ec02338e7c65dcc5f8b3e617f..149bafb74e22f11024a928f51b4215c198854a60 100644 (file)
@@ -95,7 +95,7 @@ static void OP_Mwait (int, int);
 static void NOP_Fixup1 (int, int);
 static void NOP_Fixup2 (int, int);
 static void OP_3DNowSuffix (int, int);
-static void OP_SIMD_Suffix (int, int);
+static void CMP_Fixup (int, int);
 static void BadOp (void);
 static void REP_Fixup (int, int);
 static void CMPXCHG8B_Fixup (int, int);
@@ -236,6 +236,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Md { OP_M, d_mode }
 #define Mp { OP_M, f_mode }            /* 32 or 48 bit memory operand for LDS, LES etc */
 #define Mq { OP_M, q_mode }
+#define Mx { OP_M, x_mode }
 #define Gb { OP_G, b_mode }
 #define Gv { OP_G, v_mode }
 #define Gd { OP_G, d_mode }
@@ -340,7 +341,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define EMCq { OP_EMC, q_mode }
 #define MXC { OP_MXC, 0 }
 #define OPSUF { OP_3DNowSuffix, 0 }
-#define OPSIMD { OP_SIMD_Suffix, 0 }
+#define CMP { CMP_Fixup, 0 }
 #define XMM0 { XMM_Fixup, 0 }
 
 /* Used handle "rep" prefix for string instructions.  */
@@ -455,13 +456,13 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #error MAX_BYTEMODE must be less than DREX_OC1
 #endif
 
-#define FLOATCODE 1
-#define USE_REG_TABLE 2
-#define USE_MOD_TABLE 3
-#define USE_RM_TABLE 4
-#define USE_PREFIX_TABLE 5
-#define USE_X86_64_TABLE 6
-#define USE_3BYTE_TABLE 7
+#define FLOATCODE              1
+#define USE_REG_TABLE          (FLOATCODE + 1)
+#define USE_MOD_TABLE          (USE_REG_TABLE + 1)
+#define USE_RM_TABLE           (USE_MOD_TABLE + 1)
+#define USE_PREFIX_TABLE       (USE_RM_TABLE + 1)
+#define USE_X86_64_TABLE       (USE_PREFIX_TABLE + 1)
+#define USE_3BYTE_TABLE                (USE_X86_64_TABLE + 1)
 
 #define FLOAT                  NULL, { { NULL, FLOATCODE } }
 
@@ -491,8 +492,8 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define REG_FF                 (REG_FE + 1)
 #define REG_0F00               (REG_FF + 1)
 #define REG_0F01               (REG_0F00 + 1)
-#define REG_0F0E               (REG_0F01 + 1)
-#define REG_0F18               (REG_0F0E + 1)
+#define REG_0F0D               (REG_0F01 + 1)
+#define REG_0F18               (REG_0F0D + 1)
 #define REG_0F71               (REG_0F18 + 1)
 #define REG_0F72               (REG_0F71 + 1)
 #define REG_0F73               (REG_0F72 + 1)
@@ -503,27 +504,31 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define REG_0FC7               (REG_0FBA + 1)
 
 #define MOD_8D                 0
-#define MOD_0F13               (MOD_8D + 1)
-#define MOD_0F17               (MOD_0F13 + 1)
-#define MOD_0F20               (MOD_0F17 + 1)
-#define MOD_0F21               (MOD_0F20 + 1)
-#define MOD_0F22               (MOD_0F21 + 1)
-#define MOD_0F23               (MOD_0F22 + 1)
-#define MOD_0F24               (MOD_0F23 + 1)
-#define MOD_0F26               (MOD_0F24 + 1)
-#define MOD_0FB2               (MOD_0F26 + 1)
-#define MOD_0FB4               (MOD_0FB2 + 1)
-#define MOD_0FB5               (MOD_0FB4 + 1)
-#define MOD_0F01_REG_0         (MOD_0FB5 + 1)
+#define MOD_0F01_REG_0         (MOD_8D + 1)
 #define MOD_0F01_REG_1         (MOD_0F01_REG_0 + 1)
 #define MOD_0F01_REG_2         (MOD_0F01_REG_1 + 1)
 #define MOD_0F01_REG_3         (MOD_0F01_REG_2 + 1)
 #define MOD_0F01_REG_7         (MOD_0F01_REG_3 + 1)
-#define MOD_0F18_REG_0         (MOD_0F01_REG_7 + 1)
+#define MOD_0F12_PREFIX_0      (MOD_0F01_REG_7 + 1)
+#define MOD_0F13               (MOD_0F12_PREFIX_0 + 1)
+#define MOD_0F16_PREFIX_0      (MOD_0F13 + 1)
+#define MOD_0F17               (MOD_0F16_PREFIX_0 + 1)
+#define MOD_0F18_REG_0         (MOD_0F17 + 1)
 #define MOD_0F18_REG_1         (MOD_0F18_REG_0 + 1)
 #define MOD_0F18_REG_2         (MOD_0F18_REG_1 + 1)
 #define MOD_0F18_REG_3         (MOD_0F18_REG_2 + 1)
-#define MOD_0F71_REG_2         (MOD_0F18_REG_3 + 1)
+#define MOD_0F20               (MOD_0F18_REG_3 + 1)
+#define MOD_0F21               (MOD_0F20 + 1)
+#define MOD_0F22               (MOD_0F21 + 1)
+#define MOD_0F23               (MOD_0F22 + 1)
+#define MOD_0F24               (MOD_0F23 + 1)
+#define MOD_0F26               (MOD_0F24 + 1)
+#define MOD_0F2B_PREFIX_0      (MOD_0F26 + 1)
+#define MOD_0F2B_PREFIX_1      (MOD_0F2B_PREFIX_0 + 1)
+#define MOD_0F2B_PREFIX_2      (MOD_0F2B_PREFIX_1 + 1)
+#define MOD_0F2B_PREFIX_3      (MOD_0F2B_PREFIX_2 + 1)
+#define MOD_0F51               (MOD_0F2B_PREFIX_3 + 1)
+#define MOD_0F71_REG_2         (MOD_0F51 + 1)
 #define MOD_0F71_REG_4         (MOD_0F71_REG_2 + 1)
 #define MOD_0F71_REG_6         (MOD_0F71_REG_4 + 1)
 #define MOD_0F72_REG_2         (MOD_0F71_REG_6 + 1)
@@ -537,21 +542,27 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define MOD_0FAE_REG_1         (MOD_0FAE_REG_0 + 1)
 #define MOD_0FAE_REG_2         (MOD_0FAE_REG_1 + 1)
 #define MOD_0FAE_REG_3         (MOD_0FAE_REG_2 + 1)
-#define MOD_0FAE_REG_5         (MOD_0FAE_REG_3 + 1)
+#define MOD_0FAE_REG_4         (MOD_0FAE_REG_3 + 1)
+#define MOD_0FAE_REG_5         (MOD_0FAE_REG_4 + 1)
 #define MOD_0FAE_REG_6         (MOD_0FAE_REG_5 + 1)
 #define MOD_0FAE_REG_7         (MOD_0FAE_REG_6 + 1)
-#define MOD_0FC7_REG_6         (MOD_0FAE_REG_7 + 1)
+#define MOD_0FB2               (MOD_0FAE_REG_7 + 1)
+#define MOD_0FB4               (MOD_0FB2 + 1)
+#define MOD_0FB5               (MOD_0FB4 + 1)
+#define MOD_0FC7_REG_6         (MOD_0FB5 + 1)
 #define MOD_0FC7_REG_7         (MOD_0FC7_REG_6 + 1)
-#define MOD_0F12_PREFIX_0      (MOD_0FC7_REG_7 + 1)
-#define MOD_0F16_PREFIX_0      (MOD_0F12_PREFIX_0 + 1)
-#define MOD_0FF0_PREFIX_3      (MOD_0F16_PREFIX_0 + 1)
-#define MOD_62_32BIT           (MOD_0FF0_PREFIX_3 + 1)
+#define MOD_0FD7               (MOD_0FC7_REG_7 + 1)
+#define MOD_0FE7_PREFIX_2      (MOD_0FD7 + 1)
+#define MOD_0FF0_PREFIX_3      (MOD_0FE7_PREFIX_2 + 1)
+#define MOD_0F382A_PREFIX_2    (MOD_0FF0_PREFIX_3 + 1)
+#define MOD_62_32BIT           (MOD_0F382A_PREFIX_2 + 1)
 #define MOD_C4_32BIT           (MOD_62_32BIT + 1)
 #define MOD_C5_32BIT           (MOD_C4_32BIT + 1)
 
 #define RM_0F01_REG_0          0
 #define RM_0F01_REG_1          (RM_0F01_REG_0 + 1)
-#define RM_0F01_REG_3          (RM_0F01_REG_1 + 1)
+#define RM_0F01_REG_2          (RM_0F01_REG_1 + 1)
+#define RM_0F01_REG_3          (RM_0F01_REG_2 + 1)
 #define RM_0F01_REG_7          (RM_0F01_REG_3 + 1)
 #define RM_0FAE_REG_5          (RM_0F01_REG_7 + 1)
 #define RM_0FAE_REG_6          (RM_0FAE_REG_5 + 1)
@@ -586,7 +597,9 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define PREFIX_0F6D            (PREFIX_0F6C + 1)
 #define PREFIX_0F6F            (PREFIX_0F6D + 1)
 #define PREFIX_0F70            (PREFIX_0F6F + 1)
-#define PREFIX_0F78            (PREFIX_0F70 + 1)
+#define PREFIX_0F73_REG_3      (PREFIX_0F70 + 1)
+#define PREFIX_0F73_REG_7      (PREFIX_0F73_REG_3 + 1)
+#define PREFIX_0F78            (PREFIX_0F73_REG_7 + 1)
 #define PREFIX_0F79            (PREFIX_0F78 + 1)
 #define PREFIX_0F7C            (PREFIX_0F79 + 1)
 #define PREFIX_0F7D            (PREFIX_0F7C + 1)
@@ -595,7 +608,9 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define PREFIX_0FB8            (PREFIX_0F7F + 1)
 #define PREFIX_0FBD            (PREFIX_0FB8 + 1)
 #define PREFIX_0FC2            (PREFIX_0FBD + 1)
-#define PREFIX_0FD0            (PREFIX_0FC2 + 1)
+#define PREFIX_0FC3            (PREFIX_0FC2 + 1)
+#define PREFIX_0FC7_REG_6      (PREFIX_0FC3 + 1)
+#define PREFIX_0FD0            (PREFIX_0FC7_REG_6 + 1)
 #define PREFIX_0FD6            (PREFIX_0FD0 + 1)
 #define PREFIX_0FE6            (PREFIX_0FD6 + 1)
 #define PREFIX_0FE7            (PREFIX_0FE6 + 1)
@@ -655,9 +670,6 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define PREFIX_0F3A61          (PREFIX_0F3A60 + 1)
 #define PREFIX_0F3A62          (PREFIX_0F3A61 + 1)
 #define PREFIX_0F3A63          (PREFIX_0F3A62 + 1)
-#define PREFIX_0F73_REG_3      (PREFIX_0F3A63 + 1)
-#define PREFIX_0F73_REG_7      (PREFIX_0F73_REG_3 + 1)
-#define PREFIX_0FC7_REG_6      (PREFIX_0F73_REG_7 + 1)
 
 #define X86_64_06              0
 #define X86_64_07              (X86_64_06 + 1)
@@ -710,24 +722,25 @@ struct dis386 {
    'A' => print 'b' if no register operands or suffix_always is true
    'B' => print 'b' if suffix_always is true
    'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
-   .      size prefix
+         size prefix
    'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
-   .      suffix_always is true
+         suffix_always is true
    'E' => print 'e' if 32-bit form of jcxz
    'F' => print 'w' or 'l' depending on address size prefix (loop insns)
    'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
    'H' => print ",pt" or ",pn" branch hint
    'I' => honor following macro letter even in Intel mode (implemented only
-   .      for some of the macro letters)
+         for some of the macro letters)
    'J' => print 'l'
    'K' => print 'd' or 'q' if rex prefix is present.
    'L' => print 'l' if suffix_always is true
+   'M' => print 'r' if intel_mnemonic is false.
    'N' => print 'n' if instruction has no wait "prefix"
    'O' => print 'd' or 'o' (or 'q' in Intel mode)
    'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
-   .      or suffix_always is true.  print 'q' if rex prefix is present.
-   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
-   .      is true
+         or suffix_always is true.  print 'q' if rex prefix is present.
+   'Q' => print 'w', 'l' or 'q' for memory operand or suffix_always
+         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
@@ -738,6 +751,12 @@ struct dis386 {
    'Y' => 'q' if instruction has an REX 64bit overwrite prefix and
          suffix_always is true.
    '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.
+
+   2 upper case letter macros:
+   'LQ' => print 'l' ('d' in Intel mode) or 'q' for memory operand
+          or suffix_always is true
 
    Many of the above letters print nothing in Intel mode.  See "putop"
    for the details.
@@ -1052,7 +1071,7 @@ static const struct dis386 dis386_twobyte[] = {
   { "(bad)",           { XX } },
   { "ud2a",            { XX } },
   { "(bad)",           { XX } },
-  { REG_TABLE (REG_0F0E) },
+  { REG_TABLE (REG_0F0D) },
   { "femms",           { XX } },
   { "",                        { MX, EM, OPSUF } }, /* See OP_3DNowSuffix.  */
   /* 10 */
@@ -1066,12 +1085,12 @@ static const struct dis386 dis386_twobyte[] = {
   { MOD_TABLE (MOD_0F17) },
   /* 18 */
   { REG_TABLE (REG_0F18) },
-  { "(bad)",           { XX } },
-  { "(bad)",           { XX } },
-  { "(bad)",           { XX } },
-  { "(bad)",           { XX } },
-  { "(bad)",           { XX } },
-  { "(bad)",           { XX } },
+  { "nopQ",            { Ev } },
+  { "nopQ",            { Ev } },
+  { "nopQ",            { Ev } },
+  { "nopQ",            { Ev } },
+  { "nopQ",            { Ev } },
+  { "nopQ",            { Ev } },
   { "nopQ",            { Ev } },
   /* 20 */
   { MOD_TABLE (MOD_0F20) },
@@ -1128,7 +1147,7 @@ static const struct dis386 dis386_twobyte[] = {
   { "cmovle",          { Gv, Ev } },
   { "cmovg",           { Gv, Ev } },
   /* 50 */
-  { "movmskpX",                { Gdq, XS } },
+  { MOD_TABLE (MOD_0F51) },
   { PREFIX_TABLE (PREFIX_0F51) },
   { PREFIX_TABLE (PREFIX_0F52) },
   { PREFIX_TABLE (PREFIX_0F53) },
@@ -1257,7 +1276,7 @@ static const struct dis386 dis386_twobyte[] = {
   { "xaddB",           { Eb, Gb } },
   { "xaddS",           { Ev, Gv } },
   { PREFIX_TABLE (PREFIX_0FC2) },
-  { "movntiS",         { Ev, Gv } },
+  { PREFIX_TABLE (PREFIX_0FC3) },
   { "pinsrw",          { MX, Edqw, Ib } },
   { "pextrw",          { Gdq, MS, Ib } },
   { "shufpX",          { XM, EXx, Ib } },
@@ -1279,7 +1298,7 @@ static const struct dis386 dis386_twobyte[] = {
   { "paddq",           { MX, EM } },
   { "pmullw",          { MX, EM } },
   { PREFIX_TABLE (PREFIX_0FD6) },
-  { "pmovmskb",                { Gdq, MS } },
+  { MOD_TABLE (MOD_0FD7) },
   /* d8 */
   { "psubusb",         { MX, EM } },
   { "psubusw",         { MX, EM } },
@@ -1354,7 +1373,7 @@ static const unsigned char twobyte_has_modrm[256] = {
   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
   /*       -------------------------------        */
   /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
-  /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
+  /* 10 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1f */
   /* 20 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 2f */
   /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
   /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
@@ -1664,7 +1683,7 @@ static const struct dis386 reg_table[][8] = {
     { "lmsw",  { Ew } },
     { MOD_TABLE (MOD_0F01_REG_7) },
   },
-  /* REG_0F0E */
+  /* REG_0F0D */
   {
     { "prefetch",      { Eb } },
     { "prefetchw",     { Eb } },
@@ -1747,7 +1766,7 @@ static const struct dis386 reg_table[][8] = {
     { MOD_TABLE (MOD_0FAE_REG_1) },
     { MOD_TABLE (MOD_0FAE_REG_2) },
     { MOD_TABLE (MOD_0FAE_REG_3) },
-    { "(bad)", { XX } },
+    { MOD_TABLE (MOD_0FAE_REG_4) },
     { MOD_TABLE (MOD_0FAE_REG_5) },
     { MOD_TABLE (MOD_0FAE_REG_6) },
     { MOD_TABLE (MOD_0FAE_REG_7) },
@@ -1820,17 +1839,17 @@ static const struct dis386 prefix_table[][4] = {
   /* PREFIX_0F2A */
   {
     { "cvtpi2ps", { XM, EMCq } },
-    { "cvtsi2ssY", { XM, Ev } },
+    { "cvtsi2ss%LQ", { XM, Ev } },
     { "cvtpi2pd", { XM, EMCq } },
-    { "cvtsi2sdY", { XM, Ev } },
+    { "cvtsi2sd%LQ", { XM, Ev } },
   },
 
   /* PREFIX_0F2B */
   {
-    {"movntps", { Ev, XM } },
-    {"movntss", { Ed, XM } },
-    {"movntpd", { Ev, XM } },
-    {"movntsd", { Eq, XM } },
+    { MOD_TABLE (MOD_0F2B_PREFIX_0) },
+    { MOD_TABLE (MOD_0F2B_PREFIX_1) },
+    { MOD_TABLE (MOD_0F2B_PREFIX_2) },
+    { MOD_TABLE (MOD_0F2B_PREFIX_3) },
   },
 
   /* PREFIX_0F2C */
@@ -2009,6 +2028,22 @@ static const struct dis386 prefix_table[][4] = {
     { "pshuflw",{ XM, EXx, Ib } },
   },
 
+  /* PREFIX_0F73_REG_3 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "psrldq",        { XS, Ib } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_0F73_REG_7 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "pslldq",        { XS, Ib } },
+    { "(bad)", { XX } },
+  },
+
   /* PREFIX_0F78 */
   {
     {"vmread", { Em, Gm } },
@@ -2075,10 +2110,26 @@ static const struct dis386 prefix_table[][4] = {
 
   /* PREFIX_0FC2 */
   {
-    { "", { XM, EXx, OPSIMD } },       /* See OP_SIMD_SUFFIX.  */
-    { "", { XM, EXd, OPSIMD } },
-    { "", { XM, EXx, OPSIMD } },
-    { "", { XM, EXq, OPSIMD } },
+    { "cmpps", { XM, EXx, CMP } },
+    { "cmpss", { XM, EXd, CMP } },
+    { "cmppd", { XM, EXx, CMP } },
+    { "cmpsd", { XM, EXq, CMP } },
+  },
+
+  /* PREFIX_0FC3 */
+  {
+    { "movntiS", { Ma, Gv } },
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_0FC7_REG_6 */
+  {
+    { "vmptrld",{ Mq } },
+    { "vmxon", { Mq } },
+    { "vmclear",{ Mq } },
+    { "(bad)", { XX } },
   },
 
   /* PREFIX_0FD0 */
@@ -2107,9 +2158,9 @@ static const struct dis386 prefix_table[][4] = {
 
   /* PREFIX_0FE7 */
   {
-    { "movntq",        { EM, MX } },
+    { "movntq",        { Mq, MX } },
     { "(bad)", { XX } },
-    { "movntdq",{ EM, XM } },
+    { MOD_TABLE (MOD_0FE7_PREFIX_2) },
     { "(bad)", { XX } },
   },
 
@@ -2229,7 +2280,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "movntdqa", { XM, EM } },
+    { MOD_TABLE (MOD_0F382A_PREFIX_2) },
     { "(bad)", { XX } },
   },
 
@@ -2560,30 +2611,6 @@ static const struct dis386 prefix_table[][4] = {
     { "pcmpistri", { XM, EXx, Ib } },
     { "(bad)", { XX } },
   },
-
-  /* PREFIX_0F73_REG_3 */
-  {
-    { "(bad)", { XX } },
-    { "(bad)", { XX } },
-    { "psrldq",        { XS, Ib } },
-    { "(bad)", { XX } },
-  },
-
-  /* PREFIX_0F73_REG_7 */
-  {
-    { "(bad)", { XX } },
-    { "(bad)", { XX } },
-    { "pslldq",        { XS, Ib } },
-    { "(bad)", { XX } },
-  },
-
-  /* PREFIX_0FC7_REG_6 */
-  {
-    { "vmptrld",{ Mq } },
-    { "vmxon", { Mq } },
-    { "vmclear",{ Mq } },
-    { "(bad)", { XX } },
-  },
 };
 
 static const struct dis386 x86_64_table[][2] = {
@@ -4511,16 +4538,71 @@ static const struct dis386 mod_table[][2] = {
     { "leaS",          { Gv, M } },
     { "(bad)",         { XX } },
   },
+  {
+    /* MOD_0F01_REG_0 */
+    { X86_64_TABLE (X86_64_0F01_REG_0) },
+    { RM_TABLE (RM_0F01_REG_0) },
+  },
+  {
+    /* MOD_0F01_REG_1 */
+    { X86_64_TABLE (X86_64_0F01_REG_1) },
+    { RM_TABLE (RM_0F01_REG_1) },
+  },
+  {
+    /* MOD_0F01_REG_2 */
+    { X86_64_TABLE (X86_64_0F01_REG_2) },
+    { RM_TABLE (RM_0F01_REG_2) },
+  },
+  {
+    /* MOD_0F01_REG_3 */
+    { X86_64_TABLE (X86_64_0F01_REG_3) },
+    { RM_TABLE (RM_0F01_REG_3) },
+  },
+  {
+    /* MOD_0F01_REG_7 */
+    { "invlpg",                { Mb } },
+    { RM_TABLE (RM_0F01_REG_7) },
+  },
+  {
+    /* MOD_0F12_PREFIX_0 */
+    { "movlps",                { XM, EXq } },
+    { "movhlps",       { XM, EXq } },
+  },
   {
     /* MOD_0F13 */
     { "movlpX",                { EXq, XM } },
     { "(bad)",         { XX } },
   },
+  {
+    /* MOD_0F16_PREFIX_0 */
+    { "movhps",                { XM, EXq } },
+    { "movlhps",       { XM, EXq } },
+  },
   {
     /* MOD_0F17 */
     { "movhpX",                { EXq, XM } },
     { "(bad)",         { XX } },
   },
+  {
+    /* MOD_0F18_REG_0 */
+    { "prefetchnta",   { Mb } },
+    { "(bad)",         { XX } },
+  },
+  {
+    /* MOD_0F18_REG_1 */
+    { "prefetcht0",    { Mb } },
+    { "(bad)",         { XX } },
+  },
+  {
+    /* MOD_0F18_REG_2 */
+    { "prefetcht1",    { Mb } },
+    { "(bad)",         { XX } },
+  },
+  {
+    /* MOD_0F18_REG_3 */
+    { "prefetcht2",    { Mb } },
+    { "(bad)",         { XX } },
+  },
   {
     /* MOD_0F20 */
     { "(bad)",         { XX } },
@@ -4552,64 +4634,29 @@ static const struct dis386 mod_table[][2] = {
     { "movL",          { Td, Rd } },
   },
   {
-    /* MOD_0FB2 */
-    { "lssS",          { Gv, Mp } },
-    { "(bad)",         { XX } },
-  },
-  {
-    /* MOD_0FB4 */
-    { "lfsS",          { Gv, Mp } },
-    { "(bad)",         { XX } },
-  },
-  {
-    /* MOD_0FB5 */
-    { "lgsS",          { Gv, Mp } },
-    { "(bad)",         { XX } },
-  },
-  {
-    /* MOD_0F01_REG_0 */
-    { X86_64_TABLE (X86_64_0F01_REG_0) },
-    { RM_TABLE (RM_0F01_REG_0) },
-  },
-  {
-    /* MOD_0F01_REG_1 */
-    { X86_64_TABLE (X86_64_0F01_REG_1) },
-    { RM_TABLE (RM_0F01_REG_1) },
-  },
-  {
-    /* MOD_0F01_REG_2 */
-    { X86_64_TABLE (X86_64_0F01_REG_2) },
+    /* MOD_0F2B_PREFIX_0 */
+    {"movntps",                { Mx, XM } },
     { "(bad)",         { XX } },
   },
   {
-    /* MOD_0F01_REG_3 */
-    { X86_64_TABLE (X86_64_0F01_REG_3) },
-    { RM_TABLE (RM_0F01_REG_3) },
-  },
-  {
-    /* MOD_0F01_REG_7 */
-    { "invlpg",                { Mb } },
-    { RM_TABLE (RM_0F01_REG_7) },
-  },
-  {
-    /* MOD_0F18_REG_0 */
-    { "prefetchnta",   { Mb } },
+    /* MOD_0F2B_PREFIX_1 */
+    {"movntss",                { Md, XM } },
     { "(bad)",         { XX } },
   },
   {
-    /* MOD_0F18_REG_1 */
-    { "prefetcht0",    { Mb } },
+    /* MOD_0F2B_PREFIX_2 */
+    {"movntpd",                { Mx, XM } },
     { "(bad)",         { XX } },
   },
   {
-    /* MOD_0F18_REG_2 */
-    { "prefetcht1",    { Mb } },
+    /* MOD_0F2B_PREFIX_3 */
+    {"movntsd",                { Mq, XM } },
     { "(bad)",         { XX } },
   },
   {
-    /* MOD_0F18_REG_3 */
-    { "prefetcht2",    { Mb } },
+    /* MOD_0F51 */
     { "(bad)",         { XX } },
+    { "movmskpX",      { Gdq, XS } },
   },
   {
     /* MOD_0F71_REG_2 */
@@ -4682,8 +4729,13 @@ static const struct dis386 mod_table[][2] = {
     { "(bad)",         { XX } },
   },
   {
-    /* MOD_0FAE_REG_5 */
+    /* MOD_0FAE_REG_4 */
+    { "xsave",         { M } },
     { "(bad)",         { XX } },
+  },
+  {
+    /* MOD_0FAE_REG_5 */
+    { "xrstor",                { M } },
     { RM_TABLE (RM_0FAE_REG_5) },
   },
   {
@@ -4696,6 +4748,21 @@ static const struct dis386 mod_table[][2] = {
     { "clflush",       { Mb } },
     { RM_TABLE (RM_0FAE_REG_7) },
   },
+  {
+    /* MOD_0FB2 */
+    { "lssS",          { Gv, Mp } },
+    { "(bad)",         { XX } },
+  },
+  {
+    /* MOD_0FB4 */
+    { "lfsS",          { Gv, Mp } },
+    { "(bad)",         { XX } },
+  },
+  {
+    /* MOD_0FB5 */
+    { "lgsS",          { Gv, Mp } },
+    { "(bad)",         { XX } },
+  },
   {
     /* MOD_0FC7_REG_6 */
     { PREFIX_TABLE (PREFIX_0FC7_REG_6) },
@@ -4707,20 +4774,25 @@ static const struct dis386 mod_table[][2] = {
     { "(bad)",         { XX } },
   },
   {
-    /* MOD_0F12_PREFIX_0 */
-    { "movlps",                { XM, EXq } },
-    { "movhlps",       { XM, EXq } },
+    /* MOD_0FD7 */
+    { "(bad)",         { XX } },
+    { "pmovmskb",      { Gdq, MS } },
   },
   {
-    /* MOD_0F16_PREFIX_0 */
-    { "movhps",                { XM, EXq } },
-    { "movlhps",       { XM, EXq } },
+    /* MOD_0FE7_PREFIX_2 */
+    { "movntdq",       { Mx, XM } },
+    { "(bad)",         { XX } },
   },
   {
     /* MOD_0FF0_PREFIX_3 */
     { "lddqu",         { XM, M } },
     { "(bad)",         { XX } },
   },
+  {
+    /* MOD_0F382A_PREFIX_2 */
+    { "movntdqa",      { XM, Mx } },
+    { "(bad)",         { XX } },
+  },
   {
     /* MOD_62_32BIT */
     { "bound{S|}",     { Gv, Ma } },
@@ -4761,6 +4833,17 @@ static const struct dis386 rm_table[][8] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
   },
+  {
+    /* RM_0F01_REG_2 */
+    { "xgetbv",                { Skip_MODRM } },
+    { "xsetbv",                { Skip_MODRM } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+  },
   {
     /* RM_0F01_REG_3 */
     { "vmrun",         { Skip_MODRM } },
@@ -5010,6 +5093,7 @@ static bfd_vma start_pc;
  */
 
 static char intel_syntax;
+static char intel_mnemonic = !SYSV386_COMPAT;
 static char open_char;
 static char close_char;
 static char separator_char;
@@ -5054,6 +5138,10 @@ with the -M switch (multiple options should be separated by commas):\n"));
   fprintf (stream, _("  i8086       Disassemble in 16bit mode\n"));
   fprintf (stream, _("  att         Display instruction in AT&T syntax\n"));
   fprintf (stream, _("  intel       Display instruction in Intel syntax\n"));
+  fprintf (stream, _("  att-mnemonic\n"
+                    "              Display instruction in AT&T mnemonic\n"));
+  fprintf (stream, _("  intel-mnemonic\n"
+                    "              Display instruction in Intel mnemonic\n"));
   fprintf (stream, _("  addr64      Assume 64bit address size\n"));
   fprintf (stream, _("  addr32      Assume 32bit address size\n"));
   fprintf (stream, _("  addr16      Assume 16bit address size\n"));
@@ -5197,10 +5285,14 @@ print_insn (bfd_vma pc, disassemble_info *info)
       else if (CONST_STRNEQ (p, "intel"))
        {
          intel_syntax = 1;
+         if (CONST_STRNEQ (p + 5, "-mnemonic"))
+           intel_mnemonic = 1;
        }
       else if (CONST_STRNEQ (p, "att"))
        {
          intel_syntax = 0;
+         if (CONST_STRNEQ (p + 3, "-mnemonic"))
+           intel_mnemonic = 0;
        }
       else if (CONST_STRNEQ (p, "addr"))
        {
@@ -5742,17 +5834,10 @@ static const struct dis386 float_reg[][8] = {
     { "fmul",  { STi, ST } },
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-#if SYSV386_COMPAT
-    { "fsub",  { STi, ST } },
-    { "fsubr", { STi, ST } },
-    { "fdiv",  { STi, ST } },
-    { "fdivr", { STi, ST } },
-#else
-    { "fsubr", { STi, ST } },
-    { "fsub",  { STi, ST } },
-    { "fdivr", { STi, ST } },
-    { "fdiv",  { STi, ST } },
-#endif
+    { "fsub!M",        { STi, ST } },
+    { "fsubM", { STi, ST } },
+    { "fdiv!M",        { STi, ST } },
+    { "fdivM", { STi, ST } },
   },
   /* dd */
   {
@@ -5771,17 +5856,10 @@ static const struct dis386 float_reg[][8] = {
     { "fmulp", { STi, ST } },
     { "(bad)", { XX } },
     { FGRPde_3 },
-#if SYSV386_COMPAT
-    { "fsubp", { STi, ST } },
-    { "fsubrp",        { STi, ST } },
-    { "fdivp", { STi, ST } },
-    { "fdivrp",        { STi, ST } },
-#else
-    { "fsubrp",        { STi, ST } },
-    { "fsubp", { STi, ST } },
-    { "fdivrp",        { STi, ST } },
-    { "fdivp", { STi, ST } },
-#endif
+    { "fsub!Mp", { STi, ST } },
+    { "fsubMp",        { STi, ST } },
+    { "fdiv!Mp", { STi, ST } },
+    { "fdivMp",        { STi, ST } },
   },
   /* df */
   {
@@ -5919,6 +5997,15 @@ putop (const char *template, int sizeflag)
 {
   const char *p;
   int alt = 0;
+  int cond = 1;
+  unsigned int l = 0, len = 1;
+  char last[4];
+
+#define SAVE_LAST(c)                   \
+  if (l < len && l < sizeof (last))    \
+    last[l++] = c;                     \
+  else                                 \
+    abort ();
 
   for (p = template; *p; p++)
     {
@@ -5927,6 +6014,12 @@ putop (const char *template, int sizeflag)
        default:
          *obufp++ = *p;
          break;
+       case '%':
+         len++;
+         break;
+       case '!':
+         cond = 0;
+         break;
        case '{':
          alt = 0;
          if (intel_syntax)
@@ -6060,12 +6153,23 @@ putop (const char *template, int sizeflag)
              break;
            }
          /* Fall through.  */
+         goto case_L;
        case 'L':
+         if (l != 0 || len != 1)
+           {
+             SAVE_LAST (*p);
+             break;
+           }
+case_L:
          if (intel_syntax)
            break;
          if (sizeflag & SUFFIX_ALWAYS)
            *obufp++ = 'l';
          break;
+       case 'M':
+         if (intel_mnemonic != cond)
+           *obufp++ = 'r';
+         break;
        case 'N':
          if ((prefixes & PREFIX_FWAIT) == 0)
            *obufp++ = 'n';
@@ -6122,22 +6226,45 @@ putop (const char *template, int sizeflag)
              break;
            }
          /* Fall through.  */
+         goto case_Q;
        case 'Q':
-         if (intel_syntax && !alt)
-           break;
-         USED_REX (REX_W);
-         if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
+         if (l == 0 && len == 1)
            {
-             if (rex & REX_W)
-               *obufp++ = 'q';
-             else
+case_Q:
+             if (intel_syntax && !alt)
+               break;
+             USED_REX (REX_W);
+             if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
                {
-                 if (sizeflag & DFLAG)
-                   *obufp++ = intel_syntax ? 'd' : 'l';
+                 if (rex & REX_W)
+                   *obufp++ = 'q';
                  else
-                   *obufp++ = 'w';
+                   {
+                     if (sizeflag & DFLAG)
+                       *obufp++ = intel_syntax ? 'd' : 'l';
+                     else
+                       *obufp++ = 'w';
+                   }
+                 used_prefixes |= (prefixes & PREFIX_DATA);
                }
-             used_prefixes |= (prefixes & PREFIX_DATA);
+           }
+         else
+           {
+             if (l != 1 || len != 2 || last[0] != 'L')
+               {
+                 SAVE_LAST (*p);
+                 break;
+               }
+             if (intel_syntax
+                 || (modrm.mod == 3 && !(sizeflag & SUFFIX_ALWAYS)))
+               break;
+             if ((rex & REX_W))
+               {
+                 USED_REX (REX_W);
+                 *obufp++ = 'q';
+               }
+             else
+               *obufp++ = 'l';
            }
          break;
        case 'R':
@@ -6536,7 +6663,7 @@ OP_E_extended (int bytemode, int sizeflag, int has_drex)
       int havebase;
       int haveindex;
       int needindex;
-      int base;
+      int base, rbase;
       int index = 0;
       int scale = 0;
 
@@ -6558,7 +6685,7 @@ OP_E_extended (int bytemode, int sizeflag, int has_drex)
          haveindex = index != 4;
          codep++;
        }
-      base += add;
+      rbase = base + add;
 
       /* If we have a DREX byte, skip it now 
         (it has already been handled) */
@@ -6571,7 +6698,7 @@ OP_E_extended (int bytemode, int sizeflag, int has_drex)
       switch (modrm.mod)
        {
        case 0:
-         if ((base & 7) == 5)
+         if (base == 5)
            {
              havebase = 0;
              if (address_mode == mode_64bit && !havesib)
@@ -6601,7 +6728,7 @@ OP_E_extended (int bytemode, int sizeflag, int has_drex)
                  || (havesib && (haveindex || scale != 0)));
 
       if (!intel_syntax)
-       if (modrm.mod != 0 || (base & 7) == 5)
+       if (modrm.mod != 0 || base == 5)
          {
            if (havedisp || riprel)
              print_displacement (scratchbuf, disp);
@@ -6629,7 +6756,7 @@ OP_E_extended (int bytemode, int sizeflag, int has_drex)
          *obufp = '\0';
          if (havebase)
            oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
-                    ? names64[base] : names32[base]);
+                    ? names64[rbase] : names32[rbase]);
          if (havesib)
            {
              /* ESP/RSP won't allow index.  If base isn't ESP/RSP,
@@ -6660,7 +6787,7 @@ OP_E_extended (int bytemode, int sizeflag, int has_drex)
                }
            }
          if (intel_syntax
-             && (disp || modrm.mod != 0 || (base & 7) == 5))
+             && (disp || modrm.mod != 0 || base == 5))
            {
              if (!havedisp || (bfd_signed_vma) disp >= 0)
                {
@@ -6686,7 +6813,7 @@ OP_E_extended (int bytemode, int sizeflag, int has_drex)
        }
       else if (intel_syntax)
        {
-         if (modrm.mod != 0 || (base & 7) == 5)
+         if (modrm.mod != 0 || base == 5)
            {
              if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
                              | PREFIX_ES | PREFIX_FS | PREFIX_GS))
@@ -7737,42 +7864,28 @@ static const char *simd_cmp_op[] = {
 };
 
 static void
-OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+CMP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
 {
   unsigned int cmp_type;
 
   FETCH_DATA (the_info, codep + 1);
-  obufp = obuf + strlen (obuf);
   cmp_type = *codep++ & 0xff;
   if (cmp_type < 8)
     {
-      char suffix1 = 'p', suffix2 = 's';
-      used_prefixes |= (prefixes & PREFIX_REPZ);
-      if (prefixes & PREFIX_REPZ)
-       suffix1 = 's';
-      else
-       {
-         used_prefixes |= (prefixes & PREFIX_DATA);
-         if (prefixes & PREFIX_DATA)
-           suffix2 = 'd';
-         else
-           {
-             used_prefixes |= (prefixes & PREFIX_REPNZ);
-             if (prefixes & PREFIX_REPNZ)
-               suffix1 = 's', suffix2 = 'd';
-           }
-       }
-      sprintf (scratchbuf, "cmp%s%c%c",
-              simd_cmp_op[cmp_type], suffix1, suffix2);
-      used_prefixes |= (prefixes & PREFIX_REPZ);
-      oappend (scratchbuf);
+      char suffix [3];
+      char *p = obuf + strlen (obuf) - 2;
+      suffix[0] = p[0];
+      suffix[1] = p[1];
+      suffix[2] = '\0';
+      sprintf (p, "%s%s", simd_cmp_op[cmp_type], suffix);
     }
   else
     {
-      /* We have a bad extension byte.  Clean up.  */
-      op_out[0][0] = '\0';
-      op_out[1][0] = '\0';
-      BadOp ();
+      /* We have a reserved extension byte.  Output it directly.  */
+      scratchbuf[0] = '$';
+      print_operand_value (scratchbuf + 1, 1, cmp_type);
+      oappend (scratchbuf + intel_syntax);
+      scratchbuf[0] = '\0';
     }
 }
 
This page took 0.036468 seconds and 4 git commands to generate.