gas/testsuite/
[external/binutils.git] / opcodes / i386-dis.c
index 2991016..43d7ac3 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, 2011
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
@@ -108,6 +108,9 @@ static void OP_3DNowSuffix (int, int);
 static void CMP_Fixup (int, int);
 static void BadOp (void);
 static void REP_Fixup (int, int);
+static void HLE_Fixup1 (int, int);
+static void HLE_Fixup2 (int, int);
+static void HLE_Fixup3 (int, int);
 static void CMPXCHG8B_Fixup (int, int);
 static void XMM_Fixup (int, int);
 static void CRC32_Fixup (int, int);
@@ -254,7 +257,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #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 sIv { OP_sI, v_mode }
 #define Iq { OP_I, q_mode }
 #define Iv64 { OP_I64, v_mode }
 #define Iw { OP_I, w_mode }
@@ -412,6 +415,14 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define ALr { REP_Fixup, al_reg }
 #define eAXr { REP_Fixup, eAX_reg }
 
+/* Used handle HLE prefix for lockable instructions.  */
+#define Ebh1 { HLE_Fixup1, b_mode }
+#define Evh1 { HLE_Fixup1, v_mode }
+#define Ebh2 { HLE_Fixup2, b_mode }
+#define Evh2 { HLE_Fixup2, v_mode }
+#define Ebh3 { HLE_Fixup3, b_mode }
+#define Evh3 { HLE_Fixup3, v_mode }
+
 #define cond_jump_flag { NULL, cond_jump_mode }
 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
 
