1//===- X86DisassemblerTables.cpp - Disassembler tables ----------*- C++ -*-===// 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 Emitter. 11// It contains the implementation of the disassembler tables. 12// Documentation for the disassembler emitter in general can be found in 13// X86DisasemblerEmitter.h. 14// 15//===----------------------------------------------------------------------===// 16 17#include "X86DisassemblerShared.h" 18#include "X86DisassemblerTables.h" 19 20#include "llvm/TableGen/TableGenBackend.h" 21#include "llvm/ADT/STLExtras.h" 22#include "llvm/Support/ErrorHandling.h" 23#include "llvm/Support/Format.h" 24#include <map> 25 26using namespace llvm; 27using namespace X86Disassembler; 28 29/// inheritsFrom - Indicates whether all instructions in one class also belong 30/// to another class. 31/// 32/// @param child - The class that may be the subset 33/// @param parent - The class that may be the superset 34/// @return - True if child is a subset of parent, false otherwise. 35static inline bool inheritsFrom(InstructionContext child, 36 InstructionContext parent, 37 bool VEX_LIG = false) { 38 if (child == parent) 39 return true; 40 41 switch (parent) { 42 case IC: 43 return(inheritsFrom(child, IC_64BIT) || 44 inheritsFrom(child, IC_OPSIZE) || 45 inheritsFrom(child, IC_ADSIZE) || 46 inheritsFrom(child, IC_XD) || 47 inheritsFrom(child, IC_XS)); 48 case IC_64BIT: 49 return(inheritsFrom(child, IC_64BIT_REXW) || 50 inheritsFrom(child, IC_64BIT_OPSIZE) || 51 inheritsFrom(child, IC_64BIT_ADSIZE) || 52 inheritsFrom(child, IC_64BIT_XD) || 53 inheritsFrom(child, IC_64BIT_XS)); 54 case IC_OPSIZE: 55 return inheritsFrom(child, IC_64BIT_OPSIZE); 56 case IC_ADSIZE: 57 case IC_64BIT_ADSIZE: 58 return false; 59 case IC_XD: 60 return inheritsFrom(child, IC_64BIT_XD); 61 case IC_XS: 62 return inheritsFrom(child, IC_64BIT_XS); 63 case IC_XD_OPSIZE: 64 return inheritsFrom(child, IC_64BIT_XD_OPSIZE); 65 case IC_XS_OPSIZE: 66 return inheritsFrom(child, IC_64BIT_XS_OPSIZE); 67 case IC_64BIT_REXW: 68 return(inheritsFrom(child, IC_64BIT_REXW_XS) || 69 inheritsFrom(child, IC_64BIT_REXW_XD) || 70 inheritsFrom(child, IC_64BIT_REXW_OPSIZE)); 71 case IC_64BIT_OPSIZE: 72 return(inheritsFrom(child, IC_64BIT_REXW_OPSIZE)); 73 case IC_64BIT_XD: 74 return(inheritsFrom(child, IC_64BIT_REXW_XD)); 75 case IC_64BIT_XS: 76 return(inheritsFrom(child, IC_64BIT_REXW_XS)); 77 case IC_64BIT_XD_OPSIZE: 78 case IC_64BIT_XS_OPSIZE: 79 return false; 80 case IC_64BIT_REXW_XD: 81 case IC_64BIT_REXW_XS: 82 case IC_64BIT_REXW_OPSIZE: 83 return false; 84 case IC_VEX: 85 return inheritsFrom(child, IC_VEX_W) || 86 (VEX_LIG && inheritsFrom(child, IC_VEX_L)); 87 case IC_VEX_XS: 88 return inheritsFrom(child, IC_VEX_W_XS) || 89 (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS)); 90 case IC_VEX_XD: 91 return inheritsFrom(child, IC_VEX_W_XD) || 92 (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD)); 93 case IC_VEX_OPSIZE: 94 return inheritsFrom(child, IC_VEX_W_OPSIZE) || 95 (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE)); 96 case IC_VEX_W: 97 case IC_VEX_W_XS: 98 case IC_VEX_W_XD: 99 case IC_VEX_W_OPSIZE: 100 return false; 101 case IC_VEX_L: 102 case IC_VEX_L_XS: 103 case IC_VEX_L_XD: 104 return false; 105 case IC_VEX_L_OPSIZE: 106 return inheritsFrom(child, IC_VEX_L_W_OPSIZE); 107 case IC_VEX_L_W_OPSIZE: 108 return false; 109 default: 110 llvm_unreachable("Unknown instruction class"); 111 } 112} 113 114/// outranks - Indicates whether, if an instruction has two different applicable 115/// classes, which class should be preferred when performing decode. This 116/// imposes a total ordering (ties are resolved toward "lower") 117/// 118/// @param upper - The class that may be preferable 119/// @param lower - The class that may be less preferable 120/// @return - True if upper is to be preferred, false otherwise. 121static inline bool outranks(InstructionContext upper, 122 InstructionContext lower) { 123 assert(upper < IC_max); 124 assert(lower < IC_max); 125 126#define ENUM_ENTRY(n, r, d) r, 127 static int ranks[IC_max] = { 128 INSTRUCTION_CONTEXTS 129 }; 130#undef ENUM_ENTRY 131 132 return (ranks[upper] > ranks[lower]); 133} 134 135/// stringForContext - Returns a string containing the name of a particular 136/// InstructionContext, usually for diagnostic purposes. 137/// 138/// @param insnContext - The instruction class to transform to a string. 139/// @return - A statically-allocated string constant that contains the 140/// name of the instruction class. 141static inline const char* stringForContext(InstructionContext insnContext) { 142 switch (insnContext) { 143 default: 144 llvm_unreachable("Unhandled instruction class"); 145#define ENUM_ENTRY(n, r, d) case n: return #n; break; 146 INSTRUCTION_CONTEXTS 147#undef ENUM_ENTRY 148 } 149} 150 151/// stringForOperandType - Like stringForContext, but for OperandTypes. 152static inline const char* stringForOperandType(OperandType type) { 153 switch (type) { 154 default: 155 llvm_unreachable("Unhandled type"); 156#define ENUM_ENTRY(i, d) case i: return #i; 157 TYPES 158#undef ENUM_ENTRY 159 } 160} 161 162/// stringForOperandEncoding - like stringForContext, but for 163/// OperandEncodings. 164static inline const char* stringForOperandEncoding(OperandEncoding encoding) { 165 switch (encoding) { 166 default: 167 llvm_unreachable("Unhandled encoding"); 168#define ENUM_ENTRY(i, d) case i: return #i; 169 ENCODINGS 170#undef ENUM_ENTRY 171 } 172} 173 174void DisassemblerTables::emitOneID(raw_ostream &o, unsigned &i, InstrUID id, 175 bool addComma) const { 176 if (id) 177 o.indent(i * 2) << format("0x%hx", id); 178 else 179 o.indent(i * 2) << 0; 180 181 if (addComma) 182 o << ", "; 183 else 184 o << " "; 185 186 o << "/* "; 187 o << InstructionSpecifiers[id].name; 188 o << "*/"; 189 190 o << "\n"; 191} 192 193/// emitEmptyTable - Emits the modRMEmptyTable, which is used as a ID table by 194/// all ModR/M decisions for instructions that are invalid for all possible 195/// ModR/M byte values. 196/// 197/// @param o - The output stream on which to emit the table. 198/// @param i - The indentation level for that output stream. 199static void emitEmptyTable(raw_ostream &o, unsigned &i) { 200 o.indent(i * 2) << "0x0, /* EmptyTable */\n"; 201} 202 203/// getDecisionType - Determines whether a ModRM decision with 255 entries can 204/// be compacted by eliminating redundant information. 205/// 206/// @param decision - The decision to be compacted. 207/// @return - The compactest available representation for the decision. 208static ModRMDecisionType getDecisionType(ModRMDecision &decision) { 209 bool satisfiesOneEntry = true; 210 bool satisfiesSplitRM = true; 211 bool satisfiesSplitReg = true; 212 bool satisfiesSplitMisc = true; 213 214 for (unsigned index = 0; index < 256; ++index) { 215 if (decision.instructionIDs[index] != decision.instructionIDs[0]) 216 satisfiesOneEntry = false; 217 218 if (((index & 0xc0) == 0xc0) && 219 (decision.instructionIDs[index] != decision.instructionIDs[0xc0])) 220 satisfiesSplitRM = false; 221 222 if (((index & 0xc0) != 0xc0) && 223 (decision.instructionIDs[index] != decision.instructionIDs[0x00])) 224 satisfiesSplitRM = false; 225 226 if (((index & 0xc0) == 0xc0) && 227 (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8])) 228 satisfiesSplitReg = false; 229 230 if (((index & 0xc0) != 0xc0) && 231 (decision.instructionIDs[index] != decision.instructionIDs[index&0x38])) 232 satisfiesSplitMisc = false; 233 } 234 235 if (satisfiesOneEntry) 236 return MODRM_ONEENTRY; 237 238 if (satisfiesSplitRM) 239 return MODRM_SPLITRM; 240 241 if (satisfiesSplitReg && satisfiesSplitMisc) 242 return MODRM_SPLITREG; 243 244 if (satisfiesSplitMisc) 245 return MODRM_SPLITMISC; 246 247 return MODRM_FULL; 248} 249 250/// stringForDecisionType - Returns a statically-allocated string corresponding 251/// to a particular decision type. 252/// 253/// @param dt - The decision type. 254/// @return - A pointer to the statically-allocated string (e.g., 255/// "MODRM_ONEENTRY" for MODRM_ONEENTRY). 256static const char* stringForDecisionType(ModRMDecisionType dt) { 257#define ENUM_ENTRY(n) case n: return #n; 258 switch (dt) { 259 default: 260 llvm_unreachable("Unknown decision type"); 261 MODRMTYPES 262 }; 263#undef ENUM_ENTRY 264} 265 266/// stringForModifierType - Returns a statically-allocated string corresponding 267/// to an opcode modifier type. 268/// 269/// @param mt - The modifier type. 270/// @return - A pointer to the statically-allocated string (e.g., 271/// "MODIFIER_NONE" for MODIFIER_NONE). 272static const char* stringForModifierType(ModifierType mt) { 273#define ENUM_ENTRY(n) case n: return #n; 274 switch(mt) { 275 default: 276 llvm_unreachable("Unknown modifier type"); 277 MODIFIER_TYPES 278 }; 279#undef ENUM_ENTRY 280} 281 282DisassemblerTables::DisassemblerTables() { 283 unsigned i; 284 285 for (i = 0; i < array_lengthof(Tables); i++) { 286 Tables[i] = new ContextDecision; 287 memset(Tables[i], 0, sizeof(ContextDecision)); 288 } 289 290 HasConflicts = false; 291} 292 293DisassemblerTables::~DisassemblerTables() { 294 unsigned i; 295 296 for (i = 0; i < array_lengthof(Tables); i++) 297 delete Tables[i]; 298} 299 300void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, 301 unsigned &i1, unsigned &i2, 302 ModRMDecision &decision) const { 303 static uint32_t sTableNumber = 0; 304 static uint32_t sEntryNumber = 1; 305 ModRMDecisionType dt = getDecisionType(decision); 306 307 if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) 308 { 309 o2.indent(i2) << "{ /* ModRMDecision */" << "\n"; 310 i2++; 311 312 o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; 313 o2.indent(i2) << 0 << " /* EmptyTable */\n"; 314 315 i2--; 316 o2.indent(i2) << "}"; 317 return; 318 } 319 320 o1 << "/* Table" << sTableNumber << " */\n"; 321 i1++; 322 323 switch (dt) { 324 default: 325 llvm_unreachable("Unknown decision type"); 326 case MODRM_ONEENTRY: 327 emitOneID(o1, i1, decision.instructionIDs[0], true); 328 break; 329 case MODRM_SPLITRM: 330 emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00 331 emitOneID(o1, i1, decision.instructionIDs[0xc0], true); // mod = 0b11 332 break; 333 case MODRM_SPLITREG: 334 for (unsigned index = 0; index < 64; index += 8) 335 emitOneID(o1, i1, decision.instructionIDs[index], true); 336 for (unsigned index = 0xc0; index < 256; index += 8) 337 emitOneID(o1, i1, decision.instructionIDs[index], true); 338 break; 339 case MODRM_SPLITMISC: 340 for (unsigned index = 0; index < 64; index += 8) 341 emitOneID(o1, i1, decision.instructionIDs[index], true); 342 for (unsigned index = 0xc0; index < 256; ++index) 343 emitOneID(o1, i1, decision.instructionIDs[index], true); 344 break; 345 case MODRM_FULL: 346 for (unsigned index = 0; index < 256; ++index) 347 emitOneID(o1, i1, decision.instructionIDs[index], true); 348 break; 349 } 350 351 i1--; 352 353 o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n"; 354 i2++; 355 356 o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; 357 o2.indent(i2) << sEntryNumber << " /* Table" << sTableNumber << " */\n"; 358 359 i2--; 360 o2.indent(i2) << "}"; 361 362 switch (dt) { 363 default: 364 llvm_unreachable("Unknown decision type"); 365 case MODRM_ONEENTRY: 366 sEntryNumber += 1; 367 break; 368 case MODRM_SPLITRM: 369 sEntryNumber += 2; 370 break; 371 case MODRM_SPLITREG: 372 sEntryNumber += 16; 373 break; 374 case MODRM_SPLITMISC: 375 sEntryNumber += 8 + 64; 376 break; 377 case MODRM_FULL: 378 sEntryNumber += 256; 379 break; 380 } 381 382 // We assume that the index can fit into uint16_t. 383 assert(sEntryNumber < 65536U && 384 "Index into ModRMDecision is too large for uint16_t!"); 385 386 ++sTableNumber; 387} 388 389void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, 390 unsigned &i1, unsigned &i2, 391 OpcodeDecision &decision) const { 392 o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n"; 393 i2++; 394 o2.indent(i2) << "{" << "\n"; 395 i2++; 396 397 for (unsigned index = 0; index < 256; ++index) { 398 o2.indent(i2); 399 400 o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n"; 401 402 emitModRMDecision(o1, o2, i1, i2, decision.modRMDecisions[index]); 403 404 if (index < 255) 405 o2 << ","; 406 407 o2 << "\n"; 408 } 409 410 i2--; 411 o2.indent(i2) << "}" << "\n"; 412 i2--; 413 o2.indent(i2) << "}" << "\n"; 414} 415 416void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, 417 unsigned &i1, unsigned &i2, 418 ContextDecision &decision, 419 const char* name) const { 420 o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n"; 421 i2++; 422 o2.indent(i2) << "{ /* opcodeDecisions */" << "\n"; 423 i2++; 424 425 for (unsigned index = 0; index < IC_max; ++index) { 426 o2.indent(i2) << "/* "; 427 o2 << stringForContext((InstructionContext)index); 428 o2 << " */"; 429 o2 << "\n"; 430 431 emitOpcodeDecision(o1, o2, i1, i2, decision.opcodeDecisions[index]); 432 433 if (index + 1 < IC_max) 434 o2 << ", "; 435 } 436 437 i2--; 438 o2.indent(i2) << "}" << "\n"; 439 i2--; 440 o2.indent(i2) << "};" << "\n"; 441} 442 443void DisassemblerTables::emitInstructionInfo(raw_ostream &o, 444 unsigned &i) const { 445 unsigned NumInstructions = InstructionSpecifiers.size(); 446 447 o << "static const struct OperandSpecifier x86OperandSets[][" 448 << X86_MAX_OPERANDS << "] = {\n"; 449 450 typedef std::vector<std::pair<const char *, const char *> > OperandListTy; 451 std::map<OperandListTy, unsigned> OperandSets; 452 453 unsigned OperandSetNum = 0; 454 for (unsigned Index = 0; Index < NumInstructions; ++Index) { 455 OperandListTy OperandList; 456 457 for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; 458 ++OperandIndex) { 459 const char *Encoding = 460 stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[Index] 461 .operands[OperandIndex].encoding); 462 const char *Type = 463 stringForOperandType((OperandType)InstructionSpecifiers[Index] 464 .operands[OperandIndex].type); 465 OperandList.push_back(std::make_pair(Encoding, Type)); 466 } 467 unsigned &N = OperandSets[OperandList]; 468 if (N != 0) continue; 469 470 N = ++OperandSetNum; 471 472 o << " { /* " << (OperandSetNum - 1) << " */\n"; 473 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) { 474 o << " { " << OperandList[i].first << ", " 475 << OperandList[i].second << " },\n"; 476 } 477 o << " },\n"; 478 } 479 o << "};" << "\n\n"; 480 481 o.indent(i * 2) << "static const struct InstructionSpecifier "; 482 o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n"; 483 484 i++; 485 486 for (unsigned index = 0; index < NumInstructions; ++index) { 487 o.indent(i * 2) << "{ /* " << index << " */" << "\n"; 488 i++; 489 490 o.indent(i * 2) << stringForModifierType( 491 (ModifierType)InstructionSpecifiers[index].modifierType); 492 o << ",\n"; 493 494 o.indent(i * 2) << "0x"; 495 o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase); 496 o << ",\n"; 497 498 OperandListTy OperandList; 499 for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; 500 ++OperandIndex) { 501 const char *Encoding = 502 stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[index] 503 .operands[OperandIndex].encoding); 504 const char *Type = 505 stringForOperandType((OperandType)InstructionSpecifiers[index] 506 .operands[OperandIndex].type); 507 OperandList.push_back(std::make_pair(Encoding, Type)); 508 } 509 o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n"; 510 511 o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */"; 512 o << "\n"; 513 514 i--; 515 o.indent(i * 2) << "}"; 516 517 if (index + 1 < NumInstructions) 518 o << ","; 519 520 o << "\n"; 521 } 522 523 i--; 524 o.indent(i * 2) << "};" << "\n"; 525} 526 527void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const { 528 o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR 529 "[256] = {\n"; 530 i++; 531 532 for (unsigned index = 0; index < 256; ++index) { 533 o.indent(i * 2); 534 535 if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) 536 o << "IC_VEX_L_W_OPSIZE"; 537 else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE)) 538 o << "IC_VEX_L_OPSIZE"; 539 else if ((index & ATTR_VEXL) && (index & ATTR_XD)) 540 o << "IC_VEX_L_XD"; 541 else if ((index & ATTR_VEXL) && (index & ATTR_XS)) 542 o << "IC_VEX_L_XS"; 543 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) 544 o << "IC_VEX_W_OPSIZE"; 545 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XD)) 546 o << "IC_VEX_W_XD"; 547 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XS)) 548 o << "IC_VEX_W_XS"; 549 else if (index & ATTR_VEXL) 550 o << "IC_VEX_L"; 551 else if ((index & ATTR_VEX) && (index & ATTR_REXW)) 552 o << "IC_VEX_W"; 553 else if ((index & ATTR_VEX) && (index & ATTR_OPSIZE)) 554 o << "IC_VEX_OPSIZE"; 555 else if ((index & ATTR_VEX) && (index & ATTR_XD)) 556 o << "IC_VEX_XD"; 557 else if ((index & ATTR_VEX) && (index & ATTR_XS)) 558 o << "IC_VEX_XS"; 559 else if (index & ATTR_VEX) 560 o << "IC_VEX"; 561 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) 562 o << "IC_64BIT_REXW_XS"; 563 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) 564 o << "IC_64BIT_REXW_XD"; 565 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 566 (index & ATTR_OPSIZE)) 567 o << "IC_64BIT_REXW_OPSIZE"; 568 else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE)) 569 o << "IC_64BIT_XD_OPSIZE"; 570 else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE)) 571 o << "IC_64BIT_XS_OPSIZE"; 572 else if ((index & ATTR_64BIT) && (index & ATTR_XS)) 573 o << "IC_64BIT_XS"; 574 else if ((index & ATTR_64BIT) && (index & ATTR_XD)) 575 o << "IC_64BIT_XD"; 576 else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE)) 577 o << "IC_64BIT_OPSIZE"; 578 else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE)) 579 o << "IC_64BIT_ADSIZE"; 580 else if ((index & ATTR_64BIT) && (index & ATTR_REXW)) 581 o << "IC_64BIT_REXW"; 582 else if ((index & ATTR_64BIT)) 583 o << "IC_64BIT"; 584 else if ((index & ATTR_XS) && (index & ATTR_OPSIZE)) 585 o << "IC_XS_OPSIZE"; 586 else if ((index & ATTR_XD) && (index & ATTR_OPSIZE)) 587 o << "IC_XD_OPSIZE"; 588 else if (index & ATTR_XS) 589 o << "IC_XS"; 590 else if (index & ATTR_XD) 591 o << "IC_XD"; 592 else if (index & ATTR_OPSIZE) 593 o << "IC_OPSIZE"; 594 else if (index & ATTR_ADSIZE) 595 o << "IC_ADSIZE"; 596 else 597 o << "IC"; 598 599 if (index < 255) 600 o << ","; 601 else 602 o << " "; 603 604 o << " /* " << index << " */"; 605 606 o << "\n"; 607 } 608 609 i--; 610 o.indent(i * 2) << "};" << "\n"; 611} 612 613void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2, 614 unsigned &i1, unsigned &i2) const { 615 emitContextDecision(o1, o2, i1, i2, *Tables[0], ONEBYTE_STR); 616 emitContextDecision(o1, o2, i1, i2, *Tables[1], TWOBYTE_STR); 617 emitContextDecision(o1, o2, i1, i2, *Tables[2], THREEBYTE38_STR); 618 emitContextDecision(o1, o2, i1, i2, *Tables[3], THREEBYTE3A_STR); 619 emitContextDecision(o1, o2, i1, i2, *Tables[4], THREEBYTEA6_STR); 620 emitContextDecision(o1, o2, i1, i2, *Tables[5], THREEBYTEA7_STR); 621} 622 623void DisassemblerTables::emit(raw_ostream &o) const { 624 unsigned i1 = 0; 625 unsigned i2 = 0; 626 627 std::string s1; 628 std::string s2; 629 630 raw_string_ostream o1(s1); 631 raw_string_ostream o2(s2); 632 633 emitInstructionInfo(o, i2); 634 o << "\n"; 635 636 emitContextTable(o, i2); 637 o << "\n"; 638 639 o << "static const InstrUID modRMTable[] = {\n"; 640 i1++; 641 emitEmptyTable(o1, i1); 642 i1--; 643 emitContextDecisions(o1, o2, i1, i2); 644 645 o << o1.str(); 646 o << " 0x0\n"; 647 o << "};\n"; 648 o << "\n"; 649 o << o2.str(); 650 o << "\n"; 651 o << "\n"; 652} 653 654void DisassemblerTables::setTableFields(ModRMDecision &decision, 655 const ModRMFilter &filter, 656 InstrUID uid, 657 uint8_t opcode) { 658 for (unsigned index = 0; index < 256; ++index) { 659 if (filter.accepts(index)) { 660 if (decision.instructionIDs[index] == uid) 661 continue; 662 663 if (decision.instructionIDs[index] != 0) { 664 InstructionSpecifier &newInfo = 665 InstructionSpecifiers[uid]; 666 InstructionSpecifier &previousInfo = 667 InstructionSpecifiers[decision.instructionIDs[index]]; 668 669 if(newInfo.filtered) 670 continue; // filtered instructions get lowest priority 671 672 if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" || 673 newInfo.name == "XCHG32ar" || 674 newInfo.name == "XCHG32ar64" || 675 newInfo.name == "XCHG64ar")) 676 continue; // special case for XCHG*ar and NOOP 677 678 if (outranks(previousInfo.insnContext, newInfo.insnContext)) 679 continue; 680 681 if (previousInfo.insnContext == newInfo.insnContext && 682 !previousInfo.filtered) { 683 errs() << "Error: Primary decode conflict: "; 684 errs() << newInfo.name << " would overwrite " << previousInfo.name; 685 errs() << "\n"; 686 errs() << "ModRM " << index << "\n"; 687 errs() << "Opcode " << (uint16_t)opcode << "\n"; 688 errs() << "Context " << stringForContext(newInfo.insnContext) << "\n"; 689 HasConflicts = true; 690 } 691 } 692 693 decision.instructionIDs[index] = uid; 694 } 695 } 696} 697 698void DisassemblerTables::setTableFields(OpcodeType type, 699 InstructionContext insnContext, 700 uint8_t opcode, 701 const ModRMFilter &filter, 702 InstrUID uid, 703 bool is32bit, 704 bool ignoresVEX_L) { 705 ContextDecision &decision = *Tables[type]; 706 707 for (unsigned index = 0; index < IC_max; ++index) { 708 if (is32bit && inheritsFrom((InstructionContext)index, IC_64BIT)) 709 continue; 710 711 if (inheritsFrom((InstructionContext)index, 712 InstructionSpecifiers[uid].insnContext, ignoresVEX_L)) 713 setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], 714 filter, 715 uid, 716 opcode); 717 } 718} 719