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