1 | //===- X86DisassemblerTables.cpp - Disassembler tables ----------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file is part of the X86 Disassembler Emitter. |
10 | // It contains the implementation of the disassembler tables. |
11 | // Documentation for the disassembler emitter in general can be found in |
12 | // X86DisassemblerEmitter.h. |
13 | // |
14 | //===----------------------------------------------------------------------===// |
15 | |
16 | #include "X86DisassemblerTables.h" |
17 | #include "X86DisassemblerShared.h" |
18 | #include "X86ModRMFilters.h" |
19 | #include "llvm/ADT/SmallVector.h" |
20 | #include "llvm/Support/ErrorHandling.h" |
21 | #include "llvm/Support/Format.h" |
22 | #include "llvm/Support/raw_ostream.h" |
23 | #include <map> |
24 | |
25 | using namespace llvm; |
26 | using namespace X86Disassembler; |
27 | |
28 | /// stringForContext - Returns a string containing the name of a particular |
29 | /// InstructionContext, usually for diagnostic purposes. |
30 | /// |
31 | /// @param insnContext - The instruction class to transform to a string. |
32 | /// @return - A statically-allocated string constant that contains the |
33 | /// name of the instruction class. |
34 | static inline const char *stringForContext(InstructionContext insnContext) { |
35 | switch (insnContext) { |
36 | default: |
37 | llvm_unreachable("Unhandled instruction class" ); |
38 | #define ENUM_ENTRY(n, r, d) \ |
39 | case n: \ |
40 | return #n; \ |
41 | break; |
42 | #define ENUM_ENTRY_K_B(n, r, d) \ |
43 | ENUM_ENTRY(n, r, d) \ |
44 | ENUM_ENTRY(n##_K_B, r, d) \ |
45 | ENUM_ENTRY(n##_KZ, r, d) \ |
46 | ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d) ENUM_ENTRY(n##_KZ_B, r, d) |
47 | INSTRUCTION_CONTEXTS |
48 | #undef ENUM_ENTRY |
49 | #undef ENUM_ENTRY_K_B |
50 | } |
51 | } |
52 | |
53 | /// stringForOperandType - Like stringForContext, but for OperandTypes. |
54 | static inline const char *stringForOperandType(OperandType type) { |
55 | switch (type) { |
56 | default: |
57 | llvm_unreachable("Unhandled type" ); |
58 | #define ENUM_ENTRY(i, d) \ |
59 | case i: \ |
60 | return #i; |
61 | TYPES |
62 | #undef ENUM_ENTRY |
63 | } |
64 | } |
65 | |
66 | /// stringForOperandEncoding - like stringForContext, but for |
67 | /// OperandEncodings. |
68 | static inline const char *stringForOperandEncoding(OperandEncoding encoding) { |
69 | switch (encoding) { |
70 | default: |
71 | llvm_unreachable("Unhandled encoding" ); |
72 | #define ENUM_ENTRY(i, d) \ |
73 | case i: \ |
74 | return #i; |
75 | ENCODINGS |
76 | #undef ENUM_ENTRY |
77 | } |
78 | } |
79 | |
80 | /// inheritsFrom - Indicates whether all instructions in one class also belong |
81 | /// to another class. |
82 | /// |
83 | /// @param child - The class that may be the subset |
84 | /// @param parent - The class that may be the superset |
85 | /// @return - True if child is a subset of parent, false otherwise. |
86 | static inline bool inheritsFrom(InstructionContext child, |
87 | InstructionContext parent, bool noPrefix = true, |
88 | bool VEX_LIG = false, bool WIG = false, |
89 | bool AdSize64 = false) { |
90 | if (child == parent) |
91 | return true; |
92 | |
93 | switch (parent) { |
94 | case IC: |
95 | return (inheritsFrom(child, parent: IC_64BIT, noPrefix: AdSize64) || |
96 | (noPrefix && inheritsFrom(child, parent: IC_OPSIZE, noPrefix)) || |
97 | inheritsFrom(child, parent: IC_ADSIZE) || |
98 | (noPrefix && inheritsFrom(child, parent: IC_XD, noPrefix)) || |
99 | (noPrefix && inheritsFrom(child, parent: IC_XS, noPrefix))); |
100 | case IC_64BIT: |
101 | return (inheritsFrom(child, parent: IC_64BIT_REXW) || |
102 | (noPrefix && inheritsFrom(child, parent: IC_64BIT_OPSIZE, noPrefix)) || |
103 | (!AdSize64 && inheritsFrom(child, parent: IC_64BIT_ADSIZE)) || |
104 | (noPrefix && inheritsFrom(child, parent: IC_64BIT_XD, noPrefix)) || |
105 | (noPrefix && inheritsFrom(child, parent: IC_64BIT_XS, noPrefix))); |
106 | case IC_OPSIZE: |
107 | return inheritsFrom(child, parent: IC_64BIT_OPSIZE) || |
108 | inheritsFrom(child, parent: IC_OPSIZE_ADSIZE); |
109 | case IC_ADSIZE: |
110 | return (noPrefix && inheritsFrom(child, parent: IC_OPSIZE_ADSIZE, noPrefix)); |
111 | case IC_OPSIZE_ADSIZE: |
112 | return false; |
113 | case IC_64BIT_ADSIZE: |
114 | return (noPrefix && inheritsFrom(child, parent: IC_64BIT_OPSIZE_ADSIZE, noPrefix)); |
115 | case IC_64BIT_OPSIZE_ADSIZE: |
116 | return false; |
117 | case IC_XD: |
118 | return inheritsFrom(child, parent: IC_64BIT_XD); |
119 | case IC_XS: |
120 | return inheritsFrom(child, parent: IC_64BIT_XS); |
121 | case IC_XD_OPSIZE: |
122 | return inheritsFrom(child, parent: IC_64BIT_XD_OPSIZE); |
123 | case IC_XS_OPSIZE: |
124 | return inheritsFrom(child, parent: IC_64BIT_XS_OPSIZE); |
125 | case IC_XD_ADSIZE: |
126 | return inheritsFrom(child, parent: IC_64BIT_XD_ADSIZE); |
127 | case IC_XS_ADSIZE: |
128 | return inheritsFrom(child, parent: IC_64BIT_XS_ADSIZE); |
129 | case IC_64BIT_REXW: |
130 | return ((noPrefix && inheritsFrom(child, parent: IC_64BIT_REXW_XS, noPrefix)) || |
131 | (noPrefix && inheritsFrom(child, parent: IC_64BIT_REXW_XD, noPrefix)) || |
132 | (noPrefix && inheritsFrom(child, parent: IC_64BIT_REXW_OPSIZE, noPrefix)) || |
133 | (!AdSize64 && inheritsFrom(child, parent: IC_64BIT_REXW_ADSIZE))); |
134 | case IC_64BIT_OPSIZE: |
135 | return inheritsFrom(child, parent: IC_64BIT_REXW_OPSIZE) || |
136 | (!AdSize64 && inheritsFrom(child, parent: IC_64BIT_OPSIZE_ADSIZE)) || |
137 | (!AdSize64 && inheritsFrom(child, parent: IC_64BIT_REXW_ADSIZE)); |
138 | case IC_64BIT_XD: |
139 | return (inheritsFrom(child, parent: IC_64BIT_REXW_XD) || |
140 | (!AdSize64 && inheritsFrom(child, parent: IC_64BIT_XD_ADSIZE))); |
141 | case IC_64BIT_XS: |
142 | return (inheritsFrom(child, parent: IC_64BIT_REXW_XS) || |
143 | (!AdSize64 && inheritsFrom(child, parent: IC_64BIT_XS_ADSIZE))); |
144 | case IC_64BIT_XD_OPSIZE: |
145 | case IC_64BIT_XS_OPSIZE: |
146 | return false; |
147 | case IC_64BIT_XD_ADSIZE: |
148 | case IC_64BIT_XS_ADSIZE: |
149 | return false; |
150 | case IC_64BIT_REXW_XD: |
151 | case IC_64BIT_REXW_XS: |
152 | case IC_64BIT_REXW_OPSIZE: |
153 | case IC_64BIT_REXW_ADSIZE: |
154 | case IC_64BIT_REX2: |
155 | return false; |
156 | case IC_VEX: |
157 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_VEX_L_W)) || |
158 | (WIG && inheritsFrom(child, parent: IC_VEX_W)) || |
159 | (VEX_LIG && inheritsFrom(child, parent: IC_VEX_L)); |
160 | case IC_VEX_XS: |
161 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_VEX_L_W_XS)) || |
162 | (WIG && inheritsFrom(child, parent: IC_VEX_W_XS)) || |
163 | (VEX_LIG && inheritsFrom(child, parent: IC_VEX_L_XS)); |
164 | case IC_VEX_XD: |
165 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_VEX_L_W_XD)) || |
166 | (WIG && inheritsFrom(child, parent: IC_VEX_W_XD)) || |
167 | (VEX_LIG && inheritsFrom(child, parent: IC_VEX_L_XD)); |
168 | case IC_VEX_OPSIZE: |
169 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_VEX_L_W_OPSIZE)) || |
170 | (WIG && inheritsFrom(child, parent: IC_VEX_W_OPSIZE)) || |
171 | (VEX_LIG && inheritsFrom(child, parent: IC_VEX_L_OPSIZE)); |
172 | case IC_VEX_W: |
173 | return VEX_LIG && inheritsFrom(child, parent: IC_VEX_L_W); |
174 | case IC_VEX_W_XS: |
175 | return VEX_LIG && inheritsFrom(child, parent: IC_VEX_L_W_XS); |
176 | case IC_VEX_W_XD: |
177 | return VEX_LIG && inheritsFrom(child, parent: IC_VEX_L_W_XD); |
178 | case IC_VEX_W_OPSIZE: |
179 | return VEX_LIG && inheritsFrom(child, parent: IC_VEX_L_W_OPSIZE); |
180 | case IC_VEX_L: |
181 | return WIG && inheritsFrom(child, parent: IC_VEX_L_W); |
182 | case IC_VEX_L_XS: |
183 | return WIG && inheritsFrom(child, parent: IC_VEX_L_W_XS); |
184 | case IC_VEX_L_XD: |
185 | return WIG && inheritsFrom(child, parent: IC_VEX_L_W_XD); |
186 | case IC_VEX_L_OPSIZE: |
187 | return WIG && inheritsFrom(child, parent: IC_VEX_L_W_OPSIZE); |
188 | case IC_VEX_L_W: |
189 | case IC_VEX_L_W_XS: |
190 | case IC_VEX_L_W_XD: |
191 | case IC_VEX_L_W_OPSIZE: |
192 | return false; |
193 | case IC_EVEX: |
194 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W)) || |
195 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W)) || |
196 | (WIG && inheritsFrom(child, parent: IC_EVEX_W)) || |
197 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L)) || |
198 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2)); |
199 | case IC_EVEX_XS: |
200 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS)) || |
201 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS)) || |
202 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XS)) || |
203 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XS)) || |
204 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XS)); |
205 | case IC_EVEX_XD: |
206 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD)) || |
207 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD)) || |
208 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XD)) || |
209 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XD)) || |
210 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XD)); |
211 | case IC_EVEX_OPSIZE: |
212 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE)) || |
213 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE)) || |
214 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_OPSIZE)) || |
215 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_OPSIZE)) || |
216 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_OPSIZE)); |
217 | case IC_EVEX_OPSIZE_ADSIZE: |
218 | case IC_EVEX_XS_ADSIZE: |
219 | case IC_EVEX_XD_ADSIZE: |
220 | return false; |
221 | case IC_EVEX_K: |
222 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_K)) || |
223 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K)) || |
224 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_K)) || |
225 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_K)) || |
226 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_K)); |
227 | case IC_EVEX_XS_K: |
228 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K)) || |
229 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K)) || |
230 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XS_K)) || |
231 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XS_K)) || |
232 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XS_K)); |
233 | case IC_EVEX_XD_K: |
234 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K)) || |
235 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K)) || |
236 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XD_K)) || |
237 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XD_K)) || |
238 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XD_K)); |
239 | case IC_EVEX_OPSIZE_K: |
240 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K)) || |
241 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K)) || |
242 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_OPSIZE_K)) || |
243 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_OPSIZE_K)) || |
244 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_OPSIZE_K)); |
245 | case IC_EVEX_KZ: |
246 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ)) || |
247 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ)) || |
248 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_KZ)) || |
249 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_KZ)) || |
250 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_KZ)); |
251 | case IC_EVEX_XS_KZ: |
252 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ)) || |
253 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ)) || |
254 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XS_KZ)) || |
255 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XS_KZ)) || |
256 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XS_KZ)); |
257 | case IC_EVEX_XD_KZ: |
258 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ)) || |
259 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ)) || |
260 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XD_KZ)) || |
261 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XD_KZ)) || |
262 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XD_KZ)); |
263 | case IC_EVEX_OPSIZE_KZ: |
264 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ)) || |
265 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ)) || |
266 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_OPSIZE_KZ)) || |
267 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_OPSIZE_KZ)) || |
268 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_OPSIZE_KZ)); |
269 | case IC_EVEX_W: |
270 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W)) || |
271 | inheritsFrom(child, parent: IC_EVEX_W_OPSIZE) || |
272 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W)); |
273 | case IC_EVEX_W_XS: |
274 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS)) || |
275 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS)); |
276 | case IC_EVEX_W_XD: |
277 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD)) || |
278 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD)); |
279 | case IC_EVEX_W_OPSIZE: |
280 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE)) || |
281 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE)); |
282 | case IC_EVEX_W_K: |
283 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_K)) || |
284 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K)); |
285 | case IC_EVEX_W_XS_K: |
286 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K)) || |
287 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K)); |
288 | case IC_EVEX_W_XD_K: |
289 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K)) || |
290 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K)); |
291 | case IC_EVEX_W_OPSIZE_K: |
292 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K)) || |
293 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K)); |
294 | case IC_EVEX_W_KZ: |
295 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ)) || |
296 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ)); |
297 | case IC_EVEX_W_XS_KZ: |
298 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ)) || |
299 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ)); |
300 | case IC_EVEX_W_XD_KZ: |
301 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ)) || |
302 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ)); |
303 | case IC_EVEX_W_OPSIZE_KZ: |
304 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ)) || |
305 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ)); |
306 | case IC_EVEX_L: |
307 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W); |
308 | case IC_EVEX_L_XS: |
309 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS); |
310 | case IC_EVEX_L_XD: |
311 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD); |
312 | case IC_EVEX_L_OPSIZE: |
313 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE); |
314 | case IC_EVEX_L_K: |
315 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_K); |
316 | case IC_EVEX_L_XS_K: |
317 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K); |
318 | case IC_EVEX_L_XD_K: |
319 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K); |
320 | case IC_EVEX_L_OPSIZE_K: |
321 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K); |
322 | case IC_EVEX_L_KZ: |
323 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ); |
324 | case IC_EVEX_L_XS_KZ: |
325 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ); |
326 | case IC_EVEX_L_XD_KZ: |
327 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ); |
328 | case IC_EVEX_L_OPSIZE_KZ: |
329 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ); |
330 | case IC_EVEX_L_W: |
331 | case IC_EVEX_L_W_XS: |
332 | case IC_EVEX_L_W_XD: |
333 | case IC_EVEX_L_W_OPSIZE: |
334 | return false; |
335 | case IC_EVEX_L_W_K: |
336 | case IC_EVEX_L_W_XS_K: |
337 | case IC_EVEX_L_W_XD_K: |
338 | case IC_EVEX_L_W_OPSIZE_K: |
339 | return false; |
340 | case IC_EVEX_L_W_KZ: |
341 | case IC_EVEX_L_W_XS_KZ: |
342 | case IC_EVEX_L_W_XD_KZ: |
343 | case IC_EVEX_L_W_OPSIZE_KZ: |
344 | return false; |
345 | case IC_EVEX_L2: |
346 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W); |
347 | case IC_EVEX_L2_XS: |
348 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS); |
349 | case IC_EVEX_L2_XD: |
350 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD); |
351 | case IC_EVEX_L2_OPSIZE: |
352 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE); |
353 | case IC_EVEX_L2_K: |
354 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K); |
355 | case IC_EVEX_L2_XS_K: |
356 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K); |
357 | case IC_EVEX_L2_XD_K: |
358 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K); |
359 | case IC_EVEX_L2_OPSIZE_K: |
360 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K); |
361 | case IC_EVEX_L2_KZ: |
362 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ); |
363 | case IC_EVEX_L2_XS_KZ: |
364 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ); |
365 | case IC_EVEX_L2_XD_KZ: |
366 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ); |
367 | case IC_EVEX_L2_OPSIZE_KZ: |
368 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ); |
369 | case IC_EVEX_L2_W: |
370 | case IC_EVEX_L2_W_XS: |
371 | case IC_EVEX_L2_W_XD: |
372 | case IC_EVEX_L2_W_OPSIZE: |
373 | return false; |
374 | case IC_EVEX_L2_W_K: |
375 | case IC_EVEX_L2_W_XS_K: |
376 | case IC_EVEX_L2_W_XD_K: |
377 | case IC_EVEX_L2_W_OPSIZE_K: |
378 | return false; |
379 | case IC_EVEX_L2_W_KZ: |
380 | case IC_EVEX_L2_W_XS_KZ: |
381 | case IC_EVEX_L2_W_XD_KZ: |
382 | case IC_EVEX_L2_W_OPSIZE_KZ: |
383 | return false; |
384 | case IC_EVEX_B: |
385 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_B)) || |
386 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_B)) || |
387 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_B)) || |
388 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_B)) || |
389 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_B)); |
390 | case IC_EVEX_XS_B: |
391 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_B)) || |
392 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_B)) || |
393 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XS_B)) || |
394 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XS_B)) || |
395 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XS_B)); |
396 | case IC_EVEX_XD_B: |
397 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_B)) || |
398 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_B)) || |
399 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XD_B)) || |
400 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XD_B)) || |
401 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XD_B)); |
402 | case IC_EVEX_OPSIZE_B: |
403 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_B)) || |
404 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_B)) || |
405 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_OPSIZE_B)) || |
406 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_OPSIZE_B)) || |
407 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_OPSIZE_B)); |
408 | case IC_EVEX_K_B: |
409 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_K_B)) || |
410 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K_B)) || |
411 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_K_B)) || |
412 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_K_B)) || |
413 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_K_B)); |
414 | case IC_EVEX_XS_K_B: |
415 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K_B)) || |
416 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K_B)) || |
417 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XS_K_B)) || |
418 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XS_K_B)) || |
419 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XS_K_B)); |
420 | case IC_EVEX_XD_K_B: |
421 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K_B)) || |
422 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K_B)) || |
423 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XD_K_B)) || |
424 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XD_K_B)) || |
425 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XD_K_B)); |
426 | case IC_EVEX_OPSIZE_K_B: |
427 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K_B)) || |
428 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K_B)) || |
429 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_OPSIZE_K_B)) || |
430 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_OPSIZE_K_B)) || |
431 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_OPSIZE_K_B)); |
432 | case IC_EVEX_KZ_B: |
433 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ_B)) || |
434 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ_B)) || |
435 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_KZ_B)) || |
436 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_KZ_B)) || |
437 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_KZ_B)); |
438 | case IC_EVEX_XS_KZ_B: |
439 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ_B)) || |
440 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ_B)) || |
441 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XS_KZ_B)) || |
442 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XS_KZ_B)) || |
443 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XS_KZ_B)); |
444 | case IC_EVEX_XD_KZ_B: |
445 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ_B)) || |
446 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ_B)) || |
447 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XD_KZ_B)) || |
448 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XD_KZ_B)) || |
449 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XD_KZ_B)); |
450 | case IC_EVEX_OPSIZE_KZ_B: |
451 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ_B)) || |
452 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ_B)) || |
453 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_OPSIZE_KZ_B)) || |
454 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_OPSIZE_KZ_B)) || |
455 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_OPSIZE_KZ_B)); |
456 | case IC_EVEX_W_B: |
457 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_B)) || |
458 | inheritsFrom(child, parent: IC_EVEX_W_OPSIZE_B) || |
459 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_B)); |
460 | case IC_EVEX_W_XS_B: |
461 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_B)) || |
462 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_B)); |
463 | case IC_EVEX_W_XD_B: |
464 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_B)) || |
465 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_B)); |
466 | case IC_EVEX_W_OPSIZE_B: |
467 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_B)) || |
468 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_B)); |
469 | case IC_EVEX_W_K_B: |
470 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_K_B)) || |
471 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K_B)); |
472 | case IC_EVEX_W_XS_K_B: |
473 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K_B)) || |
474 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K_B)); |
475 | case IC_EVEX_W_XD_K_B: |
476 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K_B)) || |
477 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K_B)); |
478 | case IC_EVEX_W_OPSIZE_K_B: |
479 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K_B)) || |
480 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K_B)); |
481 | case IC_EVEX_W_KZ_B: |
482 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ_B)) || |
483 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ_B)); |
484 | case IC_EVEX_W_XS_KZ_B: |
485 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ_B)) || |
486 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ_B)); |
487 | case IC_EVEX_W_XD_KZ_B: |
488 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ_B)) || |
489 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ_B)); |
490 | case IC_EVEX_W_OPSIZE_KZ_B: |
491 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ_B)) || |
492 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ_B)); |
493 | case IC_EVEX_L_B: |
494 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_B); |
495 | case IC_EVEX_L_XS_B: |
496 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_B); |
497 | case IC_EVEX_L_XD_B: |
498 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_B); |
499 | case IC_EVEX_L_OPSIZE_B: |
500 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_B); |
501 | case IC_EVEX_L_K_B: |
502 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_K_B); |
503 | case IC_EVEX_L_XS_K_B: |
504 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K_B); |
505 | case IC_EVEX_L_XD_K_B: |
506 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K_B); |
507 | case IC_EVEX_L_OPSIZE_K_B: |
508 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K_B); |
509 | case IC_EVEX_L_KZ_B: |
510 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ_B); |
511 | case IC_EVEX_L_XS_KZ_B: |
512 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ_B); |
513 | case IC_EVEX_L_XD_KZ_B: |
514 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ_B); |
515 | case IC_EVEX_L_OPSIZE_KZ_B: |
516 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ_B); |
517 | case IC_EVEX_L_W_B: |
518 | case IC_EVEX_L_W_XS_B: |
519 | case IC_EVEX_L_W_XD_B: |
520 | case IC_EVEX_L_W_OPSIZE_B: |
521 | return false; |
522 | case IC_EVEX_L_W_K_B: |
523 | case IC_EVEX_L_W_XS_K_B: |
524 | case IC_EVEX_L_W_XD_K_B: |
525 | case IC_EVEX_L_W_OPSIZE_K_B: |
526 | return false; |
527 | case IC_EVEX_L_W_KZ_B: |
528 | case IC_EVEX_L_W_XS_KZ_B: |
529 | case IC_EVEX_L_W_XD_KZ_B: |
530 | case IC_EVEX_L_W_OPSIZE_KZ_B: |
531 | return false; |
532 | case IC_EVEX_L2_B: |
533 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_B); |
534 | case IC_EVEX_L2_XS_B: |
535 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_B); |
536 | case IC_EVEX_L2_XD_B: |
537 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_B); |
538 | case IC_EVEX_L2_OPSIZE_B: |
539 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_B); |
540 | case IC_EVEX_L2_K_B: |
541 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K_B); |
542 | case IC_EVEX_L2_XS_K_B: |
543 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K_B); |
544 | case IC_EVEX_L2_XD_K_B: |
545 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K_B); |
546 | case IC_EVEX_L2_OPSIZE_K_B: |
547 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K_B); |
548 | case IC_EVEX_L2_KZ_B: |
549 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ_B); |
550 | case IC_EVEX_L2_XS_KZ_B: |
551 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ_B); |
552 | case IC_EVEX_L2_XD_KZ_B: |
553 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ_B); |
554 | case IC_EVEX_L2_OPSIZE_KZ_B: |
555 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ_B); |
556 | case IC_EVEX_L2_W_B: |
557 | case IC_EVEX_L2_W_XS_B: |
558 | case IC_EVEX_L2_W_XD_B: |
559 | case IC_EVEX_L2_W_OPSIZE_B: |
560 | return false; |
561 | case IC_EVEX_L2_W_K_B: |
562 | case IC_EVEX_L2_W_XS_K_B: |
563 | case IC_EVEX_L2_W_XD_K_B: |
564 | case IC_EVEX_L2_W_OPSIZE_K_B: |
565 | return false; |
566 | case IC_EVEX_L2_W_KZ_B: |
567 | case IC_EVEX_L2_W_XS_KZ_B: |
568 | case IC_EVEX_L2_W_XD_KZ_B: |
569 | case IC_EVEX_L2_W_OPSIZE_KZ_B: |
570 | return false; |
571 | case IC_EVEX_NF: |
572 | return WIG && inheritsFrom(child, parent: IC_EVEX_W_NF); |
573 | case IC_EVEX_B_NF: |
574 | return WIG && inheritsFrom(child, parent: IC_EVEX_W_B_NF); |
575 | case IC_EVEX_OPSIZE_NF: |
576 | case IC_EVEX_OPSIZE_B_NF: |
577 | case IC_EVEX_W_NF: |
578 | case IC_EVEX_W_B_NF: |
579 | return false; |
580 | case IC_EVEX_B_U: |
581 | case IC_EVEX_XS_B_U: |
582 | case IC_EVEX_XD_B_U: |
583 | case IC_EVEX_OPSIZE_B_U: |
584 | case IC_EVEX_W_B_U: |
585 | case IC_EVEX_W_XS_B_U: |
586 | case IC_EVEX_W_XD_B_U: |
587 | case IC_EVEX_W_OPSIZE_B_U: |
588 | case IC_EVEX_K_B_U: |
589 | case IC_EVEX_XS_K_B_U: |
590 | case IC_EVEX_XD_K_B_U: |
591 | case IC_EVEX_OPSIZE_K_B_U: |
592 | case IC_EVEX_W_K_B_U: |
593 | case IC_EVEX_W_XS_K_B_U: |
594 | case IC_EVEX_W_XD_K_B_U: |
595 | case IC_EVEX_W_OPSIZE_K_B_U: |
596 | case IC_EVEX_KZ_B_U: |
597 | case IC_EVEX_XS_KZ_B_U: |
598 | case IC_EVEX_XD_KZ_B_U: |
599 | case IC_EVEX_OPSIZE_KZ_B_U: |
600 | case IC_EVEX_W_KZ_B_U: |
601 | case IC_EVEX_W_XS_KZ_B_U: |
602 | case IC_EVEX_W_XD_KZ_B_U: |
603 | case IC_EVEX_W_OPSIZE_KZ_B_U: |
604 | return false; |
605 | default: |
606 | errs() << "Unknown instruction class: " |
607 | << stringForContext(insnContext: (InstructionContext)parent) << "\n" ; |
608 | llvm_unreachable("Unknown instruction class" ); |
609 | } |
610 | } |
611 | |
612 | /// outranks - Indicates whether, if an instruction has two different applicable |
613 | /// classes, which class should be preferred when performing decode. This |
614 | /// imposes a total ordering (ties are resolved toward "lower") |
615 | /// |
616 | /// @param upper - The class that may be preferable |
617 | /// @param lower - The class that may be less preferable |
618 | /// @return - True if upper is to be preferred, false otherwise. |
619 | static inline bool outranks(InstructionContext upper, |
620 | InstructionContext lower) { |
621 | assert(upper < IC_max); |
622 | assert(lower < IC_max); |
623 | |
624 | #define ENUM_ENTRY(n, r, d) r, |
625 | #define ENUM_ENTRY_K_B(n, r, d) \ |
626 | ENUM_ENTRY(n, r, d) \ |
627 | ENUM_ENTRY(n##_K_B, r, d) \ |
628 | ENUM_ENTRY(n##_KZ_B, r, d) \ |
629 | ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d) |
630 | static int ranks[IC_max] = {INSTRUCTION_CONTEXTS}; |
631 | #undef ENUM_ENTRY |
632 | #undef ENUM_ENTRY_K_B |
633 | |
634 | return (ranks[upper] > ranks[lower]); |
635 | } |
636 | |
637 | /// getDecisionType - Determines whether a ModRM decision with 255 entries can |
638 | /// be compacted by eliminating redundant information. |
639 | /// |
640 | /// @param decision - The decision to be compacted. |
641 | /// @return - The compactest available representation for the decision. |
642 | static ModRMDecisionType getDecisionType(ModRMDecision &decision) { |
643 | bool satisfiesOneEntry = true; |
644 | bool satisfiesSplitRM = true; |
645 | bool satisfiesSplitReg = true; |
646 | bool satisfiesSplitMisc = true; |
647 | |
648 | for (unsigned index = 0; index < 256; ++index) { |
649 | if (decision.instructionIDs[index] != decision.instructionIDs[0]) |
650 | satisfiesOneEntry = false; |
651 | |
652 | if (((index & 0xc0) == 0xc0) && |
653 | (decision.instructionIDs[index] != decision.instructionIDs[0xc0])) |
654 | satisfiesSplitRM = false; |
655 | |
656 | if (((index & 0xc0) != 0xc0) && |
657 | (decision.instructionIDs[index] != decision.instructionIDs[0x00])) |
658 | satisfiesSplitRM = false; |
659 | |
660 | if (((index & 0xc0) == 0xc0) && (decision.instructionIDs[index] != |
661 | decision.instructionIDs[index & 0xf8])) |
662 | satisfiesSplitReg = false; |
663 | |
664 | if (((index & 0xc0) != 0xc0) && (decision.instructionIDs[index] != |
665 | decision.instructionIDs[index & 0x38])) |
666 | satisfiesSplitMisc = false; |
667 | } |
668 | |
669 | if (satisfiesOneEntry) |
670 | return MODRM_ONEENTRY; |
671 | |
672 | if (satisfiesSplitRM) |
673 | return MODRM_SPLITRM; |
674 | |
675 | if (satisfiesSplitReg && satisfiesSplitMisc) |
676 | return MODRM_SPLITREG; |
677 | |
678 | if (satisfiesSplitMisc) |
679 | return MODRM_SPLITMISC; |
680 | |
681 | return MODRM_FULL; |
682 | } |
683 | |
684 | /// stringForDecisionType - Returns a statically-allocated string corresponding |
685 | /// to a particular decision type. |
686 | /// |
687 | /// @param dt - The decision type. |
688 | /// @return - A pointer to the statically-allocated string (e.g., |
689 | /// "MODRM_ONEENTRY" for MODRM_ONEENTRY). |
690 | static const char *stringForDecisionType(ModRMDecisionType dt) { |
691 | #define ENUM_ENTRY(n) \ |
692 | case n: \ |
693 | return #n; |
694 | switch (dt) { |
695 | default: |
696 | llvm_unreachable("Unknown decision type" ); |
697 | MODRMTYPES |
698 | }; |
699 | #undef ENUM_ENTRY |
700 | } |
701 | |
702 | DisassemblerTables::DisassemblerTables() { |
703 | for (unsigned i = 0; i < std::size(Tables); i++) |
704 | Tables[i] = std::make_unique<ContextDecision>(); |
705 | |
706 | HasConflicts = false; |
707 | } |
708 | |
709 | DisassemblerTables::~DisassemblerTables() {} |
710 | |
711 | void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, |
712 | unsigned &i1, unsigned &i2, |
713 | unsigned &ModRMTableNum, |
714 | ModRMDecision &decision) const { |
715 | static uint64_t sEntryNumber = 1; |
716 | ModRMDecisionType dt = getDecisionType(decision); |
717 | |
718 | if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) { |
719 | // Empty table. |
720 | o2 << "{" << stringForDecisionType(dt) << ", 0}" ; |
721 | return; |
722 | } |
723 | |
724 | std::vector<unsigned> ModRMDecision; |
725 | |
726 | switch (dt) { |
727 | default: |
728 | llvm_unreachable("Unknown decision type" ); |
729 | case MODRM_ONEENTRY: |
730 | ModRMDecision.push_back(x: decision.instructionIDs[0]); |
731 | break; |
732 | case MODRM_SPLITRM: |
733 | ModRMDecision.push_back(x: decision.instructionIDs[0x00]); |
734 | ModRMDecision.push_back(x: decision.instructionIDs[0xc0]); |
735 | break; |
736 | case MODRM_SPLITREG: |
737 | for (unsigned index = 0; index < 64; index += 8) |
738 | ModRMDecision.push_back(x: decision.instructionIDs[index]); |
739 | for (unsigned index = 0xc0; index < 256; index += 8) |
740 | ModRMDecision.push_back(x: decision.instructionIDs[index]); |
741 | break; |
742 | case MODRM_SPLITMISC: |
743 | for (unsigned index = 0; index < 64; index += 8) |
744 | ModRMDecision.push_back(x: decision.instructionIDs[index]); |
745 | for (unsigned index = 0xc0; index < 256; ++index) |
746 | ModRMDecision.push_back(x: decision.instructionIDs[index]); |
747 | break; |
748 | case MODRM_FULL: |
749 | llvm::append_range(C&: ModRMDecision, R&: decision.instructionIDs); |
750 | break; |
751 | } |
752 | |
753 | unsigned &EntryNumber = ModRMTable[ModRMDecision]; |
754 | if (EntryNumber == 0) { |
755 | EntryNumber = ModRMTableNum; |
756 | |
757 | ModRMTableNum += ModRMDecision.size(); |
758 | o1 << "/*Table" << EntryNumber << "*/\n" ; |
759 | i1++; |
760 | for (unsigned I : ModRMDecision) { |
761 | o1.indent(NumSpaces: i1 * 2) << format(Fmt: "0x%hx" , Vals: I) << ", /*" |
762 | << InstructionSpecifiers[I].name << "*/\n" ; |
763 | } |
764 | i1--; |
765 | } |
766 | |
767 | o2 << "{" << stringForDecisionType(dt) << ", " << EntryNumber << "}" ; |
768 | |
769 | switch (dt) { |
770 | default: |
771 | llvm_unreachable("Unknown decision type" ); |
772 | case MODRM_ONEENTRY: |
773 | sEntryNumber += 1; |
774 | break; |
775 | case MODRM_SPLITRM: |
776 | sEntryNumber += 2; |
777 | break; |
778 | case MODRM_SPLITREG: |
779 | sEntryNumber += 16; |
780 | break; |
781 | case MODRM_SPLITMISC: |
782 | sEntryNumber += 8 + 64; |
783 | break; |
784 | case MODRM_FULL: |
785 | sEntryNumber += 256; |
786 | break; |
787 | } |
788 | |
789 | // We assume that the index can fit into uint32_t. |
790 | assert(sEntryNumber < -1U && |
791 | "Index into ModRMDecision is too large for uint32_t!" ); |
792 | (void)sEntryNumber; |
793 | } |
794 | |
795 | void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, |
796 | unsigned &i1, unsigned &i2, |
797 | unsigned &ModRMTableNum, |
798 | OpcodeDecision &opDecision) const { |
799 | o2 << "{" ; |
800 | ++i2; |
801 | |
802 | unsigned index; |
803 | for (index = 0; index < 256; ++index) { |
804 | auto &decision = opDecision.modRMDecisions[index]; |
805 | ModRMDecisionType dt = getDecisionType(decision); |
806 | if (!(dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)) |
807 | break; |
808 | } |
809 | if (index == 256) { |
810 | // If all 256 entries are MODRM_ONEENTRY, omit output. |
811 | static_assert(MODRM_ONEENTRY == 0); |
812 | --i2; |
813 | o2 << "},\n" ; |
814 | } else { |
815 | o2 << " /* struct OpcodeDecision */ {\n" ; |
816 | for (index = 0; index < 256; ++index) { |
817 | o2.indent(NumSpaces: i2); |
818 | |
819 | o2 << "/*0x" << format(Fmt: "%02hhx" , Vals: index) << "*/" ; |
820 | |
821 | emitModRMDecision(o1, o2, i1, i2, ModRMTableNum, |
822 | decision&: opDecision.modRMDecisions[index]); |
823 | |
824 | if (index < 255) |
825 | o2 << "," ; |
826 | |
827 | o2 << "\n" ; |
828 | } |
829 | o2.indent(NumSpaces: i2) << "}\n" ; |
830 | --i2; |
831 | o2.indent(NumSpaces: i2) << "},\n" ; |
832 | } |
833 | } |
834 | |
835 | void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, |
836 | unsigned &i1, unsigned &i2, |
837 | unsigned &ModRMTableNum, |
838 | ContextDecision &decision, |
839 | const char *name) const { |
840 | o2.indent(NumSpaces: i2) << "static const struct ContextDecision " << name |
841 | << " = {{/* opcodeDecisions */\n" ; |
842 | i2++; |
843 | |
844 | for (unsigned index = 0; index < IC_max; ++index) { |
845 | o2.indent(NumSpaces: i2) << "/*" ; |
846 | o2 << stringForContext(insnContext: (InstructionContext)index); |
847 | o2 << "*/ " ; |
848 | |
849 | emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum, |
850 | opDecision&: decision.opcodeDecisions[index]); |
851 | } |
852 | |
853 | i2--; |
854 | o2.indent(NumSpaces: i2) << "}};" |
855 | << "\n" ; |
856 | } |
857 | |
858 | void DisassemblerTables::emitInstructionInfo(raw_ostream &o, |
859 | unsigned &i) const { |
860 | unsigned NumInstructions = InstructionSpecifiers.size(); |
861 | |
862 | o << "static const struct OperandSpecifier x86OperandSets[][" |
863 | << X86_MAX_OPERANDS << "] = {\n" ; |
864 | |
865 | typedef SmallVector<std::pair<OperandEncoding, OperandType>, X86_MAX_OPERANDS> |
866 | OperandListTy; |
867 | std::map<OperandListTy, unsigned> OperandSets; |
868 | |
869 | unsigned OperandSetNum = 0; |
870 | for (unsigned Index = 0; Index < NumInstructions; ++Index) { |
871 | OperandListTy OperandList; |
872 | |
873 | for (auto Operand : InstructionSpecifiers[Index].operands) { |
874 | OperandEncoding Encoding = (OperandEncoding)Operand.encoding; |
875 | OperandType Type = (OperandType)Operand.type; |
876 | OperandList.emplace_back(Args&: Encoding, Args&: Type); |
877 | } |
878 | unsigned &N = OperandSets[OperandList]; |
879 | if (N != 0) |
880 | continue; |
881 | |
882 | N = ++OperandSetNum; |
883 | |
884 | o << " { /* " << (OperandSetNum - 1) << " */\n" ; |
885 | for (const auto &[Enc, Ty] : OperandList) { |
886 | const char *Encoding = stringForOperandEncoding(encoding: Enc); |
887 | const char *Type = stringForOperandType(type: Ty); |
888 | o << " { " << Encoding << ", " << Type << " },\n" ; |
889 | } |
890 | o << " },\n" ; |
891 | } |
892 | o << "};" |
893 | << "\n\n" ; |
894 | |
895 | o.indent(NumSpaces: i * 2) << "static const struct InstructionSpecifier " ; |
896 | o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n" ; |
897 | |
898 | i++; |
899 | |
900 | for (unsigned index = 0; index < NumInstructions; ++index) { |
901 | o.indent(NumSpaces: i * 2) << "{ /* " << index << " */\n" ; |
902 | i++; |
903 | |
904 | OperandListTy OperandList; |
905 | for (auto Operand : InstructionSpecifiers[index].operands) { |
906 | OperandEncoding Encoding = (OperandEncoding)Operand.encoding; |
907 | OperandType Type = (OperandType)Operand.type; |
908 | OperandList.emplace_back(Args&: Encoding, Args&: Type); |
909 | } |
910 | o.indent(NumSpaces: i * 2) << (OperandSets[OperandList] - 1) << ",\n" ; |
911 | |
912 | o.indent(NumSpaces: i * 2) << "/* " << InstructionSpecifiers[index].name << " */\n" ; |
913 | |
914 | i--; |
915 | o.indent(NumSpaces: i * 2) << "},\n" ; |
916 | } |
917 | |
918 | i--; |
919 | o.indent(NumSpaces: i * 2) << "};" |
920 | << "\n" ; |
921 | } |
922 | |
923 | void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const { |
924 | o.indent(NumSpaces: i * 2) << "static const uint8_t " CONTEXTS_STR "[" << ATTR_max |
925 | << "] = {\n" ; |
926 | i++; |
927 | |
928 | for (unsigned index = 0; index < ATTR_max; ++index) { |
929 | o.indent(NumSpaces: i * 2); |
930 | |
931 | if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_OPSIZE)) |
932 | o << "IC_EVEX_OPSIZE_ADSIZE" ; |
933 | else if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_XD)) |
934 | o << "IC_EVEX_XD_ADSIZE" ; |
935 | else if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_XS)) |
936 | o << "IC_EVEX_XS_ADSIZE" ; |
937 | else if (index & ATTR_EVEXNF) { |
938 | o << "IC_EVEX" ; |
939 | if (index & ATTR_REXW) |
940 | o << "_W" ; |
941 | else if (index & ATTR_OPSIZE) |
942 | o << "_OPSIZE" ; |
943 | |
944 | if (index & ATTR_EVEXB) |
945 | o << "_B" ; |
946 | |
947 | o << "_NF" ; |
948 | } else if ((index & ATTR_EVEX) || (index & ATTR_VEX) || |
949 | (index & ATTR_VEXL)) { |
950 | if (index & ATTR_EVEX) |
951 | o << "IC_EVEX" ; |
952 | else |
953 | o << "IC_VEX" ; |
954 | |
955 | if ((index & ATTR_EVEXB) && (index & ATTR_EVEXU)) |
956 | ; // Ignore ATTR_VEXL and ATTR_EVEXL2 under YMM rounding. |
957 | else if ((index & ATTR_EVEX) && (index & ATTR_EVEXL2)) |
958 | o << "_L2" ; |
959 | else if (index & ATTR_VEXL) |
960 | o << "_L" ; |
961 | |
962 | if (index & ATTR_REXW) |
963 | o << "_W" ; |
964 | |
965 | if (index & ATTR_OPSIZE) |
966 | o << "_OPSIZE" ; |
967 | else if (index & ATTR_XD) |
968 | o << "_XD" ; |
969 | else if (index & ATTR_XS) |
970 | o << "_XS" ; |
971 | |
972 | if (index & ATTR_EVEX) { |
973 | if (index & ATTR_EVEXKZ) |
974 | o << "_KZ" ; |
975 | else if (index & ATTR_EVEXK) |
976 | o << "_K" ; |
977 | |
978 | if (index & ATTR_EVEXB) |
979 | o << "_B" ; |
980 | |
981 | if ((index & ATTR_EVEXB) && (index & ATTR_EVEXU)) |
982 | o << "_U" ; |
983 | } |
984 | } else if ((index & ATTR_64BIT) && (index & ATTR_REX2)) |
985 | o << "IC_64BIT_REX2" ; |
986 | else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) |
987 | o << "IC_64BIT_REXW_XS" ; |
988 | else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) |
989 | o << "IC_64BIT_REXW_XD" ; |
990 | else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && |
991 | (index & ATTR_OPSIZE)) |
992 | o << "IC_64BIT_REXW_OPSIZE" ; |
993 | else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && |
994 | (index & ATTR_ADSIZE)) |
995 | o << "IC_64BIT_REXW_ADSIZE" ; |
996 | else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE)) |
997 | o << "IC_64BIT_XD_OPSIZE" ; |
998 | else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_ADSIZE)) |
999 | o << "IC_64BIT_XD_ADSIZE" ; |
1000 | else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE)) |
1001 | o << "IC_64BIT_XS_OPSIZE" ; |
1002 | else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_ADSIZE)) |
1003 | o << "IC_64BIT_XS_ADSIZE" ; |
1004 | else if ((index & ATTR_64BIT) && (index & ATTR_XS)) |
1005 | o << "IC_64BIT_XS" ; |
1006 | else if ((index & ATTR_64BIT) && (index & ATTR_XD)) |
1007 | o << "IC_64BIT_XD" ; |
1008 | else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE) && |
1009 | (index & ATTR_ADSIZE)) |
1010 | o << "IC_64BIT_OPSIZE_ADSIZE" ; |
1011 | else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE)) |
1012 | o << "IC_64BIT_OPSIZE" ; |
1013 | else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE)) |
1014 | o << "IC_64BIT_ADSIZE" ; |
1015 | else if ((index & ATTR_64BIT) && (index & ATTR_REXW)) |
1016 | o << "IC_64BIT_REXW" ; |
1017 | else if ((index & ATTR_64BIT)) |
1018 | o << "IC_64BIT" ; |
1019 | else if ((index & ATTR_XS) && (index & ATTR_OPSIZE)) |
1020 | o << "IC_XS_OPSIZE" ; |
1021 | else if ((index & ATTR_XD) && (index & ATTR_OPSIZE)) |
1022 | o << "IC_XD_OPSIZE" ; |
1023 | else if ((index & ATTR_XS) && (index & ATTR_ADSIZE)) |
1024 | o << "IC_XS_ADSIZE" ; |
1025 | else if ((index & ATTR_XD) && (index & ATTR_ADSIZE)) |
1026 | o << "IC_XD_ADSIZE" ; |
1027 | else if (index & ATTR_XS) |
1028 | o << "IC_XS" ; |
1029 | else if (index & ATTR_XD) |
1030 | o << "IC_XD" ; |
1031 | else if ((index & ATTR_OPSIZE) && (index & ATTR_ADSIZE)) |
1032 | o << "IC_OPSIZE_ADSIZE" ; |
1033 | else if (index & ATTR_OPSIZE) |
1034 | o << "IC_OPSIZE" ; |
1035 | else if (index & ATTR_ADSIZE) |
1036 | o << "IC_ADSIZE" ; |
1037 | else |
1038 | o << "IC" ; |
1039 | |
1040 | o << ", // " << index << "\n" ; |
1041 | } |
1042 | |
1043 | i--; |
1044 | o.indent(NumSpaces: i * 2) << "};" |
1045 | << "\n" ; |
1046 | } |
1047 | |
1048 | void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2, |
1049 | unsigned &i1, unsigned &i2, |
1050 | unsigned &ModRMTableNum) const { |
1051 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[0], ONEBYTE_STR); |
1052 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[1], TWOBYTE_STR); |
1053 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[2], |
1054 | THREEBYTE38_STR); |
1055 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[3], |
1056 | THREEBYTE3A_STR); |
1057 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[4], XOP8_MAP_STR); |
1058 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[5], XOP9_MAP_STR); |
1059 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[6], XOPA_MAP_STR); |
1060 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[7], |
1061 | THREEDNOW_MAP_STR); |
1062 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[8], MAP4_STR); |
1063 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[9], MAP5_STR); |
1064 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[10], MAP6_STR); |
1065 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[11], MAP7_STR); |
1066 | } |
1067 | |
1068 | void DisassemblerTables::emit(raw_ostream &o) const { |
1069 | unsigned i1 = 0; |
1070 | unsigned i2 = 0; |
1071 | |
1072 | std::string s1; |
1073 | std::string s2; |
1074 | |
1075 | raw_string_ostream o1(s1); |
1076 | raw_string_ostream o2(s2); |
1077 | |
1078 | emitInstructionInfo(o, i&: i2); |
1079 | o << "\n" ; |
1080 | |
1081 | emitContextTable(o, i&: i2); |
1082 | o << "\n" ; |
1083 | |
1084 | unsigned ModRMTableNum = 0; |
1085 | |
1086 | o << "static const InstrUID modRMTable[] = {\n" ; |
1087 | i1++; |
1088 | std::vector<unsigned> EmptyTable(1, 0); |
1089 | ModRMTable[EmptyTable] = ModRMTableNum; |
1090 | ModRMTableNum += EmptyTable.size(); |
1091 | o1 << "/*EmptyTable*/\n" ; |
1092 | o1.indent(NumSpaces: i1 * 2) << "0x0,\n" ; |
1093 | i1--; |
1094 | emitContextDecisions(o1, o2, i1, i2, ModRMTableNum); |
1095 | |
1096 | o << s1; |
1097 | o << " 0x0\n" ; |
1098 | o << "};\n" ; |
1099 | o << "\n" ; |
1100 | o << s2; |
1101 | o << "\n" ; |
1102 | o << "\n" ; |
1103 | } |
1104 | |
1105 | void DisassemblerTables::setTableFields(ModRMDecision &decision, |
1106 | const ModRMFilter &filter, InstrUID uid, |
1107 | uint8_t opcode) { |
1108 | for (unsigned index = 0; index < 256; ++index) { |
1109 | if (filter.accepts(modRM: index)) { |
1110 | if (decision.instructionIDs[index] == uid) |
1111 | continue; |
1112 | |
1113 | if (decision.instructionIDs[index] != 0) { |
1114 | InstructionSpecifier &newInfo = InstructionSpecifiers[uid]; |
1115 | InstructionSpecifier &previousInfo = |
1116 | InstructionSpecifiers[decision.instructionIDs[index]]; |
1117 | |
1118 | if (previousInfo.name == "NOOP" && |
1119 | (newInfo.name == "XCHG16ar" || newInfo.name == "XCHG32ar" || |
1120 | newInfo.name == "XCHG64ar" )) |
1121 | continue; // special case for XCHG*ar and NOOP |
1122 | |
1123 | if (outranks(upper: previousInfo.insnContext, lower: newInfo.insnContext)) |
1124 | continue; |
1125 | |
1126 | if (previousInfo.insnContext == newInfo.insnContext) { |
1127 | errs() << "Error: Primary decode conflict: " ; |
1128 | errs() << newInfo.name << " would overwrite " << previousInfo.name; |
1129 | errs() << "\n" ; |
1130 | errs() << "ModRM " << index << "\n" ; |
1131 | errs() << "Opcode " << (uint16_t)opcode << "\n" ; |
1132 | errs() << "Context " << stringForContext(insnContext: newInfo.insnContext) << "\n" ; |
1133 | HasConflicts = true; |
1134 | } |
1135 | } |
1136 | |
1137 | decision.instructionIDs[index] = uid; |
1138 | } |
1139 | } |
1140 | } |
1141 | |
1142 | void DisassemblerTables::setTableFields( |
1143 | OpcodeType type, InstructionContext insnContext, uint8_t opcode, |
1144 | const ModRMFilter &filter, InstrUID uid, bool is32bit, bool noPrefix, |
1145 | bool ignoresVEX_L, bool ignoresW, unsigned addressSize) { |
1146 | ContextDecision &decision = *Tables[type]; |
1147 | |
1148 | for (unsigned index = 0; index < IC_max; ++index) { |
1149 | if ((is32bit || addressSize == 16) && |
1150 | inheritsFrom(child: (InstructionContext)index, parent: IC_64BIT)) |
1151 | continue; |
1152 | |
1153 | bool adSize64 = addressSize == 64; |
1154 | if (inheritsFrom(child: (InstructionContext)index, |
1155 | parent: InstructionSpecifiers[uid].insnContext, noPrefix, |
1156 | VEX_LIG: ignoresVEX_L, WIG: ignoresW, AdSize64: adSize64)) |
1157 | setTableFields(decision&: decision.opcodeDecisions[index].modRMDecisions[opcode], |
1158 | filter, uid, opcode); |
1159 | } |
1160 | } |
1161 | |