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