X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FDisassembler%2FX86Disassembler.cpp;h=5658cf8df54b75c62b732b97eda12ec1ffa6f7ac;hb=c848b1bbcf88ab5d8318d990612fb1fda206ea3d;hp=82af6fa497442b47cb2118e3e433fc8ffec20f5e;hpb=c18f4efc5dd24adcc653806455fc7ae8508e9c66;p=oota-llvm.git diff --git a/lib/Target/X86/Disassembler/X86Disassembler.cpp b/lib/Target/X86/Disassembler/X86Disassembler.cpp index 82af6fa4974..5658cf8df54 100644 --- a/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -27,26 +27,30 @@ #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" +using namespace llvm; +using namespace llvm::X86Disassembler; + +#define DEBUG_TYPE "x86-disassembler" + #define GET_REGINFO_ENUM #include "X86GenRegisterInfo.inc" #define GET_INSTRINFO_ENUM #include "X86GenInstrInfo.inc" +#define GET_SUBTARGETINFO_ENUM +#include "X86GenSubtargetInfo.inc" -using namespace llvm; -using namespace llvm::X86Disassembler; - -void x86DisassemblerDebug(const char *file, - unsigned line, - const char *s) { +void llvm::X86Disassembler::Debug(const char *file, unsigned line, + const char *s) { dbgs() << file << ":" << line << ": " << s; } -const char *x86DisassemblerGetInstrName(unsigned Opcode, const void *mii) { +const char *llvm::X86Disassembler::GetInstrName(unsigned Opcode, + const void *mii) { const MCInstrInfo *MII = static_cast(mii); return MII->getName(Opcode); } -#define debug(s) DEBUG(x86DisassemblerDebug(__FILE__, __LINE__, s)); +#define debug(s) DEBUG(Debug(__FILE__, __LINE__, s)); namespace llvm { @@ -72,13 +76,25 @@ static bool translateInstruction(MCInst &target, InternalInstruction &source, const MCDisassembler *Dis); -X86GenericDisassembler::X86GenericDisassembler(const MCSubtargetInfo &STI, - DisassemblerMode mode, - const MCInstrInfo *MII) - : MCDisassembler(STI), MII(MII), fMode(mode) {} - -X86GenericDisassembler::~X86GenericDisassembler() { - delete MII; +X86GenericDisassembler::X86GenericDisassembler( + const MCSubtargetInfo &STI, + MCContext &Ctx, + std::unique_ptr MII) + : MCDisassembler(STI, Ctx), MII(std::move(MII)) { + switch (STI.getFeatureBits() & + (X86::Mode16Bit | X86::Mode32Bit | X86::Mode64Bit)) { + case X86::Mode16Bit: + fMode = MODE_16BIT; + break; + case X86::Mode32Bit: + fMode = MODE_32BIT; + break; + case X86::Mode64Bit: + fMode = MODE_64BIT; + break; + default: + llvm_unreachable("Invalid CPU mode"); + } } /// regionReader - a callback function that wraps the readByte method from @@ -124,14 +140,14 @@ X86GenericDisassembler::getInstruction(MCInst &instr, dlog_t loggerFn = logger; if (&vStream == &nulls()) - loggerFn = 0; // Disable logging completely if it's going to nulls(). + loggerFn = nullptr; // Disable logging completely if it's going to nulls(). int ret = decodeInstruction(&internalInstr, regionReader, (const void*)®ion, loggerFn, (void*)&vStream, - (const void*)MII, + (const void*)MII.get(), address, fMode); @@ -207,6 +223,61 @@ static void tryAddingPcLoadReferenceComment(uint64_t Address, uint64_t Value, Dis->tryAddingPcLoadReferenceComment(Value, Address); } +static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = { + 0, // SEG_OVERRIDE_NONE + X86::CS, + X86::SS, + X86::DS, + X86::ES, + X86::FS, + X86::GS +}; + +/// translateSrcIndex - Appends a source index operand to an MCInst. +/// +/// @param mcInst - The MCInst to append to. +/// @param insn - The internal instruction. +static bool translateSrcIndex(MCInst &mcInst, InternalInstruction &insn) { + unsigned baseRegNo; + + if (insn.mode == MODE_64BIT) + baseRegNo = insn.prefixPresent[0x67] ? X86::ESI : X86::RSI; + else if (insn.mode == MODE_32BIT) + baseRegNo = insn.prefixPresent[0x67] ? X86::SI : X86::ESI; + else { + assert(insn.mode == MODE_16BIT); + baseRegNo = insn.prefixPresent[0x67] ? X86::ESI : X86::SI; + } + MCOperand baseReg = MCOperand::CreateReg(baseRegNo); + mcInst.addOperand(baseReg); + + MCOperand segmentReg; + segmentReg = MCOperand::CreateReg(segmentRegnums[insn.segmentOverride]); + mcInst.addOperand(segmentReg); + return false; +} + +/// translateDstIndex - Appends a destination index operand to an MCInst. +/// +/// @param mcInst - The MCInst to append to. +/// @param insn - The internal instruction. + +static bool translateDstIndex(MCInst &mcInst, InternalInstruction &insn) { + unsigned baseRegNo; + + if (insn.mode == MODE_64BIT) + baseRegNo = insn.prefixPresent[0x67] ? X86::EDI : X86::RDI; + else if (insn.mode == MODE_32BIT) + baseRegNo = insn.prefixPresent[0x67] ? X86::DI : X86::EDI; + else { + assert(insn.mode == MODE_16BIT); + baseRegNo = insn.prefixPresent[0x67] ? X86::EDI : X86::DI; + } + MCOperand baseReg = MCOperand::CreateReg(baseRegNo); + mcInst.addOperand(baseReg); + return false; +} + /// translateImmediate - Appends an immediate operand to an MCInst. /// /// @param mcInst - The MCInst to append to. @@ -231,22 +302,24 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate, default: break; case 1: - type = TYPE_MOFFS8; + if(immediate & 0x80) + immediate |= ~(0xffull); break; case 2: - type = TYPE_MOFFS16; + if(immediate & 0x8000) + immediate |= ~(0xffffull); break; case 4: - type = TYPE_MOFFS32; + if(immediate & 0x80000000) + immediate |= ~(0xffffffffull); break; case 8: - type = TYPE_MOFFS64; break; } } // By default sign-extend all X86 immediates based on their encoding. else if (type == TYPE_IMM8 || type == TYPE_IMM16 || type == TYPE_IMM32 || - type == TYPE_IMM64) { + type == TYPE_IMM64 || type == TYPE_IMMv) { uint32_t Opcode = mcInst.getOpcode(); switch (operand.encoding) { default: @@ -263,16 +336,18 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate, Opcode != X86::VMPSADBWrri && Opcode != X86::VDPPSYrri && Opcode != X86::VDPPSYrmi && Opcode != X86::VDPPDrri && Opcode != X86::VINSERTPSrr) - type = TYPE_MOFFS8; + if(immediate & 0x80) + immediate |= ~(0xffull); break; case ENCODING_IW: - type = TYPE_MOFFS16; + if(immediate & 0x8000) + immediate |= ~(0xffffull); break; case ENCODING_ID: - type = TYPE_MOFFS32; + if(immediate & 0x80000000) + immediate |= ~(0xffffffffull); break; case ENCODING_IO: - type = TYPE_MOFFS64; break; } } @@ -292,34 +367,32 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate, case TYPE_REL8: isBranch = true; pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize; - // fall through to sign extend the immediate if needed. - case TYPE_MOFFS8: if(immediate & 0x80) immediate |= ~(0xffull); break; - case TYPE_MOFFS16: - if(immediate & 0x8000) - immediate |= ~(0xffffull); - break; case TYPE_REL32: case TYPE_REL64: isBranch = true; pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize; - // fall through to sign extend the immediate if needed. - case TYPE_MOFFS32: if(immediate & 0x80000000) immediate |= ~(0xffffffffull); break; - case TYPE_MOFFS64: default: // operand is 64 bits wide. Do nothing. break; } - + if(!tryAddingSymbolicOperand(immediate + pcrel, isBranch, insn.startLocation, insn.immediateOffset, insn.immediateSize, mcInst, Dis)) mcInst.addOperand(MCOperand::CreateImm(immediate)); + + if (type == TYPE_MOFFS8 || type == TYPE_MOFFS16 || + type == TYPE_MOFFS32 || type == TYPE_MOFFS64) { + MCOperand segmentReg; + segmentReg = MCOperand::CreateReg(segmentRegnums[insn.segmentOverride]); + mcInst.addOperand(segmentReg); + } } /// translateRMRegister - Translates a register stored in the R/M field of the @@ -423,13 +496,22 @@ static bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn, bool IndexIs256 = (Opcode == X86::VGATHERQPDYrm || Opcode == X86::VGATHERDPSYrm || Opcode == X86::VGATHERQPSYrm || + Opcode == X86::VGATHERDPDZrm || + Opcode == X86::VPGATHERDQZrm || Opcode == X86::VPGATHERQQYrm || Opcode == X86::VPGATHERDDYrm || Opcode == X86::VPGATHERQDYrm); - if (IndexIs128 || IndexIs256) { + bool IndexIs512 = (Opcode == X86::VGATHERQPDZrm || + Opcode == X86::VGATHERDPSZrm || + Opcode == X86::VGATHERQPSZrm || + Opcode == X86::VPGATHERQQZrm || + Opcode == X86::VPGATHERDDZrm || + Opcode == X86::VPGATHERQDZrm); + if (IndexIs128 || IndexIs256 || IndexIs512) { unsigned IndexOffset = insn.sibIndex - (insn.addressSize == 8 ? SIB_INDEX_RAX:SIB_INDEX_EAX); - SIBIndex IndexBase = IndexIs256 ? SIB_INDEX_YMM0 : SIB_INDEX_XMM0; + SIBIndex IndexBase = IndexIs512 ? SIB_INDEX_ZMM0 : + IndexIs256 ? SIB_INDEX_YMM0 : SIB_INDEX_XMM0; insn.sibIndex = (SIBIndex)(IndexBase + (insn.sibIndex == SIB_INDEX_NONE ? 4 : IndexOffset)); } @@ -518,17 +600,7 @@ static bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn, } displacement = MCOperand::CreateImm(insn.displacement); - - static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = { - 0, // SEG_OVERRIDE_NONE - X86::CS, - X86::SS, - X86::DS, - X86::ES, - X86::FS, - X86::GS - }; - + segmentReg = MCOperand::CreateReg(segmentRegnums[insn.segmentOverride]); mcInst.addOperand(baseReg); @@ -570,6 +642,9 @@ static bool translateRM(MCInst &mcInst, const OperandSpecifier &operand, case TYPE_XMM128: case TYPE_XMM256: case TYPE_XMM512: + case TYPE_VK1: + case TYPE_VK8: + case TYPE_VK16: case TYPE_DEBUGREG: case TYPE_CONTROLREG: return translateRMRegister(mcInst, insn); @@ -601,16 +676,25 @@ static bool translateRM(MCInst &mcInst, const OperandSpecifier &operand, /// /// @param mcInst - The MCInst to append to. /// @param stackPos - The stack position to translate. -/// @return - 0 on success; nonzero otherwise. -static bool translateFPRegister(MCInst &mcInst, - uint8_t stackPos) { - if (stackPos >= 8) { - debug("Invalid FP stack position"); +static void translateFPRegister(MCInst &mcInst, + uint8_t stackPos) { + mcInst.addOperand(MCOperand::CreateReg(X86::ST0 + stackPos)); +} + +/// translateMaskRegister - Translates a 3-bit mask register number to +/// LLVM form, and appends it to an MCInst. +/// +/// @param mcInst - The MCInst to append to. +/// @param maskRegNum - Number of mask register from 0 to 7. +/// @return - false on success; true otherwise. +static bool translateMaskRegister(MCInst &mcInst, + uint8_t maskRegNum) { + if (maskRegNum >= 8) { + debug("Invalid mask register number"); return true; } - - mcInst.addOperand(MCOperand::CreateReg(X86::ST0 + stackPos)); + mcInst.addOperand(MCOperand::CreateReg(X86::K0 + maskRegNum)); return false; } @@ -631,6 +715,8 @@ static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand, case ENCODING_REG: translateRegister(mcInst, insn.reg); return false; + case ENCODING_WRITEMASK: + return translateMaskRegister(mcInst, insn.writemask); case ENCODING_RM: return translateRM(mcInst, operand, insn, Dis); case ENCODING_CB: @@ -653,17 +739,20 @@ static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand, insn, Dis); return false; + case ENCODING_SI: + return translateSrcIndex(mcInst, insn); + case ENCODING_DI: + return translateDstIndex(mcInst, insn); case ENCODING_RB: case ENCODING_RW: case ENCODING_RD: case ENCODING_RO: - translateRegister(mcInst, insn.opcodeRegister); - return false; - case ENCODING_I: - return translateFPRegister(mcInst, insn.opcodeModifier); case ENCODING_Rv: translateRegister(mcInst, insn.opcodeRegister); return false; + case ENCODING_FP: + translateFPRegister(mcInst, insn.modRM & 7); + return false; case ENCODING_VVVV: translateRegister(mcInst, insn.vvvv); return false; @@ -713,22 +802,17 @@ static bool translateInstruction(MCInst &mcInst, return false; } -static MCDisassembler *createX86_32Disassembler(const Target &T, - const MCSubtargetInfo &STI) { - return new X86Disassembler::X86GenericDisassembler(STI, MODE_32BIT, - T.createMCInstrInfo()); -} - -static MCDisassembler *createX86_64Disassembler(const Target &T, - const MCSubtargetInfo &STI) { - return new X86Disassembler::X86GenericDisassembler(STI, MODE_64BIT, - T.createMCInstrInfo()); +static MCDisassembler *createX86Disassembler(const Target &T, + const MCSubtargetInfo &STI, + MCContext &Ctx) { + std::unique_ptr MII(T.createMCInstrInfo()); + return new X86Disassembler::X86GenericDisassembler(STI, Ctx, std::move(MII)); } extern "C" void LLVMInitializeX86Disassembler() { // Register the disassembler. TargetRegistry::RegisterMCDisassembler(TheX86_32Target, - createX86_32Disassembler); + createX86Disassembler); TargetRegistry::RegisterMCDisassembler(TheX86_64Target, - createX86_64Disassembler); + createX86Disassembler); }