Fix disassembly of XCHG
authorH. Peter Anvin <hpa@zytor.com>
Tue, 13 Nov 2007 05:02:33 +0000 (21:02 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 13 Nov 2007 05:02:33 +0000 (21:02 -0800)
"REX.B 90" in 64-bit mode is "xchg eax,r8d" not "nop"; equivalent
situation for "REX.WB 90" (xchg rax,r8).

assemble.c
disasm.c
insns.dat

index b6b447e..a56887e 100644 (file)
  * \311          - indicates fixed 32-bit address size, i.e. optional 0x67.
  * \312          - (disassembler only) marker on LOOP, LOOPxx instructions.
  * \313          - indicates fixed 64-bit address size, 0x67 invalid.
+ * \314          - (disassembler only) invalid with REX.B
+ * \315          - (disassembler only) invalid with REX.X
+ * \316          - (disassembler only) invalid with REX.R
+ * \317          - (disassembler only) invalid with REX.W
  * \320          - indicates fixed 16-bit operand size, i.e. optional 0x66.
  * \321          - indicates fixed 32-bit operand size, i.e. optional 0x66.
  * \322          - indicates that this instruction is only valid when the
@@ -965,6 +969,11 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
                has_prefix(ins, PPS_ASIZE, P_A32))
                return -1;
             break;
+       case 0314:
+       case 0315:
+       case 0316:
+       case 0317:
+           break;
         case 0320:
             length += (bits != 16);
             break;
@@ -1491,6 +1500,12 @@ static void gencode(int32_t segment, int64_t offset, int bits,
             ins->rex = 0;
             break;
 
+       case 0314:
+       case 0315:
+       case 0316:
+       case 0317:
+           break;
+
         case 0320:
             if (bits != 16) {
                 *bytes = 0x66;
index f89114d..686caed 100644 (file)
--- a/disasm.c
+++ b/disasm.c
@@ -584,6 +584,18 @@ static int matches(const struct itemplate *t, uint8_t *data,
                return false;
            else
                a_used = true;
+       } else if (c == 0314) {
+           if (prefix->rex & REX_B)
+               return false;
+       } else if (c == 0315) {
+           if (prefix->rex & REX_X)
+               return false;
+       } else if (c == 0316) {
+           if (prefix->rex & REX_R)
+               return false;
+       } else if (c == 0317) {
+           if (prefix->rex & REX_W)
+               return false;
         } else if (c == 0320) {
             if (osize != 16)
                 return false;
index 48a9c5f..c297fbf 100644 (file)
--- a/insns.dat
+++ b/insns.dat
@@ -773,7 +773,7 @@ NEG         rm8                     \1\xF6\203                      8086
 NEG            rm16                    \320\1\xF7\203                  8086
 NEG            rm32                    \321\1\xF7\203                  386
 NEG            rm64                    \324\1\xF7\203                  X64
-NOP            void                    \1\x90                          8086
+NOP            void                    \314\1\x90                      8086
 NOP            rm16                    \320\2\x0F\x1F\200              P6
 NOP            rm32                    \321\2\x0F\x1F\200              P6
 NOP            rm64                    \324\2\x0F\x1F\200              X64