#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 }
#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 } }
#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)
#define PREFIX_0FB8 (PREFIX_0F7F + 1)
#define PREFIX_0FBD (PREFIX_0FB8 + 1)
#define PREFIX_0FC2 (PREFIX_0FBD + 1)
-#define PREFIX_0FC7_REG_6 (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)
'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
'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.
{ "(bad)", { XX } },
{ "ud2a", { XX } },
{ "(bad)", { XX } },
- { REG_TABLE (REG_0F0E) },
+ { REG_TABLE (REG_0F0D) },
{ "femms", { XX } },
{ "", { MX, EM, OPSUF } }, /* See OP_3DNowSuffix. */
/* 10 */
{ 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) },
{ "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 } },
/* 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 */
{ "lmsw", { Ew } },
{ MOD_TABLE (MOD_0F01_REG_7) },
},
- /* REG_0F0E */
+ /* REG_0F0D */
{
{ "prefetch", { Eb } },
{ "prefetchw", { Eb } },
/* PREFIX_0F2A */
{
{ "cvtpi2ps", { XM, EMCq } },
- { "cvtsi2ssY", { XM, Ev } },
+ { "cvtsi2ss%LQ", { XM, Ev } },
{ "cvtpi2pd", { XM, EMCq } },
- { "cvtsi2sdY", { XM, Ev } },
+ { "cvtsi2sd%LQ", { XM, Ev } },
},
/* PREFIX_0F2B */
{ "cmpsd", { XM, EXq, CMP } },
},
+ /* PREFIX_0FC3 */
+ {
+ { "movntiS", { Ma, Gv } },
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ },
+
/* PREFIX_0FC7_REG_6 */
{
{ "vmptrld",{ Mq } },
/* PREFIX_0FE7 */
{
- { "movntq", { EM, MX } },
+ { "movntq", { Mq, MX } },
{ "(bad)", { XX } },
{ MOD_TABLE (MOD_0FE7_PREFIX_2) },
{ "(bad)", { XX } },
},
{
/* MOD_0F2B_PREFIX_0 */
- {"movntps", { Ev, XM } },
+ {"movntps", { Mx, XM } },
{ "(bad)", { XX } },
},
{
/* MOD_0F2B_PREFIX_1 */
- {"movntss", { Ed, XM } },
+ {"movntss", { Md, XM } },
{ "(bad)", { XX } },
},
{
/* MOD_0F2B_PREFIX_2 */
- {"movntpd", { Ev, XM } },
+ {"movntpd", { Mx, XM } },
{ "(bad)", { XX } },
},
{
/* MOD_0F2B_PREFIX_3 */
- {"movntsd", { Eq, XM } },
+ {"movntsd", { Mq, XM } },
{ "(bad)", { XX } },
},
{
},
{
/* MOD_0FE7_PREFIX_2 */
- { "movntdq", { EM, XM } },
+ { "movntdq", { Mx, XM } },
{ "(bad)", { XX } },
},
{
},
{
/* MOD_0F382A_PREFIX_2 */
- { "movntdqa", { XM, EM } },
+ { "movntdqa", { XM, Mx } },
{ "(bad)", { XX } },
},
{
*/
static char intel_syntax;
+static char intel_mnemonic = !SYSV386_COMPAT;
static char open_char;
static char close_char;
static char separator_char;
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"));
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"))
{
{ "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 */
{
{ "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 */
{
{
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++)
{
default:
*obufp++ = *p;
break;
+ case '%':
+ len++;
+ break;
+ case '!':
+ cond = 0;
+ break;
case '{':
alt = 0;
if (intel_syntax)
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';
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':
int havebase;
int haveindex;
int needindex;
- int base;
+ int base, rbase;
int index = 0;
int scale = 0;
haveindex = index != 4;
codep++;
}
- base += add;
+ rbase = base + add;
/* If we have a DREX byte, skip it now
(it has already been handled) */
switch (modrm.mod)
{
case 0:
- if ((base & 7) == 5)
+ if (base == 5)
{
havebase = 0;
if (address_mode == mode_64bit && !havesib)
|| (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);
*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,
}
}
if (intel_syntax
- && (disp || modrm.mod != 0 || (base & 7) == 5))
+ && (disp || modrm.mod != 0 || base == 5))
{
if (!havedisp || (bfd_signed_vma) disp >= 0)
{
}
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))