gas/
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 12 Jun 2006 18:55:44 +0000 (18:55 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 12 Jun 2006 18:55:44 +0000 (18:55 +0000)
2006-06-12  H.J. Lu  <hongjiu.lu@intel.com>

* config/tc-i386.c (process_suffix): Don't add rex64 for
"xchg %rax,%rax".

gas/testsuite/

2006-06-12  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 %eax,%eax,
xchg %rax,%rax, rex64 xchg %rax,%rax and xchg %rax,%r8.
* gas/i386/x86-64-opcode.d: Updated.

include/opcode/

2006-06-12  H.J. Lu  <hongjiu.lu@intel.com>

* i386.h (i386_optab): Update comment for 64bit NOP.

opcodes/

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.

gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/opcode.d
gas/testsuite/gas/i386/opcode.s
gas/testsuite/gas/i386/x86-64-opcode.d
gas/testsuite/gas/i386/x86-64-opcode.s
include/opcode/ChangeLog
include/opcode/i386.h
opcodes/ChangeLog
opcodes/i386-dis.c

index a225bb09aa71424e420e6d492b3c58f11077f4fc..72942724ea5e70fa4740666417e5f03313cec1c5 100644 (file)
@@ -1,3 +1,8 @@
+2006-06-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * config/tc-i386.c (process_suffix): Don't add rex64 for
+       "xchg %rax,%rax".
+
 2006-06-09  Thiemo Seufer  <ths@mips.com>
 
        * config/tc-mips.c (mips_ip): Maintain argument count.
index 694618f06c0241c7d1fb51a36e83b641e3cae668..4a469088ce639693c4c6e656f4a5c501028d71bd 100644 (file)
@@ -2615,7 +2615,15 @@ process_suffix (void)
       if (i.suffix == QWORD_MNEM_SUFFIX
          && flag_code == CODE_64BIT
          && (i.tm.opcode_modifier & NoRex64) == 0)
-       i.rex |= REX_MODE64;
+       {
+         /* Special case for xchg %rax,%rax.  It is NOP and doesn't
+            need rex64.  */
+         if (i.operands != 2
+             || i.types [0] != (Acc | Reg64)
+             || i.types [1] != (Acc | Reg64)
+             || strcmp (i.tm.name, "xchg") != 0)
+         i.rex |= REX_MODE64;
+       }
 
       /* Size floating point instruction.  */
       if (i.suffix == LONG_MNEM_SUFFIX)
index 1fd5057499be484bedbe341581024db12017138a..2b16921e0bdffbeaef3e79ea099c406d8743ef17 100644 (file)
@@ -1,3 +1,12 @@
+2006-06-12  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 %eax,%eax,
+       xchg %rax,%rax, rex64 xchg %rax,%rax and xchg %rax,%r8.
+       * gas/i386/x86-64-opcode.d: Updated.
+
 2006-06-09  Thiemo Seufer  <ths@mips.com>
             Nigel Stephens  <nigel@mips.com>
 
index 808ddc5371a4cbe6a58ec032df77d9625c438be9..fa58807c5ef9f3c71615237a902f9befeeeae489 100644 (file)
@@ -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
        \.\.\.
index 8d7cd050f165eb0523e01593ab255d6a7ff622bf..a03ce13099fa0b6c2f8389e0f3d75fcb22183031 100644 (file)
@@ -566,5 +566,7 @@ foo:
  movsbw 0x90909090(%eax),%dx
  xadd   %dx,0x90909090(%eax)
 
+ xchg   %ax,%ax
+
 # Force a good alignment.
  .p2align 4,0
index 13d58be1bdb84b97ae5f10c2d133162efccd41c5..f6427d4e00d26df5869f6582666cad3d1bc9cfa7 100644 (file)
@@ -266,6 +266,9 @@ 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]+:[   ]+87 c0[        ]+xchg[         ]+%eax,%eax[    ]*(#.*)*
+[       ]*[0-9a-f]+:[   ]+90[   ]+nop[  ]*(#.*)*
+[       ]*[0-9a-f]+:[   ]+48 90[        ]+rex64 nop[    ]*(#.*)*
+[       ]*[0-9a-f]+:[   ]+49 90[        ]+xchg[         ]+%rax,%r8[     ]*(#.*)*
+#pass
index 8b132b3904682509277548af8856580558e58435..8d3de00a8e68881b96f95db651aa77df1f7f815a 100644 (file)
 
        # IN
 
+
+
+       xchg %ax,%ax                  # 66  --   -- --   90
+       xchg %eax,%eax                # --  --   -- --   87 C0
+       xchg %rax,%rax                # --  --   -- --   90
+       rex64 xchg %rax,%rax          # 48  --   -- --   90
+       xchg %rax,%r8                 # --  --   -- 49   90
+
  .p2align 4,0
index ab1793efd592c7ee558d0a0f9e16665360eec150..edc00fa6deefb6c235936aa820fa017b113bd5ec 100644 (file)
@@ -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>
 
index 2b2c1e0f9790f8a7ed75826bd0dfc896898c247b..c46c86d4c1d6458267d1fdec468bfed68ffa9f5d 100644 (file)
@@ -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 } },
 
index 0357828ce21c8f289099786131b5f338e61e4bf9..826c54ec912dc770f211f4deade895f8e2211a9a 100644 (file)
@@ -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
index 39016193b59848a0ee43ea988e380e60a9a5a4fd..49a3e9ff72e8f121eba54287075e0c97a17d41a4 100644 (file)
@@ -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[] = {