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