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) << "static const InstrUID modRMEmptyTable[1] = { 0 };\n"; 200 o << "\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. 208 static ModRMDecisionType getDecisionType(ModRMDecision &decision) 209 { 210 bool satisfiesOneEntry = true; 211 bool satisfiesSplitRM = 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 228 if (satisfiesOneEntry) 229 return MODRM_ONEENTRY; 230 231 if (satisfiesSplitRM) 232 return MODRM_SPLITRM; 233 234 return MODRM_FULL; 235 } 236 237 /// stringForDecisionType - Returns a statically-allocated string corresponding 238 /// to a particular decision type. 239 /// 240 /// @param dt - The decision type. 241 /// @return - A pointer to the statically-allocated string (e.g., 242 /// "MODRM_ONEENTRY" for MODRM_ONEENTRY). 243 static const char* stringForDecisionType(ModRMDecisionType dt) 244 { 245 #define ENUM_ENTRY(n) case n: return #n; 246 switch (dt) { 247 default: 248 llvm_unreachable("Unknown decision type"); 249 MODRMTYPES 250 }; 251 #undef ENUM_ENTRY 252 } 253 254 /// stringForModifierType - Returns a statically-allocated string corresponding 255 /// to an opcode modifier type. 256 /// 257 /// @param mt - The modifier type. 258 /// @return - A pointer to the statically-allocated string (e.g., 259 /// "MODIFIER_NONE" for MODIFIER_NONE). 260 static const char* stringForModifierType(ModifierType mt) 261 { 262 #define ENUM_ENTRY(n) case n: return #n; 263 switch(mt) { 264 default: 265 llvm_unreachable("Unknown modifier type"); 266 MODIFIER_TYPES 267 }; 268 #undef ENUM_ENTRY 269 } 270 271 DisassemblerTables::DisassemblerTables() { 272 unsigned i; 273 274 for (i = 0; i < array_lengthof(Tables); i++) { 275 Tables[i] = new ContextDecision; 276 memset(Tables[i], 0, sizeof(ContextDecision)); 277 } 278 279 HasConflicts = false; 280 } 281 282 DisassemblerTables::~DisassemblerTables() { 283 unsigned i; 284 285 for (i = 0; i < array_lengthof(Tables); i++) 286 delete Tables[i]; 287 } 288 289 void DisassemblerTables::emitModRMDecision(raw_ostream &o1, 290 raw_ostream &o2, 291 uint32_t &i1, 292 uint32_t &i2, 293 ModRMDecision &decision) 294 const { 295 static uint64_t sTableNumber = 0; 296 uint64_t thisTableNumber = sTableNumber; 297 ModRMDecisionType dt = getDecisionType(decision); 298 uint16_t index; 299 300 if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) 301 { 302 o2.indent(i2) << "{ /* ModRMDecision */" << "\n"; 303 i2++; 304 305 o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; 306 o2.indent(i2) << "modRMEmptyTable"; 307 308 i2--; 309 o2.indent(i2) << "}"; 310 return; 311 } 312 313 o1.indent(i1) << "static const InstrUID modRMTable" << thisTableNumber; 314 315 switch (dt) { 316 default: 317 llvm_unreachable("Unknown decision type"); 318 case MODRM_ONEENTRY: 319 o1 << "[1]"; 320 break; 321 case MODRM_SPLITRM: 322 o1 << "[2]"; 323 break; 324 case MODRM_FULL: 325 o1 << "[256]"; 326 break; 327 } 328 329 o1 << " = {" << "\n"; 330 i1++; 331 332 switch (dt) { 333 default: 334 llvm_unreachable("Unknown decision type"); 335 case MODRM_ONEENTRY: 336 emitOneID(o1, i1, decision.instructionIDs[0], false); 337 break; 338 case MODRM_SPLITRM: 339 emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00 340 emitOneID(o1, i1, decision.instructionIDs[0xc0], false); // mod = 0b11 341 break; 342 case MODRM_FULL: 343 for (index = 0; index < 256; ++index) 344 emitOneID(o1, i1, decision.instructionIDs[index], index < 255); 345 break; 346 } 347 348 i1--; 349 o1.indent(i1) << "};" << "\n"; 350 o1 << "\n"; 351 352 o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n"; 353 i2++; 354 355 o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; 356 o2.indent(i2) << "modRMTable" << sTableNumber << "\n"; 357 358 i2--; 359 o2.indent(i2) << "}"; 360 361 ++sTableNumber; 362 } 363 364 void DisassemblerTables::emitOpcodeDecision( 365 raw_ostream &o1, 366 raw_ostream &o2, 367 uint32_t &i1, 368 uint32_t &i2, 369 OpcodeDecision &decision) const { 370 uint16_t index; 371 372 o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n"; 373 i2++; 374 o2.indent(i2) << "{" << "\n"; 375 i2++; 376 377 for (index = 0; index < 256; ++index) { 378 o2.indent(i2); 379 380 o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n"; 381 382 emitModRMDecision(o1, o2, i1, i2, decision.modRMDecisions[index]); 383 384 if (index < 255) 385 o2 << ","; 386 387 o2 << "\n"; 388 } 389 390 i2--; 391 o2.indent(i2) << "}" << "\n"; 392 i2--; 393 o2.indent(i2) << "}" << "\n"; 394 } 395 396 void DisassemblerTables::emitContextDecision( 397 raw_ostream &o1, 398 raw_ostream &o2, 399 uint32_t &i1, 400 uint32_t &i2, 401 ContextDecision &decision, 402 const char* name) const { 403 o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n"; 404 i2++; 405 o2.indent(i2) << "{ /* opcodeDecisions */" << "\n"; 406 i2++; 407 408 unsigned index; 409 410 for (index = 0; index < IC_max; ++index) { 411 o2.indent(i2) << "/* "; 412 o2 << stringForContext((InstructionContext)index); 413 o2 << " */"; 414 o2 << "\n"; 415 416 emitOpcodeDecision(o1, o2, i1, i2, decision.opcodeDecisions[index]); 417 418 if (index + 1 < IC_max) 419 o2 << ", "; 420 } 421 422 i2--; 423 o2.indent(i2) << "}" << "\n"; 424 i2--; 425 o2.indent(i2) << "};" << "\n"; 426 } 427 428 void DisassemblerTables::emitInstructionInfo(raw_ostream &o, uint32_t &i) 429 const { 430 o.indent(i * 2) << "static const struct InstructionSpecifier "; 431 o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n"; 432 433 i++; 434 435 uint16_t numInstructions = InstructionSpecifiers.size(); 436 uint16_t index, operandIndex; 437 438 for (index = 0; index < numInstructions; ++index) { 439 o.indent(i * 2) << "{ /* " << index << " */" << "\n"; 440 i++; 441 442 o.indent(i * 2) << 443 stringForModifierType(InstructionSpecifiers[index].modifierType); 444 o << "," << "\n"; 445 446 o.indent(i * 2) << "0x"; 447 o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase); 448 o << "," << "\n"; 449 450 o.indent(i * 2) << "{" << "\n"; 451 i++; 452 453 for (operandIndex = 0; operandIndex < X86_MAX_OPERANDS; ++operandIndex) { 454 o.indent(i * 2) << "{ "; 455 o << stringForOperandEncoding(InstructionSpecifiers[index] 456 .operands[operandIndex] 457 .encoding); 458 o << ", "; 459 o << stringForOperandType(InstructionSpecifiers[index] 460 .operands[operandIndex] 461 .type); 462 o << " }"; 463 464 if (operandIndex < X86_MAX_OPERANDS - 1) 465 o << ","; 466 467 o << "\n"; 468 } 469 470 i--; 471 o.indent(i * 2) << "}," << "\n"; 472 473 o.indent(i * 2) << "\"" << InstructionSpecifiers[index].name << "\""; 474 o << "\n"; 475 476 i--; 477 o.indent(i * 2) << "}"; 478 479 if (index + 1 < numInstructions) 480 o << ","; 481 482 o << "\n"; 483 } 484 485 i--; 486 o.indent(i * 2) << "};" << "\n"; 487 } 488 489 void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const { 490 uint16_t index; 491 492 o.indent(i * 2) << "static const InstructionContext " CONTEXTS_STR 493 "[256] = {\n"; 494 i++; 495 496 for (index = 0; index < 256; ++index) { 497 o.indent(i * 2); 498 499 if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) 500 o << "IC_VEX_L_W_OPSIZE"; 501 else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE)) 502 o << "IC_VEX_L_OPSIZE"; 503 else if ((index & ATTR_VEXL) && (index & ATTR_XD)) 504 o << "IC_VEX_L_XD"; 505 else if ((index & ATTR_VEXL) && (index & ATTR_XS)) 506 o << "IC_VEX_L_XS"; 507 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) 508 o << "IC_VEX_W_OPSIZE"; 509 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XD)) 510 o << "IC_VEX_W_XD"; 511 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XS)) 512 o << "IC_VEX_W_XS"; 513 else if (index & ATTR_VEXL) 514 o << "IC_VEX_L"; 515 else if ((index & ATTR_VEX) && (index & ATTR_REXW)) 516 o << "IC_VEX_W"; 517 else if ((index & ATTR_VEX) && (index & ATTR_OPSIZE)) 518 o << "IC_VEX_OPSIZE"; 519 else if ((index & ATTR_VEX) && (index & ATTR_XD)) 520 o << "IC_VEX_XD"; 521 else if ((index & ATTR_VEX) && (index & ATTR_XS)) 522 o << "IC_VEX_XS"; 523 else if (index & ATTR_VEX) 524 o << "IC_VEX"; 525 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) 526 o << "IC_64BIT_REXW_XS"; 527 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) 528 o << "IC_64BIT_REXW_XD"; 529 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 530 (index & ATTR_OPSIZE)) 531 o << "IC_64BIT_REXW_OPSIZE"; 532 else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE)) 533 o << "IC_64BIT_XD_OPSIZE"; 534 else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE)) 535 o << "IC_64BIT_XS_OPSIZE"; 536 else if ((index & ATTR_64BIT) && (index & ATTR_XS)) 537 o << "IC_64BIT_XS"; 538 else if ((index & ATTR_64BIT) && (index & ATTR_XD)) 539 o << "IC_64BIT_XD"; 540 else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE)) 541 o << "IC_64BIT_OPSIZE"; 542 else if ((index & ATTR_64BIT) && (index & ATTR_REXW)) 543 o << "IC_64BIT_REXW"; 544 else if ((index & ATTR_64BIT)) 545 o << "IC_64BIT"; 546 else if ((index & ATTR_XS) && (index & ATTR_OPSIZE)) 547 o << "IC_XS_OPSIZE"; 548 else if ((index & ATTR_XD) && (index & ATTR_OPSIZE)) 549 o << "IC_XD_OPSIZE"; 550 else if (index & ATTR_XS) 551 o << "IC_XS"; 552 else if (index & ATTR_XD) 553 o << "IC_XD"; 554 else if (index & ATTR_OPSIZE) 555 o << "IC_OPSIZE"; 556 else 557 o << "IC"; 558 559 if (index < 255) 560 o << ","; 561 else 562 o << " "; 563 564 o << " /* " << index << " */"; 565 566 o << "\n"; 567 } 568 569 i--; 570 o.indent(i * 2) << "};" << "\n"; 571 } 572 573 void DisassemblerTables::emitContextDecisions(raw_ostream &o1, 574 raw_ostream &o2, 575 uint32_t &i1, 576 uint32_t &i2) 577 const { 578 emitContextDecision(o1, o2, i1, i2, *Tables[0], ONEBYTE_STR); 579 emitContextDecision(o1, o2, i1, i2, *Tables[1], TWOBYTE_STR); 580 emitContextDecision(o1, o2, i1, i2, *Tables[2], THREEBYTE38_STR); 581 emitContextDecision(o1, o2, i1, i2, *Tables[3], THREEBYTE3A_STR); 582 emitContextDecision(o1, o2, i1, i2, *Tables[4], THREEBYTEA6_STR); 583 emitContextDecision(o1, o2, i1, i2, *Tables[5], THREEBYTEA7_STR); 584 } 585 586 void DisassemblerTables::emit(raw_ostream &o) const { 587 uint32_t i1 = 0; 588 uint32_t i2 = 0; 589 590 std::string s1; 591 std::string s2; 592 593 raw_string_ostream o1(s1); 594 raw_string_ostream o2(s2); 595 596 emitInstructionInfo(o, i2); 597 o << "\n"; 598 599 emitContextTable(o, i2); 600 o << "\n"; 601 602 emitEmptyTable(o1, i1); 603 emitContextDecisions(o1, o2, i1, i2); 604 605 o << o1.str(); 606 o << "\n"; 607 o << o2.str(); 608 o << "\n"; 609 o << "\n"; 610 } 611 612 void DisassemblerTables::setTableFields(ModRMDecision &decision, 613 const ModRMFilter &filter, 614 InstrUID uid, 615 uint8_t opcode) { 616 unsigned index; 617 618 for (index = 0; index < 256; ++index) { 619 if (filter.accepts(index)) { 620 if (decision.instructionIDs[index] == uid) 621 continue; 622 623 if (decision.instructionIDs[index] != 0) { 624 InstructionSpecifier &newInfo = 625 InstructionSpecifiers[uid]; 626 InstructionSpecifier &previousInfo = 627 InstructionSpecifiers[decision.instructionIDs[index]]; 628 629 if(newInfo.filtered) 630 continue; // filtered instructions get lowest priority 631 632 if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" || 633 newInfo.name == "XCHG32ar" || 634 newInfo.name == "XCHG32ar64" || 635 newInfo.name == "XCHG64ar")) 636 continue; // special case for XCHG*ar and NOOP 637 638 if (outranks(previousInfo.insnContext, newInfo.insnContext)) 639 continue; 640 641 if (previousInfo.insnContext == newInfo.insnContext && 642 !previousInfo.filtered) { 643 errs() << "Error: Primary decode conflict: "; 644 errs() << newInfo.name << " would overwrite " << previousInfo.name; 645 errs() << "\n"; 646 errs() << "ModRM " << index << "\n"; 647 errs() << "Opcode " << (uint16_t)opcode << "\n"; 648 errs() << "Context " << stringForContext(newInfo.insnContext) << "\n"; 649 HasConflicts = true; 650 } 651 } 652 653 decision.instructionIDs[index] = uid; 654 } 655 } 656 } 657 658 void DisassemblerTables::setTableFields(OpcodeType type, 659 InstructionContext insnContext, 660 uint8_t opcode, 661 const ModRMFilter &filter, 662 InstrUID uid, 663 bool is32bit, 664 bool ignoresVEX_L) { 665 unsigned index; 666 667 ContextDecision &decision = *Tables[type]; 668 669 for (index = 0; index < IC_max; ++index) { 670 if (is32bit && inheritsFrom((InstructionContext)index, IC_64BIT)) 671 continue; 672 673 if (inheritsFrom((InstructionContext)index, 674 InstructionSpecifiers[uid].insnContext, ignoresVEX_L)) 675 setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], 676 filter, 677 uid, 678 opcode); 679 } 680 } 681