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