summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/opcode/ChangeLog4
-rw-r--r--include/opcode/i386.h10
-rw-r--r--opcodes/ChangeLog7
-rw-r--r--opcodes/i386-dis.c26
4 files changed, 34 insertions, 13 deletions
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index ab1793efd59..edc00fa6dee 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,7 @@
+2006-06-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * i386.h (i386_optab): Update comment for 64bit NOP.
+
2006-06-06 Ben Elliston <bje@au.ibm.com>
Anton Blanchard <anton@samba.org>
diff --git a/include/opcode/i386.h b/include/opcode/i386.h
index 2b2c1e0f979..c46c86d4c1d 100644
--- a/include/opcode/i386.h
+++ b/include/opcode/i386.h
@@ -179,19 +179,11 @@ static const template i386_optab[] =
/* Exchange instructions.
xchg commutes: we allow both operand orders.
- In the 64bit code, xchg eax, eax is reused for new nop instruction. */
-#if 0 /* While the two entries that are disabled generate shorter code
- for xchg eax, reg (on x86_64), the special case xchg eax, eax
- does not get handled correctly - it degenerates into nop, but
- that way the side effect of zero-extending eax to rax is lost. */
-{"xchg", 2, 0x90, X, 0, wlq_Suf|ShortForm, { WordReg, Acc, 0 } },
-{"xchg", 2, 0x90, X, 0, wlq_Suf|ShortForm, { Acc, WordReg, 0 } },
-#else
+ In the 64bit code, xchg rax, rax is reused for new nop instruction. */
{"xchg", 2, 0x90, X, CpuNo64, wl_Suf|ShortForm, { WordReg, Acc, 0 } },
{"xchg", 2, 0x90, X, CpuNo64, wl_Suf|ShortForm, { Acc, WordReg, 0 } },
{"xchg", 2, 0x90, X, Cpu64, wq_Suf|ShortForm, { Reg16|Reg64, Acc, 0 } },
{"xchg", 2, 0x90, X, Cpu64, wq_Suf|ShortForm, { Acc, Reg16|Reg64, 0 } },
-#endif
{"xchg", 2, 0x86, X, 0, bwlq_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } },
{"xchg", 2, 0x86, X, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, Reg, 0 } },
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 0357828ce21..826c54ec912 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,10 @@
+2006-06-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * i386-dis.c (NOP_Fixup): Removed.
+ (NOP_Fixup1): New.
+ (NOP_Fixup2): Likewise.
+ (dis386): Use NOP_Fixup1 and NOP_Fixup2 on 0x90.
+
2006-06-12 Julian Brown <julian@codesourcery.com>
* arm-dis.c (print_insn_neon): Disassemble 32-bit immediates as signed
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 39016193b59..49a3e9ff72e 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -91,7 +91,8 @@ static void OP_M (int, int);
static void OP_VMX (int, int);
static void OP_0fae (int, int);
static void OP_0f07 (int, int);
-static void NOP_Fixup (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 SIMD_Fixup (int, int);
@@ -679,7 +680,7 @@ static const struct dis386 dis386[] = {
{ "movQ", Sw, Sv, XX },
{ "popU", stackEv, XX, XX },
/* 90 */
- { "nop", NOP_Fixup, 0, XX, XX },
+ { "xchgS", NOP_Fixup1, eAX_reg, NOP_Fixup2, eAX_reg, XX },
{ "xchgS", RMeCX, eAX, XX },
{ "xchgS", RMeDX, eAX, XX },
{ "xchgS", RMeBX, eAX, XX },
@@ -4360,12 +4361,29 @@ OP_0fae (int bytemode, int sizeflag)
OP_E (bytemode, sizeflag);
}
+/* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
+ 32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix
+ is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
+ */
+
static void
-NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+NOP_Fixup1 (int bytemode, int sizeflag)
{
- /* NOP with REPZ prefix is called PAUSE. */
if (prefixes == PREFIX_REPZ)
strcpy (obuf, "pause");
+ else if (prefixes == PREFIX_DATA
+ || ((rex & REX_MODE64) && rex != 0x48))
+ OP_REG (bytemode, sizeflag);
+ else
+ strcpy (obuf, "nop");
+}
+
+static void
+NOP_Fixup2 (int bytemode, int sizeflag)
+{
+ if (prefixes == PREFIX_DATA
+ || ((rex & REX_MODE64) && rex != 0x48))
+ OP_IMREG (bytemode, sizeflag);
}
static const char *const Suffix3DNow[] = {