Add a new compression type to ModRM table that detects when the memory modRM byte...
[oota-llvm.git] / utils / TableGen / X86DisassemblerTables.cpp
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   bool satisfiesSplitMisc = true;
213
214   for (unsigned index = 0; index < 256; ++index) {
215     if (decision.instructionIDs[index] != decision.instructionIDs[0])
216       satisfiesOneEntry = false;
217
218     if (((index & 0xc0) == 0xc0) &&
219        (decision.instructionIDs[index] != decision.instructionIDs[0xc0]))
220       satisfiesSplitRM = false;
221
222     if (((index & 0xc0) != 0xc0) &&
223        (decision.instructionIDs[index] != decision.instructionIDs[0x00]))
224       satisfiesSplitRM = false;
225
226     if (((index & 0xc0) == 0xc0) &&
227        (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8]))
228       satisfiesSplitReg = false;
229
230     if (((index & 0xc0) != 0xc0) &&
231        (decision.instructionIDs[index] != decision.instructionIDs[index&0x38]))
232       satisfiesSplitMisc = false;
233   }
234
235   if (satisfiesOneEntry)
236     return MODRM_ONEENTRY;
237
238   if (satisfiesSplitRM)
239     return MODRM_SPLITRM;
240
241   if (satisfiesSplitReg && satisfiesSplitMisc)
242     return MODRM_SPLITREG;
243
244   if (satisfiesSplitMisc)
245     return MODRM_SPLITMISC;
246
247   return MODRM_FULL;
248 }
249
250 /// stringForDecisionType - Returns a statically-allocated string corresponding
251 ///   to a particular decision type.
252 ///
253 /// @param dt - The decision type.
254 /// @return   - A pointer to the statically-allocated string (e.g.,
255 ///             "MODRM_ONEENTRY" for MODRM_ONEENTRY).
256 static const char* stringForDecisionType(ModRMDecisionType dt) {
257 #define ENUM_ENTRY(n) case n: return #n;
258   switch (dt) {
259     default:
260       llvm_unreachable("Unknown decision type");
261     MODRMTYPES
262   };
263 #undef ENUM_ENTRY
264 }
265
266 /// stringForModifierType - Returns a statically-allocated string corresponding
267 ///   to an opcode modifier type.
268 ///
269 /// @param mt - The modifier type.
270 /// @return   - A pointer to the statically-allocated string (e.g.,
271 ///             "MODIFIER_NONE" for MODIFIER_NONE).
272 static const char* stringForModifierType(ModifierType mt) {
273 #define ENUM_ENTRY(n) case n: return #n;
274   switch(mt) {
275     default:
276       llvm_unreachable("Unknown modifier type");
277     MODIFIER_TYPES
278   };
279 #undef ENUM_ENTRY
280 }
281
282 DisassemblerTables::DisassemblerTables() {
283   unsigned i;
284
285   for (i = 0; i < array_lengthof(Tables); i++) {
286     Tables[i] = new ContextDecision;
287     memset(Tables[i], 0, sizeof(ContextDecision));
288   }
289
290   HasConflicts = false;
291 }
292
293 DisassemblerTables::~DisassemblerTables() {
294   unsigned i;
295
296   for (i = 0; i < array_lengthof(Tables); i++)
297     delete Tables[i];
298 }
299
300 void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
301                                            unsigned &i1, unsigned &i2,
302                                            ModRMDecision &decision) const {
303   static uint32_t sTableNumber = 0;
304   static uint32_t sEntryNumber = 1;
305   ModRMDecisionType dt = getDecisionType(decision);
306
307   if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)
308   {
309     o2.indent(i2) << "{ /* ModRMDecision */" << "\n";
310     i2++;
311
312     o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
313     o2.indent(i2) << 0 << " /* EmptyTable */\n";
314
315     i2--;
316     o2.indent(i2) << "}";
317     return;
318   }
319
320   o1 << "/* Table" << sTableNumber << " */\n";
321   i1++;
322
323   switch (dt) {
324     default:
325       llvm_unreachable("Unknown decision type");
326     case MODRM_ONEENTRY:
327       emitOneID(o1, i1, decision.instructionIDs[0], true);
328       break;
329     case MODRM_SPLITRM:
330       emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00
331       emitOneID(o1, i1, decision.instructionIDs[0xc0], true); // mod = 0b11
332       break;
333     case MODRM_SPLITREG:
334       for (unsigned index = 0; index < 64; index += 8)
335         emitOneID(o1, i1, decision.instructionIDs[index], true);
336       for (unsigned index = 0xc0; index < 256; index += 8)
337         emitOneID(o1, i1, decision.instructionIDs[index], true);
338       break;
339     case MODRM_SPLITMISC:
340       for (unsigned index = 0; index < 64; index += 8)
341         emitOneID(o1, i1, decision.instructionIDs[index], true);
342       for (unsigned index = 0xc0; index < 256; ++index)
343         emitOneID(o1, i1, decision.instructionIDs[index], true);
344       break;
345     case MODRM_FULL:
346       for (unsigned index = 0; index < 256; ++index)
347         emitOneID(o1, i1, decision.instructionIDs[index], true);
348       break;
349   }
350
351   i1--;
352
353   o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n";
354   i2++;
355
356   o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
357   o2.indent(i2) << sEntryNumber << " /* Table" << sTableNumber << " */\n";
358
359   i2--;
360   o2.indent(i2) << "}";
361
362   switch (dt) {
363     default:
364       llvm_unreachable("Unknown decision type");
365     case MODRM_ONEENTRY:
366       sEntryNumber += 1;
367       break;
368     case MODRM_SPLITRM:
369       sEntryNumber += 2;
370       break;
371     case MODRM_SPLITREG:
372       sEntryNumber += 16;
373       break;
374     case MODRM_SPLITMISC:
375       sEntryNumber += 8 + 64;
376       break;
377     case MODRM_FULL:
378       sEntryNumber += 256;
379       break;
380   }
381
382   // We assume that the index can fit into uint16_t.
383   assert(sEntryNumber < 65536U &&
384          "Index into ModRMDecision is too large for uint16_t!");
385
386   ++sTableNumber;
387 }
388
389 void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2,
390                                             unsigned &i1, unsigned &i2,
391                                             OpcodeDecision &decision) const {
392   o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n";
393   i2++;
394   o2.indent(i2) << "{" << "\n";
395   i2++;
396
397   for (unsigned index = 0; index < 256; ++index) {
398     o2.indent(i2);
399
400     o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n";
401
402     emitModRMDecision(o1, o2, i1, i2, decision.modRMDecisions[index]);
403
404     if (index <  255)
405       o2 << ",";
406
407     o2 << "\n";
408   }
409
410   i2--;
411   o2.indent(i2) << "}" << "\n";
412   i2--;
413   o2.indent(i2) << "}" << "\n";
414 }
415
416 void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2,
417                                              unsigned &i1, unsigned &i2,
418                                              ContextDecision &decision,
419                                              const char* name) const {
420   o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n";
421   i2++;
422   o2.indent(i2) << "{ /* opcodeDecisions */" << "\n";
423   i2++;
424
425   for (unsigned index = 0; index < IC_max; ++index) {
426     o2.indent(i2) << "/* ";
427     o2 << stringForContext((InstructionContext)index);
428     o2 << " */";
429     o2 << "\n";
430
431     emitOpcodeDecision(o1, o2, i1, i2, decision.opcodeDecisions[index]);
432
433     if (index + 1 < IC_max)
434       o2 << ", ";
435   }
436
437   i2--;
438   o2.indent(i2) << "}" << "\n";
439   i2--;
440   o2.indent(i2) << "};" << "\n";
441 }
442
443 void DisassemblerTables::emitInstructionInfo(raw_ostream &o,
444                                              unsigned &i) const {
445   unsigned NumInstructions = InstructionSpecifiers.size();
446
447   o << "static const struct OperandSpecifier x86OperandSets[]["
448     << X86_MAX_OPERANDS << "] = {\n";
449
450   typedef std::vector<std::pair<const char *, const char *> > OperandListTy;
451   std::map<OperandListTy, unsigned> OperandSets;
452
453   unsigned OperandSetNum = 0;
454   for (unsigned Index = 0; Index < NumInstructions; ++Index) {
455     OperandListTy OperandList;
456
457     for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
458          ++OperandIndex) {
459       const char *Encoding =
460         stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[Index]
461                                  .operands[OperandIndex].encoding);
462       const char *Type =
463         stringForOperandType((OperandType)InstructionSpecifiers[Index]
464                              .operands[OperandIndex].type);
465       OperandList.push_back(std::make_pair(Encoding, Type));
466     }
467     unsigned &N = OperandSets[OperandList];
468     if (N != 0) continue;
469
470     N = ++OperandSetNum;
471
472     o << "  { /* " << (OperandSetNum - 1) << " */\n";
473     for (unsigned i = 0, e = OperandList.size(); i != e; ++i) {
474       o << "    { " << OperandList[i].first << ", "
475         << OperandList[i].second << " },\n";
476     }
477     o << "  },\n";
478   }
479   o << "};" << "\n\n";
480
481   o.indent(i * 2) << "static const struct InstructionSpecifier ";
482   o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n";
483
484   i++;
485
486   for (unsigned index = 0; index < NumInstructions; ++index) {
487     o.indent(i * 2) << "{ /* " << index << " */" << "\n";
488     i++;
489
490     o.indent(i * 2) << stringForModifierType(
491                        (ModifierType)InstructionSpecifiers[index].modifierType);
492     o << ",\n";
493
494     o.indent(i * 2) << "0x";
495     o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase);
496     o << ",\n";
497
498     OperandListTy OperandList;
499     for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
500          ++OperandIndex) {
501       const char *Encoding =
502         stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[index]
503                                  .operands[OperandIndex].encoding);
504       const char *Type =
505         stringForOperandType((OperandType)InstructionSpecifiers[index]
506                              .operands[OperandIndex].type);
507       OperandList.push_back(std::make_pair(Encoding, Type));
508     }
509     o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n";
510
511     o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */";
512     o << "\n";
513
514     i--;
515     o.indent(i * 2) << "}";
516
517     if (index + 1 < NumInstructions)
518       o << ",";
519
520     o << "\n";
521   }
522
523   i--;
524   o.indent(i * 2) << "};" << "\n";
525 }
526
527 void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
528   o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR
529                      "[256] = {\n";
530   i++;
531
532   for (unsigned index = 0; index < 256; ++index) {
533     o.indent(i * 2);
534
535     if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
536       o << "IC_VEX_L_W_OPSIZE";
537     else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE))
538       o << "IC_VEX_L_OPSIZE";
539     else if ((index & ATTR_VEXL) && (index & ATTR_XD))
540       o << "IC_VEX_L_XD";
541     else if ((index & ATTR_VEXL) && (index & ATTR_XS))
542       o << "IC_VEX_L_XS";
543     else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
544       o << "IC_VEX_W_OPSIZE";
545     else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XD))
546       o << "IC_VEX_W_XD";
547     else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XS))
548       o << "IC_VEX_W_XS";
549     else if (index & ATTR_VEXL)
550       o << "IC_VEX_L";
551     else if ((index & ATTR_VEX) && (index & ATTR_REXW))
552       o << "IC_VEX_W";
553     else if ((index & ATTR_VEX) && (index & ATTR_OPSIZE))
554       o << "IC_VEX_OPSIZE";
555     else if ((index & ATTR_VEX) && (index & ATTR_XD))
556       o << "IC_VEX_XD";
557     else if ((index & ATTR_VEX) && (index & ATTR_XS))
558       o << "IC_VEX_XS";
559     else if (index & ATTR_VEX)
560       o << "IC_VEX";
561     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))
562       o << "IC_64BIT_REXW_XS";
563     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD))
564       o << "IC_64BIT_REXW_XD";
565     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&
566              (index & ATTR_OPSIZE))
567       o << "IC_64BIT_REXW_OPSIZE";
568     else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
569       o << "IC_64BIT_XD_OPSIZE";
570     else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE))
571       o << "IC_64BIT_XS_OPSIZE";
572     else if ((index & ATTR_64BIT) && (index & ATTR_XS))
573       o << "IC_64BIT_XS";
574     else if ((index & ATTR_64BIT) && (index & ATTR_XD))
575       o << "IC_64BIT_XD";
576     else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE))
577       o << "IC_64BIT_OPSIZE";
578     else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE))
579       o << "IC_64BIT_ADSIZE";
580     else if ((index & ATTR_64BIT) && (index & ATTR_REXW))
581       o << "IC_64BIT_REXW";
582     else if ((index & ATTR_64BIT))
583       o << "IC_64BIT";
584     else if ((index & ATTR_XS) && (index & ATTR_OPSIZE))
585       o << "IC_XS_OPSIZE";
586     else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
587       o << "IC_XD_OPSIZE";
588     else if (index & ATTR_XS)
589       o << "IC_XS";
590     else if (index & ATTR_XD)
591       o << "IC_XD";
592     else if (index & ATTR_OPSIZE)
593       o << "IC_OPSIZE";
594     else if (index & ATTR_ADSIZE)
595       o << "IC_ADSIZE";
596     else
597       o << "IC";
598
599     if (index < 255)
600       o << ",";
601     else
602       o << " ";
603
604     o << " /* " << index << " */";
605
606     o << "\n";
607   }
608
609   i--;
610   o.indent(i * 2) << "};" << "\n";
611 }
612
613 void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2,
614                                              unsigned &i1, unsigned &i2) const {
615   emitContextDecision(o1, o2, i1, i2, *Tables[0], ONEBYTE_STR);
616   emitContextDecision(o1, o2, i1, i2, *Tables[1], TWOBYTE_STR);
617   emitContextDecision(o1, o2, i1, i2, *Tables[2], THREEBYTE38_STR);
618   emitContextDecision(o1, o2, i1, i2, *Tables[3], THREEBYTE3A_STR);
619   emitContextDecision(o1, o2, i1, i2, *Tables[4], THREEBYTEA6_STR);
620   emitContextDecision(o1, o2, i1, i2, *Tables[5], THREEBYTEA7_STR);
621 }
622
623 void DisassemblerTables::emit(raw_ostream &o) const {
624   unsigned i1 = 0;
625   unsigned i2 = 0;
626
627   std::string s1;
628   std::string s2;
629
630   raw_string_ostream o1(s1);
631   raw_string_ostream o2(s2);
632
633   emitInstructionInfo(o, i2);
634   o << "\n";
635
636   emitContextTable(o, i2);
637   o << "\n";
638
639   o << "static const InstrUID modRMTable[] = {\n";
640   i1++;
641   emitEmptyTable(o1, i1);
642   i1--;
643   emitContextDecisions(o1, o2, i1, i2);
644
645   o << o1.str();
646   o << "  0x0\n";
647   o << "};\n";
648   o << "\n";
649   o << o2.str();
650   o << "\n";
651   o << "\n";
652 }
653
654 void DisassemblerTables::setTableFields(ModRMDecision     &decision,
655                                         const ModRMFilter &filter,
656                                         InstrUID          uid,
657                                         uint8_t           opcode) {
658   for (unsigned index = 0; index < 256; ++index) {
659     if (filter.accepts(index)) {
660       if (decision.instructionIDs[index] == uid)
661         continue;
662
663       if (decision.instructionIDs[index] != 0) {
664         InstructionSpecifier &newInfo =
665           InstructionSpecifiers[uid];
666         InstructionSpecifier &previousInfo =
667           InstructionSpecifiers[decision.instructionIDs[index]];
668
669         if(newInfo.filtered)
670           continue; // filtered instructions get lowest priority
671
672         if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" ||
673                                            newInfo.name == "XCHG32ar" ||
674                                            newInfo.name == "XCHG32ar64" ||
675                                            newInfo.name == "XCHG64ar"))
676           continue; // special case for XCHG*ar and NOOP
677
678         if (outranks(previousInfo.insnContext, newInfo.insnContext))
679           continue;
680
681         if (previousInfo.insnContext == newInfo.insnContext &&
682             !previousInfo.filtered) {
683           errs() << "Error: Primary decode conflict: ";
684           errs() << newInfo.name << " would overwrite " << previousInfo.name;
685           errs() << "\n";
686           errs() << "ModRM   " << index << "\n";
687           errs() << "Opcode  " << (uint16_t)opcode << "\n";
688           errs() << "Context " << stringForContext(newInfo.insnContext) << "\n";
689           HasConflicts = true;
690         }
691       }
692
693       decision.instructionIDs[index] = uid;
694     }
695   }
696 }
697
698 void DisassemblerTables::setTableFields(OpcodeType          type,
699                                         InstructionContext  insnContext,
700                                         uint8_t             opcode,
701                                         const ModRMFilter   &filter,
702                                         InstrUID            uid,
703                                         bool                is32bit,
704                                         bool                ignoresVEX_L) {
705   ContextDecision &decision = *Tables[type];
706
707   for (unsigned index = 0; index < IC_max; ++index) {
708     if (is32bit && inheritsFrom((InstructionContext)index, IC_64BIT))
709       continue;
710
711     if (inheritsFrom((InstructionContext)index,
712                      InstructionSpecifiers[uid].insnContext, ignoresVEX_L))
713       setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode],
714                      filter,
715                      uid,
716                      opcode);
717   }
718 }