From 6bea2c7f9b2530a1ce247139d184954136dd16ff Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 27 Jun 2018 19:03:36 +0000 Subject: [PATCH] [X86] Teach the disassembler to use %eiz/%riz instead of NoRegister when the SIB byte is present, but doesn't encode an index register and there was another shorter encoding that would achieve the same result. 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 --- .../Target/X86/Disassembler/X86Disassembler.cpp | 25 ++++++++++++---- llvm/test/MC/Disassembler/X86/x86-32.txt | 12 ++++++++ llvm/test/MC/Disassembler/X86/x86-64.txt | 34 +++++++++++++++++----- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp index b658963..c9beae0 100644 --- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -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"); diff --git a/llvm/test/MC/Disassembler/X86/x86-32.txt b/llvm/test/MC/Disassembler/X86/x86-32.txt index fc0f4c4..068bfbe 100644 --- a/llvm/test/MC/Disassembler/X86/x86-32.txt +++ b/llvm/test/MC/Disassembler/X86/x86-32.txt @@ -889,3 +889,15 @@ #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 diff --git a/llvm/test/MC/Disassembler/X86/x86-64.txt b/llvm/test/MC/Disassembler/X86/x86-64.txt index 3ffd721..bcaa7da 100644 --- a/llvm/test/MC/Disassembler/X86/x86-64.txt +++ b/llvm/test/MC/Disassembler/X86/x86-64.txt @@ -272,30 +272,48 @@ # 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 -- 2.7.4