b22aeddb7d9dfccd27fc9874d634e5a45fd84eea
[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   return 0;
145 }
146
147 /// stringForOperandType - Like stringForContext, but for OperandTypes.
148 static inline const char* stringForOperandType(OperandType type) {
149   switch (type) {
150   default:
151     llvm_unreachable("Unhandled type");
152 #define ENUM_ENTRY(i, d) case i: return #i;
153   TYPES
154 #undef ENUM_ENTRY
155   }
156 }
157
158 /// stringForOperandEncoding - like stringForContext, but for
159 ///   OperandEncodings.
160 static inline const char* stringForOperandEncoding(OperandEncoding encoding) {
161   switch (encoding) {
162   default:
163     llvm_unreachable("Unhandled encoding");
164 #define ENUM_ENTRY(i, d) case i: return #i;
165   ENCODINGS
166 #undef ENUM_ENTRY
167   }
168 }
169
170 void DisassemblerTables::emitOneID(raw_ostream &o,
171                                    uint32_t &i,
172                                    InstrUID id,
173                                    bool addComma) const {
174   if (id)
175     o.indent(i * 2) << format("0x%hx", id);
176   else
177     o.indent(i * 2) << 0;
178   
179   if (addComma)
180     o << ", ";
181   else
182     o << "  ";
183   
184   o << "/* ";
185   o << InstructionSpecifiers[id].name;
186   o << "*/";
187   
188   o << "\n";
189 }
190
191 /// emitEmptyTable - Emits the modRMEmptyTable, which is used as a ID table by
192 ///   all ModR/M decisions for instructions that are invalid for all possible
193 ///   ModR/M byte values.
194 ///
195 /// @param o        - The output stream on which to emit the table.
196 /// @param i        - The indentation level for that output stream.
197 static void emitEmptyTable(raw_ostream &o, uint32_t &i)
198 {
199   o.indent(i * 2) << "0x0, /* EmptyTable */\n";
200 }
201
202 /// getDecisionType - Determines whether a ModRM decision with 255 entries can
203 ///   be compacted by eliminating redundant information.
204 ///
205 /// @param decision - The decision to be compacted.
206 /// @return         - The compactest available representation for the decision.
207 static ModRMDecisionType getDecisionType(ModRMDecision &decision)
208 {
209   bool satisfiesOneEntry = true;
210   bool satisfiesSplitRM = true;
211   bool satisfiesSplitReg = true;
212
213   uint16_t index;
214
215   for (index = 0; index < 256; ++index) {
216     if (decision.instructionIDs[index] != decision.instructionIDs[0])
217       satisfiesOneEntry = false;
218
219     if (((index & 0xc0) == 0xc0) &&
220        (decision.instructionIDs[index] != decision.instructionIDs[0xc0]))
221       satisfiesSplitRM = false;
222
223     if (((index & 0xc0) != 0xc0) &&
224        (decision.instructionIDs[index] != decision.instructionIDs[0x00]))
225       satisfiesSplitRM = false;
226
227     if (((index & 0xc0) == 0xc0) &&
228        (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8]))
229       satisfiesSplitReg = false;
230
231     if (((index & 0xc0) != 0xc0) &&
232        (decision.instructionIDs[index] != decision.instructionIDs[index&0x38]))
233       satisfiesSplitReg = false;
234   }
235
236   if (satisfiesOneEntry)
237     return MODRM_ONEENTRY;
238
239   if (satisfiesSplitRM)
240     return MODRM_SPLITRM;
241
242   if (satisfiesSplitReg)
243     return MODRM_SPLITREG;
244
245   return MODRM_FULL;
246 }
247
248 /// stringForDecisionType - Returns a statically-allocated string corresponding
249 ///   to a particular decision type.
250 ///
251 /// @param dt - The decision type.
252 /// @return   - A pointer to the statically-allocated string (e.g., 
253 ///             "MODRM_ONEENTRY" for MODRM_ONEENTRY).
254 static const char* stringForDecisionType(ModRMDecisionType dt)
255 {
256 #define ENUM_ENTRY(n) case n: return #n;
257   switch (dt) {
258     default:
259       llvm_unreachable("Unknown decision type");  
260     MODRMTYPES
261   };  
262 #undef ENUM_ENTRY
263 }
264   
265 /// stringForModifierType - Returns a statically-allocated string corresponding
266 ///   to an opcode modifier type.
267 ///
268 /// @param mt - The modifier type.
269 /// @return   - A pointer to the statically-allocated string (e.g.,
270 ///             "MODIFIER_NONE" for MODIFIER_NONE).
271 static const char* stringForModifierType(ModifierType mt)
272 {
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,
301                                            raw_ostream &o2,
302                                            uint32_t &i1,
303                                            uint32_t &i2,
304                                            ModRMDecision &decision)
305   const {
306   static uint64_t sTableNumber = 0;
307   static uint64_t sEntryNumber = 1;
308   ModRMDecisionType dt = getDecisionType(decision);
309   uint16_t index;
310
311   if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)
312   {
313     o2.indent(i2) << "{ /* ModRMDecision */" << "\n";
314     i2++;
315
316     o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
317     o2.indent(i2) << 0 << " /* EmptyTable */\n";
318
319     i2--;
320     o2.indent(i2) << "}";
321     return;
322   }
323
324   o1 << "/* Table" << sTableNumber << " */\n";
325   i1++;
326
327   switch (dt) {
328     default:
329       llvm_unreachable("Unknown decision type");
330     case MODRM_ONEENTRY:
331       emitOneID(o1, i1, decision.instructionIDs[0], true);
332       break;
333     case MODRM_SPLITRM:
334       emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00
335       emitOneID(o1, i1, decision.instructionIDs[0xc0], true); // mod = 0b11
336       break;
337     case MODRM_SPLITREG:
338       for (index = 0; index < 64; index += 8)
339         emitOneID(o1, i1, decision.instructionIDs[index], true);
340       for (index = 0xc0; index < 256; index += 8)
341         emitOneID(o1, i1, decision.instructionIDs[index], true);
342       break;
343     case MODRM_FULL:
344       for (index = 0; index < 256; ++index)
345         emitOneID(o1, i1, decision.instructionIDs[index], true);
346       break;
347   }
348
349   i1--;
350
351   o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n";
352   i2++;
353
354   o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
355   o2.indent(i2) << sEntryNumber << " /* Table" << sTableNumber << " */\n";
356
357   i2--;
358   o2.indent(i2) << "}";
359
360   switch (dt) {
361     default:
362       llvm_unreachable("Unknown decision type");
363     case MODRM_ONEENTRY:
364       sEntryNumber += 1;
365       break;
366     case MODRM_SPLITRM:
367       sEntryNumber += 2;
368       break;
369     case MODRM_SPLITREG:
370       sEntryNumber += 16;
371       break;
372     case MODRM_FULL:
373       sEntryNumber += 256;
374       break;
375   }
376
377   ++sTableNumber;
378 }
379
380 void DisassemblerTables::emitOpcodeDecision(
381   raw_ostream &o1,
382   raw_ostream &o2,
383   uint32_t &i1,
384   uint32_t &i2,
385   OpcodeDecision &decision) const {
386   uint16_t index;
387
388   o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n";
389   i2++;
390   o2.indent(i2) << "{" << "\n";
391   i2++;
392
393   for (index = 0; index < 256; ++index) {
394     o2.indent(i2);
395
396     o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n";
397
398     emitModRMDecision(o1, o2, i1, i2, decision.modRMDecisions[index]);
399
400     if (index <  255)
401       o2 << ",";
402
403     o2 << "\n";
404   }
405
406   i2--;
407   o2.indent(i2) << "}" << "\n";
408   i2--;
409   o2.indent(i2) << "}" << "\n";
410 }
411
412 void DisassemblerTables::emitContextDecision(
413   raw_ostream &o1,
414   raw_ostream &o2,
415   uint32_t &i1,
416   uint32_t &i2,
417   ContextDecision &decision,
418   const char* name) const {
419   o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n";
420   i2++;
421   o2.indent(i2) << "{ /* opcodeDecisions */" << "\n";
422   i2++;
423
424   unsigned index;
425
426   for (index = 0; index < IC_max; ++index) {
427     o2.indent(i2) << "/* ";
428     o2 << stringForContext((InstructionContext)index);
429     o2 << " */";
430     o2 << "\n";
431
432     emitOpcodeDecision(o1, o2, i1, i2, decision.opcodeDecisions[index]);
433
434     if (index + 1 < IC_max)
435       o2 << ", ";
436   }
437
438   i2--;
439   o2.indent(i2) << "}" << "\n";
440   i2--;
441   o2.indent(i2) << "};" << "\n";
442 }
443
444 void DisassemblerTables::emitInstructionInfo(raw_ostream &o, uint32_t &i) 
445   const {
446   o.indent(i * 2) << "static const struct InstructionSpecifier ";
447   o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n";
448   
449   i++;
450
451   uint16_t numInstructions = InstructionSpecifiers.size();
452   uint16_t index, operandIndex;
453
454   for (index = 0; index < numInstructions; ++index) {
455     o.indent(i * 2) << "{ /* " << index << " */" << "\n";
456     i++;
457     
458     o.indent(i * 2) << 
459       stringForModifierType(InstructionSpecifiers[index].modifierType);
460     o << "," << "\n";
461     
462     o.indent(i * 2) << "0x";
463     o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase);
464     o << "," << "\n";
465
466     o.indent(i * 2) << "{" << "\n";
467     i++;
468
469     for (operandIndex = 0; operandIndex < X86_MAX_OPERANDS; ++operandIndex) {
470       o.indent(i * 2) << "{ ";
471       o << stringForOperandEncoding(InstructionSpecifiers[index]
472                                     .operands[operandIndex]
473                                     .encoding);
474       o << ", ";
475       o << stringForOperandType(InstructionSpecifiers[index]
476                                 .operands[operandIndex]
477                                 .type);
478       o << " }";
479
480       if (operandIndex < X86_MAX_OPERANDS - 1)
481         o << ",";
482
483       o << "\n";
484     }
485
486     i--;
487     o.indent(i * 2) << "}," << "\n";
488     
489     o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */";
490     o << "\n";
491
492     i--;
493     o.indent(i * 2) << "}";
494
495     if (index + 1 < numInstructions)
496       o << ",";
497
498     o << "\n";
499   }
500
501   i--;
502   o.indent(i * 2) << "};" << "\n";
503 }
504
505 void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
506   uint16_t index;
507
508   o.indent(i * 2) << "static const InstructionContext " CONTEXTS_STR
509                      "[256] = {\n";
510   i++;
511
512   for (index = 0; index < 256; ++index) {
513     o.indent(i * 2);
514
515     if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
516       o << "IC_VEX_L_W_OPSIZE";
517     else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE))
518       o << "IC_VEX_L_OPSIZE";
519     else if ((index & ATTR_VEXL) && (index & ATTR_XD))
520       o << "IC_VEX_L_XD";
521     else if ((index & ATTR_VEXL) && (index & ATTR_XS))
522       o << "IC_VEX_L_XS";
523     else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
524       o << "IC_VEX_W_OPSIZE";
525     else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XD))
526       o << "IC_VEX_W_XD";
527     else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XS))
528       o << "IC_VEX_W_XS";
529     else if (index & ATTR_VEXL)
530       o << "IC_VEX_L";
531     else if ((index & ATTR_VEX) && (index & ATTR_REXW))
532       o << "IC_VEX_W";
533     else if ((index & ATTR_VEX) && (index & ATTR_OPSIZE))
534       o << "IC_VEX_OPSIZE";
535     else if ((index & ATTR_VEX) && (index & ATTR_XD))
536       o << "IC_VEX_XD";
537     else if ((index & ATTR_VEX) && (index & ATTR_XS))
538       o << "IC_VEX_XS";
539     else if (index & ATTR_VEX)
540       o << "IC_VEX";
541     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))
542       o << "IC_64BIT_REXW_XS";
543     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD))
544       o << "IC_64BIT_REXW_XD";
545     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && 
546              (index & ATTR_OPSIZE))
547       o << "IC_64BIT_REXW_OPSIZE";
548     else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
549       o << "IC_64BIT_XD_OPSIZE";
550     else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE))
551       o << "IC_64BIT_XS_OPSIZE";
552     else if ((index & ATTR_64BIT) && (index & ATTR_XS))
553       o << "IC_64BIT_XS";
554     else if ((index & ATTR_64BIT) && (index & ATTR_XD))
555       o << "IC_64BIT_XD";
556     else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE))
557       o << "IC_64BIT_OPSIZE";
558     else if ((index & ATTR_64BIT) && (index & ATTR_REXW))
559       o << "IC_64BIT_REXW";
560     else if ((index & ATTR_64BIT))
561       o << "IC_64BIT";
562     else if ((index & ATTR_XS) && (index & ATTR_OPSIZE))
563       o << "IC_XS_OPSIZE";
564     else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
565       o << "IC_XD_OPSIZE";
566     else if (index & ATTR_XS)
567       o << "IC_XS";
568     else if (index & ATTR_XD)
569       o << "IC_XD";
570     else if (index & ATTR_OPSIZE)
571       o << "IC_OPSIZE";
572     else
573       o << "IC";
574
575     if (index < 255)
576       o << ",";
577     else
578       o << " ";
579
580     o << " /* " << index << " */";
581
582     o << "\n";
583   }
584
585   i--;
586   o.indent(i * 2) << "};" << "\n";
587 }
588
589 void DisassemblerTables::emitContextDecisions(raw_ostream &o1,
590                                             raw_ostream &o2,
591                                             uint32_t &i1,
592                                             uint32_t &i2)
593   const {
594   emitContextDecision(o1, o2, i1, i2, *Tables[0], ONEBYTE_STR);
595   emitContextDecision(o1, o2, i1, i2, *Tables[1], TWOBYTE_STR);
596   emitContextDecision(o1, o2, i1, i2, *Tables[2], THREEBYTE38_STR);
597   emitContextDecision(o1, o2, i1, i2, *Tables[3], THREEBYTE3A_STR);
598   emitContextDecision(o1, o2, i1, i2, *Tables[4], THREEBYTEA6_STR);
599   emitContextDecision(o1, o2, i1, i2, *Tables[5], THREEBYTEA7_STR);
600 }
601
602 void DisassemblerTables::emit(raw_ostream &o) const {
603   uint32_t i1 = 0;
604   uint32_t i2 = 0;
605   
606   std::string s1;
607   std::string s2;
608   
609   raw_string_ostream o1(s1);
610   raw_string_ostream o2(s2);
611   
612   emitInstructionInfo(o, i2);
613   o << "\n";
614
615   emitContextTable(o, i2);
616   o << "\n";
617
618   o << "static const InstrUID modRMTable[] = {\n";
619   i1++;
620   emitEmptyTable(o1, i1);
621   i1--;
622   emitContextDecisions(o1, o2, i1, i2);
623
624   o << o1.str();
625   o << "  0x0\n";
626   o << "};\n";
627   o << "\n";
628   o << o2.str();
629   o << "\n";
630   o << "\n";
631 }
632
633 void DisassemblerTables::setTableFields(ModRMDecision     &decision,
634                                         const ModRMFilter &filter,
635                                         InstrUID          uid,
636                                         uint8_t           opcode) {
637   unsigned index;
638
639   for (index = 0; index < 256; ++index) {
640     if (filter.accepts(index)) {
641       if (decision.instructionIDs[index] == uid)
642         continue;
643
644       if (decision.instructionIDs[index] != 0) {
645         InstructionSpecifier &newInfo =
646           InstructionSpecifiers[uid];
647         InstructionSpecifier &previousInfo =
648           InstructionSpecifiers[decision.instructionIDs[index]];
649         
650         if(newInfo.filtered)
651           continue; // filtered instructions get lowest priority
652         
653         if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" ||
654                                            newInfo.name == "XCHG32ar" ||
655                                            newInfo.name == "XCHG32ar64" ||
656                                            newInfo.name == "XCHG64ar"))
657           continue; // special case for XCHG*ar and NOOP
658
659         if (outranks(previousInfo.insnContext, newInfo.insnContext))
660           continue;
661         
662         if (previousInfo.insnContext == newInfo.insnContext &&
663             !previousInfo.filtered) {
664           errs() << "Error: Primary decode conflict: ";
665           errs() << newInfo.name << " would overwrite " << previousInfo.name;
666           errs() << "\n";
667           errs() << "ModRM   " << index << "\n";
668           errs() << "Opcode  " << (uint16_t)opcode << "\n";
669           errs() << "Context " << stringForContext(newInfo.insnContext) << "\n";
670           HasConflicts = true;
671         }
672       }
673
674       decision.instructionIDs[index] = uid;
675     }
676   }
677 }
678
679 void DisassemblerTables::setTableFields(OpcodeType          type,
680                                         InstructionContext  insnContext,
681                                         uint8_t             opcode,
682                                         const ModRMFilter   &filter,
683                                         InstrUID            uid,
684                                         bool                is32bit,
685                                         bool                ignoresVEX_L) {
686   unsigned index;
687   
688   ContextDecision &decision = *Tables[type];
689
690   for (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 }