Home | History | Annotate | Download | only in TableGen
      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 "X86DisassemblerShared.h"
     18 #include "X86DisassemblerTables.h"
     19 
     20 #include "llvm/TableGen/TableGenBackend.h"
     21 #include "llvm/ADT/STLExtras.h"
     22 #include "llvm/Support/ErrorHandling.h"
     23 #include "llvm/Support/Format.h"
     24 #include <map>
     25 
     26 using namespace llvm;
     27 using namespace X86Disassembler;
     28 
     29 /// inheritsFrom - Indicates whether all instructions in one class also belong
     30 ///   to another class.
     31 ///
     32 /// @param child  - The class that may be the subset
     33 /// @param parent - The class that may be the superset
     34 /// @return       - True if child is a subset of parent, false otherwise.
     35 static inline bool inheritsFrom(InstructionContext child,
     36                                 InstructionContext parent,
     37                                 bool VEX_LIG = false) {
     38   if (child == parent)
     39     return true;
     40 
     41   switch (parent) {
     42   case IC:
     43     return(inheritsFrom(child, IC_64BIT) ||
     44            inheritsFrom(child, IC_OPSIZE) ||
     45            inheritsFrom(child, IC_ADSIZE) ||
     46            inheritsFrom(child, IC_XD) ||
     47            inheritsFrom(child, IC_XS));
     48   case IC_64BIT:
     49     return(inheritsFrom(child, IC_64BIT_REXW)   ||
     50            inheritsFrom(child, IC_64BIT_OPSIZE) ||
     51            inheritsFrom(child, IC_64BIT_ADSIZE) ||
     52            inheritsFrom(child, IC_64BIT_XD)     ||
     53            inheritsFrom(child, IC_64BIT_XS));
     54   case IC_OPSIZE:
     55     return inheritsFrom(child, IC_64BIT_OPSIZE);
     56   case IC_ADSIZE:
     57   case IC_64BIT_ADSIZE:
     58     return false;
     59   case IC_XD:
     60     return inheritsFrom(child, IC_64BIT_XD);
     61   case IC_XS:
     62     return inheritsFrom(child, IC_64BIT_XS);
     63   case IC_XD_OPSIZE:
     64     return inheritsFrom(child, IC_64BIT_XD_OPSIZE);
     65   case IC_XS_OPSIZE:
     66     return inheritsFrom(child, IC_64BIT_XS_OPSIZE);
     67   case IC_64BIT_REXW:
     68     return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
     69            inheritsFrom(child, IC_64BIT_REXW_XD) ||
     70            inheritsFrom(child, IC_64BIT_REXW_OPSIZE));
     71   case IC_64BIT_OPSIZE:
     72     return(inheritsFrom(child, IC_64BIT_REXW_OPSIZE));
     73   case IC_64BIT_XD:
     74     return(inheritsFrom(child, IC_64BIT_REXW_XD));
     75   case IC_64BIT_XS:
     76     return(inheritsFrom(child, IC_64BIT_REXW_XS));
     77   case IC_64BIT_XD_OPSIZE:
     78   case IC_64BIT_XS_OPSIZE:
     79     return false;
     80   case IC_64BIT_REXW_XD:
     81   case IC_64BIT_REXW_XS:
     82   case IC_64BIT_REXW_OPSIZE:
     83     return false;
     84   case IC_VEX:
     85     return inheritsFrom(child, IC_VEX_W) ||
     86            (VEX_LIG && inheritsFrom(child, IC_VEX_L));
     87   case IC_VEX_XS:
     88     return inheritsFrom(child, IC_VEX_W_XS) ||
     89            (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS));
     90   case IC_VEX_XD:
     91     return inheritsFrom(child, IC_VEX_W_XD) ||
     92            (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD));
     93   case IC_VEX_OPSIZE:
     94     return inheritsFrom(child, IC_VEX_W_OPSIZE) ||
     95            (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE));
     96   case IC_VEX_W:
     97   case IC_VEX_W_XS:
     98   case IC_VEX_W_XD:
     99   case IC_VEX_W_OPSIZE:
    100     return false;
    101   case IC_VEX_L:
    102   case IC_VEX_L_XS:
    103   case IC_VEX_L_XD:
    104     return false;
    105   case IC_VEX_L_OPSIZE:
    106     return inheritsFrom(child, IC_VEX_L_W_OPSIZE);
    107   case IC_VEX_L_W_OPSIZE:
    108     return false;
    109   default:
    110     llvm_unreachable("Unknown instruction class");
    111   }
    112 }
    113 
    114 /// outranks - Indicates whether, if an instruction has two different applicable
    115 ///   classes, which class should be preferred when performing decode.  This
    116 ///   imposes a total ordering (ties are resolved toward "lower")
    117 ///
    118 /// @param upper  - The class that may be preferable
    119 /// @param lower  - The class that may be less preferable
    120 /// @return       - True if upper is to be preferred, false otherwise.
    121 static inline bool outranks(InstructionContext upper,
    122                             InstructionContext lower) {
    123   assert(upper < IC_max);
    124   assert(lower < IC_max);
    125 
    126 #define ENUM_ENTRY(n, r, d) r,
    127   static int ranks[IC_max] = {
    128     INSTRUCTION_CONTEXTS
    129   };
    130 #undef ENUM_ENTRY
    131 
    132   return (ranks[upper] > ranks[lower]);
    133 }
    134 
    135 /// stringForContext - Returns a string containing the name of a particular
    136 ///   InstructionContext, usually for diagnostic purposes.
    137 ///
    138 /// @param insnContext  - The instruction class to transform to a string.
    139 /// @return           - A statically-allocated string constant that contains the
    140 ///                     name of the instruction class.
    141 static inline const char* stringForContext(InstructionContext insnContext) {
    142   switch (insnContext) {
    143   default:
    144     llvm_unreachable("Unhandled instruction class");
    145 #define ENUM_ENTRY(n, r, d)   case n: return #n; break;
    146   INSTRUCTION_CONTEXTS
    147 #undef ENUM_ENTRY
    148   }
    149 }
    150 
    151 /// stringForOperandType - Like stringForContext, but for OperandTypes.
    152 static inline const char* stringForOperandType(OperandType type) {
    153   switch (type) {
    154   default:
    155     llvm_unreachable("Unhandled type");
    156 #define ENUM_ENTRY(i, d) case i: return #i;
    157   TYPES
    158 #undef ENUM_ENTRY
    159   }
    160 }
    161 
    162 /// stringForOperandEncoding - like stringForContext, but for
    163 ///   OperandEncodings.
    164 static inline const char* stringForOperandEncoding(OperandEncoding encoding) {
    165   switch (encoding) {
    166   default:
    167     llvm_unreachable("Unhandled encoding");
    168 #define ENUM_ENTRY(i, d) case i: return #i;
    169   ENCODINGS
    170 #undef ENUM_ENTRY
    171   }
    172 }
    173 
    174 void DisassemblerTables::emitOneID(raw_ostream &o, unsigned &i, InstrUID id,
    175                                    bool addComma) const {
    176   if (id)
    177     o.indent(i * 2) << format("0x%hx", id);
    178   else
    179     o.indent(i * 2) << 0;
    180 
    181   if (addComma)
    182     o << ", ";
    183   else
    184     o << "  ";
    185 
    186   o << "/* ";
    187   o << InstructionSpecifiers[id].name;
    188   o << "*/";
    189 
    190   o << "\n";
    191 }
    192 
    193 /// emitEmptyTable - Emits the modRMEmptyTable, which is used as a ID table by
    194 ///   all ModR/M decisions for instructions that are invalid for all possible
    195 ///   ModR/M byte values.
    196 ///
    197 /// @param o        - The output stream on which to emit the table.
    198 /// @param i        - The indentation level for that output stream.
    199 static void emitEmptyTable(raw_ostream &o, unsigned &i) {
    200   o.indent(i * 2) << "0x0, /* EmptyTable */\n";
    201 }
    202 
    203 /// getDecisionType - Determines whether a ModRM decision with 255 entries can
    204 ///   be compacted by eliminating redundant information.
    205 ///
    206 /// @param decision - The decision to be compacted.
    207 /// @return         - The compactest available representation for the decision.
    208 static ModRMDecisionType getDecisionType(ModRMDecision &decision) {
    209   bool satisfiesOneEntry = true;
    210   bool satisfiesSplitRM = true;
    211   bool satisfiesSplitReg = true;
    212 
    213   for (unsigned index = 0; index < 256; ++index) {
    214     if (decision.instructionIDs[index] != decision.instructionIDs[0])
    215       satisfiesOneEntry = false;
    216 
    217     if (((index & 0xc0) == 0xc0) &&
    218        (decision.instructionIDs[index] != decision.instructionIDs[0xc0]))
    219       satisfiesSplitRM = false;
    220 
    221     if (((index & 0xc0) != 0xc0) &&
    222        (decision.instructionIDs[index] != decision.instructionIDs[0x00]))
    223       satisfiesSplitRM = false;
    224 
    225     if (((index & 0xc0) == 0xc0) &&
    226        (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8]))
    227       satisfiesSplitReg = false;
    228 
    229     if (((index & 0xc0) != 0xc0) &&
    230        (decision.instructionIDs[index] != decision.instructionIDs[index&0x38]))
    231       satisfiesSplitReg = false;
    232   }
    233 
    234   if (satisfiesOneEntry)
    235     return MODRM_ONEENTRY;
    236 
    237   if (satisfiesSplitRM)
    238     return MODRM_SPLITRM;
    239 
    240   if (satisfiesSplitReg)
    241     return MODRM_SPLITREG;
    242 
    243   return MODRM_FULL;
    244 }
    245 
    246 /// stringForDecisionType - Returns a statically-allocated string corresponding
    247 ///   to a particular decision type.
    248 ///
    249 /// @param dt - The decision type.
    250 /// @return   - A pointer to the statically-allocated string (e.g.,
    251 ///             "MODRM_ONEENTRY" for MODRM_ONEENTRY).
    252 static const char* stringForDecisionType(ModRMDecisionType dt) {
    253 #define ENUM_ENTRY(n) case n: return #n;
    254   switch (dt) {
    255     default:
    256       llvm_unreachable("Unknown decision type");
    257     MODRMTYPES
    258   };
    259 #undef ENUM_ENTRY
    260 }
    261 
    262 /// stringForModifierType - Returns a statically-allocated string corresponding
    263 ///   to an opcode modifier type.
    264 ///
    265 /// @param mt - The modifier type.
    266 /// @return   - A pointer to the statically-allocated string (e.g.,
    267 ///             "MODIFIER_NONE" for MODIFIER_NONE).
    268 static const char* stringForModifierType(ModifierType mt) {
    269 #define ENUM_ENTRY(n) case n: return #n;
    270   switch(mt) {
    271     default:
    272       llvm_unreachable("Unknown modifier type");
    273     MODIFIER_TYPES
    274   };
    275 #undef ENUM_ENTRY
    276 }
    277 
    278 DisassemblerTables::DisassemblerTables() {
    279   unsigned i;
    280 
    281   for (i = 0; i < array_lengthof(Tables); i++) {
    282     Tables[i] = new ContextDecision;
    283     memset(Tables[i], 0, sizeof(ContextDecision));
    284   }
    285 
    286   HasConflicts = false;
    287 }
    288 
    289 DisassemblerTables::~DisassemblerTables() {
    290   unsigned i;
    291 
    292   for (i = 0; i < array_lengthof(Tables); i++)
    293     delete Tables[i];
    294 }
    295 
    296 void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
    297                                            unsigned &i1, unsigned &i2,
    298                                            ModRMDecision &decision) const {
    299   static uint32_t sTableNumber = 0;
    300   static uint32_t sEntryNumber = 1;
    301   ModRMDecisionType dt = getDecisionType(decision);
    302 
    303   if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)
    304   {
    305     o2.indent(i2) << "{ /* ModRMDecision */" << "\n";
    306     i2++;
    307 
    308     o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
    309     o2.indent(i2) << 0 << " /* EmptyTable */\n";
    310 
    311     i2--;
    312     o2.indent(i2) << "}";
    313     return;
    314   }
    315 
    316   o1 << "/* Table" << sTableNumber << " */\n";
    317   i1++;
    318 
    319   switch (dt) {
    320     default:
    321       llvm_unreachable("Unknown decision type");
    322     case MODRM_ONEENTRY:
    323       emitOneID(o1, i1, decision.instructionIDs[0], true);
    324       break;
    325     case MODRM_SPLITRM:
    326       emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00
    327       emitOneID(o1, i1, decision.instructionIDs[0xc0], true); // mod = 0b11
    328       break;
    329     case MODRM_SPLITREG:
    330       for (unsigned index = 0; index < 64; index += 8)
    331         emitOneID(o1, i1, decision.instructionIDs[index], true);
    332       for (unsigned index = 0xc0; index < 256; index += 8)
    333         emitOneID(o1, i1, decision.instructionIDs[index], true);
    334       break;
    335     case MODRM_FULL:
    336       for (unsigned index = 0; index < 256; ++index)
    337         emitOneID(o1, i1, decision.instructionIDs[index], true);
    338       break;
    339   }
    340 
    341   i1--;
    342 
    343   o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n";
    344   i2++;
    345 
    346   o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
    347   o2.indent(i2) << sEntryNumber << " /* Table" << sTableNumber << " */\n";
    348 
    349   i2--;
    350   o2.indent(i2) << "}";
    351 
    352   switch (dt) {
    353     default:
    354       llvm_unreachable("Unknown decision type");
    355     case MODRM_ONEENTRY:
    356       sEntryNumber += 1;
    357       break;
    358     case MODRM_SPLITRM:
    359       sEntryNumber += 2;
    360       break;
    361     case MODRM_SPLITREG:
    362       sEntryNumber += 16;
    363       break;
    364     case MODRM_FULL:
    365       sEntryNumber += 256;
    366       break;
    367   }
    368 
    369   ++sTableNumber;
    370 }
    371 
    372 void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2,
    373                                             unsigned &i1, unsigned &i2,
    374                                             OpcodeDecision &decision) const {
    375   o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n";
    376   i2++;
    377   o2.indent(i2) << "{" << "\n";
    378   i2++;
    379 
    380   for (unsigned index = 0; index < 256; ++index) {
    381     o2.indent(i2);
    382 
    383     o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n";
    384 
    385     emitModRMDecision(o1, o2, i1, i2, decision.modRMDecisions[index]);
    386 
    387     if (index <  255)
    388       o2 << ",";
    389 
    390     o2 << "\n";
    391   }
    392 
    393   i2--;
    394   o2.indent(i2) << "}" << "\n";
    395   i2--;
    396   o2.indent(i2) << "}" << "\n";
    397 }
    398 
    399 void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2,
    400                                              unsigned &i1, unsigned &i2,
    401                                              ContextDecision &decision,
    402                                              const char* name) const {
    403   o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n";
    404   i2++;
    405   o2.indent(i2) << "{ /* opcodeDecisions */" << "\n";
    406   i2++;
    407 
    408   for (unsigned index = 0; index < IC_max; ++index) {
    409     o2.indent(i2) << "/* ";
    410     o2 << stringForContext((InstructionContext)index);
    411     o2 << " */";
    412     o2 << "\n";
    413 
    414     emitOpcodeDecision(o1, o2, i1, i2, decision.opcodeDecisions[index]);
    415 
    416     if (index + 1 < IC_max)
    417       o2 << ", ";
    418   }
    419 
    420   i2--;
    421   o2.indent(i2) << "}" << "\n";
    422   i2--;
    423   o2.indent(i2) << "};" << "\n";
    424 }
    425 
    426 void DisassemblerTables::emitInstructionInfo(raw_ostream &o,
    427                                              unsigned &i) const {
    428   unsigned NumInstructions = InstructionSpecifiers.size();
    429 
    430   o << "static const struct OperandSpecifier x86OperandSets[]["
    431     << X86_MAX_OPERANDS << "] = {\n";
    432 
    433   typedef std::vector<std::pair<const char *, const char *> > OperandListTy;
    434   std::map<OperandListTy, unsigned> OperandSets;
    435 
    436   unsigned OperandSetNum = 0;
    437   for (unsigned Index = 0; Index < NumInstructions; ++Index) {
    438     OperandListTy OperandList;
    439 
    440     for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
    441          ++OperandIndex) {
    442       const char *Encoding =
    443         stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[Index]
    444                                  .operands[OperandIndex].encoding);
    445       const char *Type =
    446         stringForOperandType((OperandType)InstructionSpecifiers[Index]
    447                              .operands[OperandIndex].type);
    448       OperandList.push_back(std::make_pair(Encoding, Type));
    449     }
    450     unsigned &N = OperandSets[OperandList];
    451     if (N != 0) continue;
    452 
    453     N = ++OperandSetNum;
    454 
    455     o << "  { /* " << (OperandSetNum - 1) << " */\n";
    456     for (unsigned i = 0, e = OperandList.size(); i != e; ++i) {
    457       o << "    { " << OperandList[i].first << ", "
    458         << OperandList[i].second << " },\n";
    459     }
    460     o << "  },\n";
    461   }
    462   o << "};" << "\n\n";
    463 
    464   o.indent(i * 2) << "static const struct InstructionSpecifier ";
    465   o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n";
    466 
    467   i++;
    468 
    469   for (unsigned index = 0; index < NumInstructions; ++index) {
    470     o.indent(i * 2) << "{ /* " << index << " */" << "\n";
    471     i++;
    472 
    473     o.indent(i * 2) << stringForModifierType(
    474                        (ModifierType)InstructionSpecifiers[index].modifierType);
    475     o << ",\n";
    476 
    477     o.indent(i * 2) << "0x";
    478     o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase);
    479     o << ",\n";
    480 
    481     OperandListTy OperandList;
    482     for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
    483          ++OperandIndex) {
    484       const char *Encoding =
    485         stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[index]
    486                                  .operands[OperandIndex].encoding);
    487       const char *Type =
    488         stringForOperandType((OperandType)InstructionSpecifiers[index]
    489                              .operands[OperandIndex].type);
    490       OperandList.push_back(std::make_pair(Encoding, Type));
    491     }
    492     o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n";
    493 
    494     o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */";
    495     o << "\n";
    496 
    497     i--;
    498     o.indent(i * 2) << "}";
    499 
    500     if (index + 1 < NumInstructions)
    501       o << ",";
    502 
    503     o << "\n";
    504   }
    505 
    506   i--;
    507   o.indent(i * 2) << "};" << "\n";
    508 }
    509 
    510 void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
    511   o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR
    512                      "[256] = {\n";
    513   i++;
    514 
    515   for (unsigned index = 0; index < 256; ++index) {
    516     o.indent(i * 2);
    517 
    518     if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
    519       o << "IC_VEX_L_W_OPSIZE";
    520     else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE))
    521       o << "IC_VEX_L_OPSIZE";
    522     else if ((index & ATTR_VEXL) && (index & ATTR_XD))
    523       o << "IC_VEX_L_XD";
    524     else if ((index & ATTR_VEXL) && (index & ATTR_XS))
    525       o << "IC_VEX_L_XS";
    526     else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
    527       o << "IC_VEX_W_OPSIZE";
    528     else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XD))
    529       o << "IC_VEX_W_XD";
    530     else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XS))
    531       o << "IC_VEX_W_XS";
    532     else if (index & ATTR_VEXL)
    533       o << "IC_VEX_L";
    534     else if ((index & ATTR_VEX) && (index & ATTR_REXW))
    535       o << "IC_VEX_W";
    536     else if ((index & ATTR_VEX) && (index & ATTR_OPSIZE))
    537       o << "IC_VEX_OPSIZE";
    538     else if ((index & ATTR_VEX) && (index & ATTR_XD))
    539       o << "IC_VEX_XD";
    540     else if ((index & ATTR_VEX) && (index & ATTR_XS))
    541       o << "IC_VEX_XS";
    542     else if (index & ATTR_VEX)
    543       o << "IC_VEX";
    544     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))
    545       o << "IC_64BIT_REXW_XS";
    546     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD))
    547       o << "IC_64BIT_REXW_XD";
    548     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&
    549              (index & ATTR_OPSIZE))
    550       o << "IC_64BIT_REXW_OPSIZE";
    551     else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
    552       o << "IC_64BIT_XD_OPSIZE";
    553     else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE))
    554       o << "IC_64BIT_XS_OPSIZE";
    555     else if ((index & ATTR_64BIT) && (index & ATTR_XS))
    556       o << "IC_64BIT_XS";
    557     else if ((index & ATTR_64BIT) && (index & ATTR_XD))
    558       o << "IC_64BIT_XD";
    559     else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE))
    560       o << "IC_64BIT_OPSIZE";
    561     else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE))
    562       o << "IC_64BIT_ADSIZE";
    563     else if ((index & ATTR_64BIT) && (index & ATTR_REXW))
    564       o << "IC_64BIT_REXW";
    565     else if ((index & ATTR_64BIT))
    566       o << "IC_64BIT";
    567     else if ((index & ATTR_XS) && (index & ATTR_OPSIZE))
    568       o << "IC_XS_OPSIZE";
    569     else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
    570       o << "IC_XD_OPSIZE";
    571     else if (index & ATTR_XS)
    572       o << "IC_XS";
    573     else if (index & ATTR_XD)
    574       o << "IC_XD";
    575     else if (index & ATTR_OPSIZE)
    576       o << "IC_OPSIZE";
    577     else if (index & ATTR_ADSIZE)
    578       o << "IC_ADSIZE";
    579     else
    580       o << "IC";
    581 
    582     if (index < 255)
    583       o << ",";
    584     else
    585       o << " ";
    586 
    587     o << " /* " << index << " */";
    588 
    589     o << "\n";
    590   }
    591 
    592   i--;
    593   o.indent(i * 2) << "};" << "\n";
    594 }
    595 
    596 void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2,
    597                                              unsigned &i1, unsigned &i2) const {
    598   emitContextDecision(o1, o2, i1, i2, *Tables[0], ONEBYTE_STR);
    599   emitContextDecision(o1, o2, i1, i2, *Tables[1], TWOBYTE_STR);
    600   emitContextDecision(o1, o2, i1, i2, *Tables[2], THREEBYTE38_STR);
    601   emitContextDecision(o1, o2, i1, i2, *Tables[3], THREEBYTE3A_STR);
    602   emitContextDecision(o1, o2, i1, i2, *Tables[4], THREEBYTEA6_STR);
    603   emitContextDecision(o1, o2, i1, i2, *Tables[5], THREEBYTEA7_STR);
    604 }
    605 
    606 void DisassemblerTables::emit(raw_ostream &o) const {
    607   unsigned i1 = 0;
    608   unsigned i2 = 0;
    609 
    610   std::string s1;
    611   std::string s2;
    612 
    613   raw_string_ostream o1(s1);
    614   raw_string_ostream o2(s2);
    615 
    616   emitInstructionInfo(o, i2);
    617   o << "\n";
    618 
    619   emitContextTable(o, i2);
    620   o << "\n";
    621 
    622   o << "static const InstrUID modRMTable[] = {\n";
    623   i1++;
    624   emitEmptyTable(o1, i1);
    625   i1--;
    626   emitContextDecisions(o1, o2, i1, i2);
    627 
    628   o << o1.str();
    629   o << "  0x0\n";
    630   o << "};\n";
    631   o << "\n";
    632   o << o2.str();
    633   o << "\n";
    634   o << "\n";
    635 }
    636 
    637 void DisassemblerTables::setTableFields(ModRMDecision     &decision,
    638                                         const ModRMFilter &filter,
    639                                         InstrUID          uid,
    640                                         uint8_t           opcode) {
    641   for (unsigned index = 0; index < 256; ++index) {
    642     if (filter.accepts(index)) {
    643       if (decision.instructionIDs[index] == uid)
    644         continue;
    645 
    646       if (decision.instructionIDs[index] != 0) {
    647         InstructionSpecifier &newInfo =
    648           InstructionSpecifiers[uid];
    649         InstructionSpecifier &previousInfo =
    650           InstructionSpecifiers[decision.instructionIDs[index]];
    651 
    652         if(newInfo.filtered)
    653           continue; // filtered instructions get lowest priority
    654 
    655         if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" ||
    656                                            newInfo.name == "XCHG32ar" ||
    657                                            newInfo.name == "XCHG32ar64" ||
    658                                            newInfo.name == "XCHG64ar"))
    659           continue; // special case for XCHG*ar and NOOP
    660 
    661         if (outranks(previousInfo.insnContext, newInfo.insnContext))
    662           continue;
    663 
    664         if (previousInfo.insnContext == newInfo.insnContext &&
    665             !previousInfo.filtered) {
    666           errs() << "Error: Primary decode conflict: ";
    667           errs() << newInfo.name << " would overwrite " << previousInfo.name;
    668           errs() << "\n";
    669           errs() << "ModRM   " << index << "\n";
    670           errs() << "Opcode  " << (uint16_t)opcode << "\n";
    671           errs() << "Context " << stringForContext(newInfo.insnContext) << "\n";
    672           HasConflicts = true;
    673         }
    674       }
    675 
    676       decision.instructionIDs[index] = uid;
    677     }
    678   }
    679 }
    680 
    681 void DisassemblerTables::setTableFields(OpcodeType          type,
    682                                         InstructionContext  insnContext,
    683                                         uint8_t             opcode,
    684                                         const ModRMFilter   &filter,
    685                                         InstrUID            uid,
    686                                         bool                is32bit,
    687                                         bool                ignoresVEX_L) {
    688   ContextDecision &decision = *Tables[type];
    689 
    690   for (unsigned index = 0; index < IC_max; ++index) {
    691     if (is32bit && inheritsFrom((InstructionContext)index, IC_64BIT))
    692       continue;
    693 
    694     if (inheritsFrom((InstructionContext)index,
    695                      InstructionSpecifiers[uid].insnContext, ignoresVEX_L))
    696       setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode],
    697                      filter,
    698                      uid,
    699                      opcode);
    700   }
    701 }
    702