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