X86DisassemblerTables.cpp revision 280031
1201360Srdivacky//===- X86DisassemblerTables.cpp - Disassembler tables ----------*- C++ -*-===// 2201360Srdivacky// 3201360Srdivacky// The LLVM Compiler Infrastructure 4201360Srdivacky// 5201360Srdivacky// This file is distributed under the University of Illinois Open Source 6201360Srdivacky// License. See LICENSE.TXT for details. 7201360Srdivacky// 8201360Srdivacky//===----------------------------------------------------------------------===// 9201360Srdivacky// 10201360Srdivacky// This file is part of the X86 Disassembler Emitter. 11201360Srdivacky// It contains the implementation of the disassembler tables. 12201360Srdivacky// Documentation for the disassembler emitter in general can be found in 13201360Srdivacky// X86DisasemblerEmitter.h. 14201360Srdivacky// 15201360Srdivacky//===----------------------------------------------------------------------===// 16201360Srdivacky 17249423Sdim#include "X86DisassemblerTables.h" 18201360Srdivacky#include "X86DisassemblerShared.h" 19221345Sdim#include "llvm/ADT/STLExtras.h" 20201360Srdivacky#include "llvm/Support/ErrorHandling.h" 21201360Srdivacky#include "llvm/Support/Format.h" 22239462Sdim#include <map> 23201360Srdivacky 24201360Srdivackyusing namespace llvm; 25201360Srdivackyusing namespace X86Disassembler; 26239462Sdim 27276479Sdim/// stringForContext - Returns a string containing the name of a particular 28276479Sdim/// InstructionContext, usually for diagnostic purposes. 29276479Sdim/// 30276479Sdim/// @param insnContext - The instruction class to transform to a string. 31276479Sdim/// @return - A statically-allocated string constant that contains the 32276479Sdim/// name of the instruction class. 33276479Sdimstatic inline const char* stringForContext(InstructionContext insnContext) { 34276479Sdim switch (insnContext) { 35276479Sdim default: 36276479Sdim llvm_unreachable("Unhandled instruction class"); 37276479Sdim#define ENUM_ENTRY(n, r, d) case n: return #n; break; 38276479Sdim#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) ENUM_ENTRY(n##_K_B, r, d)\ 39276479Sdim ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d)\ 40276479Sdim ENUM_ENTRY(n##_KZ_B, r, d) 41276479Sdim INSTRUCTION_CONTEXTS 42276479Sdim#undef ENUM_ENTRY 43276479Sdim#undef ENUM_ENTRY_K_B 44276479Sdim } 45276479Sdim} 46276479Sdim 47276479Sdim/// stringForOperandType - Like stringForContext, but for OperandTypes. 48276479Sdimstatic inline const char* stringForOperandType(OperandType type) { 49276479Sdim switch (type) { 50276479Sdim default: 51276479Sdim llvm_unreachable("Unhandled type"); 52276479Sdim#define ENUM_ENTRY(i, d) case i: return #i; 53276479Sdim TYPES 54276479Sdim#undef ENUM_ENTRY 55276479Sdim } 56276479Sdim} 57276479Sdim 58276479Sdim/// stringForOperandEncoding - like stringForContext, but for 59276479Sdim/// OperandEncodings. 60276479Sdimstatic inline const char* stringForOperandEncoding(OperandEncoding encoding) { 61276479Sdim switch (encoding) { 62276479Sdim default: 63276479Sdim llvm_unreachable("Unhandled encoding"); 64276479Sdim#define ENUM_ENTRY(i, d) case i: return #i; 65276479Sdim ENCODINGS 66276479Sdim#undef ENUM_ENTRY 67276479Sdim } 68276479Sdim} 69276479Sdim 70201360Srdivacky/// inheritsFrom - Indicates whether all instructions in one class also belong 71201360Srdivacky/// to another class. 72201360Srdivacky/// 73201360Srdivacky/// @param child - The class that may be the subset 74201360Srdivacky/// @param parent - The class that may be the superset 75201360Srdivacky/// @return - True if child is a subset of parent, false otherwise. 76201360Srdivackystatic inline bool inheritsFrom(InstructionContext child, 77226633Sdim InstructionContext parent, 78280031Sdim bool VEX_LIG = false, bool AdSize64 = false) { 79201360Srdivacky if (child == parent) 80201360Srdivacky return true; 81239462Sdim 82201360Srdivacky switch (parent) { 83201360Srdivacky case IC: 84280031Sdim return(inheritsFrom(child, IC_64BIT, AdSize64) || 85226633Sdim inheritsFrom(child, IC_OPSIZE) || 86234353Sdim inheritsFrom(child, IC_ADSIZE) || 87226633Sdim inheritsFrom(child, IC_XD) || 88226633Sdim inheritsFrom(child, IC_XS)); 89201360Srdivacky case IC_64BIT: 90201360Srdivacky return(inheritsFrom(child, IC_64BIT_REXW) || 91201360Srdivacky inheritsFrom(child, IC_64BIT_OPSIZE) || 92280031Sdim (!AdSize64 && inheritsFrom(child, IC_64BIT_ADSIZE)) || 93201360Srdivacky inheritsFrom(child, IC_64BIT_XD) || 94201360Srdivacky inheritsFrom(child, IC_64BIT_XS)); 95201360Srdivacky case IC_OPSIZE: 96280031Sdim return inheritsFrom(child, IC_64BIT_OPSIZE) || 97280031Sdim inheritsFrom(child, IC_OPSIZE_ADSIZE); 98234353Sdim case IC_ADSIZE: 99280031Sdim return inheritsFrom(child, IC_OPSIZE_ADSIZE); 100280031Sdim case IC_OPSIZE_ADSIZE: 101280031Sdim return false; 102234353Sdim case IC_64BIT_ADSIZE: 103280031Sdim return inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE); 104280031Sdim case IC_64BIT_OPSIZE_ADSIZE: 105234353Sdim return false; 106201360Srdivacky case IC_XD: 107226633Sdim return inheritsFrom(child, IC_64BIT_XD); 108201360Srdivacky case IC_XS: 109226633Sdim return inheritsFrom(child, IC_64BIT_XS); 110226633Sdim case IC_XD_OPSIZE: 111226633Sdim return inheritsFrom(child, IC_64BIT_XD_OPSIZE); 112226633Sdim case IC_XS_OPSIZE: 113226633Sdim return inheritsFrom(child, IC_64BIT_XS_OPSIZE); 114201360Srdivacky case IC_64BIT_REXW: 115201360Srdivacky return(inheritsFrom(child, IC_64BIT_REXW_XS) || 116201360Srdivacky inheritsFrom(child, IC_64BIT_REXW_XD) || 117280031Sdim inheritsFrom(child, IC_64BIT_REXW_OPSIZE) || 118280031Sdim (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE))); 119201360Srdivacky case IC_64BIT_OPSIZE: 120280031Sdim return inheritsFrom(child, IC_64BIT_REXW_OPSIZE) || 121280031Sdim (!AdSize64 && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE)) || 122280031Sdim (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE)); 123201360Srdivacky case IC_64BIT_XD: 124201360Srdivacky return(inheritsFrom(child, IC_64BIT_REXW_XD)); 125201360Srdivacky case IC_64BIT_XS: 126201360Srdivacky return(inheritsFrom(child, IC_64BIT_REXW_XS)); 127226633Sdim case IC_64BIT_XD_OPSIZE: 128226633Sdim case IC_64BIT_XS_OPSIZE: 129226633Sdim return false; 130201360Srdivacky case IC_64BIT_REXW_XD: 131201360Srdivacky case IC_64BIT_REXW_XS: 132201360Srdivacky case IC_64BIT_REXW_OPSIZE: 133280031Sdim case IC_64BIT_REXW_ADSIZE: 134201360Srdivacky return false; 135221345Sdim case IC_VEX: 136261991Sdim return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W)) || 137261991Sdim inheritsFrom(child, IC_VEX_W) || 138226633Sdim (VEX_LIG && inheritsFrom(child, IC_VEX_L)); 139221345Sdim case IC_VEX_XS: 140261991Sdim return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS)) || 141261991Sdim inheritsFrom(child, IC_VEX_W_XS) || 142226633Sdim (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS)); 143221345Sdim case IC_VEX_XD: 144261991Sdim return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD)) || 145261991Sdim inheritsFrom(child, IC_VEX_W_XD) || 146226633Sdim (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD)); 147226633Sdim case IC_VEX_OPSIZE: 148261991Sdim return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) || 149261991Sdim inheritsFrom(child, IC_VEX_W_OPSIZE) || 150226633Sdim (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE)); 151226633Sdim case IC_VEX_W: 152261991Sdim return VEX_LIG && inheritsFrom(child, IC_VEX_L_W); 153226633Sdim case IC_VEX_W_XS: 154261991Sdim return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS); 155226633Sdim case IC_VEX_W_XD: 156261991Sdim return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD); 157226633Sdim case IC_VEX_W_OPSIZE: 158261991Sdim return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE); 159221345Sdim case IC_VEX_L: 160261991Sdim return inheritsFrom(child, IC_VEX_L_W); 161221345Sdim case IC_VEX_L_XS: 162261991Sdim return inheritsFrom(child, IC_VEX_L_W_XS); 163221345Sdim case IC_VEX_L_XD: 164261991Sdim return inheritsFrom(child, IC_VEX_L_W_XD); 165226633Sdim case IC_VEX_L_OPSIZE: 166234353Sdim return inheritsFrom(child, IC_VEX_L_W_OPSIZE); 167261991Sdim case IC_VEX_L_W: 168261991Sdim case IC_VEX_L_W_XS: 169261991Sdim case IC_VEX_L_W_XD: 170234353Sdim case IC_VEX_L_W_OPSIZE: 171221345Sdim return false; 172261991Sdim case IC_EVEX: 173261991Sdim return inheritsFrom(child, IC_EVEX_W) || 174261991Sdim inheritsFrom(child, IC_EVEX_L_W); 175261991Sdim case IC_EVEX_XS: 176261991Sdim return inheritsFrom(child, IC_EVEX_W_XS) || 177261991Sdim inheritsFrom(child, IC_EVEX_L_W_XS); 178261991Sdim case IC_EVEX_XD: 179261991Sdim return inheritsFrom(child, IC_EVEX_W_XD) || 180261991Sdim inheritsFrom(child, IC_EVEX_L_W_XD); 181261991Sdim case IC_EVEX_OPSIZE: 182261991Sdim return inheritsFrom(child, IC_EVEX_W_OPSIZE) || 183261991Sdim inheritsFrom(child, IC_EVEX_L_W_OPSIZE); 184280031Sdim case IC_EVEX_B: 185280031Sdim return false; 186261991Sdim case IC_EVEX_W: 187261991Sdim case IC_EVEX_W_XS: 188261991Sdim case IC_EVEX_W_XD: 189261991Sdim case IC_EVEX_W_OPSIZE: 190261991Sdim return false; 191261991Sdim case IC_EVEX_L: 192280031Sdim case IC_EVEX_L_K_B: 193280031Sdim case IC_EVEX_L_KZ_B: 194280031Sdim case IC_EVEX_L_B: 195261991Sdim case IC_EVEX_L_XS: 196261991Sdim case IC_EVEX_L_XD: 197261991Sdim case IC_EVEX_L_OPSIZE: 198261991Sdim return false; 199261991Sdim case IC_EVEX_L_W: 200261991Sdim case IC_EVEX_L_W_XS: 201261991Sdim case IC_EVEX_L_W_XD: 202261991Sdim case IC_EVEX_L_W_OPSIZE: 203261991Sdim return false; 204261991Sdim case IC_EVEX_L2: 205261991Sdim case IC_EVEX_L2_XS: 206261991Sdim case IC_EVEX_L2_XD: 207261991Sdim case IC_EVEX_L2_OPSIZE: 208261991Sdim return false; 209261991Sdim case IC_EVEX_L2_W: 210261991Sdim case IC_EVEX_L2_W_XS: 211261991Sdim case IC_EVEX_L2_W_XD: 212261991Sdim case IC_EVEX_L2_W_OPSIZE: 213261991Sdim return false; 214261991Sdim case IC_EVEX_K: 215261991Sdim return inheritsFrom(child, IC_EVEX_W_K) || 216261991Sdim inheritsFrom(child, IC_EVEX_L_W_K); 217261991Sdim case IC_EVEX_XS_K: 218261991Sdim return inheritsFrom(child, IC_EVEX_W_XS_K) || 219261991Sdim inheritsFrom(child, IC_EVEX_L_W_XS_K); 220261991Sdim case IC_EVEX_XD_K: 221261991Sdim return inheritsFrom(child, IC_EVEX_W_XD_K) || 222261991Sdim inheritsFrom(child, IC_EVEX_L_W_XD_K); 223280031Sdim case IC_EVEX_K_B: 224280031Sdim case IC_EVEX_KZ: 225280031Sdim return false; 226280031Sdim case IC_EVEX_XS_KZ: 227280031Sdim return inheritsFrom(child, IC_EVEX_W_XS_KZ) || 228280031Sdim inheritsFrom(child, IC_EVEX_L_W_XS_KZ); 229280031Sdim case IC_EVEX_XD_KZ: 230280031Sdim return inheritsFrom(child, IC_EVEX_W_XD_KZ) || 231280031Sdim inheritsFrom(child, IC_EVEX_L_W_XD_KZ); 232280031Sdim case IC_EVEX_KZ_B: 233261991Sdim case IC_EVEX_OPSIZE_K: 234276479Sdim case IC_EVEX_OPSIZE_B: 235280031Sdim case IC_EVEX_OPSIZE_K_B: 236280031Sdim case IC_EVEX_OPSIZE_KZ: 237280031Sdim case IC_EVEX_OPSIZE_KZ_B: 238276479Sdim return false; 239261991Sdim case IC_EVEX_W_K: 240261991Sdim case IC_EVEX_W_XS_K: 241261991Sdim case IC_EVEX_W_XD_K: 242261991Sdim case IC_EVEX_W_OPSIZE_K: 243276479Sdim case IC_EVEX_W_OPSIZE_B: 244280031Sdim case IC_EVEX_W_OPSIZE_K_B: 245261991Sdim return false; 246261991Sdim case IC_EVEX_L_K: 247261991Sdim case IC_EVEX_L_XS_K: 248261991Sdim case IC_EVEX_L_XD_K: 249261991Sdim case IC_EVEX_L_OPSIZE_K: 250280031Sdim case IC_EVEX_L_OPSIZE_B: 251280031Sdim case IC_EVEX_L_OPSIZE_K_B: 252261991Sdim return false; 253261991Sdim case IC_EVEX_W_KZ: 254261991Sdim case IC_EVEX_W_XS_KZ: 255261991Sdim case IC_EVEX_W_XD_KZ: 256261991Sdim case IC_EVEX_W_OPSIZE_KZ: 257280031Sdim case IC_EVEX_W_OPSIZE_KZ_B: 258261991Sdim return false; 259261991Sdim case IC_EVEX_L_KZ: 260261991Sdim case IC_EVEX_L_XS_KZ: 261261991Sdim case IC_EVEX_L_XD_KZ: 262261991Sdim case IC_EVEX_L_OPSIZE_KZ: 263280031Sdim case IC_EVEX_L_OPSIZE_KZ_B: 264261991Sdim return false; 265261991Sdim case IC_EVEX_L_W_K: 266261991Sdim case IC_EVEX_L_W_XS_K: 267261991Sdim case IC_EVEX_L_W_XD_K: 268261991Sdim case IC_EVEX_L_W_OPSIZE_K: 269280031Sdim case IC_EVEX_L_W_OPSIZE_B: 270280031Sdim case IC_EVEX_L_W_OPSIZE_K_B: 271261991Sdim case IC_EVEX_L_W_KZ: 272261991Sdim case IC_EVEX_L_W_XS_KZ: 273261991Sdim case IC_EVEX_L_W_XD_KZ: 274261991Sdim case IC_EVEX_L_W_OPSIZE_KZ: 275280031Sdim case IC_EVEX_L_W_OPSIZE_KZ_B: 276261991Sdim return false; 277261991Sdim case IC_EVEX_L2_K: 278261991Sdim case IC_EVEX_L2_B: 279276479Sdim case IC_EVEX_L2_K_B: 280276479Sdim case IC_EVEX_L2_KZ_B: 281261991Sdim case IC_EVEX_L2_XS_K: 282276479Sdim case IC_EVEX_L2_XS_B: 283276479Sdim case IC_EVEX_L2_XD_B: 284261991Sdim case IC_EVEX_L2_XD_K: 285261991Sdim case IC_EVEX_L2_OPSIZE_K: 286261991Sdim case IC_EVEX_L2_OPSIZE_B: 287261991Sdim case IC_EVEX_L2_OPSIZE_K_B: 288261991Sdim case IC_EVEX_L2_KZ: 289261991Sdim case IC_EVEX_L2_XS_KZ: 290261991Sdim case IC_EVEX_L2_XD_KZ: 291261991Sdim case IC_EVEX_L2_OPSIZE_KZ: 292261991Sdim case IC_EVEX_L2_OPSIZE_KZ_B: 293261991Sdim return false; 294261991Sdim case IC_EVEX_L2_W_K: 295261991Sdim case IC_EVEX_L2_W_B: 296261991Sdim case IC_EVEX_L2_W_XS_K: 297261991Sdim case IC_EVEX_L2_W_XD_K: 298276479Sdim case IC_EVEX_L2_W_XD_B: 299261991Sdim case IC_EVEX_L2_W_OPSIZE_K: 300261991Sdim case IC_EVEX_L2_W_OPSIZE_B: 301261991Sdim case IC_EVEX_L2_W_OPSIZE_K_B: 302261991Sdim case IC_EVEX_L2_W_KZ: 303261991Sdim case IC_EVEX_L2_W_XS_KZ: 304261991Sdim case IC_EVEX_L2_W_XD_KZ: 305261991Sdim case IC_EVEX_L2_W_OPSIZE_KZ: 306261991Sdim case IC_EVEX_L2_W_OPSIZE_KZ_B: 307261991Sdim return false; 308201360Srdivacky default: 309276479Sdim errs() << "Unknown instruction class: " << 310276479Sdim stringForContext((InstructionContext)parent) << "\n"; 311226633Sdim llvm_unreachable("Unknown instruction class"); 312201360Srdivacky } 313201360Srdivacky} 314201360Srdivacky 315201360Srdivacky/// outranks - Indicates whether, if an instruction has two different applicable 316201360Srdivacky/// classes, which class should be preferred when performing decode. This 317201360Srdivacky/// imposes a total ordering (ties are resolved toward "lower") 318201360Srdivacky/// 319201360Srdivacky/// @param upper - The class that may be preferable 320201360Srdivacky/// @param lower - The class that may be less preferable 321201360Srdivacky/// @return - True if upper is to be preferred, false otherwise. 322239462Sdimstatic inline bool outranks(InstructionContext upper, 323201360Srdivacky InstructionContext lower) { 324201360Srdivacky assert(upper < IC_max); 325201360Srdivacky assert(lower < IC_max); 326239462Sdim 327201360Srdivacky#define ENUM_ENTRY(n, r, d) r, 328261991Sdim#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) \ 329261991Sdim ENUM_ENTRY(n##_K_B, r, d) ENUM_ENTRY(n##_KZ_B, r, d) \ 330261991Sdim ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d) 331201360Srdivacky static int ranks[IC_max] = { 332201360Srdivacky INSTRUCTION_CONTEXTS 333201360Srdivacky }; 334201360Srdivacky#undef ENUM_ENTRY 335261991Sdim#undef ENUM_ENTRY_K_B 336239462Sdim 337201360Srdivacky return (ranks[upper] > ranks[lower]); 338201360Srdivacky} 339201360Srdivacky 340201360Srdivacky/// getDecisionType - Determines whether a ModRM decision with 255 entries can 341201360Srdivacky/// be compacted by eliminating redundant information. 342201360Srdivacky/// 343201360Srdivacky/// @param decision - The decision to be compacted. 344201360Srdivacky/// @return - The compactest available representation for the decision. 345239462Sdimstatic ModRMDecisionType getDecisionType(ModRMDecision &decision) { 346201360Srdivacky bool satisfiesOneEntry = true; 347201360Srdivacky bool satisfiesSplitRM = true; 348234353Sdim bool satisfiesSplitReg = true; 349243830Sdim bool satisfiesSplitMisc = true; 350234353Sdim 351239462Sdim for (unsigned index = 0; index < 256; ++index) { 352201360Srdivacky if (decision.instructionIDs[index] != decision.instructionIDs[0]) 353201360Srdivacky satisfiesOneEntry = false; 354234353Sdim 355201360Srdivacky if (((index & 0xc0) == 0xc0) && 356201360Srdivacky (decision.instructionIDs[index] != decision.instructionIDs[0xc0])) 357201360Srdivacky satisfiesSplitRM = false; 358234353Sdim 359201360Srdivacky if (((index & 0xc0) != 0xc0) && 360201360Srdivacky (decision.instructionIDs[index] != decision.instructionIDs[0x00])) 361201360Srdivacky satisfiesSplitRM = false; 362234353Sdim 363234353Sdim if (((index & 0xc0) == 0xc0) && 364234353Sdim (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8])) 365234353Sdim satisfiesSplitReg = false; 366234353Sdim 367234353Sdim if (((index & 0xc0) != 0xc0) && 368234353Sdim (decision.instructionIDs[index] != decision.instructionIDs[index&0x38])) 369243830Sdim satisfiesSplitMisc = false; 370201360Srdivacky } 371234353Sdim 372201360Srdivacky if (satisfiesOneEntry) 373201360Srdivacky return MODRM_ONEENTRY; 374234353Sdim 375201360Srdivacky if (satisfiesSplitRM) 376201360Srdivacky return MODRM_SPLITRM; 377234353Sdim 378243830Sdim if (satisfiesSplitReg && satisfiesSplitMisc) 379234353Sdim return MODRM_SPLITREG; 380234353Sdim 381243830Sdim if (satisfiesSplitMisc) 382243830Sdim return MODRM_SPLITMISC; 383243830Sdim 384201360Srdivacky return MODRM_FULL; 385201360Srdivacky} 386201360Srdivacky 387201360Srdivacky/// stringForDecisionType - Returns a statically-allocated string corresponding 388201360Srdivacky/// to a particular decision type. 389201360Srdivacky/// 390201360Srdivacky/// @param dt - The decision type. 391239462Sdim/// @return - A pointer to the statically-allocated string (e.g., 392201360Srdivacky/// "MODRM_ONEENTRY" for MODRM_ONEENTRY). 393239462Sdimstatic const char* stringForDecisionType(ModRMDecisionType dt) { 394201360Srdivacky#define ENUM_ENTRY(n) case n: return #n; 395201360Srdivacky switch (dt) { 396201360Srdivacky default: 397239462Sdim llvm_unreachable("Unknown decision type"); 398201360Srdivacky MODRMTYPES 399239462Sdim }; 400201360Srdivacky#undef ENUM_ENTRY 401201360Srdivacky} 402239462Sdim 403201360SrdivackyDisassemblerTables::DisassemblerTables() { 404201360Srdivacky unsigned i; 405239462Sdim 406221345Sdim for (i = 0; i < array_lengthof(Tables); i++) { 407201360Srdivacky Tables[i] = new ContextDecision; 408201360Srdivacky memset(Tables[i], 0, sizeof(ContextDecision)); 409201360Srdivacky } 410239462Sdim 411201360Srdivacky HasConflicts = false; 412201360Srdivacky} 413239462Sdim 414201360SrdivackyDisassemblerTables::~DisassemblerTables() { 415201360Srdivacky unsigned i; 416239462Sdim 417221345Sdim for (i = 0; i < array_lengthof(Tables); i++) 418201360Srdivacky delete Tables[i]; 419201360Srdivacky} 420239462Sdim 421239462Sdimvoid DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, 422239462Sdim unsigned &i1, unsigned &i2, 423261991Sdim unsigned &ModRMTableNum, 424239462Sdim ModRMDecision &decision) const { 425239462Sdim static uint32_t sTableNumber = 0; 426239462Sdim static uint32_t sEntryNumber = 1; 427201360Srdivacky ModRMDecisionType dt = getDecisionType(decision); 428234353Sdim 429201360Srdivacky if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) 430201360Srdivacky { 431201360Srdivacky o2.indent(i2) << "{ /* ModRMDecision */" << "\n"; 432201360Srdivacky i2++; 433234353Sdim 434201360Srdivacky o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; 435234353Sdim o2.indent(i2) << 0 << " /* EmptyTable */\n"; 436234353Sdim 437201360Srdivacky i2--; 438201360Srdivacky o2.indent(i2) << "}"; 439201360Srdivacky return; 440201360Srdivacky } 441234353Sdim 442261991Sdim std::vector<unsigned> ModRMDecision; 443234353Sdim 444201360Srdivacky switch (dt) { 445201360Srdivacky default: 446201360Srdivacky llvm_unreachable("Unknown decision type"); 447201360Srdivacky case MODRM_ONEENTRY: 448261991Sdim ModRMDecision.push_back(decision.instructionIDs[0]); 449201360Srdivacky break; 450201360Srdivacky case MODRM_SPLITRM: 451261991Sdim ModRMDecision.push_back(decision.instructionIDs[0x00]); 452261991Sdim ModRMDecision.push_back(decision.instructionIDs[0xc0]); 453201360Srdivacky break; 454234353Sdim case MODRM_SPLITREG: 455239462Sdim for (unsigned index = 0; index < 64; index += 8) 456261991Sdim ModRMDecision.push_back(decision.instructionIDs[index]); 457239462Sdim for (unsigned index = 0xc0; index < 256; index += 8) 458261991Sdim ModRMDecision.push_back(decision.instructionIDs[index]); 459234353Sdim break; 460243830Sdim case MODRM_SPLITMISC: 461243830Sdim for (unsigned index = 0; index < 64; index += 8) 462261991Sdim ModRMDecision.push_back(decision.instructionIDs[index]); 463243830Sdim for (unsigned index = 0xc0; index < 256; ++index) 464261991Sdim ModRMDecision.push_back(decision.instructionIDs[index]); 465243830Sdim break; 466201360Srdivacky case MODRM_FULL: 467239462Sdim for (unsigned index = 0; index < 256; ++index) 468261991Sdim ModRMDecision.push_back(decision.instructionIDs[index]); 469234353Sdim break; 470201360Srdivacky } 471201360Srdivacky 472261991Sdim unsigned &EntryNumber = ModRMTable[ModRMDecision]; 473261991Sdim if (EntryNumber == 0) { 474261991Sdim EntryNumber = ModRMTableNum; 475234353Sdim 476261991Sdim ModRMTableNum += ModRMDecision.size(); 477261991Sdim o1 << "/* Table" << EntryNumber << " */\n"; 478261991Sdim i1++; 479261991Sdim for (std::vector<unsigned>::const_iterator I = ModRMDecision.begin(), 480261991Sdim E = ModRMDecision.end(); I != E; ++I) { 481261991Sdim o1.indent(i1 * 2) << format("0x%hx", *I) << ", /* " 482261991Sdim << InstructionSpecifiers[*I].name << " */\n"; 483261991Sdim } 484261991Sdim i1--; 485261991Sdim } 486261991Sdim 487234353Sdim o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n"; 488234353Sdim i2++; 489234353Sdim 490234353Sdim o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; 491261991Sdim o2.indent(i2) << EntryNumber << " /* Table" << EntryNumber << " */\n"; 492234353Sdim 493234353Sdim i2--; 494234353Sdim o2.indent(i2) << "}"; 495234353Sdim 496201360Srdivacky switch (dt) { 497201360Srdivacky default: 498201360Srdivacky llvm_unreachable("Unknown decision type"); 499201360Srdivacky case MODRM_ONEENTRY: 500234353Sdim sEntryNumber += 1; 501201360Srdivacky break; 502201360Srdivacky case MODRM_SPLITRM: 503234353Sdim sEntryNumber += 2; 504201360Srdivacky break; 505234353Sdim case MODRM_SPLITREG: 506234353Sdim sEntryNumber += 16; 507234353Sdim break; 508243830Sdim case MODRM_SPLITMISC: 509243830Sdim sEntryNumber += 8 + 64; 510243830Sdim break; 511201360Srdivacky case MODRM_FULL: 512234353Sdim sEntryNumber += 256; 513201360Srdivacky break; 514201360Srdivacky } 515234353Sdim 516243830Sdim // We assume that the index can fit into uint16_t. 517243830Sdim assert(sEntryNumber < 65536U && 518243830Sdim "Index into ModRMDecision is too large for uint16_t!"); 519243830Sdim 520201360Srdivacky ++sTableNumber; 521201360Srdivacky} 522201360Srdivacky 523239462Sdimvoid DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, 524239462Sdim unsigned &i1, unsigned &i2, 525261991Sdim unsigned &ModRMTableNum, 526239462Sdim OpcodeDecision &decision) const { 527201360Srdivacky o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n"; 528201360Srdivacky i2++; 529201360Srdivacky o2.indent(i2) << "{" << "\n"; 530201360Srdivacky i2++; 531201360Srdivacky 532239462Sdim for (unsigned index = 0; index < 256; ++index) { 533201360Srdivacky o2.indent(i2); 534201360Srdivacky 535201360Srdivacky o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n"; 536201360Srdivacky 537261991Sdim emitModRMDecision(o1, o2, i1, i2, ModRMTableNum, 538261991Sdim decision.modRMDecisions[index]); 539201360Srdivacky 540201360Srdivacky if (index < 255) 541201360Srdivacky o2 << ","; 542201360Srdivacky 543201360Srdivacky o2 << "\n"; 544201360Srdivacky } 545201360Srdivacky 546201360Srdivacky i2--; 547201360Srdivacky o2.indent(i2) << "}" << "\n"; 548201360Srdivacky i2--; 549201360Srdivacky o2.indent(i2) << "}" << "\n"; 550201360Srdivacky} 551201360Srdivacky 552239462Sdimvoid DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, 553239462Sdim unsigned &i1, unsigned &i2, 554261991Sdim unsigned &ModRMTableNum, 555239462Sdim ContextDecision &decision, 556239462Sdim const char* name) const { 557218893Sdim o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n"; 558201360Srdivacky i2++; 559201360Srdivacky o2.indent(i2) << "{ /* opcodeDecisions */" << "\n"; 560201360Srdivacky i2++; 561201360Srdivacky 562239462Sdim for (unsigned index = 0; index < IC_max; ++index) { 563201360Srdivacky o2.indent(i2) << "/* "; 564201360Srdivacky o2 << stringForContext((InstructionContext)index); 565201360Srdivacky o2 << " */"; 566201360Srdivacky o2 << "\n"; 567201360Srdivacky 568261991Sdim emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum, 569261991Sdim decision.opcodeDecisions[index]); 570201360Srdivacky 571201360Srdivacky if (index + 1 < IC_max) 572201360Srdivacky o2 << ", "; 573201360Srdivacky } 574201360Srdivacky 575201360Srdivacky i2--; 576201360Srdivacky o2.indent(i2) << "}" << "\n"; 577201360Srdivacky i2--; 578201360Srdivacky o2.indent(i2) << "};" << "\n"; 579201360Srdivacky} 580201360Srdivacky 581239462Sdimvoid DisassemblerTables::emitInstructionInfo(raw_ostream &o, 582239462Sdim unsigned &i) const { 583239462Sdim unsigned NumInstructions = InstructionSpecifiers.size(); 584239462Sdim 585239462Sdim o << "static const struct OperandSpecifier x86OperandSets[][" 586239462Sdim << X86_MAX_OPERANDS << "] = {\n"; 587239462Sdim 588239462Sdim typedef std::vector<std::pair<const char *, const char *> > OperandListTy; 589239462Sdim std::map<OperandListTy, unsigned> OperandSets; 590239462Sdim 591239462Sdim unsigned OperandSetNum = 0; 592239462Sdim for (unsigned Index = 0; Index < NumInstructions; ++Index) { 593239462Sdim OperandListTy OperandList; 594239462Sdim 595239462Sdim for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; 596239462Sdim ++OperandIndex) { 597239462Sdim const char *Encoding = 598239462Sdim stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[Index] 599239462Sdim .operands[OperandIndex].encoding); 600239462Sdim const char *Type = 601239462Sdim stringForOperandType((OperandType)InstructionSpecifiers[Index] 602239462Sdim .operands[OperandIndex].type); 603239462Sdim OperandList.push_back(std::make_pair(Encoding, Type)); 604239462Sdim } 605239462Sdim unsigned &N = OperandSets[OperandList]; 606239462Sdim if (N != 0) continue; 607239462Sdim 608239462Sdim N = ++OperandSetNum; 609239462Sdim 610239462Sdim o << " { /* " << (OperandSetNum - 1) << " */\n"; 611239462Sdim for (unsigned i = 0, e = OperandList.size(); i != e; ++i) { 612239462Sdim o << " { " << OperandList[i].first << ", " 613239462Sdim << OperandList[i].second << " },\n"; 614239462Sdim } 615239462Sdim o << " },\n"; 616239462Sdim } 617239462Sdim o << "};" << "\n\n"; 618239462Sdim 619218893Sdim o.indent(i * 2) << "static const struct InstructionSpecifier "; 620218893Sdim o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n"; 621239462Sdim 622201360Srdivacky i++; 623201360Srdivacky 624239462Sdim for (unsigned index = 0; index < NumInstructions; ++index) { 625201360Srdivacky o.indent(i * 2) << "{ /* " << index << " */" << "\n"; 626201360Srdivacky i++; 627234353Sdim 628239462Sdim OperandListTy OperandList; 629239462Sdim for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; 630239462Sdim ++OperandIndex) { 631239462Sdim const char *Encoding = 632239462Sdim stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[index] 633239462Sdim .operands[OperandIndex].encoding); 634239462Sdim const char *Type = 635239462Sdim stringForOperandType((OperandType)InstructionSpecifiers[index] 636239462Sdim .operands[OperandIndex].type); 637239462Sdim OperandList.push_back(std::make_pair(Encoding, Type)); 638201360Srdivacky } 639239462Sdim o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n"; 640201360Srdivacky 641234353Sdim o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */"; 642201360Srdivacky o << "\n"; 643201360Srdivacky 644201360Srdivacky i--; 645201360Srdivacky o.indent(i * 2) << "}"; 646201360Srdivacky 647239462Sdim if (index + 1 < NumInstructions) 648201360Srdivacky o << ","; 649201360Srdivacky 650201360Srdivacky o << "\n"; 651201360Srdivacky } 652201360Srdivacky 653201360Srdivacky i--; 654201360Srdivacky o.indent(i * 2) << "};" << "\n"; 655201360Srdivacky} 656201360Srdivacky 657239462Sdimvoid DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const { 658276479Sdim const unsigned int tableSize = 16384; 659239462Sdim o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR 660276479Sdim "[" << tableSize << "] = {\n"; 661201360Srdivacky i++; 662201360Srdivacky 663276479Sdim for (unsigned index = 0; index < tableSize; ++index) { 664201360Srdivacky o.indent(i * 2); 665201360Srdivacky 666276479Sdim if (index & ATTR_EVEX) { 667276479Sdim o << "IC_EVEX"; 668276479Sdim if (index & ATTR_EVEXL2) 669276479Sdim o << "_L2"; 670276479Sdim else if (index & ATTR_EVEXL) 671276479Sdim o << "_L"; 672276479Sdim if (index & ATTR_REXW) 673276479Sdim o << "_W"; 674276479Sdim if (index & ATTR_OPSIZE) 675276479Sdim o << "_OPSIZE"; 676276479Sdim else if (index & ATTR_XD) 677276479Sdim o << "_XD"; 678276479Sdim else if (index & ATTR_XS) 679276479Sdim o << "_XS"; 680276479Sdim if (index & ATTR_EVEXKZ) 681276479Sdim o << "_KZ"; 682276479Sdim else if (index & ATTR_EVEXK) 683276479Sdim o << "_K"; 684276479Sdim if (index & ATTR_EVEXB) 685276479Sdim o << "_B"; 686276479Sdim } 687276479Sdim else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) 688234353Sdim o << "IC_VEX_L_W_OPSIZE"; 689261991Sdim else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XD)) 690261991Sdim o << "IC_VEX_L_W_XD"; 691261991Sdim else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XS)) 692261991Sdim o << "IC_VEX_L_W_XS"; 693261991Sdim else if ((index & ATTR_VEXL) && (index & ATTR_REXW)) 694261991Sdim o << "IC_VEX_L_W"; 695234353Sdim else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE)) 696221345Sdim o << "IC_VEX_L_OPSIZE"; 697221345Sdim else if ((index & ATTR_VEXL) && (index & ATTR_XD)) 698221345Sdim o << "IC_VEX_L_XD"; 699221345Sdim else if ((index & ATTR_VEXL) && (index & ATTR_XS)) 700221345Sdim o << "IC_VEX_L_XS"; 701221345Sdim else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) 702221345Sdim o << "IC_VEX_W_OPSIZE"; 703221345Sdim else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XD)) 704221345Sdim o << "IC_VEX_W_XD"; 705221345Sdim else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XS)) 706221345Sdim o << "IC_VEX_W_XS"; 707221345Sdim else if (index & ATTR_VEXL) 708221345Sdim o << "IC_VEX_L"; 709221345Sdim else if ((index & ATTR_VEX) && (index & ATTR_REXW)) 710221345Sdim o << "IC_VEX_W"; 711221345Sdim else if ((index & ATTR_VEX) && (index & ATTR_OPSIZE)) 712221345Sdim o << "IC_VEX_OPSIZE"; 713221345Sdim else if ((index & ATTR_VEX) && (index & ATTR_XD)) 714221345Sdim o << "IC_VEX_XD"; 715221345Sdim else if ((index & ATTR_VEX) && (index & ATTR_XS)) 716221345Sdim o << "IC_VEX_XS"; 717226633Sdim else if (index & ATTR_VEX) 718226633Sdim o << "IC_VEX"; 719221345Sdim else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) 720201360Srdivacky o << "IC_64BIT_REXW_XS"; 721201360Srdivacky else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) 722201360Srdivacky o << "IC_64BIT_REXW_XD"; 723239462Sdim else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 724201360Srdivacky (index & ATTR_OPSIZE)) 725201360Srdivacky o << "IC_64BIT_REXW_OPSIZE"; 726280031Sdim else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 727280031Sdim (index & ATTR_ADSIZE)) 728280031Sdim o << "IC_64BIT_REXW_ADSIZE"; 729226633Sdim else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE)) 730226633Sdim o << "IC_64BIT_XD_OPSIZE"; 731226633Sdim else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE)) 732226633Sdim o << "IC_64BIT_XS_OPSIZE"; 733201360Srdivacky else if ((index & ATTR_64BIT) && (index & ATTR_XS)) 734201360Srdivacky o << "IC_64BIT_XS"; 735201360Srdivacky else if ((index & ATTR_64BIT) && (index & ATTR_XD)) 736201360Srdivacky o << "IC_64BIT_XD"; 737280031Sdim else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE) && 738280031Sdim (index & ATTR_ADSIZE)) 739280031Sdim o << "IC_64BIT_OPSIZE_ADSIZE"; 740201360Srdivacky else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE)) 741201360Srdivacky o << "IC_64BIT_OPSIZE"; 742234353Sdim else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE)) 743234353Sdim o << "IC_64BIT_ADSIZE"; 744201360Srdivacky else if ((index & ATTR_64BIT) && (index & ATTR_REXW)) 745201360Srdivacky o << "IC_64BIT_REXW"; 746201360Srdivacky else if ((index & ATTR_64BIT)) 747201360Srdivacky o << "IC_64BIT"; 748226633Sdim else if ((index & ATTR_XS) && (index & ATTR_OPSIZE)) 749226633Sdim o << "IC_XS_OPSIZE"; 750226633Sdim else if ((index & ATTR_XD) && (index & ATTR_OPSIZE)) 751226633Sdim o << "IC_XD_OPSIZE"; 752201360Srdivacky else if (index & ATTR_XS) 753201360Srdivacky o << "IC_XS"; 754201360Srdivacky else if (index & ATTR_XD) 755201360Srdivacky o << "IC_XD"; 756280031Sdim else if ((index & ATTR_OPSIZE) && (index & ATTR_ADSIZE)) 757280031Sdim o << "IC_OPSIZE_ADSIZE"; 758201360Srdivacky else if (index & ATTR_OPSIZE) 759201360Srdivacky o << "IC_OPSIZE"; 760234353Sdim else if (index & ATTR_ADSIZE) 761234353Sdim o << "IC_ADSIZE"; 762201360Srdivacky else 763201360Srdivacky o << "IC"; 764201360Srdivacky 765276479Sdim if (index < tableSize - 1) 766201360Srdivacky o << ","; 767201360Srdivacky else 768201360Srdivacky o << " "; 769201360Srdivacky 770201360Srdivacky o << " /* " << index << " */"; 771201360Srdivacky 772201360Srdivacky o << "\n"; 773201360Srdivacky } 774201360Srdivacky 775201360Srdivacky i--; 776201360Srdivacky o.indent(i * 2) << "};" << "\n"; 777201360Srdivacky} 778201360Srdivacky 779239462Sdimvoid DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2, 780261991Sdim unsigned &i1, unsigned &i2, 781261991Sdim unsigned &ModRMTableNum) const { 782261991Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[0], ONEBYTE_STR); 783261991Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[1], TWOBYTE_STR); 784261991Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[2], THREEBYTE38_STR); 785261991Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[3], THREEBYTE3A_STR); 786276479Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], XOP8_MAP_STR); 787276479Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], XOP9_MAP_STR); 788276479Sdim emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOPA_MAP_STR); 789201360Srdivacky} 790201360Srdivacky 791201360Srdivackyvoid DisassemblerTables::emit(raw_ostream &o) const { 792239462Sdim unsigned i1 = 0; 793239462Sdim unsigned i2 = 0; 794239462Sdim 795201360Srdivacky std::string s1; 796201360Srdivacky std::string s2; 797239462Sdim 798201360Srdivacky raw_string_ostream o1(s1); 799201360Srdivacky raw_string_ostream o2(s2); 800239462Sdim 801201360Srdivacky emitInstructionInfo(o, i2); 802201360Srdivacky o << "\n"; 803201360Srdivacky 804201360Srdivacky emitContextTable(o, i2); 805201360Srdivacky o << "\n"; 806234353Sdim 807261991Sdim unsigned ModRMTableNum = 0; 808261991Sdim 809234353Sdim o << "static const InstrUID modRMTable[] = {\n"; 810234353Sdim i1++; 811261991Sdim std::vector<unsigned> EmptyTable(1, 0); 812261991Sdim ModRMTable[EmptyTable] = ModRMTableNum; 813261991Sdim ModRMTableNum += EmptyTable.size(); 814261991Sdim o1 << "/* EmptyTable */\n"; 815261991Sdim o1.indent(i1 * 2) << "0x0,\n"; 816234353Sdim i1--; 817261991Sdim emitContextDecisions(o1, o2, i1, i2, ModRMTableNum); 818234353Sdim 819201360Srdivacky o << o1.str(); 820234353Sdim o << " 0x0\n"; 821234353Sdim o << "};\n"; 822201360Srdivacky o << "\n"; 823201360Srdivacky o << o2.str(); 824201360Srdivacky o << "\n"; 825201360Srdivacky o << "\n"; 826201360Srdivacky} 827201360Srdivacky 828201360Srdivackyvoid DisassemblerTables::setTableFields(ModRMDecision &decision, 829201360Srdivacky const ModRMFilter &filter, 830201360Srdivacky InstrUID uid, 831201360Srdivacky uint8_t opcode) { 832239462Sdim for (unsigned index = 0; index < 256; ++index) { 833201360Srdivacky if (filter.accepts(index)) { 834201360Srdivacky if (decision.instructionIDs[index] == uid) 835201360Srdivacky continue; 836201360Srdivacky 837201360Srdivacky if (decision.instructionIDs[index] != 0) { 838201360Srdivacky InstructionSpecifier &newInfo = 839201360Srdivacky InstructionSpecifiers[uid]; 840201360Srdivacky InstructionSpecifier &previousInfo = 841201360Srdivacky InstructionSpecifiers[decision.instructionIDs[index]]; 842239462Sdim 843226633Sdim if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" || 844226633Sdim newInfo.name == "XCHG32ar" || 845226633Sdim newInfo.name == "XCHG32ar64" || 846226633Sdim newInfo.name == "XCHG64ar")) 847226633Sdim continue; // special case for XCHG*ar and NOOP 848201360Srdivacky 849201360Srdivacky if (outranks(previousInfo.insnContext, newInfo.insnContext)) 850201360Srdivacky continue; 851239462Sdim 852276479Sdim if (previousInfo.insnContext == newInfo.insnContext) { 853201360Srdivacky errs() << "Error: Primary decode conflict: "; 854201360Srdivacky errs() << newInfo.name << " would overwrite " << previousInfo.name; 855201360Srdivacky errs() << "\n"; 856201360Srdivacky errs() << "ModRM " << index << "\n"; 857201360Srdivacky errs() << "Opcode " << (uint16_t)opcode << "\n"; 858201360Srdivacky errs() << "Context " << stringForContext(newInfo.insnContext) << "\n"; 859201360Srdivacky HasConflicts = true; 860201360Srdivacky } 861201360Srdivacky } 862201360Srdivacky 863201360Srdivacky decision.instructionIDs[index] = uid; 864201360Srdivacky } 865201360Srdivacky } 866201360Srdivacky} 867201360Srdivacky 868201360Srdivackyvoid DisassemblerTables::setTableFields(OpcodeType type, 869201360Srdivacky InstructionContext insnContext, 870201360Srdivacky uint8_t opcode, 871201360Srdivacky const ModRMFilter &filter, 872226633Sdim InstrUID uid, 873226633Sdim bool is32bit, 874280031Sdim bool ignoresVEX_L, 875280031Sdim unsigned addressSize) { 876201360Srdivacky ContextDecision &decision = *Tables[type]; 877201360Srdivacky 878239462Sdim for (unsigned index = 0; index < IC_max; ++index) { 879280031Sdim if ((is32bit || addressSize == 16) && 880280031Sdim inheritsFrom((InstructionContext)index, IC_64BIT)) 881226633Sdim continue; 882226633Sdim 883280031Sdim bool adSize64 = addressSize == 64; 884239462Sdim if (inheritsFrom((InstructionContext)index, 885280031Sdim InstructionSpecifiers[uid].insnContext, ignoresVEX_L, 886280031Sdim adSize64)) 887239462Sdim setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], 888201360Srdivacky filter, 889201360Srdivacky uid, 890201360Srdivacky opcode); 891201360Srdivacky } 892201360Srdivacky} 893