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