1 //===-- X86Disassembler.cpp - Disassembler for x86 and x86_64 -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is part of the X86 Disassembler. 11 // It contains code to translate the data produced by the decoder into 12 // MCInsts. 13 // Documentation for the disassembler can be found in X86Disassembler.h. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "X86Disassembler.h" 18 #include "X86DisassemblerDecoder.h" 19 #include "llvm/MC/MCContext.h" 20 #include "llvm/MC/MCDisassembler.h" 21 #include "llvm/MC/MCExpr.h" 22 #include "llvm/MC/MCInst.h" 23 #include "llvm/MC/MCInstrInfo.h" 24 #include "llvm/MC/MCSubtargetInfo.h" 25 #include "llvm/Support/Debug.h" 26 #include "llvm/Support/MemoryObject.h" 27 #include "llvm/Support/TargetRegistry.h" 28 #include "llvm/Support/raw_ostream.h" 29 30 #define GET_REGINFO_ENUM 31 #include "X86GenRegisterInfo.inc" 32 #define GET_INSTRINFO_ENUM 33 #include "X86GenInstrInfo.inc" 34 35 using namespace llvm; 36 using namespace llvm::X86Disassembler; 37 38 void x86DisassemblerDebug(const char *file, 39 unsigned line, 40 const char *s) { 41 dbgs() << file << ":" << line << ": " << s; 42 } 43 44 const char *x86DisassemblerGetInstrName(unsigned Opcode, const void *mii) { 45 const MCInstrInfo *MII = static_cast<const MCInstrInfo *>(mii); 46 return MII->getName(Opcode); 47 } 48 49 #define debug(s) DEBUG(x86DisassemblerDebug(__FILE__, __LINE__, s)); 50 51 namespace llvm { 52 53 // Fill-ins to make the compiler happy. These constants are never actually 54 // assigned; they are just filler to make an automatically-generated switch 55 // statement work. 56 namespace X86 { 57 enum { 58 BX_SI = 500, 59 BX_DI = 501, 60 BP_SI = 502, 61 BP_DI = 503, 62 sib = 504, 63 sib64 = 505 64 }; 65 } 66 67 extern Target TheX86_32Target, TheX86_64Target; 68 69 } 70 71 static bool translateInstruction(MCInst &target, 72 InternalInstruction &source, 73 const MCDisassembler *Dis); 74 75 X86GenericDisassembler::X86GenericDisassembler(const MCSubtargetInfo &STI, 76 DisassemblerMode mode, 77 const MCInstrInfo *MII) 78 : MCDisassembler(STI), MII(MII), fMode(mode) {} 79 80 X86GenericDisassembler::~X86GenericDisassembler() { 81 delete MII; 82 } 83 84 /// regionReader - a callback function that wraps the readByte method from 85 /// MemoryObject. 86 /// 87 /// @param arg - The generic callback parameter. In this case, this should 88 /// be a pointer to a MemoryObject. 89 /// @param byte - A pointer to the byte to be read. 90 /// @param address - The address to be read. 91 static int regionReader(const void* arg, uint8_t* byte, uint64_t address) { 92 const MemoryObject* region = static_cast<const MemoryObject*>(arg); 93 return region->readByte(address, byte); 94 } 95 96 /// logger - a callback function that wraps the operator<< method from 97 /// raw_ostream. 98 /// 99 /// @param arg - The generic callback parameter. This should be a pointe 100 /// to a raw_ostream. 101 /// @param log - A string to be logged. logger() adds a newline. 102 static void logger(void* arg, const char* log) { 103 if (!arg) 104 return; 105 106 raw_ostream &vStream = *(static_cast<raw_ostream*>(arg)); 107 vStream << log << "\n"; 108 } 109 110 // 111 // Public interface for the disassembler 112 // 113 114 MCDisassembler::DecodeStatus 115 X86GenericDisassembler::getInstruction(MCInst &instr, 116 uint64_t &size, 117 const MemoryObject ®ion, 118 uint64_t address, 119 raw_ostream &vStream, 120 raw_ostream &cStream) const { 121 CommentStream = &cStream; 122 123 InternalInstruction internalInstr; 124 125 dlog_t loggerFn = logger; 126 if (&vStream == &nulls()) 127 loggerFn = 0; // Disable logging completely if it's going to nulls(). 128 129 int ret = decodeInstruction(&internalInstr, 130 regionReader, 131 (const void*)®ion, 132 loggerFn, 133 (void*)&vStream, 134 (const void*)MII, 135 address, 136 fMode); 137 138 if (ret) { 139 size = internalInstr.readerCursor - address; 140 return Fail; 141 } 142 else { 143 size = internalInstr.length; 144 return (!translateInstruction(instr, internalInstr, this)) ? 145 Success : Fail; 146 } 147 } 148 149 // 150 // Private code that translates from struct InternalInstructions to MCInsts. 151 // 152 153 /// translateRegister - Translates an internal register to the appropriate LLVM 154 /// register, and appends it as an operand to an MCInst. 155 /// 156 /// @param mcInst - The MCInst to append to. 157 /// @param reg - The Reg to append. 158 static void translateRegister(MCInst &mcInst, Reg reg) { 159 #define ENTRY(x) X86::x, 160 uint8_t llvmRegnums[] = { 161 ALL_REGS 162 0 163 }; 164 #undef ENTRY 165 166 uint8_t llvmRegnum = llvmRegnums[reg]; 167 mcInst.addOperand(MCOperand::CreateReg(llvmRegnum)); 168 } 169 170 /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 171 /// immediate Value in the MCInst. 172 /// 173 /// @param Value - The immediate Value, has had any PC adjustment made by 174 /// the caller. 175 /// @param isBranch - If the instruction is a branch instruction 176 /// @param Address - The starting address of the instruction 177 /// @param Offset - The byte offset to this immediate in the instruction 178 /// @param Width - The byte width of this immediate in the instruction 179 /// 180 /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was 181 /// called then that function is called to get any symbolic information for the 182 /// immediate in the instruction using the Address, Offset and Width. If that 183 /// returns non-zero then the symbolic information it returns is used to create 184 /// an MCExpr and that is added as an operand to the MCInst. If getOpInfo() 185 /// returns zero and isBranch is true then a symbol look up for immediate Value 186 /// is done and if a symbol is found an MCExpr is created with that, else 187 /// an MCExpr with the immediate Value is created. This function returns true 188 /// if it adds an operand to the MCInst and false otherwise. 189 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 190 uint64_t Address, uint64_t Offset, 191 uint64_t Width, MCInst &MI, 192 const MCDisassembler *Dis) { 193 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 194 Offset, Width); 195 } 196 197 /// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being 198 /// referenced by a load instruction with the base register that is the rip. 199 /// These can often be addresses in a literal pool. The Address of the 200 /// instruction and its immediate Value are used to determine the address 201 /// being referenced in the literal pool entry. The SymbolLookUp call back will 202 /// return a pointer to a literal 'C' string if the referenced address is an 203 /// address into a section with 'C' string literals. 204 static void tryAddingPcLoadReferenceComment(uint64_t Address, uint64_t Value, 205 const void *Decoder) { 206 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 207 Dis->tryAddingPcLoadReferenceComment(Value, Address); 208 } 209 210 /// translateImmediate - Appends an immediate operand to an MCInst. 211 /// 212 /// @param mcInst - The MCInst to append to. 213 /// @param immediate - The immediate value to append. 214 /// @param operand - The operand, as stored in the descriptor table. 215 /// @param insn - The internal instruction. 216 static void translateImmediate(MCInst &mcInst, uint64_t immediate, 217 const OperandSpecifier &operand, 218 InternalInstruction &insn, 219 const MCDisassembler *Dis) { 220 // Sign-extend the immediate if necessary. 221 222 OperandType type = (OperandType)operand.type; 223 224 bool isBranch = false; 225 uint64_t pcrel = 0; 226 if (type == TYPE_RELv) { 227 isBranch = true; 228 pcrel = insn.startLocation + 229 insn.immediateOffset + insn.immediateSize; 230 switch (insn.displacementSize) { 231 default: 232 break; 233 case 1: 234 type = TYPE_MOFFS8; 235 break; 236 case 2: 237 type = TYPE_MOFFS16; 238 break; 239 case 4: 240 type = TYPE_MOFFS32; 241 break; 242 case 8: 243 type = TYPE_MOFFS64; 244 break; 245 } 246 } 247 // By default sign-extend all X86 immediates based on their encoding. 248 else if (type == TYPE_IMM8 || type == TYPE_IMM16 || type == TYPE_IMM32 || 249 type == TYPE_IMM64) { 250 uint32_t Opcode = mcInst.getOpcode(); 251 switch (operand.encoding) { 252 default: 253 break; 254 case ENCODING_IB: 255 // Special case those X86 instructions that use the imm8 as a set of 256 // bits, bit count, etc. and are not sign-extend. 257 if (Opcode != X86::BLENDPSrri && Opcode != X86::BLENDPDrri && 258 Opcode != X86::PBLENDWrri && Opcode != X86::MPSADBWrri && 259 Opcode != X86::DPPSrri && Opcode != X86::DPPDrri && 260 Opcode != X86::INSERTPSrr && Opcode != X86::VBLENDPSYrri && 261 Opcode != X86::VBLENDPSYrmi && Opcode != X86::VBLENDPDYrri && 262 Opcode != X86::VBLENDPDYrmi && Opcode != X86::VPBLENDWrri && 263 Opcode != X86::VMPSADBWrri && Opcode != X86::VDPPSYrri && 264 Opcode != X86::VDPPSYrmi && Opcode != X86::VDPPDrri && 265 Opcode != X86::VINSERTPSrr) 266 type = TYPE_MOFFS8; 267 break; 268 case ENCODING_IW: 269 type = TYPE_MOFFS16; 270 break; 271 case ENCODING_ID: 272 type = TYPE_MOFFS32; 273 break; 274 case ENCODING_IO: 275 type = TYPE_MOFFS64; 276 break; 277 } 278 } 279 280 switch (type) { 281 case TYPE_XMM32: 282 case TYPE_XMM64: 283 case TYPE_XMM128: 284 mcInst.addOperand(MCOperand::CreateReg(X86::XMM0 + (immediate >> 4))); 285 return; 286 case TYPE_XMM256: 287 mcInst.addOperand(MCOperand::CreateReg(X86::YMM0 + (immediate >> 4))); 288 return; 289 case TYPE_XMM512: 290 mcInst.addOperand(MCOperand::CreateReg(X86::ZMM0 + (immediate >> 4))); 291 return; 292 case TYPE_REL8: 293 isBranch = true; 294 pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize; 295 // fall through to sign extend the immediate if needed. 296 case TYPE_MOFFS8: 297 if(immediate & 0x80) 298 immediate |= ~(0xffull); 299 break; 300 case TYPE_MOFFS16: 301 if(immediate & 0x8000) 302 immediate |= ~(0xffffull); 303 break; 304 case TYPE_REL32: 305 case TYPE_REL64: 306 isBranch = true; 307 pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize; 308 // fall through to sign extend the immediate if needed. 309 case TYPE_MOFFS32: 310 if(immediate & 0x80000000) 311 immediate |= ~(0xffffffffull); 312 break; 313 case TYPE_MOFFS64: 314 default: 315 // operand is 64 bits wide. Do nothing. 316 break; 317 } 318 319 if(!tryAddingSymbolicOperand(immediate + pcrel, isBranch, insn.startLocation, 320 insn.immediateOffset, insn.immediateSize, 321 mcInst, Dis)) 322 mcInst.addOperand(MCOperand::CreateImm(immediate)); 323 } 324 325 /// translateRMRegister - Translates a register stored in the R/M field of the 326 /// ModR/M byte to its LLVM equivalent and appends it to an MCInst. 327 /// @param mcInst - The MCInst to append to. 328 /// @param insn - The internal instruction to extract the R/M field 329 /// from. 330 /// @return - 0 on success; -1 otherwise 331 static bool translateRMRegister(MCInst &mcInst, 332 InternalInstruction &insn) { 333 if (insn.eaBase == EA_BASE_sib || insn.eaBase == EA_BASE_sib64) { 334 debug("A R/M register operand may not have a SIB byte"); 335 return true; 336 } 337 338 switch (insn.eaBase) { 339 default: 340 debug("Unexpected EA base register"); 341 return true; 342 case EA_BASE_NONE: 343 debug("EA_BASE_NONE for ModR/M base"); 344 return true; 345 #define ENTRY(x) case EA_BASE_##x: 346 ALL_EA_BASES 347 #undef ENTRY 348 debug("A R/M register operand may not have a base; " 349 "the operand must be a register."); 350 return true; 351 #define ENTRY(x) \ 352 case EA_REG_##x: \ 353 mcInst.addOperand(MCOperand::CreateReg(X86::x)); break; 354 ALL_REGS 355 #undef ENTRY 356 } 357 358 return false; 359 } 360 361 /// translateRMMemory - Translates a memory operand stored in the Mod and R/M 362 /// fields of an internal instruction (and possibly its SIB byte) to a memory 363 /// operand in LLVM's format, and appends it to an MCInst. 364 /// 365 /// @param mcInst - The MCInst to append to. 366 /// @param insn - The instruction to extract Mod, R/M, and SIB fields 367 /// from. 368 /// @return - 0 on success; nonzero otherwise 369 static bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn, 370 const MCDisassembler *Dis) { 371 // Addresses in an MCInst are represented as five operands: 372 // 1. basereg (register) The R/M base, or (if there is a SIB) the 373 // SIB base 374 // 2. scaleamount (immediate) 1, or (if there is a SIB) the specified 375 // scale amount 376 // 3. indexreg (register) x86_registerNONE, or (if there is a SIB) 377 // the index (which is multiplied by the 378 // scale amount) 379 // 4. displacement (immediate) 0, or the displacement if there is one 380 // 5. segmentreg (register) x86_registerNONE for now, but could be set 381 // if we have segment overrides 382 383 MCOperand baseReg; 384 MCOperand scaleAmount; 385 MCOperand indexReg; 386 MCOperand displacement; 387 MCOperand segmentReg; 388 uint64_t pcrel = 0; 389 390 if (insn.eaBase == EA_BASE_sib || insn.eaBase == EA_BASE_sib64) { 391 if (insn.sibBase != SIB_BASE_NONE) { 392 switch (insn.sibBase) { 393 default: 394 debug("Unexpected sibBase"); 395 return true; 396 #define ENTRY(x) \ 397 case SIB_BASE_##x: \ 398 baseReg = MCOperand::CreateReg(X86::x); break; 399 ALL_SIB_BASES 400 #undef ENTRY 401 } 402 } else { 403 baseReg = MCOperand::CreateReg(0); 404 } 405 406 // Check whether we are handling VSIB addressing mode for GATHER. 407 // If sibIndex was set to SIB_INDEX_NONE, index offset is 4 and 408 // we should use SIB_INDEX_XMM4|YMM4 for VSIB. 409 // I don't see a way to get the correct IndexReg in readSIB: 410 // We can tell whether it is VSIB or SIB after instruction ID is decoded, 411 // but instruction ID may not be decoded yet when calling readSIB. 412 uint32_t Opcode = mcInst.getOpcode(); 413 bool IndexIs128 = (Opcode == X86::VGATHERDPDrm || 414 Opcode == X86::VGATHERDPDYrm || 415 Opcode == X86::VGATHERQPDrm || 416 Opcode == X86::VGATHERDPSrm || 417 Opcode == X86::VGATHERQPSrm || 418 Opcode == X86::VPGATHERDQrm || 419 Opcode == X86::VPGATHERDQYrm || 420 Opcode == X86::VPGATHERQQrm || 421 Opcode == X86::VPGATHERDDrm || 422 Opcode == X86::VPGATHERQDrm); 423 bool IndexIs256 = (Opcode == X86::VGATHERQPDYrm || 424 Opcode == X86::VGATHERDPSYrm || 425 Opcode == X86::VGATHERQPSYrm || 426 Opcode == X86::VPGATHERQQYrm || 427 Opcode == X86::VPGATHERDDYrm || 428 Opcode == X86::VPGATHERQDYrm); 429 if (IndexIs128 || IndexIs256) { 430 unsigned IndexOffset = insn.sibIndex - 431 (insn.addressSize == 8 ? SIB_INDEX_RAX:SIB_INDEX_EAX); 432 SIBIndex IndexBase = IndexIs256 ? SIB_INDEX_YMM0 : SIB_INDEX_XMM0; 433 insn.sibIndex = (SIBIndex)(IndexBase + 434 (insn.sibIndex == SIB_INDEX_NONE ? 4 : IndexOffset)); 435 } 436 437 if (insn.sibIndex != SIB_INDEX_NONE) { 438 switch (insn.sibIndex) { 439 default: 440 debug("Unexpected sibIndex"); 441 return true; 442 #define ENTRY(x) \ 443 case SIB_INDEX_##x: \ 444 indexReg = MCOperand::CreateReg(X86::x); break; 445 EA_BASES_32BIT 446 EA_BASES_64BIT 447 REGS_XMM 448 REGS_YMM 449 REGS_ZMM 450 #undef ENTRY 451 } 452 } else { 453 indexReg = MCOperand::CreateReg(0); 454 } 455 456 scaleAmount = MCOperand::CreateImm(insn.sibScale); 457 } else { 458 switch (insn.eaBase) { 459 case EA_BASE_NONE: 460 if (insn.eaDisplacement == EA_DISP_NONE) { 461 debug("EA_BASE_NONE and EA_DISP_NONE for ModR/M base"); 462 return true; 463 } 464 if (insn.mode == MODE_64BIT){ 465 pcrel = insn.startLocation + 466 insn.displacementOffset + insn.displacementSize; 467 tryAddingPcLoadReferenceComment(insn.startLocation + 468 insn.displacementOffset, 469 insn.displacement + pcrel, Dis); 470 baseReg = MCOperand::CreateReg(X86::RIP); // Section 2.2.1.6 471 } 472 else 473 baseReg = MCOperand::CreateReg(0); 474 475 indexReg = MCOperand::CreateReg(0); 476 break; 477 case EA_BASE_BX_SI: 478 baseReg = MCOperand::CreateReg(X86::BX); 479 indexReg = MCOperand::CreateReg(X86::SI); 480 break; 481 case EA_BASE_BX_DI: 482 baseReg = MCOperand::CreateReg(X86::BX); 483 indexReg = MCOperand::CreateReg(X86::DI); 484 break; 485 case EA_BASE_BP_SI: 486 baseReg = MCOperand::CreateReg(X86::BP); 487 indexReg = MCOperand::CreateReg(X86::SI); 488 break; 489 case EA_BASE_BP_DI: 490 baseReg = MCOperand::CreateReg(X86::BP); 491 indexReg = MCOperand::CreateReg(X86::DI); 492 break; 493 default: 494 indexReg = MCOperand::CreateReg(0); 495 switch (insn.eaBase) { 496 default: 497 debug("Unexpected eaBase"); 498 return true; 499 // Here, we will use the fill-ins defined above. However, 500 // BX_SI, BX_DI, BP_SI, and BP_DI are all handled above and 501 // sib and sib64 were handled in the top-level if, so they're only 502 // placeholders to keep the compiler happy. 503 #define ENTRY(x) \ 504 case EA_BASE_##x: \ 505 baseReg = MCOperand::CreateReg(X86::x); break; 506 ALL_EA_BASES 507 #undef ENTRY 508 #define ENTRY(x) case EA_REG_##x: 509 ALL_REGS 510 #undef ENTRY 511 debug("A R/M memory operand may not be a register; " 512 "the base field must be a base."); 513 return true; 514 } 515 } 516 517 scaleAmount = MCOperand::CreateImm(1); 518 } 519 520 displacement = MCOperand::CreateImm(insn.displacement); 521 522 static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = { 523 0, // SEG_OVERRIDE_NONE 524 X86::CS, 525 X86::SS, 526 X86::DS, 527 X86::ES, 528 X86::FS, 529 X86::GS 530 }; 531 532 segmentReg = MCOperand::CreateReg(segmentRegnums[insn.segmentOverride]); 533 534 mcInst.addOperand(baseReg); 535 mcInst.addOperand(scaleAmount); 536 mcInst.addOperand(indexReg); 537 if(!tryAddingSymbolicOperand(insn.displacement + pcrel, false, 538 insn.startLocation, insn.displacementOffset, 539 insn.displacementSize, mcInst, Dis)) 540 mcInst.addOperand(displacement); 541 mcInst.addOperand(segmentReg); 542 return false; 543 } 544 545 /// translateRM - Translates an operand stored in the R/M (and possibly SIB) 546 /// byte of an instruction to LLVM form, and appends it to an MCInst. 547 /// 548 /// @param mcInst - The MCInst to append to. 549 /// @param operand - The operand, as stored in the descriptor table. 550 /// @param insn - The instruction to extract Mod, R/M, and SIB fields 551 /// from. 552 /// @return - 0 on success; nonzero otherwise 553 static bool translateRM(MCInst &mcInst, const OperandSpecifier &operand, 554 InternalInstruction &insn, const MCDisassembler *Dis) { 555 switch (operand.type) { 556 default: 557 debug("Unexpected type for a R/M operand"); 558 return true; 559 case TYPE_R8: 560 case TYPE_R16: 561 case TYPE_R32: 562 case TYPE_R64: 563 case TYPE_Rv: 564 case TYPE_MM: 565 case TYPE_MM32: 566 case TYPE_MM64: 567 case TYPE_XMM: 568 case TYPE_XMM32: 569 case TYPE_XMM64: 570 case TYPE_XMM128: 571 case TYPE_XMM256: 572 case TYPE_XMM512: 573 case TYPE_DEBUGREG: 574 case TYPE_CONTROLREG: 575 return translateRMRegister(mcInst, insn); 576 case TYPE_M: 577 case TYPE_M8: 578 case TYPE_M16: 579 case TYPE_M32: 580 case TYPE_M64: 581 case TYPE_M128: 582 case TYPE_M256: 583 case TYPE_M512: 584 case TYPE_Mv: 585 case TYPE_M32FP: 586 case TYPE_M64FP: 587 case TYPE_M80FP: 588 case TYPE_M16INT: 589 case TYPE_M32INT: 590 case TYPE_M64INT: 591 case TYPE_M1616: 592 case TYPE_M1632: 593 case TYPE_M1664: 594 case TYPE_LEA: 595 return translateRMMemory(mcInst, insn, Dis); 596 } 597 } 598 599 /// translateFPRegister - Translates a stack position on the FPU stack to its 600 /// LLVM form, and appends it to an MCInst. 601 /// 602 /// @param mcInst - The MCInst to append to. 603 /// @param stackPos - The stack position to translate. 604 /// @return - 0 on success; nonzero otherwise. 605 static bool translateFPRegister(MCInst &mcInst, 606 uint8_t stackPos) { 607 if (stackPos >= 8) { 608 debug("Invalid FP stack position"); 609 return true; 610 } 611 612 mcInst.addOperand(MCOperand::CreateReg(X86::ST0 + stackPos)); 613 614 return false; 615 } 616 617 /// translateOperand - Translates an operand stored in an internal instruction 618 /// to LLVM's format and appends it to an MCInst. 619 /// 620 /// @param mcInst - The MCInst to append to. 621 /// @param operand - The operand, as stored in the descriptor table. 622 /// @param insn - The internal instruction. 623 /// @return - false on success; true otherwise. 624 static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand, 625 InternalInstruction &insn, 626 const MCDisassembler *Dis) { 627 switch (operand.encoding) { 628 default: 629 debug("Unhandled operand encoding during translation"); 630 return true; 631 case ENCODING_REG: 632 translateRegister(mcInst, insn.reg); 633 return false; 634 case ENCODING_RM: 635 return translateRM(mcInst, operand, insn, Dis); 636 case ENCODING_CB: 637 case ENCODING_CW: 638 case ENCODING_CD: 639 case ENCODING_CP: 640 case ENCODING_CO: 641 case ENCODING_CT: 642 debug("Translation of code offsets isn't supported."); 643 return true; 644 case ENCODING_IB: 645 case ENCODING_IW: 646 case ENCODING_ID: 647 case ENCODING_IO: 648 case ENCODING_Iv: 649 case ENCODING_Ia: 650 translateImmediate(mcInst, 651 insn.immediates[insn.numImmediatesTranslated++], 652 operand, 653 insn, 654 Dis); 655 return false; 656 case ENCODING_RB: 657 case ENCODING_RW: 658 case ENCODING_RD: 659 case ENCODING_RO: 660 translateRegister(mcInst, insn.opcodeRegister); 661 return false; 662 case ENCODING_I: 663 return translateFPRegister(mcInst, insn.opcodeModifier); 664 case ENCODING_Rv: 665 translateRegister(mcInst, insn.opcodeRegister); 666 return false; 667 case ENCODING_VVVV: 668 translateRegister(mcInst, insn.vvvv); 669 return false; 670 case ENCODING_DUP: 671 return translateOperand(mcInst, insn.operands[operand.type - TYPE_DUP0], 672 insn, Dis); 673 } 674 } 675 676 /// translateInstruction - Translates an internal instruction and all its 677 /// operands to an MCInst. 678 /// 679 /// @param mcInst - The MCInst to populate with the instruction's data. 680 /// @param insn - The internal instruction. 681 /// @return - false on success; true otherwise. 682 static bool translateInstruction(MCInst &mcInst, 683 InternalInstruction &insn, 684 const MCDisassembler *Dis) { 685 if (!insn.spec) { 686 debug("Instruction has no specification"); 687 return true; 688 } 689 690 mcInst.setOpcode(insn.instructionID); 691 // If when reading the prefix bytes we determined the overlapping 0xf2 or 0xf3 692 // prefix bytes should be disassembled as xrelease and xacquire then set the 693 // opcode to those instead of the rep and repne opcodes. 694 if (insn.xAcquireRelease) { 695 if(mcInst.getOpcode() == X86::REP_PREFIX) 696 mcInst.setOpcode(X86::XRELEASE_PREFIX); 697 else if(mcInst.getOpcode() == X86::REPNE_PREFIX) 698 mcInst.setOpcode(X86::XACQUIRE_PREFIX); 699 } 700 701 int index; 702 703 insn.numImmediatesTranslated = 0; 704 705 for (index = 0; index < X86_MAX_OPERANDS; ++index) { 706 if (insn.operands[index].encoding != ENCODING_NONE) { 707 if (translateOperand(mcInst, insn.operands[index], insn, Dis)) { 708 return true; 709 } 710 } 711 } 712 713 return false; 714 } 715 716 static MCDisassembler *createX86_32Disassembler(const Target &T, 717 const MCSubtargetInfo &STI) { 718 return new X86Disassembler::X86GenericDisassembler(STI, MODE_32BIT, 719 T.createMCInstrInfo()); 720 } 721 722 static MCDisassembler *createX86_64Disassembler(const Target &T, 723 const MCSubtargetInfo &STI) { 724 return new X86Disassembler::X86GenericDisassembler(STI, MODE_64BIT, 725 T.createMCInstrInfo()); 726 } 727 728 extern "C" void LLVMInitializeX86Disassembler() { 729 // Register the disassembler. 730 TargetRegistry::RegisterMCDisassembler(TheX86_32Target, 731 createX86_32Disassembler); 732 TargetRegistry::RegisterMCDisassembler(TheX86_64Target, 733 createX86_64Disassembler); 734 } 735