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