diff options
Diffstat (limited to 'lib/Target/X86/Disassembler/X86Disassembler.cpp')
-rw-r--r-- | lib/Target/X86/Disassembler/X86Disassembler.cpp | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/lib/Target/X86/Disassembler/X86Disassembler.cpp b/lib/Target/X86/Disassembler/X86Disassembler.cpp index c58254ae38c1..62312777318e 100644 --- a/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -103,7 +103,7 @@ StringRef llvm::X86Disassembler::GetInstrName(unsigned Opcode, return MII->getName(Opcode); } -#define debug(s) DEBUG(Debug(__FILE__, __LINE__, s)); +#define debug(s) LLVM_DEBUG(Debug(__FILE__, __LINE__, s)); namespace llvm { @@ -247,6 +247,8 @@ MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction( // It should not be 'pause' f3 90 InternalInstr.opcode != 0x90) Flags |= X86::IP_HAS_REPEAT; + if (InternalInstr.hasLockPrefix) + Flags |= X86::IP_HAS_LOCK; } Instr.setFlags(Flags); } @@ -265,13 +267,10 @@ MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction( /// @param reg - The Reg to append. static void translateRegister(MCInst &mcInst, Reg reg) { #define ENTRY(x) X86::x, - uint8_t llvmRegnums[] = { - ALL_REGS - 0 - }; + static constexpr MCPhysReg llvmRegnums[] = {ALL_REGS}; #undef ENTRY - uint8_t llvmRegnum = llvmRegnums[reg]; + MCPhysReg llvmRegnum = llvmRegnums[reg]; mcInst.addOperand(MCOperand::createReg(llvmRegnum)); } @@ -664,8 +663,6 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate, case TYPE_ZMM: mcInst.addOperand(MCOperand::createReg(X86::ZMM0 + (immediate >> 4))); return; - case TYPE_BNDR: - mcInst.addOperand(MCOperand::createReg(X86::BND0 + (immediate >> 4))); default: // operand is 64 bits wide. Do nothing. break; @@ -761,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) { @@ -780,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); @@ -797,12 +809,14 @@ static bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn, tryAddingPcLoadReferenceComment(insn.startLocation + insn.displacementOffset, insn.displacement + pcrel, Dis); - baseReg = MCOperand::createReg(X86::RIP); // Section 2.2.1.6 + // Section 2.2.1.6 + baseReg = MCOperand::createReg(insn.addressSize == 4 ? X86::EIP : + 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); @@ -821,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"); |