[llvm-commits] [llvm] r140971 - in /llvm/trunk: lib/Target/X86/Disassembler/X86DisassemblerDecoder.c test/MC/Disassembler/X86/simple-tests.txt

Craig Topper craig.topper at gmail.com
Sun Oct 2 09:56:10 PDT 2011


Author: ctopper
Date: Sun Oct  2 11:56:09 2011
New Revision: 140971

URL: http://llvm.org/viewvc/llvm-project?rev=140971&view=rev
Log:
Special case disassembler handling of REX.B prefix on NOP instruction to decode as XCHG R8D, EAX instead. Fixes PR10344.

Modified:
    llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
    llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt

Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c?rev=140971&r1=140970&r2=140971&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c (original)
+++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c Sun Oct  2 11:56:09 2011
@@ -58,8 +58,8 @@
  * @return            - TRUE if the ModR/M byte is required, FALSE otherwise.
  */
 static int modRMRequired(OpcodeType type,
-                                InstructionContext insnContext,
-                                uint8_t opcode) {
+                         InstructionContext insnContext,
+                         uint8_t opcode) {
   const struct ContextDecision* decision = 0;
   
   switch (type) {
@@ -885,6 +885,43 @@
     }
     return 0;
   }
+
+  if (insn->opcodeType == ONEBYTE && insn->opcode == 0x90 &&
+      insn->rexPrefix & 0x01) {
+    /*
+     * NOOP shouldn't decode as NOOP if REX.b is set. Instead
+     * it should decode as XCHG %r8, %eax.
+     */
+
+    const struct InstructionSpecifier *spec;
+    uint16_t instructionIDWithNewOpcode;
+    const struct InstructionSpecifier *specWithNewOpcode;
+
+    spec = specifierForUID(instructionID);
+    
+    // Borrow opcode from one of the other XCHGar opcodes
+    insn->opcode = 0x91;
+   
+    if (getIDWithAttrMask(&instructionIDWithNewOpcode,
+                          insn,
+                          attrMask)) {
+      insn->opcode = 0x90;
+
+      insn->instructionID = instructionID;
+      insn->spec = spec;
+      return 0;
+    }
+
+    specWithNewOpcode = specifierForUID(instructionIDWithNewOpcode);
+
+    // Change back 
+    insn->opcode = 0x90;
+
+    insn->instructionID = instructionIDWithNewOpcode;
+    insn->spec = specWithNewOpcode;
+
+    return 0;
+  }
   
   insn->instructionID = instructionID;
   insn->spec = specifierForUID(insn->instructionID);

Modified: llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt?rev=140971&r1=140970&r2=140971&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt (original)
+++ llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt Sun Oct  2 11:56:09 2011
@@ -308,3 +308,6 @@
 
 # CHECK: invvpid (%rax), %rax
 0x66 0x0f 0x38 0x81 0x00
+
+# CHECK: xchgl %r8d, %eax
+0x41 0x90





More information about the llvm-commits mailing list