From 7fb35a2fd83f5deadefcb230669b07e1d5b98137 Mon Sep 17 00:00:00 2001 From: Sean Callanan Date: Tue, 22 Dec 2009 21:12:55 +0000 Subject: Fixes to the X86 disassembler: Made LEA memory operands emit only 4 MCInst operands. Made the scale operand equal 1 for instructions that have no SIB byte. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91919 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/Disassembler/X86Disassembler.cpp | 21 ++++++++++++++++----- .../X86/Disassembler/X86DisassemblerDecoderCommon.h | 1 + utils/TableGen/X86RecognizableInstr.cpp | 6 +++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/Target/X86/Disassembler/X86Disassembler.cpp b/lib/Target/X86/Disassembler/X86Disassembler.cpp index c6622b7b5e..a31686027a 100644 --- a/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -183,8 +183,12 @@ static void translateRMRegister(MCInst &mcInst, /// @param mcInst - The MCInst to append to. /// @param insn - The instruction to extract Mod, R/M, and SIB fields /// from. +/// @param sr - Whether or not to emit the segment register. The +/// LEA instruction does not expect a segment-register +/// operand. static void translateRMMemory(MCInst &mcInst, - InternalInstruction &insn) { + InternalInstruction &insn, + bool sr) { // Addresses in an MCInst are represented as five operands: // 1. basereg (register) The R/M base, or (if there is a SIB) the // SIB base @@ -209,7 +213,7 @@ static void translateRMMemory(MCInst &mcInst, default: llvm_unreachable("Unexpected sibBase"); #define ENTRY(x) \ - case SIB_BASE_##x: \ + case SIB_BASE_##x: \ baseReg = MCOperand::CreateReg(X86::x); break; ALL_SIB_BASES #undef ENTRY @@ -222,7 +226,7 @@ static void translateRMMemory(MCInst &mcInst, switch (insn.sibIndex) { default: llvm_unreachable("Unexpected sibIndex"); -#define ENTRY(x) \ +#define ENTRY(x) \ case SIB_INDEX_##x: \ indexReg = MCOperand::CreateReg(X86::x); break; EA_BASES_32BIT @@ -286,6 +290,8 @@ static void translateRMMemory(MCInst &mcInst, break; } } + + scaleAmount = MCOperand::CreateImm(1); } displacement = MCOperand::CreateImm(insn.displacement); @@ -306,7 +312,9 @@ static void translateRMMemory(MCInst &mcInst, mcInst.addOperand(scaleAmount); mcInst.addOperand(indexReg); mcInst.addOperand(displacement); - mcInst.addOperand(segmentReg); + + if (sr) + mcInst.addOperand(segmentReg); } /// translateRM - Translates an operand stored in the R/M (and possibly SIB) @@ -356,7 +364,10 @@ static void translateRM(MCInst &mcInst, case TYPE_M1616: case TYPE_M1632: case TYPE_M1664: - translateRMMemory(mcInst, insn); + translateRMMemory(mcInst, insn, true); + break; + case TYPE_LEA: + translateRMMemory(mcInst, insn, false); break; } } diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h index b226257c1e..c213f89ebc 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h @@ -245,6 +245,7 @@ struct ContextDecision { ENUM_ENTRY(TYPE_M16, "2-byte") \ ENUM_ENTRY(TYPE_M32, "4-byte") \ ENUM_ENTRY(TYPE_M64, "8-byte") \ + ENUM_ENTRY(TYPE_LEA, "Effective address") \ ENUM_ENTRY(TYPE_M128, "16-byte (SSE/SSE2)") \ ENUM_ENTRY(TYPE_M1616, "2+2-byte segment+offset address") \ ENUM_ENTRY(TYPE_M1632, "2+4-byte") \ diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index edc75e63d2..2b6e30d93d 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -817,9 +817,9 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("brtarget", TYPE_RELv) TYPE("brtarget8", TYPE_REL8) TYPE("f80mem", TYPE_M80FP) - TYPE("lea32mem", TYPE_M32) - TYPE("lea64_32mem", TYPE_M64) - TYPE("lea64mem", TYPE_M64) + TYPE("lea32mem", TYPE_LEA) + TYPE("lea64_32mem", TYPE_LEA) + TYPE("lea64mem", TYPE_LEA) TYPE("VR64", TYPE_MM64) TYPE("i64imm", TYPE_IMMv) TYPE("opaque32mem", TYPE_M1616) -- cgit v1.2.3