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 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W)); |
272 | case IC_EVEX_W_XS: |
273 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS)) || |
274 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS)); |
275 | case IC_EVEX_W_XD: |
276 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD)) || |
277 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD)); |
278 | case IC_EVEX_W_OPSIZE: |
279 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE)) || |
280 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE)); |
281 | case IC_EVEX_W_K: |
282 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_K)) || |
283 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K)); |
284 | case IC_EVEX_W_XS_K: |
285 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K)) || |
286 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K)); |
287 | case IC_EVEX_W_XD_K: |
288 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K)) || |
289 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K)); |
290 | case IC_EVEX_W_OPSIZE_K: |
291 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K)) || |
292 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K)); |
293 | case IC_EVEX_W_KZ: |
294 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ)) || |
295 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ)); |
296 | case IC_EVEX_W_XS_KZ: |
297 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ)) || |
298 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ)); |
299 | case IC_EVEX_W_XD_KZ: |
300 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ)) || |
301 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ)); |
302 | case IC_EVEX_W_OPSIZE_KZ: |
303 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ)) || |
304 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ)); |
305 | case IC_EVEX_L: |
306 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W); |
307 | case IC_EVEX_L_XS: |
308 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS); |
309 | case IC_EVEX_L_XD: |
310 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD); |
311 | case IC_EVEX_L_OPSIZE: |
312 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE); |
313 | case IC_EVEX_L_K: |
314 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_K); |
315 | case IC_EVEX_L_XS_K: |
316 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K); |
317 | case IC_EVEX_L_XD_K: |
318 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K); |
319 | case IC_EVEX_L_OPSIZE_K: |
320 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K); |
321 | case IC_EVEX_L_KZ: |
322 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ); |
323 | case IC_EVEX_L_XS_KZ: |
324 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ); |
325 | case IC_EVEX_L_XD_KZ: |
326 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ); |
327 | case IC_EVEX_L_OPSIZE_KZ: |
328 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ); |
329 | case IC_EVEX_L_W: |
330 | case IC_EVEX_L_W_XS: |
331 | case IC_EVEX_L_W_XD: |
332 | case IC_EVEX_L_W_OPSIZE: |
333 | return false; |
334 | case IC_EVEX_L_W_K: |
335 | case IC_EVEX_L_W_XS_K: |
336 | case IC_EVEX_L_W_XD_K: |
337 | case IC_EVEX_L_W_OPSIZE_K: |
338 | return false; |
339 | case IC_EVEX_L_W_KZ: |
340 | case IC_EVEX_L_W_XS_KZ: |
341 | case IC_EVEX_L_W_XD_KZ: |
342 | case IC_EVEX_L_W_OPSIZE_KZ: |
343 | return false; |
344 | case IC_EVEX_L2: |
345 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W); |
346 | case IC_EVEX_L2_XS: |
347 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS); |
348 | case IC_EVEX_L2_XD: |
349 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD); |
350 | case IC_EVEX_L2_OPSIZE: |
351 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE); |
352 | case IC_EVEX_L2_K: |
353 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K); |
354 | case IC_EVEX_L2_XS_K: |
355 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K); |
356 | case IC_EVEX_L2_XD_K: |
357 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K); |
358 | case IC_EVEX_L2_OPSIZE_K: |
359 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K); |
360 | case IC_EVEX_L2_KZ: |
361 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ); |
362 | case IC_EVEX_L2_XS_KZ: |
363 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ); |
364 | case IC_EVEX_L2_XD_KZ: |
365 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ); |
366 | case IC_EVEX_L2_OPSIZE_KZ: |
367 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ); |
368 | case IC_EVEX_L2_W: |
369 | case IC_EVEX_L2_W_XS: |
370 | case IC_EVEX_L2_W_XD: |
371 | case IC_EVEX_L2_W_OPSIZE: |
372 | return false; |
373 | case IC_EVEX_L2_W_K: |
374 | case IC_EVEX_L2_W_XS_K: |
375 | case IC_EVEX_L2_W_XD_K: |
376 | case IC_EVEX_L2_W_OPSIZE_K: |
377 | return false; |
378 | case IC_EVEX_L2_W_KZ: |
379 | case IC_EVEX_L2_W_XS_KZ: |
380 | case IC_EVEX_L2_W_XD_KZ: |
381 | case IC_EVEX_L2_W_OPSIZE_KZ: |
382 | return false; |
383 | case IC_EVEX_B: |
384 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_B)) || |
385 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_B)) || |
386 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_B)) || |
387 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_B)) || |
388 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_B)); |
389 | case IC_EVEX_XS_B: |
390 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_B)) || |
391 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_B)) || |
392 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XS_B)) || |
393 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XS_B)) || |
394 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XS_B)); |
395 | case IC_EVEX_XD_B: |
396 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_B)) || |
397 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_B)) || |
398 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XD_B)) || |
399 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XD_B)) || |
400 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XD_B)); |
401 | case IC_EVEX_OPSIZE_B: |
402 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_B)) || |
403 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_B)) || |
404 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_OPSIZE_B)) || |
405 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_OPSIZE_B)) || |
406 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_OPSIZE_B)); |
407 | case IC_EVEX_K_B: |
408 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_K_B)) || |
409 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K_B)) || |
410 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_K_B)) || |
411 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_K_B)) || |
412 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_K_B)); |
413 | case IC_EVEX_XS_K_B: |
414 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K_B)) || |
415 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K_B)) || |
416 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XS_K_B)) || |
417 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XS_K_B)) || |
418 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XS_K_B)); |
419 | case IC_EVEX_XD_K_B: |
420 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K_B)) || |
421 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K_B)) || |
422 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XD_K_B)) || |
423 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XD_K_B)) || |
424 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XD_K_B)); |
425 | case IC_EVEX_OPSIZE_K_B: |
426 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K_B)) || |
427 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K_B)) || |
428 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_OPSIZE_K_B)) || |
429 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_OPSIZE_K_B)) || |
430 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_OPSIZE_K_B)); |
431 | case IC_EVEX_KZ_B: |
432 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ_B)) || |
433 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ_B)) || |
434 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_KZ_B)) || |
435 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_KZ_B)) || |
436 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_KZ_B)); |
437 | case IC_EVEX_XS_KZ_B: |
438 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ_B)) || |
439 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ_B)) || |
440 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XS_KZ_B)) || |
441 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XS_KZ_B)) || |
442 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XS_KZ_B)); |
443 | case IC_EVEX_XD_KZ_B: |
444 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ_B)) || |
445 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ_B)) || |
446 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_XD_KZ_B)) || |
447 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_XD_KZ_B)) || |
448 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_XD_KZ_B)); |
449 | case IC_EVEX_OPSIZE_KZ_B: |
450 | return (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ_B)) || |
451 | (VEX_LIG && WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ_B)) || |
452 | (WIG && inheritsFrom(child, parent: IC_EVEX_W_OPSIZE_KZ_B)) || |
453 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_OPSIZE_KZ_B)) || |
454 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_OPSIZE_KZ_B)); |
455 | case IC_EVEX_W_B: |
456 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_B)) || |
457 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_B)); |
458 | case IC_EVEX_W_XS_B: |
459 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_B)) || |
460 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_B)); |
461 | case IC_EVEX_W_XD_B: |
462 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_B)) || |
463 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_B)); |
464 | case IC_EVEX_W_OPSIZE_B: |
465 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_B)) || |
466 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_B)); |
467 | case IC_EVEX_W_K_B: |
468 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_K_B)) || |
469 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K_B)); |
470 | case IC_EVEX_W_XS_K_B: |
471 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K_B)) || |
472 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K_B)); |
473 | case IC_EVEX_W_XD_K_B: |
474 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K_B)) || |
475 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K_B)); |
476 | case IC_EVEX_W_OPSIZE_K_B: |
477 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K_B)) || |
478 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K_B)); |
479 | case IC_EVEX_W_KZ_B: |
480 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ_B)) || |
481 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ_B)); |
482 | case IC_EVEX_W_XS_KZ_B: |
483 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ_B)) || |
484 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ_B)); |
485 | case IC_EVEX_W_XD_KZ_B: |
486 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ_B)) || |
487 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ_B)); |
488 | case IC_EVEX_W_OPSIZE_KZ_B: |
489 | return (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ_B)) || |
490 | (VEX_LIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ_B)); |
491 | case IC_EVEX_L_B: |
492 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_B); |
493 | case IC_EVEX_L_XS_B: |
494 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_B); |
495 | case IC_EVEX_L_XD_B: |
496 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_B); |
497 | case IC_EVEX_L_OPSIZE_B: |
498 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_B); |
499 | case IC_EVEX_L_K_B: |
500 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_K_B); |
501 | case IC_EVEX_L_XS_K_B: |
502 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_K_B); |
503 | case IC_EVEX_L_XD_K_B: |
504 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_K_B); |
505 | case IC_EVEX_L_OPSIZE_K_B: |
506 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_K_B); |
507 | case IC_EVEX_L_KZ_B: |
508 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_KZ_B); |
509 | case IC_EVEX_L_XS_KZ_B: |
510 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XS_KZ_B); |
511 | case IC_EVEX_L_XD_KZ_B: |
512 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_XD_KZ_B); |
513 | case IC_EVEX_L_OPSIZE_KZ_B: |
514 | return WIG && inheritsFrom(child, parent: IC_EVEX_L_W_OPSIZE_KZ_B); |
515 | case IC_EVEX_L_W_B: |
516 | case IC_EVEX_L_W_XS_B: |
517 | case IC_EVEX_L_W_XD_B: |
518 | case IC_EVEX_L_W_OPSIZE_B: |
519 | return false; |
520 | case IC_EVEX_L_W_K_B: |
521 | case IC_EVEX_L_W_XS_K_B: |
522 | case IC_EVEX_L_W_XD_K_B: |
523 | case IC_EVEX_L_W_OPSIZE_K_B: |
524 | return false; |
525 | case IC_EVEX_L_W_KZ_B: |
526 | case IC_EVEX_L_W_XS_KZ_B: |
527 | case IC_EVEX_L_W_XD_KZ_B: |
528 | case IC_EVEX_L_W_OPSIZE_KZ_B: |
529 | return false; |
530 | case IC_EVEX_L2_B: |
531 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_B); |
532 | case IC_EVEX_L2_XS_B: |
533 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_B); |
534 | case IC_EVEX_L2_XD_B: |
535 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_B); |
536 | case IC_EVEX_L2_OPSIZE_B: |
537 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_B); |
538 | case IC_EVEX_L2_K_B: |
539 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_K_B); |
540 | case IC_EVEX_L2_XS_K_B: |
541 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_K_B); |
542 | case IC_EVEX_L2_XD_K_B: |
543 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_K_B); |
544 | case IC_EVEX_L2_OPSIZE_K_B: |
545 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_K_B); |
546 | case IC_EVEX_L2_KZ_B: |
547 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_KZ_B); |
548 | case IC_EVEX_L2_XS_KZ_B: |
549 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XS_KZ_B); |
550 | case IC_EVEX_L2_XD_KZ_B: |
551 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_XD_KZ_B); |
552 | case IC_EVEX_L2_OPSIZE_KZ_B: |
553 | return WIG && inheritsFrom(child, parent: IC_EVEX_L2_W_OPSIZE_KZ_B); |
554 | case IC_EVEX_L2_W_B: |
555 | case IC_EVEX_L2_W_XS_B: |
556 | case IC_EVEX_L2_W_XD_B: |
557 | case IC_EVEX_L2_W_OPSIZE_B: |
558 | return false; |
559 | case IC_EVEX_L2_W_K_B: |
560 | case IC_EVEX_L2_W_XS_K_B: |
561 | case IC_EVEX_L2_W_XD_K_B: |
562 | case IC_EVEX_L2_W_OPSIZE_K_B: |
563 | return false; |
564 | case IC_EVEX_L2_W_KZ_B: |
565 | case IC_EVEX_L2_W_XS_KZ_B: |
566 | case IC_EVEX_L2_W_XD_KZ_B: |
567 | case IC_EVEX_L2_W_OPSIZE_KZ_B: |
568 | return false; |
569 | case IC_EVEX_NF: |
570 | return WIG && inheritsFrom(child, parent: IC_EVEX_W_NF); |
571 | case IC_EVEX_B_NF: |
572 | return WIG && inheritsFrom(child, parent: IC_EVEX_W_B_NF); |
573 | case IC_EVEX_OPSIZE_NF: |
574 | case IC_EVEX_OPSIZE_B_NF: |
575 | case IC_EVEX_W_NF: |
576 | case IC_EVEX_W_B_NF: |
577 | return false; |
578 | default: |
579 | errs() << "Unknown instruction class: " |
580 | << stringForContext(insnContext: (InstructionContext)parent) << "\n" ; |
581 | llvm_unreachable("Unknown instruction class" ); |
582 | } |
583 | } |
584 | |
585 | /// outranks - Indicates whether, if an instruction has two different applicable |
586 | /// classes, which class should be preferred when performing decode. This |
587 | /// imposes a total ordering (ties are resolved toward "lower") |
588 | /// |
589 | /// @param upper - The class that may be preferable |
590 | /// @param lower - The class that may be less preferable |
591 | /// @return - True if upper is to be preferred, false otherwise. |
592 | static inline bool outranks(InstructionContext upper, |
593 | InstructionContext lower) { |
594 | assert(upper < IC_max); |
595 | assert(lower < IC_max); |
596 | |
597 | #define ENUM_ENTRY(n, r, d) r, |
598 | #define ENUM_ENTRY_K_B(n, r, d) \ |
599 | ENUM_ENTRY(n, r, d) \ |
600 | ENUM_ENTRY(n##_K_B, r, d) \ |
601 | ENUM_ENTRY(n##_KZ_B, r, d) \ |
602 | ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d) |
603 | static int ranks[IC_max] = {INSTRUCTION_CONTEXTS}; |
604 | #undef ENUM_ENTRY |
605 | #undef ENUM_ENTRY_K_B |
606 | |
607 | return (ranks[upper] > ranks[lower]); |
608 | } |
609 | |
610 | /// getDecisionType - Determines whether a ModRM decision with 255 entries can |
611 | /// be compacted by eliminating redundant information. |
612 | /// |
613 | /// @param decision - The decision to be compacted. |
614 | /// @return - The compactest available representation for the decision. |
615 | static ModRMDecisionType getDecisionType(ModRMDecision &decision) { |
616 | bool satisfiesOneEntry = true; |
617 | bool satisfiesSplitRM = true; |
618 | bool satisfiesSplitReg = true; |
619 | bool satisfiesSplitMisc = true; |
620 | |
621 | for (unsigned index = 0; index < 256; ++index) { |
622 | if (decision.instructionIDs[index] != decision.instructionIDs[0]) |
623 | satisfiesOneEntry = false; |
624 | |
625 | if (((index & 0xc0) == 0xc0) && |
626 | (decision.instructionIDs[index] != decision.instructionIDs[0xc0])) |
627 | satisfiesSplitRM = false; |
628 | |
629 | if (((index & 0xc0) != 0xc0) && |
630 | (decision.instructionIDs[index] != decision.instructionIDs[0x00])) |
631 | satisfiesSplitRM = false; |
632 | |
633 | if (((index & 0xc0) == 0xc0) && (decision.instructionIDs[index] != |
634 | decision.instructionIDs[index & 0xf8])) |
635 | satisfiesSplitReg = false; |
636 | |
637 | if (((index & 0xc0) != 0xc0) && (decision.instructionIDs[index] != |
638 | decision.instructionIDs[index & 0x38])) |
639 | satisfiesSplitMisc = false; |
640 | } |
641 | |
642 | if (satisfiesOneEntry) |
643 | return MODRM_ONEENTRY; |
644 | |
645 | if (satisfiesSplitRM) |
646 | return MODRM_SPLITRM; |
647 | |
648 | if (satisfiesSplitReg && satisfiesSplitMisc) |
649 | return MODRM_SPLITREG; |
650 | |
651 | if (satisfiesSplitMisc) |
652 | return MODRM_SPLITMISC; |
653 | |
654 | return MODRM_FULL; |
655 | } |
656 | |
657 | /// stringForDecisionType - Returns a statically-allocated string corresponding |
658 | /// to a particular decision type. |
659 | /// |
660 | /// @param dt - The decision type. |
661 | /// @return - A pointer to the statically-allocated string (e.g., |
662 | /// "MODRM_ONEENTRY" for MODRM_ONEENTRY). |
663 | static const char *stringForDecisionType(ModRMDecisionType dt) { |
664 | #define ENUM_ENTRY(n) \ |
665 | case n: \ |
666 | return #n; |
667 | switch (dt) { |
668 | default: |
669 | llvm_unreachable("Unknown decision type" ); |
670 | MODRMTYPES |
671 | }; |
672 | #undef ENUM_ENTRY |
673 | } |
674 | |
675 | DisassemblerTables::DisassemblerTables() { |
676 | for (unsigned i = 0; i < std::size(Tables); i++) |
677 | Tables[i] = std::make_unique<ContextDecision>(); |
678 | |
679 | HasConflicts = false; |
680 | } |
681 | |
682 | DisassemblerTables::~DisassemblerTables() {} |
683 | |
684 | void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, |
685 | unsigned &i1, unsigned &i2, |
686 | unsigned &ModRMTableNum, |
687 | ModRMDecision &decision) const { |
688 | static uint32_t sEntryNumber = 1; |
689 | ModRMDecisionType dt = getDecisionType(decision); |
690 | |
691 | if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) { |
692 | // Empty table. |
693 | o2 << "{" << stringForDecisionType(dt) << ", 0}" ; |
694 | return; |
695 | } |
696 | |
697 | std::vector<unsigned> ModRMDecision; |
698 | |
699 | switch (dt) { |
700 | default: |
701 | llvm_unreachable("Unknown decision type" ); |
702 | case MODRM_ONEENTRY: |
703 | ModRMDecision.push_back(x: decision.instructionIDs[0]); |
704 | break; |
705 | case MODRM_SPLITRM: |
706 | ModRMDecision.push_back(x: decision.instructionIDs[0x00]); |
707 | ModRMDecision.push_back(x: decision.instructionIDs[0xc0]); |
708 | break; |
709 | case MODRM_SPLITREG: |
710 | for (unsigned index = 0; index < 64; index += 8) |
711 | ModRMDecision.push_back(x: decision.instructionIDs[index]); |
712 | for (unsigned index = 0xc0; index < 256; index += 8) |
713 | ModRMDecision.push_back(x: decision.instructionIDs[index]); |
714 | break; |
715 | case MODRM_SPLITMISC: |
716 | for (unsigned index = 0; index < 64; index += 8) |
717 | ModRMDecision.push_back(x: decision.instructionIDs[index]); |
718 | for (unsigned index = 0xc0; index < 256; ++index) |
719 | ModRMDecision.push_back(x: decision.instructionIDs[index]); |
720 | break; |
721 | case MODRM_FULL: |
722 | for (unsigned short InstructionID : decision.instructionIDs) |
723 | ModRMDecision.push_back(x: InstructionID); |
724 | break; |
725 | } |
726 | |
727 | unsigned &EntryNumber = ModRMTable[ModRMDecision]; |
728 | if (EntryNumber == 0) { |
729 | EntryNumber = ModRMTableNum; |
730 | |
731 | ModRMTableNum += ModRMDecision.size(); |
732 | o1 << "/*Table" << EntryNumber << "*/\n" ; |
733 | i1++; |
734 | for (unsigned I : ModRMDecision) { |
735 | o1.indent(NumSpaces: i1 * 2) << format(Fmt: "0x%hx" , Vals: I) << ", /*" |
736 | << InstructionSpecifiers[I].name << "*/\n" ; |
737 | } |
738 | i1--; |
739 | } |
740 | |
741 | o2 << "{" << stringForDecisionType(dt) << ", " << EntryNumber << "}" ; |
742 | |
743 | switch (dt) { |
744 | default: |
745 | llvm_unreachable("Unknown decision type" ); |
746 | case MODRM_ONEENTRY: |
747 | sEntryNumber += 1; |
748 | break; |
749 | case MODRM_SPLITRM: |
750 | sEntryNumber += 2; |
751 | break; |
752 | case MODRM_SPLITREG: |
753 | sEntryNumber += 16; |
754 | break; |
755 | case MODRM_SPLITMISC: |
756 | sEntryNumber += 8 + 64; |
757 | break; |
758 | case MODRM_FULL: |
759 | sEntryNumber += 256; |
760 | break; |
761 | } |
762 | |
763 | // We assume that the index can fit into uint16_t. |
764 | assert(sEntryNumber < 65536U && |
765 | "Index into ModRMDecision is too large for uint16_t!" ); |
766 | (void)sEntryNumber; |
767 | } |
768 | |
769 | void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, |
770 | unsigned &i1, unsigned &i2, |
771 | unsigned &ModRMTableNum, |
772 | OpcodeDecision &opDecision) const { |
773 | o2 << "{" ; |
774 | ++i2; |
775 | |
776 | unsigned index; |
777 | for (index = 0; index < 256; ++index) { |
778 | auto &decision = opDecision.modRMDecisions[index]; |
779 | ModRMDecisionType dt = getDecisionType(decision); |
780 | if (!(dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)) |
781 | break; |
782 | } |
783 | if (index == 256) { |
784 | // If all 256 entries are MODRM_ONEENTRY, omit output. |
785 | static_assert(MODRM_ONEENTRY == 0); |
786 | --i2; |
787 | o2 << "},\n" ; |
788 | } else { |
789 | o2 << " /* struct OpcodeDecision */ {\n" ; |
790 | for (index = 0; index < 256; ++index) { |
791 | o2.indent(NumSpaces: i2); |
792 | |
793 | o2 << "/*0x" << format(Fmt: "%02hhx" , Vals: index) << "*/" ; |
794 | |
795 | emitModRMDecision(o1, o2, i1, i2, ModRMTableNum, |
796 | decision&: opDecision.modRMDecisions[index]); |
797 | |
798 | if (index < 255) |
799 | o2 << "," ; |
800 | |
801 | o2 << "\n" ; |
802 | } |
803 | o2.indent(NumSpaces: i2) << "}\n" ; |
804 | --i2; |
805 | o2.indent(NumSpaces: i2) << "},\n" ; |
806 | } |
807 | } |
808 | |
809 | void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, |
810 | unsigned &i1, unsigned &i2, |
811 | unsigned &ModRMTableNum, |
812 | ContextDecision &decision, |
813 | const char *name) const { |
814 | o2.indent(NumSpaces: i2) << "static const struct ContextDecision " << name |
815 | << " = {{/* opcodeDecisions */\n" ; |
816 | i2++; |
817 | |
818 | for (unsigned index = 0; index < IC_max; ++index) { |
819 | o2.indent(NumSpaces: i2) << "/*" ; |
820 | o2 << stringForContext(insnContext: (InstructionContext)index); |
821 | o2 << "*/ " ; |
822 | |
823 | emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum, |
824 | opDecision&: decision.opcodeDecisions[index]); |
825 | } |
826 | |
827 | i2--; |
828 | o2.indent(NumSpaces: i2) << "}};" |
829 | << "\n" ; |
830 | } |
831 | |
832 | void DisassemblerTables::emitInstructionInfo(raw_ostream &o, |
833 | unsigned &i) const { |
834 | unsigned NumInstructions = InstructionSpecifiers.size(); |
835 | |
836 | o << "static const struct OperandSpecifier x86OperandSets[][" |
837 | << X86_MAX_OPERANDS << "] = {\n" ; |
838 | |
839 | typedef SmallVector<std::pair<OperandEncoding, OperandType>, X86_MAX_OPERANDS> |
840 | OperandListTy; |
841 | std::map<OperandListTy, unsigned> OperandSets; |
842 | |
843 | unsigned OperandSetNum = 0; |
844 | for (unsigned Index = 0; Index < NumInstructions; ++Index) { |
845 | OperandListTy OperandList; |
846 | |
847 | for (auto Operand : InstructionSpecifiers[Index].operands) { |
848 | OperandEncoding Encoding = (OperandEncoding)Operand.encoding; |
849 | OperandType Type = (OperandType)Operand.type; |
850 | OperandList.push_back(Elt: std::pair(Encoding, Type)); |
851 | } |
852 | unsigned &N = OperandSets[OperandList]; |
853 | if (N != 0) |
854 | continue; |
855 | |
856 | N = ++OperandSetNum; |
857 | |
858 | o << " { /* " << (OperandSetNum - 1) << " */\n" ; |
859 | for (unsigned i = 0, e = OperandList.size(); i != e; ++i) { |
860 | const char *Encoding = stringForOperandEncoding(encoding: OperandList[i].first); |
861 | const char *Type = stringForOperandType(type: OperandList[i].second); |
862 | o << " { " << Encoding << ", " << Type << " },\n" ; |
863 | } |
864 | o << " },\n" ; |
865 | } |
866 | o << "};" |
867 | << "\n\n" ; |
868 | |
869 | o.indent(NumSpaces: i * 2) << "static const struct InstructionSpecifier " ; |
870 | o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n" ; |
871 | |
872 | i++; |
873 | |
874 | for (unsigned index = 0; index < NumInstructions; ++index) { |
875 | o.indent(NumSpaces: i * 2) << "{ /* " << index << " */\n" ; |
876 | i++; |
877 | |
878 | OperandListTy OperandList; |
879 | for (auto Operand : InstructionSpecifiers[index].operands) { |
880 | OperandEncoding Encoding = (OperandEncoding)Operand.encoding; |
881 | OperandType Type = (OperandType)Operand.type; |
882 | OperandList.push_back(Elt: std::pair(Encoding, Type)); |
883 | } |
884 | o.indent(NumSpaces: i * 2) << (OperandSets[OperandList] - 1) << ",\n" ; |
885 | |
886 | o.indent(NumSpaces: i * 2) << "/* " << InstructionSpecifiers[index].name << " */\n" ; |
887 | |
888 | i--; |
889 | o.indent(NumSpaces: i * 2) << "},\n" ; |
890 | } |
891 | |
892 | i--; |
893 | o.indent(NumSpaces: i * 2) << "};" |
894 | << "\n" ; |
895 | } |
896 | |
897 | void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const { |
898 | o.indent(NumSpaces: i * 2) << "static const uint8_t " CONTEXTS_STR "[" << ATTR_max |
899 | << "] = {\n" ; |
900 | i++; |
901 | |
902 | for (unsigned index = 0; index < ATTR_max; ++index) { |
903 | o.indent(NumSpaces: i * 2); |
904 | |
905 | if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_OPSIZE)) |
906 | o << "IC_EVEX_OPSIZE_ADSIZE" ; |
907 | else if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_XD)) |
908 | o << "IC_EVEX_XD_ADSIZE" ; |
909 | else if ((index & ATTR_EVEX) && (index & ATTR_ADSIZE) && (index & ATTR_XS)) |
910 | o << "IC_EVEX_XS_ADSIZE" ; |
911 | else if (index & ATTR_EVEXNF) { |
912 | o << "IC_EVEX" ; |
913 | if (index & ATTR_REXW) |
914 | o << "_W" ; |
915 | else if (index & ATTR_OPSIZE) |
916 | o << "_OPSIZE" ; |
917 | |
918 | if (index & ATTR_EVEXB) |
919 | o << "_B" ; |
920 | |
921 | o << "_NF" ; |
922 | } else if ((index & ATTR_EVEX) || (index & ATTR_VEX) || |
923 | (index & ATTR_VEXL)) { |
924 | if (index & ATTR_EVEX) |
925 | o << "IC_EVEX" ; |
926 | else |
927 | o << "IC_VEX" ; |
928 | |
929 | if ((index & ATTR_EVEX) && (index & ATTR_EVEXL2)) |
930 | o << "_L2" ; |
931 | else if (index & ATTR_VEXL) |
932 | o << "_L" ; |
933 | |
934 | if (index & ATTR_REXW) |
935 | o << "_W" ; |
936 | |
937 | if (index & ATTR_OPSIZE) |
938 | o << "_OPSIZE" ; |
939 | else if (index & ATTR_XD) |
940 | o << "_XD" ; |
941 | else if (index & ATTR_XS) |
942 | o << "_XS" ; |
943 | |
944 | if (index & ATTR_EVEX) { |
945 | if (index & ATTR_EVEXKZ) |
946 | o << "_KZ" ; |
947 | else if (index & ATTR_EVEXK) |
948 | o << "_K" ; |
949 | |
950 | if (index & ATTR_EVEXB) |
951 | o << "_B" ; |
952 | } |
953 | } else if ((index & ATTR_64BIT) && (index & ATTR_REX2)) |
954 | o << "IC_64BIT_REX2" ; |
955 | else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) |
956 | o << "IC_64BIT_REXW_XS" ; |
957 | else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) |
958 | o << "IC_64BIT_REXW_XD" ; |
959 | else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && |
960 | (index & ATTR_OPSIZE)) |
961 | o << "IC_64BIT_REXW_OPSIZE" ; |
962 | else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && |
963 | (index & ATTR_ADSIZE)) |
964 | o << "IC_64BIT_REXW_ADSIZE" ; |
965 | else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE)) |
966 | o << "IC_64BIT_XD_OPSIZE" ; |
967 | else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_ADSIZE)) |
968 | o << "IC_64BIT_XD_ADSIZE" ; |
969 | else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE)) |
970 | o << "IC_64BIT_XS_OPSIZE" ; |
971 | else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_ADSIZE)) |
972 | o << "IC_64BIT_XS_ADSIZE" ; |
973 | else if ((index & ATTR_64BIT) && (index & ATTR_XS)) |
974 | o << "IC_64BIT_XS" ; |
975 | else if ((index & ATTR_64BIT) && (index & ATTR_XD)) |
976 | o << "IC_64BIT_XD" ; |
977 | else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE) && |
978 | (index & ATTR_ADSIZE)) |
979 | o << "IC_64BIT_OPSIZE_ADSIZE" ; |
980 | else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE)) |
981 | o << "IC_64BIT_OPSIZE" ; |
982 | else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE)) |
983 | o << "IC_64BIT_ADSIZE" ; |
984 | else if ((index & ATTR_64BIT) && (index & ATTR_REXW)) |
985 | o << "IC_64BIT_REXW" ; |
986 | else if ((index & ATTR_64BIT)) |
987 | o << "IC_64BIT" ; |
988 | else if ((index & ATTR_XS) && (index & ATTR_OPSIZE)) |
989 | o << "IC_XS_OPSIZE" ; |
990 | else if ((index & ATTR_XD) && (index & ATTR_OPSIZE)) |
991 | o << "IC_XD_OPSIZE" ; |
992 | else if ((index & ATTR_XS) && (index & ATTR_ADSIZE)) |
993 | o << "IC_XS_ADSIZE" ; |
994 | else if ((index & ATTR_XD) && (index & ATTR_ADSIZE)) |
995 | o << "IC_XD_ADSIZE" ; |
996 | else if (index & ATTR_XS) |
997 | o << "IC_XS" ; |
998 | else if (index & ATTR_XD) |
999 | o << "IC_XD" ; |
1000 | else if ((index & ATTR_OPSIZE) && (index & ATTR_ADSIZE)) |
1001 | o << "IC_OPSIZE_ADSIZE" ; |
1002 | else if (index & ATTR_OPSIZE) |
1003 | o << "IC_OPSIZE" ; |
1004 | else if (index & ATTR_ADSIZE) |
1005 | o << "IC_ADSIZE" ; |
1006 | else |
1007 | o << "IC" ; |
1008 | |
1009 | o << ", // " << index << "\n" ; |
1010 | } |
1011 | |
1012 | i--; |
1013 | o.indent(NumSpaces: i * 2) << "};" |
1014 | << "\n" ; |
1015 | } |
1016 | |
1017 | void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2, |
1018 | unsigned &i1, unsigned &i2, |
1019 | unsigned &ModRMTableNum) const { |
1020 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[0], ONEBYTE_STR); |
1021 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[1], TWOBYTE_STR); |
1022 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[2], |
1023 | THREEBYTE38_STR); |
1024 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[3], |
1025 | THREEBYTE3A_STR); |
1026 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[4], XOP8_MAP_STR); |
1027 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[5], XOP9_MAP_STR); |
1028 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[6], XOPA_MAP_STR); |
1029 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[7], |
1030 | THREEDNOW_MAP_STR); |
1031 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[8], MAP4_STR); |
1032 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[9], MAP5_STR); |
1033 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[10], MAP6_STR); |
1034 | emitContextDecision(o1, o2, i1, i2, ModRMTableNum, decision&: *Tables[11], MAP7_STR); |
1035 | } |
1036 | |
1037 | void DisassemblerTables::emit(raw_ostream &o) const { |
1038 | unsigned i1 = 0; |
1039 | unsigned i2 = 0; |
1040 | |
1041 | std::string s1; |
1042 | std::string s2; |
1043 | |
1044 | raw_string_ostream o1(s1); |
1045 | raw_string_ostream o2(s2); |
1046 | |
1047 | emitInstructionInfo(o, i&: i2); |
1048 | o << "\n" ; |
1049 | |
1050 | emitContextTable(o, i&: i2); |
1051 | o << "\n" ; |
1052 | |
1053 | unsigned ModRMTableNum = 0; |
1054 | |
1055 | o << "static const InstrUID modRMTable[] = {\n" ; |
1056 | i1++; |
1057 | std::vector<unsigned> EmptyTable(1, 0); |
1058 | ModRMTable[EmptyTable] = ModRMTableNum; |
1059 | ModRMTableNum += EmptyTable.size(); |
1060 | o1 << "/*EmptyTable*/\n" ; |
1061 | o1.indent(NumSpaces: i1 * 2) << "0x0,\n" ; |
1062 | i1--; |
1063 | emitContextDecisions(o1, o2, i1, i2, ModRMTableNum); |
1064 | |
1065 | o << s1; |
1066 | o << " 0x0\n" ; |
1067 | o << "};\n" ; |
1068 | o << "\n" ; |
1069 | o << s2; |
1070 | o << "\n" ; |
1071 | o << "\n" ; |
1072 | } |
1073 | |
1074 | void DisassemblerTables::setTableFields(ModRMDecision &decision, |
1075 | const ModRMFilter &filter, InstrUID uid, |
1076 | uint8_t opcode) { |
1077 | for (unsigned index = 0; index < 256; ++index) { |
1078 | if (filter.accepts(modRM: index)) { |
1079 | if (decision.instructionIDs[index] == uid) |
1080 | continue; |
1081 | |
1082 | if (decision.instructionIDs[index] != 0) { |
1083 | InstructionSpecifier &newInfo = InstructionSpecifiers[uid]; |
1084 | InstructionSpecifier &previousInfo = |
1085 | InstructionSpecifiers[decision.instructionIDs[index]]; |
1086 | |
1087 | if (previousInfo.name == "NOOP" && |
1088 | (newInfo.name == "XCHG16ar" || newInfo.name == "XCHG32ar" || |
1089 | newInfo.name == "XCHG64ar" )) |
1090 | continue; // special case for XCHG*ar and NOOP |
1091 | |
1092 | if (outranks(upper: previousInfo.insnContext, lower: newInfo.insnContext)) |
1093 | continue; |
1094 | |
1095 | if (previousInfo.insnContext == newInfo.insnContext) { |
1096 | errs() << "Error: Primary decode conflict: " ; |
1097 | errs() << newInfo.name << " would overwrite " << previousInfo.name; |
1098 | errs() << "\n" ; |
1099 | errs() << "ModRM " << index << "\n" ; |
1100 | errs() << "Opcode " << (uint16_t)opcode << "\n" ; |
1101 | errs() << "Context " << stringForContext(insnContext: newInfo.insnContext) << "\n" ; |
1102 | HasConflicts = true; |
1103 | } |
1104 | } |
1105 | |
1106 | decision.instructionIDs[index] = uid; |
1107 | } |
1108 | } |
1109 | } |
1110 | |
1111 | void DisassemblerTables::setTableFields( |
1112 | OpcodeType type, InstructionContext insnContext, uint8_t opcode, |
1113 | const ModRMFilter &filter, InstrUID uid, bool is32bit, bool noPrefix, |
1114 | bool ignoresVEX_L, bool ignoresW, unsigned addressSize) { |
1115 | ContextDecision &decision = *Tables[type]; |
1116 | |
1117 | for (unsigned index = 0; index < IC_max; ++index) { |
1118 | if ((is32bit || addressSize == 16) && |
1119 | inheritsFrom(child: (InstructionContext)index, parent: IC_64BIT)) |
1120 | continue; |
1121 | |
1122 | bool adSize64 = addressSize == 64; |
1123 | if (inheritsFrom(child: (InstructionContext)index, |
1124 | parent: InstructionSpecifiers[uid].insnContext, noPrefix, |
1125 | VEX_LIG: ignoresVEX_L, WIG: ignoresW, AdSize64: adSize64)) |
1126 | setTableFields(decision&: decision.opcodeDecisions[index].modRMDecisions[opcode], |
1127 | filter, uid, opcode); |
1128 | } |
1129 | } |
1130 | |