@@ -642,6 +653,8 @@ enum
 enum
 {
   MOD_8D = 0,
+  MOD_C6_REG_7,
+  MOD_C7_REG_7,
   MOD_0F01_REG_0,
   MOD_0F01_REG_1,
   MOD_0F01_REG_2,
@@ -730,7 +743,9 @@ enum
 
 enum
 {
-  RM_0F01_REG_0 = 0,
+  RM_C6_REG_7 = 0,
+  RM_C7_REG_7,
+  RM_0F01_REG_0,
   RM_0F01_REG_1,
   RM_0F01_REG_2,
   RM_0F01_REG_3,
@@ -836,6 +851,7 @@ enum
   PREFIX_0F38DF,
   PREFIX_0F38F0,
   PREFIX_0F38F1,
+  PREFIX_0F38F6,
   PREFIX_0F3A08,
   PREFIX_0F3A09,
   PREFIX_0F3A0A,
@@ -1303,6 +1319,14 @@ enum
   VEX_LEN_0F3A7F_P_2,
   VEX_LEN_0F3ADF_P_2,
   VEX_LEN_0F3AF0_P_3,
+  VEX_LEN_0FXOP_08_CC,
+  VEX_LEN_0FXOP_08_CD,
+  VEX_LEN_0FXOP_08_CE,
+  VEX_LEN_0FXOP_08_CF,
+  VEX_LEN_0FXOP_08_EC,
+  VEX_LEN_0FXOP_08_ED,
+  VEX_LEN_0FXOP_08_EE,
+  VEX_LEN_0FXOP_08_EF,
   VEX_LEN_0FXOP_09_80,
   VEX_LEN_0FXOP_09_81
 };
@@ -1646,8 +1670,8 @@ struct dis386 {
 
 static const struct dis386 dis386[] = {
   /* 00 */
-  { "addB",            { Eb, Gb } },
-  { "addS",            { Ev, Gv } },
+  { "addB",            { Ebh1, Gb } },
+  { "addS",            { Evh1, Gv } },
   { "addB",            { Gb, EbS } },
   { "addS",            { Gv, EvS } },
   { "addB",            { AL, Ib } },
@@ -1655,8 +1679,8 @@ static const struct dis386 dis386[] = {
   { X86_64_TABLE (X86_64_06) },
   { X86_64_TABLE (X86_64_07) },
   /* 08 */
-  { "orB",             { Eb, Gb } },
-  { "orS",             { Ev, Gv } },
+  { "orB",             { Ebh1, Gb } },
+  { "orS",             { Evh1, Gv } },
   { "orB",             { Gb, EbS } },
   { "orS",             { Gv, EvS } },
   { "orB",             { AL, Ib } },
@@ -1664,8 +1688,8 @@ static const struct dis386 dis386[] = {
   { X86_64_TABLE (X86_64_0D) },
   { Bad_Opcode },      /* 0x0f extended opcode escape */
   /* 10 */
-  { "adcB",            { Eb, Gb } },
-  { "adcS",            { Ev, Gv } },
+  { "adcB",            { Ebh1, Gb } },
+  { "adcS",            { Evh1, Gv } },
   { "adcB",            { Gb, EbS } },
   { "adcS",            { Gv, EvS } },
   { "adcB",            { AL, Ib } },
@@ -1673,8 +1697,8 @@ static const struct dis386 dis386[] = {
   { X86_64_TABLE (X86_64_16) },
   { X86_64_TABLE (X86_64_17) },
   /* 18 */
-  { "sbbB",            { Eb, Gb } },
-  { "sbbS",            { Ev, Gv } },
+  { "sbbB",            { Ebh1, Gb } },
+  { "sbbS",            { Evh1, Gv } },
   { "sbbB",            { Gb, EbS } },
   { "sbbS",            { Gv, EvS } },
   { "sbbB",            { AL, Ib } },
@@ -1682,8 +1706,8 @@ static const struct dis386 dis386[] = {
   { X86_64_TABLE (X86_64_1E) },
   { X86_64_TABLE (X86_64_1F) },
   /* 20 */
-  { "andB",            { Eb, Gb } },
-  { "andS",            { Ev, Gv } },
+  { "andB",            { Ebh1, Gb } },
+  { "andS",            { Evh1, Gv } },
   { "andB",            { Gb, EbS } },
   { "andS",            { Gv, EvS } },
   { "andB",            { AL, Ib } },
@@ -1691,8 +1715,8 @@ static const struct dis386 dis386[] = {
   { Bad_Opcode },      /* SEG ES prefix */
   { X86_64_TABLE (X86_64_27) },
   /* 28 */
-  { "subB",            { Eb, Gb } },
-  { "subS",            { Ev, Gv } },
+  { "subB",            { Ebh1, Gb } },
+  { "subS",            { Evh1, Gv } },
   { "subB",            { Gb, EbS } },
   { "subS",            { Gv, EvS } },
   { "subB",            { AL, Ib } },
@@ -1700,8 +1724,8 @@ static const struct dis386 dis386[] = {
   { Bad_Opcode },      /* SEG CS prefix */
   { X86_64_TABLE (X86_64_2F) },
   /* 30 */
-  { "xorB",            { Eb, Gb } },
-  { "xorS",            { Ev, Gv } },
+  { "xorB",            { Ebh1, Gb } },
+  { "xorS",            { Evh1, Gv } },
   { "xorB",            { Gb, EbS } },
   { "xorS",            { Gv, EvS } },
   { "xorB",            { AL, Ib } },
@@ -1796,11 +1820,11 @@ static const struct dis386 dis386[] = {
   { REG_TABLE (REG_82) },
   { "testB",           { Eb, Gb } },
   { "testS",           { Ev, Gv } },
-  { "xchgB",           { Eb, Gb } },
-  { "xchgS",           { Ev, Gv } },
+  { "xchgB",           { Ebh2, Gb } },
+  { "xchgS",           { Evh2, Gv } },
   /* 88 */
-  { "movB",            { Eb, Gb } },
-  { "movS",            { Ev, Gv } },
+  { "movB",            { Ebh3, Gb } },
+  { "movS",            { Evh3, Gv } },
   { "movB",            { Gb, EbS } },
   { "movS",            { Gv, EvS } },
   { "movD",            { Sv, Sw } },
@@ -2129,16 +2153,16 @@ static const struct dis386 dis386_twobyte[] = {
   { "pushT",           { gs } },
   { "popT",            { gs } },
   { "rsm",             { XX } },
-  { "btsS",            { Ev, Gv } },
+  { "btsS",            { Evh1, Gv } },
   { "shrdS",           { Ev, Gv, Ib } },
   { "shrdS",           { Ev, Gv, CL } },
   { REG_TABLE (REG_0FAE) },
   { "imulS",           { Gv, Ev } },
   /* b0 */
-  { "cmpxchgB",                { Eb, Gb } },
-  { "cmpxchgS",                { Ev, Gv } },
+  { "cmpxchgB",                { Ebh1, Gb } },
+  { "cmpxchgS",                { Evh1, Gv } },
   { MOD_TABLE (MOD_0FB2) },
-  { "btrS",            { Ev, Gv } },
+  { "btrS",            { Evh1, Gv } },
   { MOD_TABLE (MOD_0FB4) },
   { MOD_TABLE (MOD_0FB5) },
   { "movz{bR|x}",      { Gv, Eb } },
@@ -2147,14 +2171,14 @@ static const struct dis386 dis386_twobyte[] = {
   { PREFIX_TABLE (PREFIX_0FB8) },
   { "ud1",             { XX } },
   { REG_TABLE (REG_0FBA) },
-  { "btcS",            { Ev, Gv } },
+  { "btcS",            { Evh1, Gv } },
   { PREFIX_TABLE (PREFIX_0FBC) },
   { PREFIX_TABLE (PREFIX_0FBD) },
   { "movs{bR|x}",      { Gv, Eb } },
   { "movs{wR|x}",      { Gv, Ew } }, /* yes, there really is movsww ! */
   /* c0 */
-  { "xaddB",           { Eb, Gb } },
-  { "xaddS",           { Ev, Gv } },
+  { "xaddB",           { Ebh1, Gb } },
+  { "xaddS",           { Evh1, Gv } },
   { PREFIX_TABLE (PREFIX_0FC2) },
   { PREFIX_TABLE (PREFIX_0FC3) },
   { "pinsrw",          { MX, Edqw, Ib } },
@@ -2436,35 +2460,35 @@ static const char *att_names_ymm[] = {
 static const struct dis386 reg_table[][8] = {
   /* REG_80 */
   {
-    { "addA",  { Eb, Ib } },
-    { "orA",   { Eb, Ib } },
-    { "adcA",  { Eb, Ib } },
-    { "sbbA",  { Eb, Ib } },
-    { "andA",  { Eb, Ib } },
-    { "subA",  { Eb, Ib } },
-    { "xorA",  { Eb, Ib } },
+    { "addA",  { Ebh1, Ib } },
+    { "orA",   { Ebh1, Ib } },
+    { "adcA",  { Ebh1, Ib } },
+    { "sbbA",  { Ebh1, Ib } },
+    { "andA",  { Ebh1, Ib } },
+    { "subA",  { Ebh1, Ib } },
+    { "xorA",  { Ebh1, Ib } },
     { "cmpA",  { Eb, Ib } },
   },
   /* REG_81 */
   {
-    { "addQ",  { Ev, Iv } },
-    { "orQ",   { Ev, Iv } },
-    { "adcQ",  { Ev, Iv } },
-    { "sbbQ",  { Ev, Iv } },
-    { "andQ",  { Ev, Iv } },
-    { "subQ",  { Ev, Iv } },
-    { "xorQ",  { Ev, Iv } },
+    { "addQ",  { Evh1, Iv } },
+    { "orQ",   { Evh1, Iv } },
+    { "adcQ",  { Evh1, Iv } },
+    { "sbbQ",  { Evh1, Iv } },
+    { "andQ",  { Evh1, Iv } },
+    { "subQ",  { Evh1, Iv } },
+    { "xorQ",  { Evh1, Iv } },
     { "cmpQ",  { Ev, Iv } },
   },
   /* REG_82 */
   {
-    { "addQ",  { Ev, sIb } },
-    { "orQ",   { Ev, sIb } },
-    { "adcQ",  { Ev, sIb } },
-    { "sbbQ",  { Ev, sIb } },
-    { "andQ",  { Ev, sIb } },
-    { "subQ",  { Ev, sIb } },
-    { "xorQ",  { Ev, sIb } },
+    { "addQ",  { Evh1, sIb } },
+    { "orQ",   { Evh1, sIb } },
+    { "adcQ",  { Evh1, sIb } },
+    { "sbbQ",  { Evh1, sIb } },
+    { "andQ",  { Evh1, sIb } },
+    { "subQ",  { Evh1, sIb } },
+    { "xorQ",  { Evh1, sIb } },
     { "cmpQ",  { Ev, sIb } },
   },
   /* REG_8F */
@@ -2500,11 +2524,25 @@ static const struct dis386 reg_table[][8] = {
   },
   /* REG_C6 */
   {
-    { "movA",  { Eb, Ib } },
+    { "movA",  { Ebh3, Ib } },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { MOD_TABLE (MOD_C6_REG_7) },
   },
   /* REG_C7 */
   {
-    { "movQ",  { Ev, Iv } },
+    { "movQ",  { Evh3, Iv } },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { MOD_TABLE (MOD_C7_REG_7) },
   },
   /* REG_D0 */
   {
@@ -2554,8 +2592,8 @@ static const struct dis386 reg_table[][8] = {
   {
     { "testA", { Eb, Ib } },
     { Bad_Opcode },
-    { "notA",  { Eb } },
-    { "negA",  { Eb } },
+    { "notA",  { Ebh1 } },
+    { "negA",  { Ebh1 } },
     { "mulA",  { Eb } },       /* Don't print the implicit %al register,  */
     { "imulA", { Eb } },       /* to distinguish these opcodes from other */
     { "divA",  { Eb } },       /* mul/imul opcodes.  Do the same for div  */
@@ -2565,8 +2603,8 @@ static const struct dis386 reg_table[][8] = {
   {
     { "testQ", { Ev, Iv } },
     { Bad_Opcode },
-    { "notQ",  { Ev } },
-    { "negQ",  { Ev } },
+    { "notQ",  { Evh1 } },
+    { "negQ",  { Evh1 } },
     { "mulQ",  { Ev } },       /* Don't print the implicit register.  */
     { "imulQ", { Ev } },
     { "divQ",  { Ev } },
@@ -2574,13 +2612,13 @@ static const struct dis386 reg_table[][8] = {
   },
   /* REG_FE */
   {
-    { "incA",  { Eb } },
-    { "decA",  { Eb } },
+    { "incA",  { Ebh1 } },
+    { "decA",  { Ebh1 } },
   },
   /* REG_FF */
   {
-    { "incQ",  { Ev } },
-    { "decQ",  { Ev } },
+    { "incQ",  { Evh1 } },
+    { "decQ",  { Evh1 } },
     { "call{T|}", { indirEv } },
     { "Jcall{T|}", { indirEp } },
     { "jmp{T|}", { indirEv } },
@@ -2686,9 +2724,9 @@ static const struct dis386 reg_table[][8] = {
     { Bad_Opcode },
     { Bad_Opcode },
     { "btQ",   { Ev, Ib } },
-    { "btsQ",  { Ev, Ib } },
-    { "btrQ",  { Ev, Ib } },
-    { "btcQ",  { Ev, Ib } },
+    { "btsQ",  { Evh1, Ib } },
+    { "btrQ",  { Evh1, Ib } },
+    { "btcQ",  { Evh1, Ib } },
   },
   /* REG_0FC7 */
   {
@@ -2852,9 +2890,9 @@ static const struct dis386 prefix_table[][4] = {
 
   /* PREFIX_0F2E */
   {
-    { "ucomiss",{ XM, EXd } }, 
+    { "ucomiss",{ XM, EXd } },
     { Bad_Opcode },
-    { "ucomisd",{ XM, EXq } }, 
+    { "ucomisd",{ XM, EXq } },
   },
 
   /* PREFIX_0F2F */
@@ -3445,7 +3483,7 @@ static const struct dis386 prefix_table[][4] = {
     { "movbeS",        { Gv, { MOVBE_Fixup, v_mode } } },
     { Bad_Opcode },
     { "movbeS",        { Gv, { MOVBE_Fixup, v_mode } } },
-    { "crc32", { Gdq, { CRC32_Fixup, b_mode } } },     
+    { "crc32", { Gdq, { CRC32_Fixup, b_mode } } },
   },
 
   /* PREFIX_0F38F1 */
@@ -3453,7 +3491,15 @@ static const struct dis386 prefix_table[][4] = {
     { "movbeS",        { { MOVBE_Fixup, v_mode }, Gv } },
     { Bad_Opcode },
     { "movbeS",        { { MOVBE_Fixup, v_mode }, Gv } },
-    { "crc32", { Gdq, { CRC32_Fixup, v_mode } } },     
+    { "crc32", { Gdq, { CRC32_Fixup, v_mode } } },
+  },
+
+  /* PREFIX_0F38F6 */
+  {
+    { Bad_Opcode },
+    { "adoxS", { Gdq, Edq} },
+    { "adcxS", { Gdq, Edq} },
+    { Bad_Opcode },
   },
 
   /* PREFIX_0F3A08 */
@@ -6026,7 +6072,7 @@ static const struct dis386 three_byte_table[][256] = {
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
-    { Bad_Opcode },
+    { PREFIX_TABLE (PREFIX_0F38F6) },
     { Bad_Opcode },
     /* f8 */
     { Bad_Opcode },
@@ -6856,10 +6902,10 @@ static const struct dis386 xop_table[][256] = {
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vpcomb",        { XM, Vex128, EXx, Ib } },
-    { "vpcomw",        { XM, Vex128, EXx, Ib } },
-    { "vpcomd",        { XM, Vex128, EXx, Ib } },
-    { "vpcomq",        { XM, Vex128, EXx, Ib } },
+    { VEX_LEN_TABLE (VEX_LEN_0FXOP_08_CC) },
+    { VEX_LEN_TABLE (VEX_LEN_0FXOP_08_CD) },
+    { VEX_LEN_TABLE (VEX_LEN_0FXOP_08_CE) },
+    { VEX_LEN_TABLE (VEX_LEN_0FXOP_08_CF) },
     /* d0 */
     { Bad_Opcode },
     { Bad_Opcode },
@@ -6892,10 +6938,10 @@ static const struct dis386 xop_table[][256] = {
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vpcomub",       { XM, Vex128, EXx, Ib } },
-    { "vpcomuw",       { XM, Vex128, EXx, Ib } },
-    { "vpcomud",       { XM, Vex128, EXx, Ib } },
-    { "vpcomuq",       { XM, Vex128, EXx, Ib } },
+    { VEX_LEN_TABLE (VEX_LEN_0FXOP_08_EC) },
+    { VEX_LEN_TABLE (VEX_LEN_0FXOP_08_ED) },
+    { VEX_LEN_TABLE (VEX_LEN_0FXOP_08_EE) },
+    { VEX_LEN_TABLE (VEX_LEN_0FXOP_08_EF) },
     /* f0 */
     { Bad_Opcode },
     { Bad_Opcode },
@@ -8964,6 +9010,46 @@ static const struct dis386 vex_len_table[][2] = {
     { "rorxS",         { Gdq, Edq, Ib } },
   },
 
+  /* VEX_LEN_0FXOP_08_CC */
+  {
+     { "vpcomb",       { XM, Vex128, EXx, Ib } },
+  },
+
+  /* VEX_LEN_0FXOP_08_CD */
+  {
+     { "vpcomw",       { XM, Vex128, EXx, Ib } },
+  },
+
+  /* VEX_LEN_0FXOP_08_CE */
+  {
+     { "vpcomd",       { XM, Vex128, EXx, Ib } },
+  },
+
+  /* VEX_LEN_0FXOP_08_CF */
+  {
+     { "vpcomq",       { XM, Vex128, EXx, Ib } },
+  },
+
+  /* VEX_LEN_0FXOP_08_EC */
+  {
+     { "vpcomub",      { XM, Vex128, EXx, Ib } },
+  },
+
+  /* VEX_LEN_0FXOP_08_ED */
+  {
+     { "vpcomuw",      { XM, Vex128, EXx, Ib } },
+  },
+
+  /* VEX_LEN_0FXOP_08_EE */
+  {
+     { "vpcomud",      { XM, Vex128, EXx, Ib } },
+  },
+
+  /* VEX_LEN_0FXOP_08_EF */
+  {
+     { "vpcomuq",      { XM, Vex128, EXx, Ib } },
+  },
+
   /* VEX_LEN_0FXOP_09_80 */
   {
     { "vfrczps",       { XM, EXxmm } },
@@ -9076,11 +9162,11 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_0F2E_P_0 */
-    { "vucomiss",      { XMScalar, EXdScalar } }, 
+    { "vucomiss",      { XMScalar, EXdScalar } },
   },
   {
     /* VEX_W_0F2E_P_2 */
-    { "vucomisd",      { XMScalar, EXqScalar } }, 
+    { "vucomisd",      { XMScalar, EXqScalar } },
   },
   {
     /* VEX_W_0F2F_P_0 */
@@ -10066,6 +10152,16 @@ static const struct dis386 mod_table[][2] = {
     { "leaS",          { Gv, M } },
   },
   {
+    /* MOD_C6_REG_7 */
+    { Bad_Opcode },
+    { RM_TABLE (RM_C6_REG_7) },
+  },
+  {
+    /* MOD_C7_REG_7 */
+    { Bad_Opcode },
+    { RM_TABLE (RM_C7_REG_7) },
+  },
+  {
     /* MOD_0F01_REG_0 */
     { X86_64_TABLE (X86_64_0F01_REG_0) },
     { RM_TABLE (RM_0F01_REG_0) },
@@ -10146,7 +10242,7 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_0F24 */
-    { Bad_Opcode },    
+    { Bad_Opcode },
     { "movL",          { Rd, Td } },
   },
   {
@@ -10284,6 +10380,7 @@ static const struct dis386 mod_table[][2] = {
   {
     /* MOD_0FC7_REG_7 */
     { "vmptrst",       { Mq } },
+    { "rdseed",                { Ev } },
   },
   {
     /* MOD_0FD7 */
@@ -10454,6 +10551,14 @@ static const struct dis386 mod_table[][2] = {
 
 static const struct dis386 rm_table[][8] = {
   {
+    /* RM_C6_REG_7 */
+    { "xabort",                { Skip_MODRM, Ib } },
+  },
+  {
+    /* RM_C7_REG_7 */
+    { "xbeginT",       { Skip_MODRM, Jv } },
+  },
+  {
     /* RM_0F01_REG_0 */
     { Bad_Opcode },
     { "vmcall",                { Skip_MODRM } },
@@ -10473,6 +10578,9 @@ static const struct dis386 rm_table[][8] = {
     { Bad_Opcode },
     { Bad_Opcode },
     { "vmfunc",                { Skip_MODRM } },
+    { "xend",          { Skip_MODRM } },
+    { "xtest",         { Skip_MODRM } },
+    { Bad_Opcode },
   },
   {
     /* RM_0F01_REG_3 */
@@ -10513,6 +10621,8 @@ static const struct dis386 rm_table[][8] = {
 #define DATA16_PREFIX  (0x66 | 0x100)
 #define DATA32_PREFIX  (0x66 | 0x200)
 #define REP_PREFIX     (0xf3 | 0x100)
+#define XACQUIRE_PREFIX        (0xf2 | 0x200)
+#define XRELEASE_PREFIX        (0xf3 | 0x400)
 
 static int
 ckprefix (void)
@@ -10743,6 +10853,10 @@ prefix_name (int pref, int sizeflag)
       return "data32";
     case REP_PREFIX:
       return "rep";
+    case XACQUIRE_PREFIX:
+      return "xacquire";
+    case XRELEASE_PREFIX:
+      return "xrelease";
     default:
       return NULL;
     }
@@ -10873,7 +10987,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
              break;
            }
        }
-      else 
+      else
        {
          vindex = 0;
          used_prefixes |= (prefixes & PREFIX_REPZ);
@@ -12161,7 +12275,7 @@ case_L:
        case 'T':
          if (!intel_syntax
              && address_mode == mode_64bit
-             && (sizeflag & DFLAG))
+             && ((sizeflag & DFLAG) || (rex & REX_W)))
            {
              *obufp++ = 'q';
              break;
@@ -12199,7 +12313,8 @@ case_L:
        case 'U':
          if (intel_syntax)
            break;
-         if (address_mode == mode_64bit && (sizeflag & DFLAG))
+         if (address_mode == mode_64bit
+              && ((sizeflag & DFLAG) || (rex & REX_W)))
            {
              if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
                *obufp++ = 'q';
@@ -12271,7 +12386,8 @@ case_Q:
            {
              if (intel_syntax)
                break;
-             if (address_mode == mode_64bit && (sizeflag & DFLAG))
+             if (address_mode == mode_64bit
+                  && ((sizeflag & DFLAG) || (rex & REX_W)))
                {
                  if (sizeflag & SUFFIX_ALWAYS)
                    *obufp++ = 'q';
@@ -12607,7 +12723,7 @@ intel_operand_size (int bytemode, int sizeflag)
       oappend ("WORD PTR ");
       break;
     case stack_v_mode:
-      if (address_mode == mode_64bit && (sizeflag & DFLAG))
+      if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W)))
        {
          oappend ("QWORD PTR ");
          break;
@@ -12884,7 +13000,7 @@ OP_E_register (int bytemode, int sizeflag)
       names = address_mode == mode_64bit ? names64 : names32;
       break;
     case stack_v_mode:
-      if (address_mode == mode_64bit && (sizeflag & DFLAG))
+      if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W)))
        {
          names = names64;
          break;
@@ -12902,7 +13018,7 @@ OP_E_register (int bytemode, int sizeflag)
        names = names64;
       else
        {
-         if ((sizeflag & DFLAG) 
+         if ((sizeflag & DFLAG)
              || (bytemode != v_mode
                  && bytemode != v_swap_mode))
            names = names32;
@@ -12969,13 +13085,13 @@ OP_E_memory (int bytemode, int sizeflag)
              switch (vex.length)
                {
                case 128:
-                 indexes64 = indexes32 = names_xmm; 
+                 indexes64 = indexes32 = names_xmm;
                  break;
                case 256:
                  if (!vex.w || bytemode == vex_vsib_q_w_dq_mode)
-                   indexes64 = indexes32 = names_ymm; 
+                   indexes64 = indexes32 = names_ymm;
                  else
-                   indexes64 = indexes32 = names_xmm; 
+                   indexes64 = indexes32 = names_xmm;
                  break;
                default:
                  abort ();
@@ -13068,11 +13184,11 @@ OP_E_memory (int bytemode, int sizeflag)
                      *obufp = '\0';
                    }
                  if (haveindex)
-                   oappend (address_mode == mode_64bit 
+                   oappend (address_mode == mode_64bit
                             && (sizeflag & AFLAG)
                             ? indexes64[vindex] : indexes32[vindex]);
                  else
-                   oappend (address_mode == mode_64bit 
+                   oappend (address_mode == mode_64bit
                             && (sizeflag & AFLAG)
                             ? index64 : index32);
 
@@ -13381,7 +13497,8 @@ OP_REG (int code, int sizeflag)
       break;
     case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
     case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
-      if (address_mode == mode_64bit && (sizeflag & DFLAG))
+      if (address_mode == mode_64bit
+          && ((sizeflag & DFLAG) || (rex & REX_W)))
        {
          s = names64[code - rAX_reg + add];
          break;
@@ -13596,9 +13713,10 @@ OP_sI (int bytemode, int sizeflag)
       if (bytemode == b_T_mode)
        {
          if (address_mode != mode_64bit
-             || !(sizeflag & DFLAG))
+             || !((sizeflag & DFLAG) || (rex & REX_W)))
            {
-             if (sizeflag & DFLAG)
+              /* The operand-size prefix is overridden by a REX prefix.  */
+              if ((sizeflag & DFLAG) || (rex & REX_W))
                op &= 0xffffffff;
              else
                op &= 0xffff;
@@ -13616,7 +13734,8 @@ OP_sI (int bytemode, int sizeflag)
        }
       break;
     case v_mode:
-      if (sizeflag & DFLAG)
+      /* The operand-size prefix is overridden by a REX prefix.  */
+      if ((sizeflag & DFLAG) || (rex & REX_W))
        op = get32s ();
       else
        op = get16 ();
@@ -14045,7 +14164,7 @@ OP_EX (int bytemode, int sizeflag)
   if ((sizeflag & SUFFIX_ALWAYS)
       && (bytemode == x_swap_mode
          || bytemode == d_swap_mode
-         || bytemode == d_scalar_swap_mode 
+         || bytemode == d_scalar_swap_mode
          || bytemode == q_swap_mode
          || bytemode == q_scalar_swap_mode))
     swap_operand ();
@@ -14060,7 +14179,7 @@ OP_EX (int bytemode, int sizeflag)
       && bytemode != xmm_mq_mode
       && bytemode != xmmq_mode
       && bytemode != d_scalar_mode
-      && bytemode != d_scalar_swap_mode 
+      && bytemode != d_scalar_swap_mode
       && bytemode != q_scalar_mode
       && bytemode != q_scalar_swap_mode
       && bytemode != vex_scalar_w_dq_mode)
@@ -14361,6 +14480,57 @@ REP_Fixup (int bytemode, int sizeflag)
     }
 }
 
+/* Similar to OP_E.  But the 0xf2/0xf3 prefixes should be displayed as
+   "xacquire"/"xrelease" for memory operand if there is a LOCK prefix.
+ */
+
+static void
+HLE_Fixup1 (int bytemode, int sizeflag)
+{
+  if (modrm.mod != 3
+      && (prefixes & PREFIX_LOCK) != 0)
+    {
+      if (prefixes & PREFIX_REPZ)
+       all_prefixes[last_repz_prefix] = XRELEASE_PREFIX;
+      if (prefixes & PREFIX_REPNZ)
+       all_prefixes[last_repnz_prefix] = XACQUIRE_PREFIX;
+    }
+
+  OP_E (bytemode, sizeflag);
+}
+
+/* Similar to OP_E.  But the 0xf2/0xf3 prefixes should be displayed as
+   "xacquire"/"xrelease" for memory operand.  No check for LOCK prefix.
+ */
+
+static void
+HLE_Fixup2 (int bytemode, int sizeflag)
+{
+  if (modrm.mod != 3)
+    {
+      if (prefixes & PREFIX_REPZ)
+       all_prefixes[last_repz_prefix] = XRELEASE_PREFIX;
+      if (prefixes & PREFIX_REPNZ)
+       all_prefixes[last_repnz_prefix] = XACQUIRE_PREFIX;
+    }
+
+  OP_E (bytemode, sizeflag);
+}
+
+/* Similar to OP_E.  But the 0xf3 prefixes should be displayed as
+   "xrelease" for memory operand.  No check for LOCK prefix.   */
+
+static void
+HLE_Fixup3 (int bytemode, int sizeflag)
+{
+  if (modrm.mod != 3
+      && last_repz_prefix > last_repnz_prefix
+      && (prefixes & PREFIX_REPZ) != 0)
+    all_prefixes[last_repz_prefix] = XRELEASE_PREFIX;
+
+  OP_E (bytemode, sizeflag);
+}
+
 static void
 CMPXCHG8B_Fixup (int bytemode, int sizeflag)
 {
@@ -14372,6 +14542,14 @@ CMPXCHG8B_Fixup (int bytemode, int sizeflag)
       mnemonicendp = stpcpy (p, "16b");
       bytemode = o_mode;
     }
+  else if ((prefixes & PREFIX_LOCK) != 0)
+    {
+      if (prefixes & PREFIX_REPZ)
+       all_prefixes[last_repz_prefix] = XRELEASE_PREFIX;
+      if (prefixes & PREFIX_REPNZ)
+       all_prefixes[last_repnz_prefix] = XACQUIRE_PREFIX;
+    }
+
   OP_M (bytemode, sizeflag);
 }
 
@@ -14420,7 +14598,7 @@ CRC32_Fixup (int bytemode, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        *p++ = 'q';
-      else 
+      else
        {
          if (sizeflag & DFLAG)
            *p++ = 'l';
@@ -14972,7 +15150,7 @@ PCLMUL_Fixup (int bytemode ATTRIBUTE_UNUSED,
       break;
     default:
       break;
-    } 
+    }
   if (pclmul_type < ARRAY_SIZE (pclmul_op))
     {
       char suffix [4];
@@ -15067,4 +15245,3 @@ OP_LWP_E (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
 
   oappend (names[vex.register_specifier]);
 }
-