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