This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: Display "xchg %ax,%ax" and "xchg %rax,%rax"
On Fri, Jun 09, 2006 at 09:48:23AM +0200, Jan Beulich wrote:
> >+ else if (prefixes == PREFIX_DATA)
> >+ {
> >+ /* We display "xchg %ax,%ax" instead of "data16 nop". */
> >+ prefixes = 0;
> >+ if (intel_syntax)
> >+ strcpy (obuf, "xchg ax,ax");
> >+ else
> >+ strcpy (obuf, "xchg %ax,%ax");
> >+ }
>
> This is wrong in 16-bit mode. It might be better to call appropriate functions than to use hard-coded strings here.
>
> + else if (rex == 0x48)
> + {
> + /* We display "xchg %rax,%rax" instead of "rex64 nop". */
> + rex = 0;
> + if (intel_syntax)
> + strcpy (obuf, "xchg rax,rax");
> + else
> + strcpy (obuf, "xchg %rax,%rax");
> + }
>
> This doesn't account for the rex bits that are ignored by this instruction. You should consume only rex.w here.
Here is the updated patch. It also fixes "xchg %rax,%r8".
H.J.
----
gas/testsuite/
2006-06-09 H.J. Lu <hongjiu.lu@intel.com>
* gas/i386/opcode.s: Add "xchg %ax,%ax".
* gas/i386/opcode.d: Updated.
* gas/i386/x86-64-opcode.s: Add "xchg %ax,%ax", "xchg %rax,%rax"
and "xchg %rax,%r8".
* gas/i386/x86-64-opcode.d: Updated.
opcodes/
2006-06-09 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.
--- binutils/gas/testsuite/gas/i386/opcode.d.xchg 2005-03-29 12:09:20.000000000 -0800
+++ binutils/gas/testsuite/gas/i386/opcode.d 2006-06-09 12:06:15.000000000 -0700
@@ -572,4 +572,5 @@ Disassembly of section .text:
9b7: 66 0f bd 90 90 90 90 90 [ ]*bsr 0x90909090\(%eax\),%dx
9bf: 66 0f be 90 90 90 90 90 [ ]*movsbw 0x90909090\(%eax\),%dx
9c7: 66 0f c1 90 90 90 90 90 [ ]*xadd %dx,0x90909090\(%eax\)
+ 9cf: 66 90 [ ]*xchg %ax,%ax
\.\.\.
--- binutils/gas/testsuite/gas/i386/opcode.s.xchg 2005-03-29 12:09:20.000000000 -0800
+++ binutils/gas/testsuite/gas/i386/opcode.s 2006-06-08 23:27:00.000000000 -0700
@@ -566,5 +566,7 @@ foo:
movsbw 0x90909090(%eax),%dx
xadd %dx,0x90909090(%eax)
+ xchg %ax,%ax
+
# Force a good alignment.
.p2align 4,0
--- binutils/gas/testsuite/gas/i386/x86-64-opcode.d.xchg 2005-03-29 12:09:20.000000000 -0800
+++ binutils/gas/testsuite/gas/i386/x86-64-opcode.d 2006-06-09 12:23:58.000000000 -0700
@@ -266,6 +266,7 @@ Disassembly of section .text:
[ ]*[0-9a-f]+:[ ]+e6 00[ ]+out[ ]+%al,\$0[x0]*[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+66 e7 00[ ]+out[ ]+%ax,\$0[x0]*[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+e7 00[ ]+out[ ]+%eax,\$0[x0]*[ ]*(#.*)*
-[ ]*[0-9a-f]+:[ ]+00 00[ ]+.*
-[ ]*[0-9a-f]+:[ ]+00 00[ ]+.*
-[ *]...
+[ ]*[0-9a-f]+:[ ]+66 90[ ]+xchg[ ]+%ax,%ax[ ]*(#.*)*
+[ ]*[0-9a-f]+:[ ]+48 90[ ]+xchg[ ]+%rax,%rax[ ]*(#.*)*
+[ ]*[0-9a-f]+:[ ]+49 90[ ]+xchg[ ]+%rax,%r8[ ]*(#.*)*
+#pass
--- binutils/gas/testsuite/gas/i386/x86-64-opcode.s.xchg 2005-03-29 12:09:20.000000000 -0800
+++ binutils/gas/testsuite/gas/i386/x86-64-opcode.s 2006-06-09 12:23:21.000000000 -0700
@@ -387,4 +387,10 @@
# IN
+
+
+ xchg %ax,%ax # 66 -- -- -- 90
+ xchg %rax,%rax # -- -- -- 48 90
+ xchg %rax,%r8 # -- -- -- 49 90
+
.p2align 4,0
--- binutils/opcodes/i386-dis.c.xchg 2006-05-11 08:52:55.000000000 -0700
+++ binutils/opcodes/i386-dis.c 2006-06-09 12:03:15.000000000 -0700
@@ -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,26 @@ OP_0fae (int bytemode, int sizeflag)
OP_E (bytemode, sizeflag);
}
+/* NOP is an alias of "xchg %eax,%eax". NOP with REPZ prefix is called
+ PAUSE. We display "xchg %ax,%ax" and "xchg %rax,%rax", instead of
+ "data16 nop" and "rex64 nop", respectively. */
+
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))
+ OP_REG (bytemode, sizeflag);
+ else
+ strcpy (obuf, "nop");
+}
+
+static void
+NOP_Fixup2 (int bytemode, int sizeflag)
+{
+ if (prefixes == PREFIX_DATA || (rex & REX_MODE64))
+ OP_IMREG (bytemode, sizeflag);
}
static const char *const Suffix3DNow[] = {