30 #define GET_REGINFO_ENUM
31 #include "X86GenRegisterInfo.inc"
32 #define GET_INSTRINFO_ENUM
33 #include "X86GenInstrInfo.inc"
36 using namespace llvm::X86Disassembler;
41 dbgs() << file <<
":" << line <<
": " << s;
49 #define debug(s) DEBUG(x86DisassemblerDebug(__FILE__, __LINE__, s));
80 X86GenericDisassembler::~X86GenericDisassembler() {
91 static int regionReader(
const void* arg, uint8_t* byte, uint64_t address) {
93 return region->
readByte(address, byte);
107 vStream << log <<
"\n";
126 if (&vStream == &
nulls())
131 (
const void*)®ion,
143 size = internalInstr.
length;
159 #define ENTRY(x) X86::x,
160 uint8_t llvmRegnums[] = {
166 uint8_t llvmRegnum = llvmRegnums[reg];
190 uint64_t Address, uint64_t Offset,
205 const void *Decoder) {
226 if (type == TYPE_RELv) {
235 immediate |= ~(0xffull);
238 if(immediate & 0x8000)
239 immediate |= ~(0xffffull);
242 if(immediate & 0x80000000)
243 immediate |= ~(0xffffffffull);
250 else if (type == TYPE_IMM8 || type == TYPE_IMM16 || type == TYPE_IMM32 ||
251 type == TYPE_IMM64) {
259 if (Opcode != X86::BLENDPSrri && Opcode != X86::BLENDPDrri &&
260 Opcode != X86::PBLENDWrri && Opcode != X86::MPSADBWrri &&
261 Opcode != X86::DPPSrri && Opcode != X86::DPPDrri &&
262 Opcode != X86::INSERTPSrr && Opcode != X86::VBLENDPSYrri &&
263 Opcode != X86::VBLENDPSYrmi && Opcode != X86::VBLENDPDYrri &&
264 Opcode != X86::VBLENDPDYrmi && Opcode != X86::VPBLENDWrri &&
265 Opcode != X86::VMPSADBWrri && Opcode != X86::VDPPSYrri &&
266 Opcode != X86::VDPPSYrmi && Opcode != X86::VDPPDrri &&
267 Opcode != X86::VINSERTPSrr)
269 immediate |= ~(0xffull);
272 if(immediate & 0x8000)
273 immediate |= ~(0xffffull);
276 if(immediate & 0x80000000)
277 immediate |= ~(0xffffffffull);
300 immediate |= ~(0xffull);
306 if(immediate & 0x80000000)
307 immediate |= ~(0xffffffffull);
328 if (insn.
eaBase == EA_BASE_sib || insn.
eaBase == EA_BASE_sib64) {
329 debug(
"A R/M register operand may not have a SIB byte");
335 debug(
"Unexpected EA base register");
338 debug(
"EA_BASE_NONE for ModR/M base");
340 #define ENTRY(x) case EA_BASE_##x:
343 debug(
"A R/M register operand may not have a base; "
344 "the operand must be a register.");
348 mcInst.addOperand(MCOperand::CreateReg(X86::x)); break;
385 if (insn.
eaBase == EA_BASE_sib || insn.
eaBase == EA_BASE_sib64) {
389 debug(
"Unexpected sibBase");
393 baseReg = MCOperand::CreateReg(X86::x); break;
408 bool IndexIs128 = (Opcode == X86::VGATHERDPDrm ||
409 Opcode == X86::VGATHERDPDYrm ||
410 Opcode == X86::VGATHERQPDrm ||
411 Opcode == X86::VGATHERDPSrm ||
412 Opcode == X86::VGATHERQPSrm ||
413 Opcode == X86::VPGATHERDQrm ||
414 Opcode == X86::VPGATHERDQYrm ||
415 Opcode == X86::VPGATHERQQrm ||
416 Opcode == X86::VPGATHERDDrm ||
417 Opcode == X86::VPGATHERQDrm);
418 bool IndexIs256 = (Opcode == X86::VGATHERQPDYrm ||
419 Opcode == X86::VGATHERDPSYrm ||
420 Opcode == X86::VGATHERQPSYrm ||
421 Opcode == X86::VPGATHERQQYrm ||
422 Opcode == X86::VPGATHERDDYrm ||
423 Opcode == X86::VPGATHERQDYrm);
424 if (IndexIs128 || IndexIs256) {
425 unsigned IndexOffset = insn.
sibIndex -
426 (insn.
addressSize == 8 ? SIB_INDEX_RAX:SIB_INDEX_EAX);
427 SIBIndex IndexBase = IndexIs256 ? SIB_INDEX_YMM0 : SIB_INDEX_XMM0;
435 debug(
"Unexpected sibIndex");
438 case SIB_INDEX_##x: \
439 indexReg = MCOperand::CreateReg(X86::x); break;
456 debug(
"EA_BASE_NONE and EA_DISP_NONE for ModR/M base");
492 debug(
"Unexpected eaBase");
500 baseReg = MCOperand::CreateReg(X86::x); break;
503 #define ENTRY(x) case EA_REG_##x:
506 debug(
"A R/M memory operand may not be a register; "
507 "the base field must be a base.");
550 switch (operand.
type) {
552 debug(
"Unexpected type for a R/M operand");
569 case TYPE_CONTROLREG:
603 debug(
"Invalid FP stack position");
624 debug(
"Unhandled operand encoding during translation");
637 debug(
"Translation of code offsets isn't supported.");
681 debug(
"Instruction has no specification");
690 if(mcInst.
getOpcode() == X86::REP_PREFIX)
692 else if(mcInst.
getOpcode() == X86::REPNE_PREFIX)
void(* dlog_t)(void *arg, const char *log)
static MCDisassembler * createX86_64Disassembler(const Target &T, const MCSubtargetInfo &STI)
virtual int readByte(uint64_t address, uint8_t *ptr) const =0
static bool translateInstruction(MCInst &target, InternalInstruction &source, const MCDisassembler *Dis)
static MCOperand CreateReg(unsigned Reg)
raw_ostream * CommentStream
static bool translateFPRegister(MCInst &mcInst, uint8_t stackPos)
static int regionReader(const void *arg, uint8_t *byte, uint64_t address)
static void translateImmediate(MCInst &mcInst, uint64_t immediate, const OperandSpecifier &operand, InternalInstruction &insn, const MCDisassembler *Dis)
uint8_t displacementOffset
X86GenericDisassembler(const MCSubtargetInfo &STI, DisassemblerMode mode, const MCInstrInfo *MII)
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
MCInstrInfo * createMCInstrInfo() const
const struct InstructionSpecifier * spec
static void translateRegister(MCInst &mcInst, Reg reg)
static void tryAddingPcLoadReferenceComment(uint64_t Address, uint64_t Value, const void *Decoder)
static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand, InternalInstruction &insn, const MCDisassembler *Dis)
uint8_t numImmediatesTranslated
void x86DisassemblerDebug(const char *file, unsigned line, const char *s)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
const char * getName(unsigned Opcode) const
getName - Returns the name for the instructions with the given opcode.
const struct OperandSpecifier * operands
bool tryAddingSymbolicOperand(MCInst &Inst, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, uint64_t InstSize) const
DecodeStatus getInstruction(MCInst &instr, uint64_t &size, const MemoryObject ®ion, uint64_t address, raw_ostream &vStream, raw_ostream &cStream) const
getInstruction - See MCDisassembler.
void setOpcode(unsigned Op)
static bool translateRM(MCInst &mcInst, const OperandSpecifier &operand, InternalInstruction &insn, const MCDisassembler *Dis)
static bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn, const MCDisassembler *Dis)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
void LLVMInitializeX86Disassembler()
unsigned getOpcode() const
EADisplacement eaDisplacement
static bool translateRMRegister(MCInst &mcInst, InternalInstruction &insn)
static MCOperand CreateImm(int64_t Val)
static void logger(void *arg, const char *log)
static bool isBranch(unsigned Opcode)
LLVM Value Representation.
const char * x86DisassemblerGetInstrName(unsigned Opcode, const void *mii)
static MCDisassembler * createX86_32Disassembler(const Target &T, const MCSubtargetInfo &STI)
raw_ostream & nulls()
nulls() - This returns a reference to a raw_ostream which discards output.
void addOperand(const MCOperand &Op)
static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, uint64_t Address, uint64_t Offset, uint64_t Width, MCInst &MI, const MCDisassembler *Dis)
void tryAddingPcLoadReferenceComment(int64_t Value, uint64_t Address) const
SegmentOverride segmentOverride
int decodeInstruction(struct InternalInstruction *insn, byteReader_t reader, const void *readerArg, dlog_t logger, void *loggerArg, const void *miiArg, uint64_t startLoc, DisassemblerMode mode)