X86DisassemblerTables.cpp revision 261991
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 "X86DisassemblerTables.h" 18#include "X86DisassemblerShared.h" 19#include "llvm/ADT/STLExtras.h" 20#include "llvm/Support/ErrorHandling.h" 21#include "llvm/Support/Format.h" 22#include "llvm/TableGen/TableGenBackend.h" 23#include <map> 24 25using namespace llvm; 26using 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. 34static 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 (VEX_LIG && inheritsFrom(child, IC_VEX_L_W)) || 85 inheritsFrom(child, IC_VEX_W) || 86 (VEX_LIG && inheritsFrom(child, IC_VEX_L)); 87 case IC_VEX_XS: 88 return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS)) || 89 inheritsFrom(child, IC_VEX_W_XS) || 90 (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS)); 91 case IC_VEX_XD: 92 return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD)) || 93 inheritsFrom(child, IC_VEX_W_XD) || 94 (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD)); 95 case IC_VEX_OPSIZE: 96 return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) || 97 inheritsFrom(child, IC_VEX_W_OPSIZE) || 98 (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE)); 99 case IC_VEX_W: 100 return VEX_LIG && inheritsFrom(child, IC_VEX_L_W); 101 case IC_VEX_W_XS: 102 return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS); 103 case IC_VEX_W_XD: 104 return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD); 105 case IC_VEX_W_OPSIZE: 106 return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE); 107 case IC_VEX_L: 108 return inheritsFrom(child, IC_VEX_L_W); 109 case IC_VEX_L_XS: 110 return inheritsFrom(child, IC_VEX_L_W_XS); 111 case IC_VEX_L_XD: 112 return inheritsFrom(child, IC_VEX_L_W_XD); 113 case IC_VEX_L_OPSIZE: 114 return inheritsFrom(child, IC_VEX_L_W_OPSIZE); 115 case IC_VEX_L_W: 116 case IC_VEX_L_W_XS: 117 case IC_VEX_L_W_XD: 118 case IC_VEX_L_W_OPSIZE: 119 return false; 120 case IC_EVEX: 121 return inheritsFrom(child, IC_EVEX_W) || 122 inheritsFrom(child, IC_EVEX_L_W); 123 case IC_EVEX_XS: 124 return inheritsFrom(child, IC_EVEX_W_XS) || 125 inheritsFrom(child, IC_EVEX_L_W_XS); 126 case IC_EVEX_XD: 127 return inheritsFrom(child, IC_EVEX_W_XD) || 128 inheritsFrom(child, IC_EVEX_L_W_XD); 129 case IC_EVEX_OPSIZE: 130 return inheritsFrom(child, IC_EVEX_W_OPSIZE) || 131 inheritsFrom(child, IC_EVEX_L_W_OPSIZE); 132 case IC_EVEX_W: 133 case IC_EVEX_W_XS: 134 case IC_EVEX_W_XD: 135 case IC_EVEX_W_OPSIZE: 136 return false; 137 case IC_EVEX_L: 138 case IC_EVEX_L_XS: 139 case IC_EVEX_L_XD: 140 case IC_EVEX_L_OPSIZE: 141 return false; 142 case IC_EVEX_L_W: 143 case IC_EVEX_L_W_XS: 144 case IC_EVEX_L_W_XD: 145 case IC_EVEX_L_W_OPSIZE: 146 return false; 147 case IC_EVEX_L2: 148 case IC_EVEX_L2_XS: 149 case IC_EVEX_L2_XD: 150 case IC_EVEX_L2_OPSIZE: 151 return false; 152 case IC_EVEX_L2_W: 153 case IC_EVEX_L2_W_XS: 154 case IC_EVEX_L2_W_XD: 155 case IC_EVEX_L2_W_OPSIZE: 156 return false; 157 case IC_EVEX_K: 158 return inheritsFrom(child, IC_EVEX_W_K) || 159 inheritsFrom(child, IC_EVEX_L_W_K); 160 case IC_EVEX_XS_K: 161 return inheritsFrom(child, IC_EVEX_W_XS_K) || 162 inheritsFrom(child, IC_EVEX_L_W_XS_K); 163 case IC_EVEX_XD_K: 164 return inheritsFrom(child, IC_EVEX_W_XD_K) || 165 inheritsFrom(child, IC_EVEX_L_W_XD_K); 166 case IC_EVEX_OPSIZE_K: 167 return inheritsFrom(child, IC_EVEX_W_OPSIZE_K) || 168 inheritsFrom(child, IC_EVEX_W_OPSIZE_K); 169 case IC_EVEX_W_K: 170 case IC_EVEX_W_XS_K: 171 case IC_EVEX_W_XD_K: 172 case IC_EVEX_W_OPSIZE_K: 173 return false; 174 case IC_EVEX_L_K: 175 case IC_EVEX_L_XS_K: 176 case IC_EVEX_L_XD_K: 177 case IC_EVEX_L_OPSIZE_K: 178 return false; 179 case IC_EVEX_W_KZ: 180 case IC_EVEX_W_XS_KZ: 181 case IC_EVEX_W_XD_KZ: 182 case IC_EVEX_W_OPSIZE_KZ: 183 return false; 184 case IC_EVEX_L_KZ: 185 case IC_EVEX_L_XS_KZ: 186 case IC_EVEX_L_XD_KZ: 187 case IC_EVEX_L_OPSIZE_KZ: 188 return false; 189 case IC_EVEX_L_W_K: 190 case IC_EVEX_L_W_XS_K: 191 case IC_EVEX_L_W_XD_K: 192 case IC_EVEX_L_W_OPSIZE_K: 193 case IC_EVEX_L_W_KZ: 194 case IC_EVEX_L_W_XS_KZ: 195 case IC_EVEX_L_W_XD_KZ: 196 case IC_EVEX_L_W_OPSIZE_KZ: 197 return false; 198 case IC_EVEX_L2_K: 199 case IC_EVEX_L2_B: 200 case IC_EVEX_L2_XS_K: 201 case IC_EVEX_L2_XD_K: 202 case IC_EVEX_L2_OPSIZE_K: 203 case IC_EVEX_L2_OPSIZE_B: 204 case IC_EVEX_L2_OPSIZE_K_B: 205 case IC_EVEX_L2_KZ: 206 case IC_EVEX_L2_XS_KZ: 207 case IC_EVEX_L2_XD_KZ: 208 case IC_EVEX_L2_OPSIZE_KZ: 209 case IC_EVEX_L2_OPSIZE_KZ_B: 210 return false; 211 case IC_EVEX_L2_W_K: 212 case IC_EVEX_L2_W_B: 213 case IC_EVEX_L2_W_XS_K: 214 case IC_EVEX_L2_W_XD_K: 215 case IC_EVEX_L2_W_OPSIZE_K: 216 case IC_EVEX_L2_W_OPSIZE_B: 217 case IC_EVEX_L2_W_OPSIZE_K_B: 218 case IC_EVEX_L2_W_KZ: 219 case IC_EVEX_L2_W_XS_KZ: 220 case IC_EVEX_L2_W_XD_KZ: 221 case IC_EVEX_L2_W_OPSIZE_KZ: 222 case IC_EVEX_L2_W_OPSIZE_KZ_B: 223 return false; 224 default: 225 llvm_unreachable("Unknown instruction class"); 226 } 227} 228 229/// outranks - Indicates whether, if an instruction has two different applicable 230/// classes, which class should be preferred when performing decode. This 231/// imposes a total ordering (ties are resolved toward "lower") 232/// 233/// @param upper - The class that may be preferable 234/// @param lower - The class that may be less preferable 235/// @return - True if upper is to be preferred, false otherwise. 236static inline bool outranks(InstructionContext upper, 237 InstructionContext lower) { 238 assert(upper < IC_max); 239 assert(lower < IC_max); 240 241#define ENUM_ENTRY(n, r, d) r, 242#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) \ 243 ENUM_ENTRY(n##_K_B, r, d) ENUM_ENTRY(n##_KZ_B, r, d) \ 244 ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d) 245 static int ranks[IC_max] = { 246 INSTRUCTION_CONTEXTS 247 }; 248#undef ENUM_ENTRY 249#undef ENUM_ENTRY_K_B 250 251 return (ranks[upper] > ranks[lower]); 252} 253 254/// stringForContext - Returns a string containing the name of a particular 255/// InstructionContext, usually for diagnostic purposes. 256/// 257/// @param insnContext - The instruction class to transform to a string. 258/// @return - A statically-allocated string constant that contains the 259/// name of the instruction class. 260static inline const char* stringForContext(InstructionContext insnContext) { 261 switch (insnContext) { 262 default: 263 llvm_unreachable("Unhandled instruction class"); 264#define ENUM_ENTRY(n, r, d) case n: return #n; break; 265#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) ENUM_ENTRY(n##_K_B, r, d)\ 266 ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d)\ 267 ENUM_ENTRY(n##_KZ_B, r, d) 268 INSTRUCTION_CONTEXTS 269#undef ENUM_ENTRY 270#undef ENUM_ENTRY_K_B 271 } 272} 273 274/// stringForOperandType - Like stringForContext, but for OperandTypes. 275static inline const char* stringForOperandType(OperandType type) { 276 switch (type) { 277 default: 278 llvm_unreachable("Unhandled type"); 279#define ENUM_ENTRY(i, d) case i: return #i; 280 TYPES 281#undef ENUM_ENTRY 282 } 283} 284 285/// stringForOperandEncoding - like stringForContext, but for 286/// OperandEncodings. 287static inline const char* stringForOperandEncoding(OperandEncoding encoding) { 288 switch (encoding) { 289 default: 290 llvm_unreachable("Unhandled encoding"); 291#define ENUM_ENTRY(i, d) case i: return #i; 292 ENCODINGS 293#undef ENUM_ENTRY 294 } 295} 296 297/// getDecisionType - Determines whether a ModRM decision with 255 entries can 298/// be compacted by eliminating redundant information. 299/// 300/// @param decision - The decision to be compacted. 301/// @return - The compactest available representation for the decision. 302static ModRMDecisionType getDecisionType(ModRMDecision &decision) { 303 bool satisfiesOneEntry = true; 304 bool satisfiesSplitRM = true; 305 bool satisfiesSplitReg = true; 306 bool satisfiesSplitMisc = true; 307 308 for (unsigned index = 0; index < 256; ++index) { 309 if (decision.instructionIDs[index] != decision.instructionIDs[0]) 310 satisfiesOneEntry = false; 311 312 if (((index & 0xc0) == 0xc0) && 313 (decision.instructionIDs[index] != decision.instructionIDs[0xc0])) 314 satisfiesSplitRM = false; 315 316 if (((index & 0xc0) != 0xc0) && 317 (decision.instructionIDs[index] != decision.instructionIDs[0x00])) 318 satisfiesSplitRM = false; 319 320 if (((index & 0xc0) == 0xc0) && 321 (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8])) 322 satisfiesSplitReg = false; 323 324 if (((index & 0xc0) != 0xc0) && 325 (decision.instructionIDs[index] != decision.instructionIDs[index&0x38])) 326 satisfiesSplitMisc = false; 327 } 328 329 if (satisfiesOneEntry) 330 return MODRM_ONEENTRY; 331 332 if (satisfiesSplitRM) 333 return MODRM_SPLITRM; 334 335 if (satisfiesSplitReg && satisfiesSplitMisc) 336 return MODRM_SPLITREG; 337 338 if (satisfiesSplitMisc) 339 return MODRM_SPLITMISC; 340 341 return MODRM_FULL; 342} 343 344/// stringForDecisionType - Returns a statically-allocated string corresponding 345/// to a particular decision type. 346/// 347/// @param dt - The decision type. 348/// @return - A pointer to the statically-allocated string (e.g., 349/// "MODRM_ONEENTRY" for MODRM_ONEENTRY). 350static const char* stringForDecisionType(ModRMDecisionType dt) { 351#define ENUM_ENTRY(n) case n: return #n; 352 switch (dt) { 353 default: 354 llvm_unreachable("Unknown decision type"); 355 MODRMTYPES 356 }; 357#undef ENUM_ENTRY 358} 359 360/// stringForModifierType - Returns a statically-allocated string corresponding 361/// to an opcode modifier type. 362/// 363/// @param mt - The modifier type. 364/// @return - A pointer to the statically-allocated string (e.g., 365/// "MODIFIER_NONE" for MODIFIER_NONE). 366static const char* stringForModifierType(ModifierType mt) { 367#define ENUM_ENTRY(n) case n: return #n; 368 switch(mt) { 369 default: 370 llvm_unreachable("Unknown modifier type"); 371 MODIFIER_TYPES 372 }; 373#undef ENUM_ENTRY 374} 375 376DisassemblerTables::DisassemblerTables() { 377 unsigned i; 378 379 for (i = 0; i < array_lengthof(Tables); i++) { 380 Tables[i] = new ContextDecision; 381 memset(Tables[i], 0, sizeof(ContextDecision)); 382 } 383 384 HasConflicts = false; 385} 386 387DisassemblerTables::~DisassemblerTables() { 388 unsigned i; 389 390 for (i = 0; i < array_lengthof(Tables); i++) 391 delete Tables[i]; 392} 393 394void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, 395 unsigned &i1, unsigned &i2, 396 unsigned &ModRMTableNum, 397 ModRMDecision &decision) const { 398 static uint32_t sTableNumber = 0; 399 static uint32_t sEntryNumber = 1; 400 ModRMDecisionType dt = getDecisionType(decision); 401 402 if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) 403 { 404 o2.indent(i2) << "{ /* ModRMDecision */" << "\n"; 405 i2++; 406 407 o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; 408 o2.indent(i2) << 0 << " /* EmptyTable */\n"; 409 410 i2--; 411 o2.indent(i2) << "}"; 412 return; 413 } 414 415 std::vector<unsigned> ModRMDecision; 416 417 switch (dt) { 418 default: 419 llvm_unreachable("Unknown decision type"); 420 case MODRM_ONEENTRY: 421 ModRMDecision.push_back(decision.instructionIDs[0]); 422 break; 423 case MODRM_SPLITRM: 424 ModRMDecision.push_back(decision.instructionIDs[0x00]); 425 ModRMDecision.push_back(decision.instructionIDs[0xc0]); 426 break; 427 case MODRM_SPLITREG: 428 for (unsigned index = 0; index < 64; index += 8) 429 ModRMDecision.push_back(decision.instructionIDs[index]); 430 for (unsigned index = 0xc0; index < 256; index += 8) 431 ModRMDecision.push_back(decision.instructionIDs[index]); 432 break; 433 case MODRM_SPLITMISC: 434 for (unsigned index = 0; index < 64; index += 8) 435 ModRMDecision.push_back(decision.instructionIDs[index]); 436 for (unsigned index = 0xc0; index < 256; ++index) 437 ModRMDecision.push_back(decision.instructionIDs[index]); 438 break; 439 case MODRM_FULL: 440 for (unsigned index = 0; index < 256; ++index) 441 ModRMDecision.push_back(decision.instructionIDs[index]); 442 break; 443 } 444 445 unsigned &EntryNumber = ModRMTable[ModRMDecision]; 446 if (EntryNumber == 0) { 447 EntryNumber = ModRMTableNum; 448 449 ModRMTableNum += ModRMDecision.size(); 450 o1 << "/* Table" << EntryNumber << " */\n"; 451 i1++; 452 for (std::vector<unsigned>::const_iterator I = ModRMDecision.begin(), 453 E = ModRMDecision.end(); I != E; ++I) { 454 o1.indent(i1 * 2) << format("0x%hx", *I) << ", /* " 455 << InstructionSpecifiers[*I].name << " */\n"; 456 } 457 i1--; 458 } 459 460 o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n"; 461 i2++; 462 463 o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; 464 o2.indent(i2) << EntryNumber << " /* Table" << EntryNumber << " */\n"; 465 466 i2--; 467 o2.indent(i2) << "}"; 468 469 switch (dt) { 470 default: 471 llvm_unreachable("Unknown decision type"); 472 case MODRM_ONEENTRY: 473 sEntryNumber += 1; 474 break; 475 case MODRM_SPLITRM: 476 sEntryNumber += 2; 477 break; 478 case MODRM_SPLITREG: 479 sEntryNumber += 16; 480 break; 481 case MODRM_SPLITMISC: 482 sEntryNumber += 8 + 64; 483 break; 484 case MODRM_FULL: 485 sEntryNumber += 256; 486 break; 487 } 488 489 // We assume that the index can fit into uint16_t. 490 assert(sEntryNumber < 65536U && 491 "Index into ModRMDecision is too large for uint16_t!"); 492 493 ++sTableNumber; 494} 495 496void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, 497 unsigned &i1, unsigned &i2, 498 unsigned &ModRMTableNum, 499 OpcodeDecision &decision) const { 500 o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n"; 501 i2++; 502 o2.indent(i2) << "{" << "\n"; 503 i2++; 504 505 for (unsigned index = 0; index < 256; ++index) { 506 o2.indent(i2); 507 508 o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n"; 509 510 emitModRMDecision(o1, o2, i1, i2, ModRMTableNum, 511 decision.modRMDecisions[index]); 512 513 if (index < 255) 514 o2 << ","; 515 516 o2 << "\n"; 517 } 518 519 i2--; 520 o2.indent(i2) << "}" << "\n"; 521 i2--; 522 o2.indent(i2) << "}" << "\n"; 523} 524 525void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, 526 unsigned &i1, unsigned &i2, 527 unsigned &ModRMTableNum, 528 ContextDecision &decision, 529 const char* name) const { 530 o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n"; 531 i2++; 532 o2.indent(i2) << "{ /* opcodeDecisions */" << "\n"; 533 i2++; 534 535 for (unsigned index = 0; index < IC_max; ++index) { 536 o2.indent(i2) << "/* "; 537 o2 << stringForContext((InstructionContext)index); 538 o2 << " */"; 539 o2 << "\n"; 540 541 emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum, 542 decision.opcodeDecisions[index]); 543 544 if (index + 1 < IC_max) 545 o2 << ", "; 546 } 547 548 i2--; 549 o2.indent(i2) << "}" << "\n"; 550 i2--; 551 o2.indent(i2) << "};" << "\n"; 552} 553 554void DisassemblerTables::emitInstructionInfo(raw_ostream &o, 555 unsigned &i) const { 556 unsigned NumInstructions = InstructionSpecifiers.size(); 557 558 o << "static const struct OperandSpecifier x86OperandSets[][" 559 << X86_MAX_OPERANDS << "] = {\n"; 560 561 typedef std::vector<std::pair<const char *, const char *> > OperandListTy; 562 std::map<OperandListTy, unsigned> OperandSets; 563 564 unsigned OperandSetNum = 0; 565 for (unsigned Index = 0; Index < NumInstructions; ++Index) { 566 OperandListTy OperandList; 567 568 for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; 569 ++OperandIndex) { 570 const char *Encoding = 571 stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[Index] 572 .operands[OperandIndex].encoding); 573 const char *Type = 574 stringForOperandType((OperandType)InstructionSpecifiers[Index] 575 .operands[OperandIndex].type); 576 OperandList.push_back(std::make_pair(Encoding, Type)); 577 } 578 unsigned &N = OperandSets[OperandList]; 579 if (N != 0) continue; 580 581 N = ++OperandSetNum; 582 583 o << " { /* " << (OperandSetNum - 1) << " */\n"; 584 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) { 585 o << " { " << OperandList[i].first << ", " 586 << OperandList[i].second << " },\n"; 587 } 588 o << " },\n"; 589 } 590 o << "};" << "\n\n"; 591 592 o.indent(i * 2) << "static const struct InstructionSpecifier "; 593 o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n"; 594 595 i++; 596 597 for (unsigned index = 0; index < NumInstructions; ++index) { 598 o.indent(i * 2) << "{ /* " << index << " */" << "\n"; 599 i++; 600 601 o.indent(i * 2) << stringForModifierType( 602 (ModifierType)InstructionSpecifiers[index].modifierType); 603 o << ",\n"; 604 605 o.indent(i * 2) << "0x"; 606 o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase); 607 o << ",\n"; 608 609 OperandListTy OperandList; 610 for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; 611 ++OperandIndex) { 612 const char *Encoding = 613 stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[index] 614 .operands[OperandIndex].encoding); 615 const char *Type = 616 stringForOperandType((OperandType)InstructionSpecifiers[index] 617 .operands[OperandIndex].type); 618 OperandList.push_back(std::make_pair(Encoding, Type)); 619 } 620 o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n"; 621 622 o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */"; 623 o << "\n"; 624 625 i--; 626 o.indent(i * 2) << "}"; 627 628 if (index + 1 < NumInstructions) 629 o << ","; 630 631 o << "\n"; 632 } 633 634 i--; 635 o.indent(i * 2) << "};" << "\n"; 636} 637 638void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const { 639 o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR 640 "[256] = {\n"; 641 i++; 642 643 for (unsigned index = 0; index < 256; ++index) { 644 o.indent(i * 2); 645 646 if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) 647 o << "IC_VEX_L_W_OPSIZE"; 648 else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XD)) 649 o << "IC_VEX_L_W_XD"; 650 else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XS)) 651 o << "IC_VEX_L_W_XS"; 652 else if ((index & ATTR_VEXL) && (index & ATTR_REXW)) 653 o << "IC_VEX_L_W"; 654 else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE)) 655 o << "IC_VEX_L_OPSIZE"; 656 else if ((index & ATTR_VEXL) && (index & ATTR_XD)) 657 o << "IC_VEX_L_XD"; 658 else if ((index & ATTR_VEXL) && (index & ATTR_XS)) 659 o << "IC_VEX_L_XS"; 660 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) 661 o << "IC_VEX_W_OPSIZE"; 662 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XD)) 663 o << "IC_VEX_W_XD"; 664 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XS)) 665 o << "IC_VEX_W_XS"; 666 else if (index & ATTR_VEXL) 667 o << "IC_VEX_L"; 668 else if ((index & ATTR_VEX) && (index & ATTR_REXW)) 669 o << "IC_VEX_W"; 670 else if ((index & ATTR_VEX) && (index & ATTR_OPSIZE)) 671 o << "IC_VEX_OPSIZE"; 672 else if ((index & ATTR_VEX) && (index & ATTR_XD)) 673 o << "IC_VEX_XD"; 674 else if ((index & ATTR_VEX) && (index & ATTR_XS)) 675 o << "IC_VEX_XS"; 676 else if (index & ATTR_VEX) 677 o << "IC_VEX"; 678 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) 679 o << "IC_64BIT_REXW_XS"; 680 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) 681 o << "IC_64BIT_REXW_XD"; 682 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 683 (index & ATTR_OPSIZE)) 684 o << "IC_64BIT_REXW_OPSIZE"; 685 else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE)) 686 o << "IC_64BIT_XD_OPSIZE"; 687 else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE)) 688 o << "IC_64BIT_XS_OPSIZE"; 689 else if ((index & ATTR_64BIT) && (index & ATTR_XS)) 690 o << "IC_64BIT_XS"; 691 else if ((index & ATTR_64BIT) && (index & ATTR_XD)) 692 o << "IC_64BIT_XD"; 693 else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE)) 694 o << "IC_64BIT_OPSIZE"; 695 else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE)) 696 o << "IC_64BIT_ADSIZE"; 697 else if ((index & ATTR_64BIT) && (index & ATTR_REXW)) 698 o << "IC_64BIT_REXW"; 699 else if ((index & ATTR_64BIT)) 700 o << "IC_64BIT"; 701 else if ((index & ATTR_XS) && (index & ATTR_OPSIZE)) 702 o << "IC_XS_OPSIZE"; 703 else if ((index & ATTR_XD) && (index & ATTR_OPSIZE)) 704 o << "IC_XD_OPSIZE"; 705 else if (index & ATTR_XS) 706 o << "IC_XS"; 707 else if (index & ATTR_XD) 708 o << "IC_XD"; 709 else if (index & ATTR_OPSIZE) 710 o << "IC_OPSIZE"; 711 else if (index & ATTR_ADSIZE) 712 o << "IC_ADSIZE"; 713 else 714 o << "IC"; 715 716 if (index < 255) 717 o << ","; 718 else 719 o << " "; 720 721 o << " /* " << index << " */"; 722 723 o << "\n"; 724 } 725 726 i--; 727 o.indent(i * 2) << "};" << "\n"; 728} 729 730void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2, 731 unsigned &i1, unsigned &i2, 732 unsigned &ModRMTableNum) const { 733 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[0], ONEBYTE_STR); 734 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[1], TWOBYTE_STR); 735 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[2], THREEBYTE38_STR); 736 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[3], THREEBYTE3A_STR); 737 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], THREEBYTEA6_STR); 738 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], THREEBYTEA7_STR); 739 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOP8_MAP_STR); 740 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[7], XOP9_MAP_STR); 741 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[8], XOPA_MAP_STR); 742} 743 744void DisassemblerTables::emit(raw_ostream &o) const { 745 unsigned i1 = 0; 746 unsigned i2 = 0; 747 748 std::string s1; 749 std::string s2; 750 751 raw_string_ostream o1(s1); 752 raw_string_ostream o2(s2); 753 754 emitInstructionInfo(o, i2); 755 o << "\n"; 756 757 emitContextTable(o, i2); 758 o << "\n"; 759 760 unsigned ModRMTableNum = 0; 761 762 o << "static const InstrUID modRMTable[] = {\n"; 763 i1++; 764 std::vector<unsigned> EmptyTable(1, 0); 765 ModRMTable[EmptyTable] = ModRMTableNum; 766 ModRMTableNum += EmptyTable.size(); 767 o1 << "/* EmptyTable */\n"; 768 o1.indent(i1 * 2) << "0x0,\n"; 769 i1--; 770 emitContextDecisions(o1, o2, i1, i2, ModRMTableNum); 771 772 o << o1.str(); 773 o << " 0x0\n"; 774 o << "};\n"; 775 o << "\n"; 776 o << o2.str(); 777 o << "\n"; 778 o << "\n"; 779} 780 781void DisassemblerTables::setTableFields(ModRMDecision &decision, 782 const ModRMFilter &filter, 783 InstrUID uid, 784 uint8_t opcode) { 785 for (unsigned index = 0; index < 256; ++index) { 786 if (filter.accepts(index)) { 787 if (decision.instructionIDs[index] == uid) 788 continue; 789 790 if (decision.instructionIDs[index] != 0) { 791 InstructionSpecifier &newInfo = 792 InstructionSpecifiers[uid]; 793 InstructionSpecifier &previousInfo = 794 InstructionSpecifiers[decision.instructionIDs[index]]; 795 796 if(newInfo.filtered) 797 continue; // filtered instructions get lowest priority 798 799 if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" || 800 newInfo.name == "XCHG32ar" || 801 newInfo.name == "XCHG32ar64" || 802 newInfo.name == "XCHG64ar")) 803 continue; // special case for XCHG*ar and NOOP 804 805 if (outranks(previousInfo.insnContext, newInfo.insnContext)) 806 continue; 807 808 if (previousInfo.insnContext == newInfo.insnContext && 809 !previousInfo.filtered) { 810 errs() << "Error: Primary decode conflict: "; 811 errs() << newInfo.name << " would overwrite " << previousInfo.name; 812 errs() << "\n"; 813 errs() << "ModRM " << index << "\n"; 814 errs() << "Opcode " << (uint16_t)opcode << "\n"; 815 errs() << "Context " << stringForContext(newInfo.insnContext) << "\n"; 816 HasConflicts = true; 817 } 818 } 819 820 decision.instructionIDs[index] = uid; 821 } 822 } 823} 824 825void DisassemblerTables::setTableFields(OpcodeType type, 826 InstructionContext insnContext, 827 uint8_t opcode, 828 const ModRMFilter &filter, 829 InstrUID uid, 830 bool is32bit, 831 bool ignoresVEX_L) { 832 ContextDecision &decision = *Tables[type]; 833 834 for (unsigned index = 0; index < IC_max; ++index) { 835 if (is32bit && inheritsFrom((InstructionContext)index, IC_64BIT)) 836 continue; 837 838 if (inheritsFrom((InstructionContext)index, 839 InstructionSpecifiers[uid].insnContext, ignoresVEX_L)) 840 setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], 841 filter, 842 uid, 843 opcode); 844 } 845} 846