[X86] Teach the disassembler to use %eiz/%riz instead of NoRegister when the SIB...
authorCraig Topper <craig.topper@intel.com>
Wed, 27 Jun 2018 19:03:36 +0000 (19:03 +0000)
committerCraig Topper <craig.topper@intel.com>
Wed, 27 Jun 2018 19:03:36 +0000 (19:03 +0000)
The %eiz/%riz are dummy registers that force the encoder to emit a SIB byte when it normally wouldn't. By emitting them in the disassembly output we ensure that assembling the disassembler output would also produce a SIB byte.

This should match the behavior of objdump from binutils.

llvm-svn: 335768

llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
llvm/test/MC/Disassembler/X86/x86-32.txt
llvm/test/MC/Disassembler/X86/x86-64.txt

index b658963..c9beae0 100644 (file)
@@ -758,7 +758,7 @@ static bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn,
 #undef ENTRY
       }
     } else {
-      baseReg = MCOperand::createReg(0);
+      baseReg = MCOperand::createReg(X86::NoRegister);
     }
 
     if (insn.sibIndex != SIB_INDEX_NONE) {
@@ -777,7 +777,22 @@ static bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn,
 #undef ENTRY
       }
     } else {
-      indexReg = MCOperand::createReg(0);
+      // Use EIZ/RIZ for a few ambiguous cases where the SIB byte is present,
+      // but no index is used and modrm alone should have been enough.
+      // -No base register in 32-bit mode. In 64-bit mode this is used to
+      //  avoid rip-relative addressing.
+      // -Any base register used other than ESP/RSP/R12D/R12. Using these as a
+      //  base always requires a SIB byte.
+      // -A scale other than 1 is used.
+      if (insn.sibScale != 1 ||
+          (insn.sibBase == SIB_BASE_NONE && insn.mode != MODE_64BIT) ||
+          ((insn.sibBase != SIB_BASE_NONE &&
+           insn.sibBase != SIB_BASE_ESP && insn.sibBase != SIB_BASE_RSP &&
+           insn.sibBase != SIB_BASE_R12D && insn.sibBase != SIB_BASE_R12)) {
+        indexReg = MCOperand::createReg(insn.addressSize == 4 ? X86::EIZ :
+                                                                X86::RIZ);
+      } else
+        indexReg = MCOperand::createReg(X86::NoRegister);
     }
 
     scaleAmount = MCOperand::createImm(insn.sibScale);
@@ -799,9 +814,9 @@ static bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn,
                                                                X86::RIP);
       }
       else
-        baseReg = MCOperand::createReg(0);
+        baseReg = MCOperand::createReg(X86::NoRegister);
 
-      indexReg = MCOperand::createReg(0);
+      indexReg = MCOperand::createReg(X86::NoRegister);
       break;
     case EA_BASE_BX_SI:
       baseReg = MCOperand::createReg(X86::BX);
@@ -820,7 +835,7 @@ static bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn,
       indexReg = MCOperand::createReg(X86::DI);
       break;
     default:
-      indexReg = MCOperand::createReg(0);
+      indexReg = MCOperand::createReg(X86::NoRegister);
       switch (insn.eaBase) {
       default:
         debug("Unexpected eaBase");
index fc0f4c4..068bfbe 100644 (file)
 
 #CHECK: vgatherdps (%esi,%zmm0,4), %zmm1 {%k2}
 0x62 0xf2 0x7d 0x42 0x92 0x0c 0x86
+
+# CHECK: addb $0, 305419896(%ebp,%eiz)
+0x80 0x84 0x25 0x78 0x56 0x34 0x12 0x00
+
+# CHECK: addb $0, 305419896(%ebp,%eiz,2)
+0x80 0x84 0x65 0x78 0x56 0x34 0x12 0x00
+
+# CHECK: addb $0, 305419896(%esp,%eiz,2)
+0x80 0x84 0x64 0x78 0x56 0x34 0x12 0x00
+
+# CHECK: addb $0, 305419896(,%eiz)
+0x80 0x04 0x25 0x78 0x56 0x34 0x12 0x00
index 3ffd721..bcaa7da 100644 (file)
 # CHECK: pextrw $3, %xmm3, (%rax)
 0x66 0x0f 0x3a 0x15 0x18 0x03
 
-# CHECK: $0, 305419896(,%r8)
+# CHECK: addb $0, 305419896(,%r8)
 0x43 0x80 0x04 0x05 0x78 0x56 0x34 0x12 0x00
 
-# CHECK: $0, 305419896(%r13,%r8)
+# CHECK: addb $0, 305419896(%r13,%r8)
 0x43 0x80 0x84 0x05 0x78 0x56 0x34 0x12 0x00
 
-# CHECK: $0, 305419896(,%r8)
+# CHECK: addb $0, 305419896(,%r8)
 0x42 0x80 0x04 0x05 0x78 0x56 0x34 0x12 0x00
 
-# CHECK: $0, 305419896(%rbp,%r8)
+# CHECK: addb $0, 305419896(%rbp,%r8)
 0x42 0x80 0x84 0x05 0x78 0x56 0x34 0x12 0x00
 
-# CHECK: $0, 305419896(,%r12)
+# CHECK: addb $0, 305419896(,%r12)
 0x42 0x80 0x04 0x25 0x78 0x56 0x34 0x12 0x00
 
-# CHECK: $0, 305419896(%rbp,%r12)
+# CHECK: addb $0, 305419896(%rbp,%r12)
 0x42 0x80 0x84 0x25 0x78 0x56 0x34 0x12 0x00
 
-# CHECK: $0, 305419896
+# CHECK: addb $0, 305419896
 0x80 0x04 0x25 0x78 0x56 0x34 0x12 0x00
 
-# CHECK: $0, 305419896(%rbp)
+# CHECK: addb $0, 305419896(%rbp)
+0x80 0x85 0x78 0x56 0x34 0x12 0x00
+
+# CHECK: addb $0, 305419896(%rbp,%riz)
 0x80 0x84 0x25 0x78 0x56 0x34 0x12 0x00
 
+# CHECK: addb $0, 305419896(%rbp,%riz,2)
+0x80 0x84 0x65 0x78 0x56 0x34 0x12 0x00
+
+# CHECK: addb $0, 305419896(%rsp,%riz,2)
+0x80 0x84 0x64 0x78 0x56 0x34 0x12 0x00
+
+# CHECK: addb $0, 305419896(%r12,%riz,2)
+0x41 0x80 0x84 0x64 0x78 0x56 0x34 0x12 0x00
+
+# CHECK: addb $0, 305419896(%esp,%eiz,2)
+0x67 0x80 0x84 0x64 0x78 0x56 0x34 0x12 0x00
+
+# CHECK: addb $0, 305419896(%r12d,%eiz,2)
+0x67 0x41 0x80 0x84 0x64 0x78 0x56 0x34 0x12 0x00
+
 # CHECK: movabsq 6510615555426900570, %rax
 0x48 0xa1 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a