1201360Srdivacky//===- X86DisassemblerTables.cpp - Disassembler tables ----------*- C++ -*-===//
2201360Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6201360Srdivacky//
7201360Srdivacky//===----------------------------------------------------------------------===//
8201360Srdivacky//
9201360Srdivacky// This file is part of the X86 Disassembler Emitter.
10201360Srdivacky// It contains the implementation of the disassembler tables.
11201360Srdivacky// Documentation for the disassembler emitter in general can be found in
12321369Sdim//  X86DisassemblerEmitter.h.
13201360Srdivacky//
14201360Srdivacky//===----------------------------------------------------------------------===//
15201360Srdivacky
16249423Sdim#include "X86DisassemblerTables.h"
17201360Srdivacky#include "X86DisassemblerShared.h"
18221345Sdim#include "llvm/ADT/STLExtras.h"
19201360Srdivacky#include "llvm/Support/ErrorHandling.h"
20201360Srdivacky#include "llvm/Support/Format.h"
21239462Sdim#include <map>
22201360Srdivacky
23201360Srdivackyusing namespace llvm;
24201360Srdivackyusing namespace X86Disassembler;
25239462Sdim
26276479Sdim/// stringForContext - Returns a string containing the name of a particular
27276479Sdim///   InstructionContext, usually for diagnostic purposes.
28276479Sdim///
29276479Sdim/// @param insnContext  - The instruction class to transform to a string.
30276479Sdim/// @return           - A statically-allocated string constant that contains the
31276479Sdim///                     name of the instruction class.
32276479Sdimstatic inline const char* stringForContext(InstructionContext insnContext) {
33276479Sdim  switch (insnContext) {
34276479Sdim  default:
35276479Sdim    llvm_unreachable("Unhandled instruction class");
36276479Sdim#define ENUM_ENTRY(n, r, d)   case n: return #n; break;
37276479Sdim#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) ENUM_ENTRY(n##_K_B, r, d)\
38276479Sdim        ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d)\
39276479Sdim        ENUM_ENTRY(n##_KZ_B, r, d)
40276479Sdim  INSTRUCTION_CONTEXTS
41276479Sdim#undef ENUM_ENTRY
42276479Sdim#undef ENUM_ENTRY_K_B
43276479Sdim  }
44276479Sdim}
45276479Sdim
46276479Sdim/// stringForOperandType - Like stringForContext, but for OperandTypes.
47276479Sdimstatic inline const char* stringForOperandType(OperandType type) {
48276479Sdim  switch (type) {
49276479Sdim  default:
50276479Sdim    llvm_unreachable("Unhandled type");
51276479Sdim#define ENUM_ENTRY(i, d) case i: return #i;
52276479Sdim  TYPES
53276479Sdim#undef ENUM_ENTRY
54276479Sdim  }
55276479Sdim}
56276479Sdim
57276479Sdim/// stringForOperandEncoding - like stringForContext, but for
58276479Sdim///   OperandEncodings.
59276479Sdimstatic inline const char* stringForOperandEncoding(OperandEncoding encoding) {
60276479Sdim  switch (encoding) {
61276479Sdim  default:
62276479Sdim    llvm_unreachable("Unhandled encoding");
63276479Sdim#define ENUM_ENTRY(i, d) case i: return #i;
64276479Sdim  ENCODINGS
65276479Sdim#undef ENUM_ENTRY
66276479Sdim  }
67276479Sdim}
68276479Sdim
69201360Srdivacky/// inheritsFrom - Indicates whether all instructions in one class also belong
70201360Srdivacky///   to another class.
71201360Srdivacky///
72201360Srdivacky/// @param child  - The class that may be the subset
73201360Srdivacky/// @param parent - The class that may be the superset
74201360Srdivacky/// @return       - True if child is a subset of parent, false otherwise.
75201360Srdivackystatic inline bool inheritsFrom(InstructionContext child,
76327952Sdim                                InstructionContext parent, bool noPrefix = true,
77327952Sdim                                bool VEX_LIG = false, bool VEX_WIG = false,
78327952Sdim                                bool AdSize64 = false) {
79201360Srdivacky  if (child == parent)
80201360Srdivacky    return true;
81239462Sdim
82201360Srdivacky  switch (parent) {
83201360Srdivacky  case IC:
84280031Sdim    return(inheritsFrom(child, IC_64BIT, AdSize64) ||
85327952Sdim           (noPrefix && inheritsFrom(child, IC_OPSIZE, noPrefix)) ||
86234353Sdim           inheritsFrom(child, IC_ADSIZE) ||
87327952Sdim           (noPrefix && inheritsFrom(child, IC_XD, noPrefix)) ||
88327952Sdim           (noPrefix && inheritsFrom(child, IC_XS, noPrefix)));
89201360Srdivacky  case IC_64BIT:
90201360Srdivacky    return(inheritsFrom(child, IC_64BIT_REXW)   ||
91327952Sdim           (noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE, noPrefix)) ||
92280031Sdim           (!AdSize64 && inheritsFrom(child, IC_64BIT_ADSIZE)) ||
93327952Sdim           (noPrefix && inheritsFrom(child, IC_64BIT_XD, noPrefix))     ||
94327952Sdim           (noPrefix && inheritsFrom(child, IC_64BIT_XS, noPrefix)));
95201360Srdivacky  case IC_OPSIZE:
96280031Sdim    return inheritsFrom(child, IC_64BIT_OPSIZE) ||
97280031Sdim           inheritsFrom(child, IC_OPSIZE_ADSIZE);
98234353Sdim  case IC_ADSIZE:
99327952Sdim    return (noPrefix && inheritsFrom(child, IC_OPSIZE_ADSIZE, noPrefix));
100280031Sdim  case IC_OPSIZE_ADSIZE:
101280031Sdim    return false;
102234353Sdim  case IC_64BIT_ADSIZE:
103327952Sdim    return (noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE, noPrefix));
104280031Sdim  case IC_64BIT_OPSIZE_ADSIZE:
105234353Sdim    return false;
106201360Srdivacky  case IC_XD:
107226633Sdim    return inheritsFrom(child, IC_64BIT_XD);
108201360Srdivacky  case IC_XS:
109226633Sdim    return inheritsFrom(child, IC_64BIT_XS);
110226633Sdim  case IC_XD_OPSIZE:
111226633Sdim    return inheritsFrom(child, IC_64BIT_XD_OPSIZE);
112226633Sdim  case IC_XS_OPSIZE:
113226633Sdim    return inheritsFrom(child, IC_64BIT_XS_OPSIZE);
114341825Sdim  case IC_XD_ADSIZE:
115341825Sdim    return inheritsFrom(child, IC_64BIT_XD_ADSIZE);
116341825Sdim  case IC_XS_ADSIZE:
117341825Sdim    return inheritsFrom(child, IC_64BIT_XS_ADSIZE);
118201360Srdivacky  case IC_64BIT_REXW:
119327952Sdim    return((noPrefix && inheritsFrom(child, IC_64BIT_REXW_XS, noPrefix)) ||
120327952Sdim           (noPrefix && inheritsFrom(child, IC_64BIT_REXW_XD, noPrefix)) ||
121327952Sdim           (noPrefix && inheritsFrom(child, IC_64BIT_REXW_OPSIZE, noPrefix)) ||
122280031Sdim           (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE)));
123201360Srdivacky  case IC_64BIT_OPSIZE:
124280031Sdim    return inheritsFrom(child, IC_64BIT_REXW_OPSIZE) ||
125280031Sdim           (!AdSize64 && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE)) ||
126280031Sdim           (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE));
127201360Srdivacky  case IC_64BIT_XD:
128341825Sdim    return(inheritsFrom(child, IC_64BIT_REXW_XD) ||
129341825Sdim           (!AdSize64 && inheritsFrom(child, IC_64BIT_XD_ADSIZE)));
130201360Srdivacky  case IC_64BIT_XS:
131341825Sdim    return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
132341825Sdim           (!AdSize64 && inheritsFrom(child, IC_64BIT_XS_ADSIZE)));
133226633Sdim  case IC_64BIT_XD_OPSIZE:
134226633Sdim  case IC_64BIT_XS_OPSIZE:
135226633Sdim    return false;
136341825Sdim  case IC_64BIT_XD_ADSIZE:
137341825Sdim  case IC_64BIT_XS_ADSIZE:
138341825Sdim    return false;
139201360Srdivacky  case IC_64BIT_REXW_XD:
140201360Srdivacky  case IC_64BIT_REXW_XS:
141201360Srdivacky  case IC_64BIT_REXW_OPSIZE:
142280031Sdim  case IC_64BIT_REXW_ADSIZE:
143201360Srdivacky    return false;
144221345Sdim  case IC_VEX:
145327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W)) ||
146327952Sdim           (VEX_WIG && inheritsFrom(child, IC_VEX_W)) ||
147226633Sdim           (VEX_LIG && inheritsFrom(child, IC_VEX_L));
148221345Sdim  case IC_VEX_XS:
149327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XS)) ||
150327952Sdim           (VEX_WIG && inheritsFrom(child, IC_VEX_W_XS)) ||
151226633Sdim           (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS));
152221345Sdim  case IC_VEX_XD:
153327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XD)) ||
154327952Sdim           (VEX_WIG && inheritsFrom(child, IC_VEX_W_XD)) ||
155226633Sdim           (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD));
156226633Sdim  case IC_VEX_OPSIZE:
157327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) ||
158327952Sdim           (VEX_WIG && inheritsFrom(child, IC_VEX_W_OPSIZE)) ||
159226633Sdim           (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE));
160226633Sdim  case IC_VEX_W:
161261991Sdim    return VEX_LIG && inheritsFrom(child, IC_VEX_L_W);
162226633Sdim  case IC_VEX_W_XS:
163261991Sdim    return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS);
164226633Sdim  case IC_VEX_W_XD:
165261991Sdim    return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD);
166226633Sdim  case IC_VEX_W_OPSIZE:
167261991Sdim    return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);
168221345Sdim  case IC_VEX_L:
169327952Sdim    return VEX_WIG && inheritsFrom(child, IC_VEX_L_W);
170221345Sdim  case IC_VEX_L_XS:
171327952Sdim    return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XS);
172221345Sdim  case IC_VEX_L_XD:
173327952Sdim    return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XD);
174226633Sdim  case IC_VEX_L_OPSIZE:
175327952Sdim    return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);
176261991Sdim  case IC_VEX_L_W:
177261991Sdim  case IC_VEX_L_W_XS:
178261991Sdim  case IC_VEX_L_W_XD:
179234353Sdim  case IC_VEX_L_W_OPSIZE:
180221345Sdim    return false;
181261991Sdim  case IC_EVEX:
182327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W)) ||
183327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W)) ||
184327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W)) ||
185327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L)) ||
186327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2));
187261991Sdim  case IC_EVEX_XS:
188327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS)) ||
189327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS)) ||
190327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS)) ||
191327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS)) ||
192327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS));
193261991Sdim  case IC_EVEX_XD:
194327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD)) ||
195327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD)) ||
196327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD)) ||
197327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD)) ||
198327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD));
199261991Sdim  case IC_EVEX_OPSIZE:
200327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE)) ||
201327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE)) ||
202327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE)) ||
203327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE)) ||
204327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE));
205327952Sdim  case IC_EVEX_K:
206327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K)) ||
207327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K)) ||
208327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_K)) ||
209327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_K)) ||
210327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K));
211327952Sdim  case IC_EVEX_XS_K:
212327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K)) ||
213327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K)) ||
214327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_K)) ||
215327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K)) ||
216327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K));
217327952Sdim  case IC_EVEX_XD_K:
218327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K)) ||
219327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K)) ||
220327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_K)) ||
221327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K)) ||
222327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K));
223327952Sdim  case IC_EVEX_OPSIZE_K:
224327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K)) ||
225327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K)) ||
226327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K)) ||
227327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K)) ||
228327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K));
229327952Sdim  case IC_EVEX_KZ:
230327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ)) ||
231327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ)) ||
232327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_KZ)) ||
233327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ)) ||
234327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ));
235327952Sdim  case IC_EVEX_XS_KZ:
236327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ)) ||
237327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ)) ||
238327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ)) ||
239327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ)) ||
240327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ));
241327952Sdim  case IC_EVEX_XD_KZ:
242327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ)) ||
243327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ)) ||
244327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ)) ||
245327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ)) ||
246327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ));
247327952Sdim  case IC_EVEX_OPSIZE_KZ:
248327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ)) ||
249327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ)) ||
250327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ)) ||
251327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ)) ||
252327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ));
253261991Sdim  case IC_EVEX_W:
254327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W)) ||
255327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W));
256261991Sdim  case IC_EVEX_W_XS:
257327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS)) ||
258327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS));
259261991Sdim  case IC_EVEX_W_XD:
260327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD)) ||
261327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD));
262261991Sdim  case IC_EVEX_W_OPSIZE:
263327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE)) ||
264327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE));
265327952Sdim  case IC_EVEX_W_K:
266327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K)) ||
267327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K));
268327952Sdim  case IC_EVEX_W_XS_K:
269327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K)) ||
270327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K));
271327952Sdim  case IC_EVEX_W_XD_K:
272327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K)) ||
273327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K));
274327952Sdim  case IC_EVEX_W_OPSIZE_K:
275327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K)) ||
276327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K));
277327952Sdim  case IC_EVEX_W_KZ:
278327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ)) ||
279327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ));
280327952Sdim  case IC_EVEX_W_XS_KZ:
281327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ)) ||
282327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ));
283327952Sdim  case IC_EVEX_W_XD_KZ:
284327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ)) ||
285327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ));
286327952Sdim  case IC_EVEX_W_OPSIZE_KZ:
287327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ)) ||
288327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ));
289261991Sdim  case IC_EVEX_L:
290327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W);
291261991Sdim  case IC_EVEX_L_XS:
292327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS);
293261991Sdim  case IC_EVEX_L_XD:
294327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD);
295261991Sdim  case IC_EVEX_L_OPSIZE:
296327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE);
297327952Sdim  case IC_EVEX_L_K:
298327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K);
299327952Sdim  case IC_EVEX_L_XS_K:
300327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K);
301327952Sdim  case IC_EVEX_L_XD_K:
302327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K);
303327952Sdim  case IC_EVEX_L_OPSIZE_K:
304327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K);
305327952Sdim  case IC_EVEX_L_KZ:
306327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ);
307327952Sdim  case IC_EVEX_L_XS_KZ:
308327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ);
309327952Sdim  case IC_EVEX_L_XD_KZ:
310327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ);
311327952Sdim  case IC_EVEX_L_OPSIZE_KZ:
312327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ);
313261991Sdim  case IC_EVEX_L_W:
314261991Sdim  case IC_EVEX_L_W_XS:
315261991Sdim  case IC_EVEX_L_W_XD:
316261991Sdim  case IC_EVEX_L_W_OPSIZE:
317261991Sdim    return false;
318327952Sdim  case IC_EVEX_L_W_K:
319327952Sdim  case IC_EVEX_L_W_XS_K:
320327952Sdim  case IC_EVEX_L_W_XD_K:
321327952Sdim  case IC_EVEX_L_W_OPSIZE_K:
322327952Sdim    return false;
323327952Sdim  case IC_EVEX_L_W_KZ:
324327952Sdim  case IC_EVEX_L_W_XS_KZ:
325327952Sdim  case IC_EVEX_L_W_XD_KZ:
326327952Sdim  case IC_EVEX_L_W_OPSIZE_KZ:
327327952Sdim    return false;
328261991Sdim  case IC_EVEX_L2:
329327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W);
330261991Sdim  case IC_EVEX_L2_XS:
331327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS);
332261991Sdim  case IC_EVEX_L2_XD:
333327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD);
334261991Sdim  case IC_EVEX_L2_OPSIZE:
335327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE);
336327952Sdim  case IC_EVEX_L2_K:
337327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K);
338327952Sdim  case IC_EVEX_L2_XS_K:
339327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K);
340327952Sdim  case IC_EVEX_L2_XD_K:
341327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K);
342327952Sdim  case IC_EVEX_L2_OPSIZE_K:
343327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K);
344327952Sdim  case IC_EVEX_L2_KZ:
345327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ);
346327952Sdim  case IC_EVEX_L2_XS_KZ:
347327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ);
348327952Sdim  case IC_EVEX_L2_XD_KZ:
349327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ);
350327952Sdim  case IC_EVEX_L2_OPSIZE_KZ:
351327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ);
352261991Sdim  case IC_EVEX_L2_W:
353261991Sdim  case IC_EVEX_L2_W_XS:
354261991Sdim  case IC_EVEX_L2_W_XD:
355261991Sdim  case IC_EVEX_L2_W_OPSIZE:
356261991Sdim    return false;
357327952Sdim  case IC_EVEX_L2_W_K:
358327952Sdim  case IC_EVEX_L2_W_XS_K:
359327952Sdim  case IC_EVEX_L2_W_XD_K:
360327952Sdim  case IC_EVEX_L2_W_OPSIZE_K:
361327952Sdim    return false;
362327952Sdim  case IC_EVEX_L2_W_KZ:
363327952Sdim  case IC_EVEX_L2_W_XS_KZ:
364327952Sdim  case IC_EVEX_L2_W_XD_KZ:
365327952Sdim  case IC_EVEX_L2_W_OPSIZE_KZ:
366327952Sdim    return false;
367327952Sdim  case IC_EVEX_B:
368327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_B)) ||
369327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_B)) ||
370327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_B)) ||
371327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_B)) ||
372327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_B));
373288943Sdim  case IC_EVEX_XS_B:
374327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) ||
375327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B)) ||
376327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_B)) ||
377327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_B)) ||
378327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_B));
379288943Sdim  case IC_EVEX_XD_B:
380327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) ||
381327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B)) ||
382327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_B)) ||
383327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_B)) ||
384327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_B));
385327952Sdim  case IC_EVEX_OPSIZE_B:
386327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) ||
387327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B)) ||
388327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_B)) ||
389327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_B)) ||
390327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_B));
391280031Sdim  case IC_EVEX_K_B:
392327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) ||
393327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B)) ||
394327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_K_B)) ||
395327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_K_B)) ||
396327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K_B));
397327952Sdim  case IC_EVEX_XS_K_B:
398327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) ||
399327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B)) ||
400327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_K_B)) ||
401327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K_B)) ||
402327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K_B));
403327952Sdim  case IC_EVEX_XD_K_B:
404327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) ||
405327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B)) ||
406327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_K_B)) ||
407327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K_B)) ||
408327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K_B));
409327952Sdim  case IC_EVEX_OPSIZE_K_B:
410327952Sdim    return (VEX_LIG && VEX_WIG &&
411327952Sdim            inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) ||
412327952Sdim           (VEX_LIG && VEX_WIG &&
413327952Sdim            inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B)) ||
414327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K_B)) ||
415327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K_B)) ||
416327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K_B));
417280031Sdim  case IC_EVEX_KZ_B:
418327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) ||
419327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B)) ||
420327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_KZ_B)) ||
421327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ_B)) ||
422327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ_B));
423327952Sdim  case IC_EVEX_XS_KZ_B:
424327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) ||
425327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B)) ||
426327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ_B)) ||
427327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ_B)) ||
428327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ_B));
429327952Sdim  case IC_EVEX_XD_KZ_B:
430327952Sdim    return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) ||
431327952Sdim           (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B)) ||
432327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ_B)) ||
433327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ_B)) ||
434327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ_B));
435280031Sdim  case IC_EVEX_OPSIZE_KZ_B:
436327952Sdim    return (VEX_LIG && VEX_WIG &&
437327952Sdim            inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) ||
438327952Sdim           (VEX_LIG && VEX_WIG &&
439327952Sdim            inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B)) ||
440327952Sdim           (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ_B)) ||
441327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ_B)) ||
442327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ_B));
443288943Sdim  case IC_EVEX_W_B:
444327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_B)) ||
445327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_B));
446288943Sdim  case IC_EVEX_W_XS_B:
447327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) ||
448327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B));
449288943Sdim  case IC_EVEX_W_XD_B:
450327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) ||
451327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B));
452327952Sdim  case IC_EVEX_W_OPSIZE_B:
453327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) ||
454327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B));
455327952Sdim  case IC_EVEX_W_K_B:
456327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) ||
457327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K_B));
458288943Sdim  case IC_EVEX_W_XS_K_B:
459327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) ||
460327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B));
461288943Sdim  case IC_EVEX_W_XD_K_B:
462327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) ||
463327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B));
464327952Sdim  case IC_EVEX_W_OPSIZE_K_B:
465327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) ||
466327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B));
467327952Sdim  case IC_EVEX_W_KZ_B:
468327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) ||
469327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B));
470288943Sdim  case IC_EVEX_W_XS_KZ_B:
471327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) ||
472327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B));
473288943Sdim  case IC_EVEX_W_XD_KZ_B:
474327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) ||
475327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B));
476280031Sdim  case IC_EVEX_W_OPSIZE_KZ_B:
477327952Sdim    return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) ||
478327952Sdim           (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B));
479327952Sdim  case IC_EVEX_L_B:
480327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_B);
481288943Sdim  case IC_EVEX_L_XS_B:
482327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B);
483327952Sdim  case IC_EVEX_L_XD_B:
484327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B);
485327952Sdim  case IC_EVEX_L_OPSIZE_B:
486327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B);
487327952Sdim  case IC_EVEX_L_K_B:
488327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K_B);
489288943Sdim  case IC_EVEX_L_XS_K_B:
490327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B);
491327952Sdim  case IC_EVEX_L_XD_K_B:
492327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B);
493327952Sdim  case IC_EVEX_L_OPSIZE_K_B:
494327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B);
495327952Sdim  case IC_EVEX_L_KZ_B:
496327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B);
497288943Sdim  case IC_EVEX_L_XS_KZ_B:
498327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B);
499288943Sdim  case IC_EVEX_L_XD_KZ_B:
500327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B);
501280031Sdim  case IC_EVEX_L_OPSIZE_KZ_B:
502327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B);
503327952Sdim  case IC_EVEX_L_W_B:
504327952Sdim  case IC_EVEX_L_W_XS_B:
505327952Sdim  case IC_EVEX_L_W_XD_B:
506327952Sdim  case IC_EVEX_L_W_OPSIZE_B:
507261991Sdim    return false;
508309124Sdim  case IC_EVEX_L_W_K_B:
509288943Sdim  case IC_EVEX_L_W_XS_K_B:
510327952Sdim  case IC_EVEX_L_W_XD_K_B:
511280031Sdim  case IC_EVEX_L_W_OPSIZE_K_B:
512327952Sdim    return false;
513288943Sdim  case IC_EVEX_L_W_KZ_B:
514327952Sdim  case IC_EVEX_L_W_XS_KZ_B:
515288943Sdim  case IC_EVEX_L_W_XD_KZ_B:
516280031Sdim  case IC_EVEX_L_W_OPSIZE_KZ_B:
517261991Sdim    return false;
518261991Sdim  case IC_EVEX_L2_B:
519327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_B);
520327952Sdim  case IC_EVEX_L2_XS_B:
521327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B);
522327952Sdim  case IC_EVEX_L2_XD_B:
523327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B);
524327952Sdim  case IC_EVEX_L2_OPSIZE_B:
525327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B);
526276479Sdim  case IC_EVEX_L2_K_B:
527327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B);
528288943Sdim  case IC_EVEX_L2_XS_K_B:
529327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B);
530288943Sdim  case IC_EVEX_L2_XD_K_B:
531327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B);
532261991Sdim  case IC_EVEX_L2_OPSIZE_K_B:
533327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B);
534327952Sdim  case IC_EVEX_L2_KZ_B:
535327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B);
536288943Sdim  case IC_EVEX_L2_XS_KZ_B:
537327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B);
538288943Sdim  case IC_EVEX_L2_XD_KZ_B:
539327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B);
540261991Sdim  case IC_EVEX_L2_OPSIZE_KZ_B:
541327952Sdim    return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B);
542261991Sdim  case IC_EVEX_L2_W_B:
543288943Sdim  case IC_EVEX_L2_W_XS_B:
544276479Sdim  case IC_EVEX_L2_W_XD_B:
545261991Sdim  case IC_EVEX_L2_W_OPSIZE_B:
546327952Sdim    return false;
547327952Sdim  case IC_EVEX_L2_W_K_B:
548327952Sdim  case IC_EVEX_L2_W_XS_K_B:
549327952Sdim  case IC_EVEX_L2_W_XD_K_B:
550261991Sdim  case IC_EVEX_L2_W_OPSIZE_K_B:
551327952Sdim    return false;
552327952Sdim  case IC_EVEX_L2_W_KZ_B:
553288943Sdim  case IC_EVEX_L2_W_XS_KZ_B:
554288943Sdim  case IC_EVEX_L2_W_XD_KZ_B:
555261991Sdim  case IC_EVEX_L2_W_OPSIZE_KZ_B:
556261991Sdim    return false;
557201360Srdivacky  default:
558276479Sdim    errs() << "Unknown instruction class: " <<
559276479Sdim      stringForContext((InstructionContext)parent) << "\n";
560226633Sdim    llvm_unreachable("Unknown instruction class");
561201360Srdivacky  }
562201360Srdivacky}
563201360Srdivacky
564201360Srdivacky/// outranks - Indicates whether, if an instruction has two different applicable
565201360Srdivacky///   classes, which class should be preferred when performing decode.  This
566201360Srdivacky///   imposes a total ordering (ties are resolved toward "lower")
567201360Srdivacky///
568201360Srdivacky/// @param upper  - The class that may be preferable
569201360Srdivacky/// @param lower  - The class that may be less preferable
570201360Srdivacky/// @return       - True if upper is to be preferred, false otherwise.
571239462Sdimstatic inline bool outranks(InstructionContext upper,
572201360Srdivacky                            InstructionContext lower) {
573201360Srdivacky  assert(upper < IC_max);
574201360Srdivacky  assert(lower < IC_max);
575239462Sdim
576201360Srdivacky#define ENUM_ENTRY(n, r, d) r,
577261991Sdim#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) \
578261991Sdim  ENUM_ENTRY(n##_K_B, r, d) ENUM_ENTRY(n##_KZ_B, r, d) \
579261991Sdim  ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d)
580201360Srdivacky  static int ranks[IC_max] = {
581201360Srdivacky    INSTRUCTION_CONTEXTS
582201360Srdivacky  };
583201360Srdivacky#undef ENUM_ENTRY
584261991Sdim#undef ENUM_ENTRY_K_B
585239462Sdim
586201360Srdivacky  return (ranks[upper] > ranks[lower]);
587201360Srdivacky}
588201360Srdivacky
589201360Srdivacky/// getDecisionType - Determines whether a ModRM decision with 255 entries can
590201360Srdivacky///   be compacted by eliminating redundant information.
591201360Srdivacky///
592201360Srdivacky/// @param decision - The decision to be compacted.
593201360Srdivacky/// @return         - The compactest available representation for the decision.
594239462Sdimstatic ModRMDecisionType getDecisionType(ModRMDecision &decision) {
595201360Srdivacky  bool satisfiesOneEntry = true;
596201360Srdivacky  bool satisfiesSplitRM = true;
597234353Sdim  bool satisfiesSplitReg = true;
598243830Sdim  bool satisfiesSplitMisc = true;
599234353Sdim
600239462Sdim  for (unsigned index = 0; index < 256; ++index) {
601201360Srdivacky    if (decision.instructionIDs[index] != decision.instructionIDs[0])
602201360Srdivacky      satisfiesOneEntry = false;
603234353Sdim
604201360Srdivacky    if (((index & 0xc0) == 0xc0) &&
605201360Srdivacky       (decision.instructionIDs[index] != decision.instructionIDs[0xc0]))
606201360Srdivacky      satisfiesSplitRM = false;
607234353Sdim
608201360Srdivacky    if (((index & 0xc0) != 0xc0) &&
609201360Srdivacky       (decision.instructionIDs[index] != decision.instructionIDs[0x00]))
610201360Srdivacky      satisfiesSplitRM = false;
611234353Sdim
612234353Sdim    if (((index & 0xc0) == 0xc0) &&
613234353Sdim       (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8]))
614234353Sdim      satisfiesSplitReg = false;
615234353Sdim
616234353Sdim    if (((index & 0xc0) != 0xc0) &&
617234353Sdim       (decision.instructionIDs[index] != decision.instructionIDs[index&0x38]))
618243830Sdim      satisfiesSplitMisc = false;
619201360Srdivacky  }
620234353Sdim
621201360Srdivacky  if (satisfiesOneEntry)
622201360Srdivacky    return MODRM_ONEENTRY;
623234353Sdim
624201360Srdivacky  if (satisfiesSplitRM)
625201360Srdivacky    return MODRM_SPLITRM;
626234353Sdim
627243830Sdim  if (satisfiesSplitReg && satisfiesSplitMisc)
628234353Sdim    return MODRM_SPLITREG;
629234353Sdim
630243830Sdim  if (satisfiesSplitMisc)
631243830Sdim    return MODRM_SPLITMISC;
632243830Sdim
633201360Srdivacky  return MODRM_FULL;
634201360Srdivacky}
635201360Srdivacky
636201360Srdivacky/// stringForDecisionType - Returns a statically-allocated string corresponding
637201360Srdivacky///   to a particular decision type.
638201360Srdivacky///
639201360Srdivacky/// @param dt - The decision type.
640239462Sdim/// @return   - A pointer to the statically-allocated string (e.g.,
641201360Srdivacky///             "MODRM_ONEENTRY" for MODRM_ONEENTRY).
642239462Sdimstatic const char* stringForDecisionType(ModRMDecisionType dt) {
643201360Srdivacky#define ENUM_ENTRY(n) case n: return #n;
644201360Srdivacky  switch (dt) {
645201360Srdivacky    default:
646239462Sdim      llvm_unreachable("Unknown decision type");
647201360Srdivacky    MODRMTYPES
648239462Sdim  };
649201360Srdivacky#undef ENUM_ENTRY
650201360Srdivacky}
651239462Sdim
652201360SrdivackyDisassemblerTables::DisassemblerTables() {
653341825Sdim  for (unsigned i = 0; i < array_lengthof(Tables); i++)
654360784Sdim    Tables[i] = std::make_unique<ContextDecision>();
655239462Sdim
656201360Srdivacky  HasConflicts = false;
657201360Srdivacky}
658239462Sdim
659201360SrdivackyDisassemblerTables::~DisassemblerTables() {
660201360Srdivacky}
661239462Sdim
662239462Sdimvoid DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
663239462Sdim                                           unsigned &i1, unsigned &i2,
664261991Sdim                                           unsigned &ModRMTableNum,
665239462Sdim                                           ModRMDecision &decision) const {
666239462Sdim  static uint32_t sTableNumber = 0;
667239462Sdim  static uint32_t sEntryNumber = 1;
668201360Srdivacky  ModRMDecisionType dt = getDecisionType(decision);
669234353Sdim
670360784Sdim  if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) {
671360784Sdim    // Empty table.
672360784Sdim    o2 << "{ " << stringForDecisionType(dt) << ", 0 }";
673201360Srdivacky    return;
674201360Srdivacky  }
675234353Sdim
676261991Sdim  std::vector<unsigned> ModRMDecision;
677234353Sdim
678201360Srdivacky  switch (dt) {
679201360Srdivacky    default:
680201360Srdivacky      llvm_unreachable("Unknown decision type");
681201360Srdivacky    case MODRM_ONEENTRY:
682261991Sdim      ModRMDecision.push_back(decision.instructionIDs[0]);
683201360Srdivacky      break;
684201360Srdivacky    case MODRM_SPLITRM:
685261991Sdim      ModRMDecision.push_back(decision.instructionIDs[0x00]);
686261991Sdim      ModRMDecision.push_back(decision.instructionIDs[0xc0]);
687201360Srdivacky      break;
688234353Sdim    case MODRM_SPLITREG:
689239462Sdim      for (unsigned index = 0; index < 64; index += 8)
690261991Sdim        ModRMDecision.push_back(decision.instructionIDs[index]);
691239462Sdim      for (unsigned index = 0xc0; index < 256; index += 8)
692261991Sdim        ModRMDecision.push_back(decision.instructionIDs[index]);
693234353Sdim      break;
694243830Sdim    case MODRM_SPLITMISC:
695243830Sdim      for (unsigned index = 0; index < 64; index += 8)
696261991Sdim        ModRMDecision.push_back(decision.instructionIDs[index]);
697243830Sdim      for (unsigned index = 0xc0; index < 256; ++index)
698261991Sdim        ModRMDecision.push_back(decision.instructionIDs[index]);
699243830Sdim      break;
700201360Srdivacky    case MODRM_FULL:
701239462Sdim      for (unsigned index = 0; index < 256; ++index)
702261991Sdim        ModRMDecision.push_back(decision.instructionIDs[index]);
703234353Sdim      break;
704201360Srdivacky  }
705201360Srdivacky
706261991Sdim  unsigned &EntryNumber = ModRMTable[ModRMDecision];
707261991Sdim  if (EntryNumber == 0) {
708261991Sdim    EntryNumber = ModRMTableNum;
709234353Sdim
710261991Sdim    ModRMTableNum += ModRMDecision.size();
711261991Sdim    o1 << "/* Table" << EntryNumber << " */\n";
712261991Sdim    i1++;
713261991Sdim    for (std::vector<unsigned>::const_iterator I = ModRMDecision.begin(),
714261991Sdim           E = ModRMDecision.end(); I != E; ++I) {
715261991Sdim      o1.indent(i1 * 2) << format("0x%hx", *I) << ", /* "
716261991Sdim                        << InstructionSpecifiers[*I].name << " */\n";
717261991Sdim    }
718261991Sdim    i1--;
719261991Sdim  }
720261991Sdim
721360784Sdim  o2 << "{ " << stringForDecisionType(dt) << ", " << EntryNumber << " /* Table"
722360784Sdim     << EntryNumber << " */ }";
723234353Sdim
724201360Srdivacky  switch (dt) {
725201360Srdivacky    default:
726201360Srdivacky      llvm_unreachable("Unknown decision type");
727201360Srdivacky    case MODRM_ONEENTRY:
728234353Sdim      sEntryNumber += 1;
729201360Srdivacky      break;
730201360Srdivacky    case MODRM_SPLITRM:
731234353Sdim      sEntryNumber += 2;
732201360Srdivacky      break;
733234353Sdim    case MODRM_SPLITREG:
734234353Sdim      sEntryNumber += 16;
735234353Sdim      break;
736243830Sdim    case MODRM_SPLITMISC:
737243830Sdim      sEntryNumber += 8 + 64;
738243830Sdim      break;
739201360Srdivacky    case MODRM_FULL:
740234353Sdim      sEntryNumber += 256;
741201360Srdivacky      break;
742201360Srdivacky  }
743234353Sdim
744243830Sdim  // We assume that the index can fit into uint16_t.
745243830Sdim  assert(sEntryNumber < 65536U &&
746243830Sdim         "Index into ModRMDecision is too large for uint16_t!");
747243830Sdim
748201360Srdivacky  ++sTableNumber;
749201360Srdivacky}
750201360Srdivacky
751239462Sdimvoid DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2,
752239462Sdim                                            unsigned &i1, unsigned &i2,
753261991Sdim                                            unsigned &ModRMTableNum,
754360784Sdim                                            OpcodeDecision &opDecision) const {
755360784Sdim  o2 << "{";
756360784Sdim  ++i2;
757201360Srdivacky
758360784Sdim  unsigned index;
759360784Sdim  for (index = 0; index < 256; ++index) {
760360784Sdim    auto &decision = opDecision.modRMDecisions[index];
761360784Sdim    ModRMDecisionType dt = getDecisionType(decision);
762360784Sdim    if (!(dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0))
763360784Sdim      break;
764360784Sdim  }
765360784Sdim  if (index == 256) {
766360784Sdim    // If all 256 entries are MODRM_ONEENTRY, omit output.
767360784Sdim    assert(MODRM_ONEENTRY == 0);
768360784Sdim    --i2;
769360784Sdim    o2 << "},\n";
770360784Sdim  } else {
771360784Sdim    o2 << " /* struct OpcodeDecision */ {\n";
772360784Sdim    ++i2;
773360784Sdim    for (index = 0; index < 256; ++index) {
774360784Sdim      o2.indent(i2);
775201360Srdivacky
776360784Sdim      o2 << "/* 0x" << format("%02hhx", index) << " */ ";
777201360Srdivacky
778360784Sdim      emitModRMDecision(o1, o2, i1, i2, ModRMTableNum,
779360784Sdim                        opDecision.modRMDecisions[index]);
780201360Srdivacky
781360784Sdim      if (index < 255)
782360784Sdim        o2 << ",";
783201360Srdivacky
784360784Sdim      o2 << "\n";
785360784Sdim    }
786360784Sdim    --i2;
787360784Sdim    o2.indent(i2) << "}\n";
788360784Sdim    --i2;
789360784Sdim    o2.indent(i2) << "},\n";
790201360Srdivacky  }
791201360Srdivacky}
792201360Srdivacky
793239462Sdimvoid DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2,
794239462Sdim                                             unsigned &i1, unsigned &i2,
795261991Sdim                                             unsigned &ModRMTableNum,
796239462Sdim                                             ContextDecision &decision,
797239462Sdim                                             const char* name) const {
798218893Sdim  o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n";
799201360Srdivacky  i2++;
800201360Srdivacky  o2.indent(i2) << "{ /* opcodeDecisions */" << "\n";
801201360Srdivacky  i2++;
802201360Srdivacky
803239462Sdim  for (unsigned index = 0; index < IC_max; ++index) {
804201360Srdivacky    o2.indent(i2) << "/* ";
805201360Srdivacky    o2 << stringForContext((InstructionContext)index);
806360784Sdim    o2 << " */ ";
807201360Srdivacky
808261991Sdim    emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum,
809261991Sdim                       decision.opcodeDecisions[index]);
810201360Srdivacky  }
811201360Srdivacky
812201360Srdivacky  i2--;
813201360Srdivacky  o2.indent(i2) << "}" << "\n";
814201360Srdivacky  i2--;
815201360Srdivacky  o2.indent(i2) << "};" << "\n";
816201360Srdivacky}
817201360Srdivacky
818239462Sdimvoid DisassemblerTables::emitInstructionInfo(raw_ostream &o,
819239462Sdim                                             unsigned &i) const {
820239462Sdim  unsigned NumInstructions = InstructionSpecifiers.size();
821239462Sdim
822239462Sdim  o << "static const struct OperandSpecifier x86OperandSets[]["
823239462Sdim    << X86_MAX_OPERANDS << "] = {\n";
824239462Sdim
825288943Sdim  typedef SmallVector<std::pair<OperandEncoding, OperandType>,
826288943Sdim                      X86_MAX_OPERANDS> OperandListTy;
827239462Sdim  std::map<OperandListTy, unsigned> OperandSets;
828239462Sdim
829239462Sdim  unsigned OperandSetNum = 0;
830239462Sdim  for (unsigned Index = 0; Index < NumInstructions; ++Index) {
831239462Sdim    OperandListTy OperandList;
832239462Sdim
833239462Sdim    for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
834239462Sdim         ++OperandIndex) {
835288943Sdim      OperandEncoding Encoding = (OperandEncoding)InstructionSpecifiers[Index]
836288943Sdim                                 .operands[OperandIndex].encoding;
837288943Sdim      OperandType Type = (OperandType)InstructionSpecifiers[Index]
838288943Sdim                         .operands[OperandIndex].type;
839239462Sdim      OperandList.push_back(std::make_pair(Encoding, Type));
840239462Sdim    }
841239462Sdim    unsigned &N = OperandSets[OperandList];
842239462Sdim    if (N != 0) continue;
843239462Sdim
844239462Sdim    N = ++OperandSetNum;
845239462Sdim
846239462Sdim    o << "  { /* " << (OperandSetNum - 1) << " */\n";
847239462Sdim    for (unsigned i = 0, e = OperandList.size(); i != e; ++i) {
848288943Sdim      const char *Encoding = stringForOperandEncoding(OperandList[i].first);
849288943Sdim      const char *Type     = stringForOperandType(OperandList[i].second);
850288943Sdim      o << "    { " << Encoding << ", " << Type << " },\n";
851239462Sdim    }
852239462Sdim    o << "  },\n";
853239462Sdim  }
854239462Sdim  o << "};" << "\n\n";
855239462Sdim
856218893Sdim  o.indent(i * 2) << "static const struct InstructionSpecifier ";
857218893Sdim  o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n";
858239462Sdim
859201360Srdivacky  i++;
860201360Srdivacky
861239462Sdim  for (unsigned index = 0; index < NumInstructions; ++index) {
862288943Sdim    o.indent(i * 2) << "{ /* " << index << " */\n";
863201360Srdivacky    i++;
864234353Sdim
865239462Sdim    OperandListTy OperandList;
866239462Sdim    for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
867239462Sdim         ++OperandIndex) {
868288943Sdim      OperandEncoding Encoding = (OperandEncoding)InstructionSpecifiers[index]
869288943Sdim                                 .operands[OperandIndex].encoding;
870288943Sdim      OperandType Type = (OperandType)InstructionSpecifiers[index]
871288943Sdim                         .operands[OperandIndex].type;
872239462Sdim      OperandList.push_back(std::make_pair(Encoding, Type));
873201360Srdivacky    }
874239462Sdim    o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n";
875201360Srdivacky
876288943Sdim    o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */\n";
877201360Srdivacky
878201360Srdivacky    i--;
879288943Sdim    o.indent(i * 2) << "},\n";
880201360Srdivacky  }
881201360Srdivacky
882201360Srdivacky  i--;
883201360Srdivacky  o.indent(i * 2) << "};" << "\n";
884201360Srdivacky}
885201360Srdivacky
886239462Sdimvoid DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
887239462Sdim  o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR
888353358Sdim                     "[" << ATTR_max << "] = {\n";
889201360Srdivacky  i++;
890201360Srdivacky
891353358Sdim  for (unsigned index = 0; index < ATTR_max; ++index) {
892201360Srdivacky    o.indent(i * 2);
893201360Srdivacky
894353358Sdim    if ((index & ATTR_EVEX) || (index & ATTR_VEX) || (index & ATTR_VEXL)) {
895353358Sdim      if (index & ATTR_EVEX)
896353358Sdim        o << "IC_EVEX";
897353358Sdim      else
898353358Sdim        o << "IC_VEX";
899353358Sdim
900353358Sdim      if ((index & ATTR_EVEX) && (index & ATTR_EVEXL2))
901276479Sdim        o << "_L2";
902353358Sdim      else if (index & ATTR_VEXL)
903276479Sdim        o << "_L";
904353358Sdim
905276479Sdim      if (index & ATTR_REXW)
906276479Sdim        o << "_W";
907353358Sdim
908276479Sdim      if (index & ATTR_OPSIZE)
909276479Sdim        o << "_OPSIZE";
910276479Sdim      else if (index & ATTR_XD)
911276479Sdim        o << "_XD";
912276479Sdim      else if (index & ATTR_XS)
913276479Sdim        o << "_XS";
914353358Sdim
915353358Sdim      if ((index & ATTR_EVEX)) {
916353358Sdim        if (index & ATTR_EVEXKZ)
917353358Sdim          o << "_KZ";
918353358Sdim        else if (index & ATTR_EVEXK)
919353358Sdim          o << "_K";
920353358Sdim
921353358Sdim        if (index & ATTR_EVEXB)
922353358Sdim          o << "_B";
923353358Sdim      }
924276479Sdim    }
925221345Sdim    else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))
926201360Srdivacky      o << "IC_64BIT_REXW_XS";
927201360Srdivacky    else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD))
928201360Srdivacky      o << "IC_64BIT_REXW_XD";
929239462Sdim    else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&
930201360Srdivacky             (index & ATTR_OPSIZE))
931201360Srdivacky      o << "IC_64BIT_REXW_OPSIZE";
932280031Sdim    else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&
933280031Sdim             (index & ATTR_ADSIZE))
934280031Sdim      o << "IC_64BIT_REXW_ADSIZE";
935226633Sdim    else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
936226633Sdim      o << "IC_64BIT_XD_OPSIZE";
937341825Sdim    else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_ADSIZE))
938341825Sdim      o << "IC_64BIT_XD_ADSIZE";
939226633Sdim    else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE))
940226633Sdim      o << "IC_64BIT_XS_OPSIZE";
941341825Sdim    else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_ADSIZE))
942341825Sdim      o << "IC_64BIT_XS_ADSIZE";
943201360Srdivacky    else if ((index & ATTR_64BIT) && (index & ATTR_XS))
944201360Srdivacky      o << "IC_64BIT_XS";
945201360Srdivacky    else if ((index & ATTR_64BIT) && (index & ATTR_XD))
946201360Srdivacky      o << "IC_64BIT_XD";
947280031Sdim    else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE) &&
948280031Sdim             (index & ATTR_ADSIZE))
949280031Sdim      o << "IC_64BIT_OPSIZE_ADSIZE";
950201360Srdivacky    else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE))
951201360Srdivacky      o << "IC_64BIT_OPSIZE";
952234353Sdim    else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE))
953234353Sdim      o << "IC_64BIT_ADSIZE";
954201360Srdivacky    else if ((index & ATTR_64BIT) && (index & ATTR_REXW))
955201360Srdivacky      o << "IC_64BIT_REXW";
956201360Srdivacky    else if ((index & ATTR_64BIT))
957201360Srdivacky      o << "IC_64BIT";
958226633Sdim    else if ((index & ATTR_XS) && (index & ATTR_OPSIZE))
959226633Sdim      o << "IC_XS_OPSIZE";
960226633Sdim    else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
961226633Sdim      o << "IC_XD_OPSIZE";
962341825Sdim    else if ((index & ATTR_XS) && (index & ATTR_ADSIZE))
963341825Sdim      o << "IC_XS_ADSIZE";
964341825Sdim    else if ((index & ATTR_XD) && (index & ATTR_ADSIZE))
965341825Sdim      o << "IC_XD_ADSIZE";
966201360Srdivacky    else if (index & ATTR_XS)
967201360Srdivacky      o << "IC_XS";
968201360Srdivacky    else if (index & ATTR_XD)
969201360Srdivacky      o << "IC_XD";
970280031Sdim    else if ((index & ATTR_OPSIZE) && (index & ATTR_ADSIZE))
971280031Sdim      o << "IC_OPSIZE_ADSIZE";
972201360Srdivacky    else if (index & ATTR_OPSIZE)
973201360Srdivacky      o << "IC_OPSIZE";
974234353Sdim    else if (index & ATTR_ADSIZE)
975234353Sdim      o << "IC_ADSIZE";
976201360Srdivacky    else
977201360Srdivacky      o << "IC";
978201360Srdivacky
979353358Sdim    o << ", /* " << index << " */";
980201360Srdivacky
981201360Srdivacky    o << "\n";
982201360Srdivacky  }
983201360Srdivacky
984201360Srdivacky  i--;
985201360Srdivacky  o.indent(i * 2) << "};" << "\n";
986201360Srdivacky}
987201360Srdivacky
988239462Sdimvoid DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2,
989261991Sdim                                              unsigned &i1, unsigned &i2,
990261991Sdim                                              unsigned &ModRMTableNum) const {
991261991Sdim  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[0], ONEBYTE_STR);
992261991Sdim  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[1], TWOBYTE_STR);
993261991Sdim  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[2], THREEBYTE38_STR);
994261991Sdim  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[3], THREEBYTE3A_STR);
995276479Sdim  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], XOP8_MAP_STR);
996276479Sdim  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], XOP9_MAP_STR);
997276479Sdim  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOPA_MAP_STR);
998341825Sdim  emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[7], THREEDNOW_MAP_STR);
999201360Srdivacky}
1000201360Srdivacky
1001201360Srdivackyvoid DisassemblerTables::emit(raw_ostream &o) const {
1002239462Sdim  unsigned i1 = 0;
1003239462Sdim  unsigned i2 = 0;
1004239462Sdim
1005201360Srdivacky  std::string s1;
1006201360Srdivacky  std::string s2;
1007239462Sdim
1008201360Srdivacky  raw_string_ostream o1(s1);
1009201360Srdivacky  raw_string_ostream o2(s2);
1010239462Sdim
1011201360Srdivacky  emitInstructionInfo(o, i2);
1012201360Srdivacky  o << "\n";
1013201360Srdivacky
1014201360Srdivacky  emitContextTable(o, i2);
1015201360Srdivacky  o << "\n";
1016234353Sdim
1017261991Sdim  unsigned ModRMTableNum = 0;
1018261991Sdim
1019234353Sdim  o << "static const InstrUID modRMTable[] = {\n";
1020234353Sdim  i1++;
1021261991Sdim  std::vector<unsigned> EmptyTable(1, 0);
1022261991Sdim  ModRMTable[EmptyTable] = ModRMTableNum;
1023261991Sdim  ModRMTableNum += EmptyTable.size();
1024261991Sdim  o1 << "/* EmptyTable */\n";
1025261991Sdim  o1.indent(i1 * 2) << "0x0,\n";
1026234353Sdim  i1--;
1027261991Sdim  emitContextDecisions(o1, o2, i1, i2, ModRMTableNum);
1028234353Sdim
1029201360Srdivacky  o << o1.str();
1030234353Sdim  o << "  0x0\n";
1031234353Sdim  o << "};\n";
1032201360Srdivacky  o << "\n";
1033201360Srdivacky  o << o2.str();
1034201360Srdivacky  o << "\n";
1035201360Srdivacky  o << "\n";
1036201360Srdivacky}
1037201360Srdivacky
1038201360Srdivackyvoid DisassemblerTables::setTableFields(ModRMDecision     &decision,
1039201360Srdivacky                                        const ModRMFilter &filter,
1040201360Srdivacky                                        InstrUID          uid,
1041201360Srdivacky                                        uint8_t           opcode) {
1042239462Sdim  for (unsigned index = 0; index < 256; ++index) {
1043201360Srdivacky    if (filter.accepts(index)) {
1044201360Srdivacky      if (decision.instructionIDs[index] == uid)
1045201360Srdivacky        continue;
1046201360Srdivacky
1047201360Srdivacky      if (decision.instructionIDs[index] != 0) {
1048201360Srdivacky        InstructionSpecifier &newInfo =
1049201360Srdivacky          InstructionSpecifiers[uid];
1050201360Srdivacky        InstructionSpecifier &previousInfo =
1051201360Srdivacky          InstructionSpecifiers[decision.instructionIDs[index]];
1052239462Sdim
1053226633Sdim        if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" ||
1054226633Sdim                                           newInfo.name == "XCHG32ar" ||
1055226633Sdim                                           newInfo.name == "XCHG64ar"))
1056226633Sdim          continue; // special case for XCHG*ar and NOOP
1057201360Srdivacky
1058201360Srdivacky        if (outranks(previousInfo.insnContext, newInfo.insnContext))
1059201360Srdivacky          continue;
1060239462Sdim
1061276479Sdim        if (previousInfo.insnContext == newInfo.insnContext) {
1062201360Srdivacky          errs() << "Error: Primary decode conflict: ";
1063201360Srdivacky          errs() << newInfo.name << " would overwrite " << previousInfo.name;
1064201360Srdivacky          errs() << "\n";
1065201360Srdivacky          errs() << "ModRM   " << index << "\n";
1066201360Srdivacky          errs() << "Opcode  " << (uint16_t)opcode << "\n";
1067201360Srdivacky          errs() << "Context " << stringForContext(newInfo.insnContext) << "\n";
1068201360Srdivacky          HasConflicts = true;
1069201360Srdivacky        }
1070201360Srdivacky      }
1071201360Srdivacky
1072201360Srdivacky      decision.instructionIDs[index] = uid;
1073201360Srdivacky    }
1074201360Srdivacky  }
1075201360Srdivacky}
1076201360Srdivacky
1077201360Srdivackyvoid DisassemblerTables::setTableFields(OpcodeType          type,
1078201360Srdivacky                                        InstructionContext  insnContext,
1079201360Srdivacky                                        uint8_t             opcode,
1080201360Srdivacky                                        const ModRMFilter   &filter,
1081226633Sdim                                        InstrUID            uid,
1082226633Sdim                                        bool                is32bit,
1083327952Sdim                                        bool                noPrefix,
1084280031Sdim                                        bool                ignoresVEX_L,
1085327952Sdim                                        bool                ignoresVEX_W,
1086280031Sdim                                        unsigned            addressSize) {
1087201360Srdivacky  ContextDecision &decision = *Tables[type];
1088201360Srdivacky
1089239462Sdim  for (unsigned index = 0; index < IC_max; ++index) {
1090280031Sdim    if ((is32bit || addressSize == 16) &&
1091280031Sdim        inheritsFrom((InstructionContext)index, IC_64BIT))
1092226633Sdim      continue;
1093226633Sdim
1094280031Sdim    bool adSize64 = addressSize == 64;
1095239462Sdim    if (inheritsFrom((InstructionContext)index,
1096327952Sdim                     InstructionSpecifiers[uid].insnContext, noPrefix,
1097327952Sdim                     ignoresVEX_L, ignoresVEX_W, adSize64))
1098239462Sdim      setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode],
1099201360Srdivacky                     filter,
1100201360Srdivacky                     uid,
1101201360Srdivacky                     opcode);
1102201360Srdivacky  }
1103201360Srdivacky}
1104