131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- X86Disassembler.cpp - Disassembler for x86 and x86_64 -------------===// 25f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar// 35f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar// The LLVM Compiler Infrastructure 45f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar// 55f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar// This file is distributed under the University of Illinois Open Source 65f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar// License. See LICENSE.TXT for details. 75f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar// 85f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar//===----------------------------------------------------------------------===// 98ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// This file is part of the X86 Disassembler. 118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// It contains code to translate the data produced by the decoder into 128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// MCInsts. 138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// Documentation for the disassembler can be found in X86Disassembler.h. 148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan//===----------------------------------------------------------------------===// 165f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar 178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#include "X86Disassembler.h" 188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#include "X86DisassemblerDecoder.h" 19b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby#include "llvm/MC/MCContext.h" 205f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar#include "llvm/MC/MCDisassembler.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCExpr.h" 228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#include "llvm/MC/MCInst.h" 23953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer#include "llvm/MC/MCInstrInfo.h" 24b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy#include "llvm/MC/MCSubtargetInfo.h" 25a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan#include "llvm/Support/Debug.h" 268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#include "llvm/Support/MemoryObject.h" 273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#include "llvm/Support/raw_ostream.h" 290122c9051a0157908e3f4e1c604435339ac4761dSean Callanan 3073f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng#define GET_REGINFO_ENUM 3173f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng#include "X86GenRegisterInfo.inc" 32d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby#define GET_INSTRINFO_ENUM 33d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby#include "X86GenInstrInfo.inc" 340122c9051a0157908e3f4e1c604435339ac4761dSean Callanan 355f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbarusing namespace llvm; 368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananusing namespace llvm::X86Disassembler; 378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 38a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callananvoid x86DisassemblerDebug(const char *file, 39a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan unsigned line, 40a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan const char *s) { 41a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan dbgs() << file << ":" << line << ": " << s; 42a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan} 43a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan 44b438615abdc826a2fef33895b50dc60e3f39f988Roman Divackyconst char *x86DisassemblerGetInstrName(unsigned Opcode, const void *mii) { 45953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer const MCInstrInfo *MII = static_cast<const MCInstrInfo *>(mii); 46953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer return MII->getName(Opcode); 47953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer} 48953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer 49a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan#define debug(s) DEBUG(x86DisassemblerDebug(__FILE__, __LINE__, s)); 50a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan 518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanannamespace llvm { 528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// Fill-ins to make the compiler happy. These constants are never actually 548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// assigned; they are just filler to make an automatically-generated switch 558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// statement work. 568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanannamespace X86 { 578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan enum { 588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan BX_SI = 500, 598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan BX_DI = 501, 608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan BP_SI = 502, 618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan BP_DI = 503, 628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan sib = 504, 638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan sib64 = 505 648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan }; 658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 670122c9051a0157908e3f4e1c604435339ac4761dSean Callananextern Target TheX86_32Target, TheX86_64Target; 680122c9051a0157908e3f4e1c604435339ac4761dSean Callanan 698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 71a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callananstatic bool translateInstruction(MCInst &target, 72b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby InternalInstruction &source, 73b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby const MCDisassembler *Dis); 748ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 75953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin KramerX86GenericDisassembler::X86GenericDisassembler(const MCSubtargetInfo &STI, 76953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer DisassemblerMode mode, 77953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer const MCInstrInfo *MII) 78953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer : MCDisassembler(STI), MII(MII), fMode(mode) {} 798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananX86GenericDisassembler::~X86GenericDisassembler() { 81953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer delete MII; 828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// regionReader - a callback function that wraps the readByte method from 858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// MemoryObject. 868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param arg - The generic callback parameter. In this case, this should 888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// be a pointer to a MemoryObject. 898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param byte - A pointer to the byte to be read. 908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param address - The address to be read. 91b438615abdc826a2fef33895b50dc60e3f39f988Roman Divackystatic int regionReader(const void* arg, uint8_t* byte, uint64_t address) { 92b438615abdc826a2fef33895b50dc60e3f39f988Roman Divacky const MemoryObject* region = static_cast<const MemoryObject*>(arg); 938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return region->readByte(address, byte); 948ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// logger - a callback function that wraps the operator<< method from 978ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// raw_ostream. 988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param arg - The generic callback parameter. This should be a pointe 1008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// to a raw_ostream. 1018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param log - A string to be logged. logger() adds a newline. 1028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananstatic void logger(void* arg, const char* log) { 1038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (!arg) 1048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return; 1058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan raw_ostream &vStream = *(static_cast<raw_ostream*>(arg)); 1078ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan vStream << log << "\n"; 1088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 1098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 1118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// Public interface for the disassembler 1128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 1138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 11483e3f67fb68d497b600da83a62f000fcce7868a9Owen AndersonMCDisassembler::DecodeStatus 11583e3f67fb68d497b600da83a62f000fcce7868a9Owen AndersonX86GenericDisassembler::getInstruction(MCInst &instr, 11683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson uint64_t &size, 117adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff const MemoryObject ®ion, 11883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson uint64_t address, 11998c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson raw_ostream &vStream, 12098c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson raw_ostream &cStream) const { 121b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby CommentStream = &cStream; 122b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby 1238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan InternalInstruction internalInstr; 12415c9a1f60c2e9d9cb854d5c0072755be91d1cc96Benjamin Kramer 12515c9a1f60c2e9d9cb854d5c0072755be91d1cc96Benjamin Kramer dlog_t loggerFn = logger; 12615c9a1f60c2e9d9cb854d5c0072755be91d1cc96Benjamin Kramer if (&vStream == &nulls()) 12715c9a1f60c2e9d9cb854d5c0072755be91d1cc96Benjamin Kramer loggerFn = 0; // Disable logging completely if it's going to nulls(). 1288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan int ret = decodeInstruction(&internalInstr, 1308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan regionReader, 131b438615abdc826a2fef33895b50dc60e3f39f988Roman Divacky (const void*)®ion, 13215c9a1f60c2e9d9cb854d5c0072755be91d1cc96Benjamin Kramer loggerFn, 1338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (void*)&vStream, 134b438615abdc826a2fef33895b50dc60e3f39f988Roman Divacky (const void*)MII, 1358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan address, 1368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan fMode); 1378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 138a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan if (ret) { 1398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan size = internalInstr.readerCursor - address; 14083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson return Fail; 1418ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 1428ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else { 1438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan size = internalInstr.length; 144b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby return (!translateInstruction(instr, internalInstr, this)) ? 145b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby Success : Fail; 1468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 1478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 1488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 1508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// Private code that translates from struct InternalInstructions to MCInsts. 1518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 1528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// translateRegister - Translates an internal register to the appropriate LLVM 1548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// register, and appends it as an operand to an MCInst. 1558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 1568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param mcInst - The MCInst to append to. 1578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param reg - The Reg to append. 1588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananstatic void translateRegister(MCInst &mcInst, Reg reg) { 1598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define ENTRY(x) X86::x, 1608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan uint8_t llvmRegnums[] = { 1618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ALL_REGS 1628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 0 1638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan }; 1648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#undef ENTRY 1658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan uint8_t llvmRegnum = llvmRegnums[reg]; 1678ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan mcInst.addOperand(MCOperand::CreateReg(llvmRegnum)); 1688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 1698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 170b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 171b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// immediate Value in the MCInst. 172b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// 173b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// @param Value - The immediate Value, has had any PC adjustment made by 174b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// the caller. 175b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// @param isBranch - If the instruction is a branch instruction 176b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// @param Address - The starting address of the instruction 177b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// @param Offset - The byte offset to this immediate in the instruction 178b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// @param Width - The byte width of this immediate in the instruction 179b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// 180b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// If the getOpInfo() function was set when setupForSymbolicDisassembly() was 181b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// called then that function is called to get any symbolic information for the 182b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// immediate in the instruction using the Address, Offset and Width. If that 183b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// returns non-zero then the symbolic information it returns is used to create 184b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// an MCExpr and that is added as an operand to the MCInst. If getOpInfo() 185b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// returns zero and isBranch is true then a symbol look up for immediate Value 186b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// is done and if a symbol is found an MCExpr is created with that, else 187b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// an MCExpr with the immediate Value is created. This function returns true 188b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby/// if it adds an operand to the MCInst and false otherwise. 189b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderbystatic bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 190b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby uint64_t Address, uint64_t Offset, 191b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby uint64_t Width, MCInst &MI, 192b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby const MCDisassembler *Dis) { 1932c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 1942c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Offset, Width); 195b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby} 196b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby 1978bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being 1988bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby/// referenced by a load instruction with the base register that is the rip. 1998bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby/// These can often be addresses in a literal pool. The Address of the 2008bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby/// instruction and its immediate Value are used to determine the address 2018bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby/// being referenced in the literal pool entry. The SymbolLookUp call back will 2028bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby/// return a pointer to a literal 'C' string if the referenced address is an 2038bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby/// address into a section with 'C' string literals. 2048bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderbystatic void tryAddingPcLoadReferenceComment(uint64_t Address, uint64_t Value, 2058bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby const void *Decoder) { 2068bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 2072c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Dis->tryAddingPcLoadReferenceComment(Value, Address); 2088bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby} 2098bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby 2108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// translateImmediate - Appends an immediate operand to an MCInst. 2118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 2128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param mcInst - The MCInst to append to. 2138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param immediate - The immediate value to append. 214be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan/// @param operand - The operand, as stored in the descriptor table. 215be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan/// @param insn - The internal instruction. 2164d1dca92bd6d4aad7121e28c7ffc93c0a6a187d7Benjamin Kramerstatic void translateImmediate(MCInst &mcInst, uint64_t immediate, 2174d1dca92bd6d4aad7121e28c7ffc93c0a6a187d7Benjamin Kramer const OperandSpecifier &operand, 218b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby InternalInstruction &insn, 219b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby const MCDisassembler *Dis) { 220be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan // Sign-extend the immediate if necessary. 221be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan 222991271d9c454c9d599b63e4ebdd27b546e1782a1Craig Topper OperandType type = (OperandType)operand.type; 223be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan 224c007eff5365d4216bcb243a3eea9c372267d0964Kevin Enderby bool isBranch = false; 225c007eff5365d4216bcb243a3eea9c372267d0964Kevin Enderby uint64_t pcrel = 0; 226be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan if (type == TYPE_RELv) { 227c007eff5365d4216bcb243a3eea9c372267d0964Kevin Enderby isBranch = true; 228c007eff5365d4216bcb243a3eea9c372267d0964Kevin Enderby pcrel = insn.startLocation + 22916b7dd64e91f1b05b40ebfeb64b49f3ac17cb426Kevin Enderby insn.immediateOffset + insn.immediateSize; 230be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan switch (insn.displacementSize) { 231be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan default: 232be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan break; 23389e59e6343303696e14d4c134582dda083cf7408Sean Callanan case 1: 234be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan type = TYPE_MOFFS8; 235be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan break; 23689e59e6343303696e14d4c134582dda083cf7408Sean Callanan case 2: 237be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan type = TYPE_MOFFS16; 238be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan break; 23989e59e6343303696e14d4c134582dda083cf7408Sean Callanan case 4: 240be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan type = TYPE_MOFFS32; 241be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan break; 24289e59e6343303696e14d4c134582dda083cf7408Sean Callanan case 8: 243be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan type = TYPE_MOFFS64; 244be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan break; 245be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan } 246be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan } 247d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby // By default sign-extend all X86 immediates based on their encoding. 248d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby else if (type == TYPE_IMM8 || type == TYPE_IMM16 || type == TYPE_IMM32 || 249d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby type == TYPE_IMM64) { 250d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby uint32_t Opcode = mcInst.getOpcode(); 251d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby switch (operand.encoding) { 252d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby default: 253d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby break; 254d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby case ENCODING_IB: 255d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby // Special case those X86 instructions that use the imm8 as a set of 256d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby // bits, bit count, etc. and are not sign-extend. 257d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby if (Opcode != X86::BLENDPSrri && Opcode != X86::BLENDPDrri && 25856cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling Opcode != X86::PBLENDWrri && Opcode != X86::MPSADBWrri && 25956cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling Opcode != X86::DPPSrri && Opcode != X86::DPPDrri && 26056cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling Opcode != X86::INSERTPSrr && Opcode != X86::VBLENDPSYrri && 26156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling Opcode != X86::VBLENDPSYrmi && Opcode != X86::VBLENDPDYrri && 26256cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling Opcode != X86::VBLENDPDYrmi && Opcode != X86::VPBLENDWrri && 26356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling Opcode != X86::VMPSADBWrri && Opcode != X86::VDPPSYrri && 26456cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling Opcode != X86::VDPPSYrmi && Opcode != X86::VDPPDrri && 26556cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling Opcode != X86::VINSERTPSrr) 26656cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling type = TYPE_MOFFS8; 267d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby break; 268d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby case ENCODING_IW: 269d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby type = TYPE_MOFFS16; 270d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby break; 271d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby case ENCODING_ID: 272d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby type = TYPE_MOFFS32; 273d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby break; 274d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby case ENCODING_IO: 275d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby type = TYPE_MOFFS64; 276d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby break; 277d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby } 278d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby } 279be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan 280be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan switch (type) { 281bf4043768c6726db523f99460645842e5024fc7fCraig Topper case TYPE_XMM32: 282bf4043768c6726db523f99460645842e5024fc7fCraig Topper case TYPE_XMM64: 2833bb43a829e03ed8ea671f5bc331772ef7afc3313Craig Topper case TYPE_XMM128: 2843bb43a829e03ed8ea671f5bc331772ef7afc3313Craig Topper mcInst.addOperand(MCOperand::CreateReg(X86::XMM0 + (immediate >> 4))); 2853bb43a829e03ed8ea671f5bc331772ef7afc3313Craig Topper return; 2863bb43a829e03ed8ea671f5bc331772ef7afc3313Craig Topper case TYPE_XMM256: 2873bb43a829e03ed8ea671f5bc331772ef7afc3313Craig Topper mcInst.addOperand(MCOperand::CreateReg(X86::YMM0 + (immediate >> 4))); 2883bb43a829e03ed8ea671f5bc331772ef7afc3313Craig Topper return; 289c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky case TYPE_XMM512: 290c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky mcInst.addOperand(MCOperand::CreateReg(X86::ZMM0 + (immediate >> 4))); 291c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky return; 292be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan case TYPE_REL8: 293b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby isBranch = true; 294b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize; 295b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby // fall through to sign extend the immediate if needed. 296b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby case TYPE_MOFFS8: 297be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan if(immediate & 0x80) 298be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan immediate |= ~(0xffull); 299be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan break; 300be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan case TYPE_MOFFS16: 301be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan if(immediate & 0x8000) 302be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan immediate |= ~(0xffffull); 303be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan break; 304be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan case TYPE_REL32: 305be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan case TYPE_REL64: 306b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby isBranch = true; 307b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize; 308b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby // fall through to sign extend the immediate if needed. 309b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby case TYPE_MOFFS32: 310be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan if(immediate & 0x80000000) 311be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan immediate |= ~(0xffffffffull); 312be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan break; 313be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan case TYPE_MOFFS64: 314be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan default: 315be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan // operand is 64 bits wide. Do nothing. 316be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan break; 317be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan } 318be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan 319b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby if(!tryAddingSymbolicOperand(immediate + pcrel, isBranch, insn.startLocation, 320b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby insn.immediateOffset, insn.immediateSize, 321b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby mcInst, Dis)) 322b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby mcInst.addOperand(MCOperand::CreateImm(immediate)); 3238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 3248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 3258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// translateRMRegister - Translates a register stored in the R/M field of the 3268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// ModR/M byte to its LLVM equivalent and appends it to an MCInst. 3278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param mcInst - The MCInst to append to. 3288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param insn - The internal instruction to extract the R/M field 3298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// from. 330a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan/// @return - 0 on success; -1 otherwise 331a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callananstatic bool translateRMRegister(MCInst &mcInst, 3328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan InternalInstruction &insn) { 333a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan if (insn.eaBase == EA_BASE_sib || insn.eaBase == EA_BASE_sib64) { 334a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("A R/M register operand may not have a SIB byte"); 335a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 336a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan } 3378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 3388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (insn.eaBase) { 339a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan default: 340a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("Unexpected EA base register"); 341a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 3428ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case EA_BASE_NONE: 343a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("EA_BASE_NONE for ModR/M base"); 344a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 3458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define ENTRY(x) case EA_BASE_##x: 3468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ALL_EA_BASES 3478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#undef ENTRY 348a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("A R/M register operand may not have a base; " 349a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan "the operand must be a register."); 350a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 351a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan#define ENTRY(x) \ 3528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case EA_REG_##x: \ 3538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan mcInst.addOperand(MCOperand::CreateReg(X86::x)); break; 3548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ALL_REGS 3558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#undef ENTRY 3568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 357a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan 358a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return false; 3598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 3608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 3618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// translateRMMemory - Translates a memory operand stored in the Mod and R/M 3628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// fields of an internal instruction (and possibly its SIB byte) to a memory 3638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// operand in LLVM's format, and appends it to an MCInst. 3648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 3658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param mcInst - The MCInst to append to. 3668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param insn - The instruction to extract Mod, R/M, and SIB fields 3678ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// from. 368a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan/// @return - 0 on success; nonzero otherwise 369b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderbystatic bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn, 370b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby const MCDisassembler *Dis) { 3718ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Addresses in an MCInst are represented as five operands: 3728ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // 1. basereg (register) The R/M base, or (if there is a SIB) the 3738ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // SIB base 3748ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // 2. scaleamount (immediate) 1, or (if there is a SIB) the specified 3758ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // scale amount 3768ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // 3. indexreg (register) x86_registerNONE, or (if there is a SIB) 3778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // the index (which is multiplied by the 3788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // scale amount) 3798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // 4. displacement (immediate) 0, or the displacement if there is one 3808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // 5. segmentreg (register) x86_registerNONE for now, but could be set 3818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // if we have segment overrides 3828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 3838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MCOperand baseReg; 3848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MCOperand scaleAmount; 3858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MCOperand indexReg; 3868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MCOperand displacement; 3878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MCOperand segmentReg; 388b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby uint64_t pcrel = 0; 3898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 3908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (insn.eaBase == EA_BASE_sib || insn.eaBase == EA_BASE_sib64) { 3918ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (insn.sibBase != SIB_BASE_NONE) { 3928ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (insn.sibBase) { 3938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan default: 394a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("Unexpected sibBase"); 395a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 3968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define ENTRY(x) \ 3977fb35a2fd83f5deadefcb230669b07e1d5b98137Sean Callanan case SIB_BASE_##x: \ 3988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan baseReg = MCOperand::CreateReg(X86::x); break; 3998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ALL_SIB_BASES 4008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#undef ENTRY 4018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 4028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } else { 4038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan baseReg = MCOperand::CreateReg(0); 4048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 4051f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren 4061f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren // Check whether we are handling VSIB addressing mode for GATHER. 4071f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren // If sibIndex was set to SIB_INDEX_NONE, index offset is 4 and 4081f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren // we should use SIB_INDEX_XMM4|YMM4 for VSIB. 4091f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren // I don't see a way to get the correct IndexReg in readSIB: 4101f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren // We can tell whether it is VSIB or SIB after instruction ID is decoded, 4111f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren // but instruction ID may not be decoded yet when calling readSIB. 4121f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren uint32_t Opcode = mcInst.getOpcode(); 41340307c7dbe2d104784763c28697d7926793674afManman Ren bool IndexIs128 = (Opcode == X86::VGATHERDPDrm || 41440307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VGATHERDPDYrm || 41540307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VGATHERQPDrm || 41640307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VGATHERDPSrm || 41740307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VGATHERQPSrm || 41840307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VPGATHERDQrm || 41940307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VPGATHERDQYrm || 42040307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VPGATHERQQrm || 42140307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VPGATHERDDrm || 42240307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VPGATHERQDrm); 42340307c7dbe2d104784763c28697d7926793674afManman Ren bool IndexIs256 = (Opcode == X86::VGATHERQPDYrm || 42440307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VGATHERDPSYrm || 42540307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VGATHERQPSYrm || 42640307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VPGATHERQQYrm || 42740307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VPGATHERDDYrm || 42840307c7dbe2d104784763c28697d7926793674afManman Ren Opcode == X86::VPGATHERQDYrm); 42940307c7dbe2d104784763c28697d7926793674afManman Ren if (IndexIs128 || IndexIs256) { 4301f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren unsigned IndexOffset = insn.sibIndex - 4311f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren (insn.addressSize == 8 ? SIB_INDEX_RAX:SIB_INDEX_EAX); 43240307c7dbe2d104784763c28697d7926793674afManman Ren SIBIndex IndexBase = IndexIs256 ? SIB_INDEX_YMM0 : SIB_INDEX_XMM0; 4331f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren insn.sibIndex = (SIBIndex)(IndexBase + 4341f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren (insn.sibIndex == SIB_INDEX_NONE ? 4 : IndexOffset)); 4351f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren } 4361f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren 4378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (insn.sibIndex != SIB_INDEX_NONE) { 4388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (insn.sibIndex) { 4398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan default: 440a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("Unexpected sibIndex"); 441a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 4427fb35a2fd83f5deadefcb230669b07e1d5b98137Sean Callanan#define ENTRY(x) \ 4438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case SIB_INDEX_##x: \ 4448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan indexReg = MCOperand::CreateReg(X86::x); break; 4458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EA_BASES_32BIT 4468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EA_BASES_64BIT 4471f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren REGS_XMM 4481f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren REGS_YMM 449c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky REGS_ZMM 4508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#undef ENTRY 4518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 4528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } else { 4538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan indexReg = MCOperand::CreateReg(0); 4548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 4558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 4568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan scaleAmount = MCOperand::CreateImm(insn.sibScale); 4578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } else { 4588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (insn.eaBase) { 4598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case EA_BASE_NONE: 460a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan if (insn.eaDisplacement == EA_DISP_NONE) { 461a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("EA_BASE_NONE and EA_DISP_NONE for ModR/M base"); 462a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 463a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan } 464b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby if (insn.mode == MODE_64BIT){ 465b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby pcrel = insn.startLocation + 466b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby insn.displacementOffset + insn.displacementSize; 4678bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby tryAddingPcLoadReferenceComment(insn.startLocation + 4688bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby insn.displacementOffset, 4698bee081a2cc6a84de125525215fffb4cc1cbe12aKevin Enderby insn.displacement + pcrel, Dis); 4708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan baseReg = MCOperand::CreateReg(X86::RIP); // Section 2.2.1.6 471b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby } 4728ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else 4738ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan baseReg = MCOperand::CreateReg(0); 4748ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 4758ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan indexReg = MCOperand::CreateReg(0); 4768ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 4778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case EA_BASE_BX_SI: 4788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan baseReg = MCOperand::CreateReg(X86::BX); 4798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan indexReg = MCOperand::CreateReg(X86::SI); 4808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 4818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case EA_BASE_BX_DI: 4828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan baseReg = MCOperand::CreateReg(X86::BX); 4838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan indexReg = MCOperand::CreateReg(X86::DI); 4848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 4858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case EA_BASE_BP_SI: 4868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan baseReg = MCOperand::CreateReg(X86::BP); 4878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan indexReg = MCOperand::CreateReg(X86::SI); 4888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 4898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case EA_BASE_BP_DI: 4908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan baseReg = MCOperand::CreateReg(X86::BP); 4918ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan indexReg = MCOperand::CreateReg(X86::DI); 4928ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 4938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan default: 4948ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan indexReg = MCOperand::CreateReg(0); 4958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (insn.eaBase) { 4968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan default: 497a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("Unexpected eaBase"); 498a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 4998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Here, we will use the fill-ins defined above. However, 5008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // BX_SI, BX_DI, BP_SI, and BP_DI are all handled above and 5018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // sib and sib64 were handled in the top-level if, so they're only 5028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // placeholders to keep the compiler happy. 5038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define ENTRY(x) \ 5048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case EA_BASE_##x: \ 5058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan baseReg = MCOperand::CreateReg(X86::x); break; 5068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ALL_EA_BASES 5078ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#undef ENTRY 5088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define ENTRY(x) case EA_REG_##x: 5098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ALL_REGS 5108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#undef ENTRY 511a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("A R/M memory operand may not be a register; " 512a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan "the base field must be a base."); 513a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 5148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5167fb35a2fd83f5deadefcb230669b07e1d5b98137Sean Callanan 5177fb35a2fd83f5deadefcb230669b07e1d5b98137Sean Callanan scaleAmount = MCOperand::CreateImm(1); 5188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan displacement = MCOperand::CreateImm(insn.displacement); 5218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = { 5238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 0, // SEG_OVERRIDE_NONE 5248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan X86::CS, 5258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan X86::SS, 5268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan X86::DS, 5278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan X86::ES, 5288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan X86::FS, 5298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan X86::GS 5308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan }; 5318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan segmentReg = MCOperand::CreateReg(segmentRegnums[insn.segmentOverride]); 5338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan mcInst.addOperand(baseReg); 5358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan mcInst.addOperand(scaleAmount); 5368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan mcInst.addOperand(indexReg); 537b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby if(!tryAddingSymbolicOperand(insn.displacement + pcrel, false, 538b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby insn.startLocation, insn.displacementOffset, 539b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby insn.displacementSize, mcInst, Dis)) 540b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby mcInst.addOperand(displacement); 54137a746bc854d050ded5e280a13aad359852eb06aChris Lattner mcInst.addOperand(segmentReg); 542a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return false; 5438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 5448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// translateRM - Translates an operand stored in the R/M (and possibly SIB) 5468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// byte of an instruction to LLVM form, and appends it to an MCInst. 5478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 5488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param mcInst - The MCInst to append to. 5498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param operand - The operand, as stored in the descriptor table. 5508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param insn - The instruction to extract Mod, R/M, and SIB fields 5518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// from. 552a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan/// @return - 0 on success; nonzero otherwise 5534d1dca92bd6d4aad7121e28c7ffc93c0a6a187d7Benjamin Kramerstatic bool translateRM(MCInst &mcInst, const OperandSpecifier &operand, 554b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby InternalInstruction &insn, const MCDisassembler *Dis) { 5558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (operand.type) { 5568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan default: 557a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("Unexpected type for a R/M operand"); 558a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 5598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_R8: 5608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_R16: 5618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_R32: 5628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_R64: 5638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_Rv: 5648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_MM: 5658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_MM32: 5668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_MM64: 5678ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_XMM: 5688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_XMM32: 5698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_XMM64: 5708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_XMM128: 571a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan case TYPE_XMM256: 572c18f4efc5dd24adcc653806455fc7ae8508e9c66Elena Demikhovsky case TYPE_XMM512: 5738ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_DEBUGREG: 5741a8b789a4b8290d263c1c75411788ca45bae3230Sean Callanan case TYPE_CONTROLREG: 575a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return translateRMRegister(mcInst, insn); 5768ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M: 5778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M8: 5788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M16: 5798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M32: 5808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M64: 5818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M128: 582a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan case TYPE_M256: 5838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M512: 5848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_Mv: 5858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M32FP: 5868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M64FP: 5878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M80FP: 5888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M16INT: 5898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M32INT: 5908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M64INT: 5918ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M1616: 5928ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M1632: 5938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case TYPE_M1664: 5947fb35a2fd83f5deadefcb230669b07e1d5b98137Sean Callanan case TYPE_LEA: 595b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby return translateRMMemory(mcInst, insn, Dis); 5968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5978ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 5988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// translateFPRegister - Translates a stack position on the FPU stack to its 6008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// LLVM form, and appends it to an MCInst. 6018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 6028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param mcInst - The MCInst to append to. 6038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param stackPos - The stack position to translate. 604a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan/// @return - 0 on success; nonzero otherwise. 605a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callananstatic bool translateFPRegister(MCInst &mcInst, 606a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan uint8_t stackPos) { 607a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan if (stackPos >= 8) { 608a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("Invalid FP stack position"); 609a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 610a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan } 6118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 6128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan mcInst.addOperand(MCOperand::CreateReg(X86::ST0 + stackPos)); 613a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan 614a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return false; 6158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 6168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 6178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// translateOperand - Translates an operand stored in an internal instruction 6188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// to LLVM's format and appends it to an MCInst. 6198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 6208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param mcInst - The MCInst to append to. 6218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param operand - The operand, as stored in the descriptor table. 6228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param insn - The internal instruction. 623a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan/// @return - false on success; true otherwise. 6244d1dca92bd6d4aad7121e28c7ffc93c0a6a187d7Benjamin Kramerstatic bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand, 625b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby InternalInstruction &insn, 626b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby const MCDisassembler *Dis) { 6278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (operand.encoding) { 6288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan default: 629a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("Unhandled operand encoding during translation"); 630a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 6318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_REG: 6328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan translateRegister(mcInst, insn.reg); 633a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return false; 6348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_RM: 635b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby return translateRM(mcInst, operand, insn, Dis); 6368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_CB: 6378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_CW: 6388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_CD: 6398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_CP: 6408ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_CO: 6418ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_CT: 642a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("Translation of code offsets isn't supported."); 643a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 6448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_IB: 6458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_IW: 6468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_ID: 6478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_IO: 6488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_Iv: 6498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_Ia: 650be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan translateImmediate(mcInst, 651be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan insn.immediates[insn.numImmediatesTranslated++], 652be192dd1e987361ecf51ff385cbf541cb7f779beSean Callanan operand, 653b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby insn, 654b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby Dis); 655a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return false; 6568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_RB: 6578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_RW: 6588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_RD: 6598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_RO: 6608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan translateRegister(mcInst, insn.opcodeRegister); 661a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return false; 6628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_I: 663a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return translateFPRegister(mcInst, insn.opcodeModifier); 6648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_Rv: 6658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan translateRegister(mcInst, insn.opcodeRegister); 666a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return false; 667a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan case ENCODING_VVVV: 668a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan translateRegister(mcInst, insn.vvvv); 669a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return false; 6708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case ENCODING_DUP: 6715a2c607153993fb7f7e04f9482520b64dffe5757Craig Topper return translateOperand(mcInst, insn.operands[operand.type - TYPE_DUP0], 672b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby insn, Dis); 6738ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 6748ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 6758ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 6768ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// translateInstruction - Translates an internal instruction and all its 6778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// operands to an MCInst. 6788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 6798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param mcInst - The MCInst to populate with the instruction's data. 6808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param insn - The internal instruction. 681a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan/// @return - false on success; true otherwise. 682a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callananstatic bool translateInstruction(MCInst &mcInst, 683b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby InternalInstruction &insn, 684b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby const MCDisassembler *Dis) { 685a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan if (!insn.spec) { 686a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan debug("Instruction has no specification"); 687a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 688a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan } 6898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 6908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan mcInst.setOpcode(insn.instructionID); 69146d7de7a192f43eb568c26c88e2dc2b804c09614Kevin Enderby // If when reading the prefix bytes we determined the overlapping 0xf2 or 0xf3 69246d7de7a192f43eb568c26c88e2dc2b804c09614Kevin Enderby // prefix bytes should be disassembled as xrelease and xacquire then set the 69346d7de7a192f43eb568c26c88e2dc2b804c09614Kevin Enderby // opcode to those instead of the rep and repne opcodes. 69446d7de7a192f43eb568c26c88e2dc2b804c09614Kevin Enderby if (insn.xAcquireRelease) { 69546d7de7a192f43eb568c26c88e2dc2b804c09614Kevin Enderby if(mcInst.getOpcode() == X86::REP_PREFIX) 69646d7de7a192f43eb568c26c88e2dc2b804c09614Kevin Enderby mcInst.setOpcode(X86::XRELEASE_PREFIX); 69746d7de7a192f43eb568c26c88e2dc2b804c09614Kevin Enderby else if(mcInst.getOpcode() == X86::REPNE_PREFIX) 69846d7de7a192f43eb568c26c88e2dc2b804c09614Kevin Enderby mcInst.setOpcode(X86::XACQUIRE_PREFIX); 69946d7de7a192f43eb568c26c88e2dc2b804c09614Kevin Enderby } 7008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 7018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan int index; 7028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 7038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insn.numImmediatesTranslated = 0; 7048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 7058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan for (index = 0; index < X86_MAX_OPERANDS; ++index) { 7065a2c607153993fb7f7e04f9482520b64dffe5757Craig Topper if (insn.operands[index].encoding != ENCODING_NONE) { 7075a2c607153993fb7f7e04f9482520b64dffe5757Craig Topper if (translateOperand(mcInst, insn.operands[index], insn, Dis)) { 708a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return true; 709a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan } 710a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan } 7118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 712a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan 713a144c3f34dd8adc093d9be6cbc3e6f39d47c75ddSean Callanan return false; 7148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 7155f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar 716953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramerstatic MCDisassembler *createX86_32Disassembler(const Target &T, 717953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer const MCSubtargetInfo &STI) { 718953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer return new X86Disassembler::X86GenericDisassembler(STI, MODE_32BIT, 719953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer T.createMCInstrInfo()); 7205f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar} 7215f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar 722953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramerstatic MCDisassembler *createX86_64Disassembler(const Target &T, 723953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer const MCSubtargetInfo &STI) { 724953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer return new X86Disassembler::X86GenericDisassembler(STI, MODE_64BIT, 725953362cdfbf1088153f65376c86d22ee0176bcdfBenjamin Kramer T.createMCInstrInfo()); 7265f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar} 7275f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar 7285f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbarextern "C" void LLVMInitializeX86Disassembler() { 7295f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar // Register the disassembler. 7305f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar TargetRegistry::RegisterMCDisassembler(TheX86_32Target, 7315f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar createX86_32Disassembler); 7325f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar TargetRegistry::RegisterMCDisassembler(TheX86_64Target, 7335f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar createX86_64Disassembler); 7345f9b9efa1719d2b716581ccce977bed65865cc18Daniel Dunbar} 735