blob: 2b5cc127960595bd7edce31ed71be36327f95718 [file] [log] [blame]
Sean Callanan8ed9f512009-12-19 02:59:52 +00001//===- X86DisassemblerTables.cpp - Disassembler tables ----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is part of the X86 Disassembler Emitter.
11// It contains the implementation of the disassembler tables.
12// Documentation for the disassembler emitter in general can be found in
Hiroshi Inoueb08063c2017-07-04 13:09:29 +000013// X86DisassemblerEmitter.h.
Sean Callanan8ed9f512009-12-19 02:59:52 +000014//
15//===----------------------------------------------------------------------===//
16
Sean Callanan8ed9f512009-12-19 02:59:52 +000017#include "X86DisassemblerTables.h"
Chandler Carruth4ffd89f2012-12-04 10:37:14 +000018#include "X86DisassemblerShared.h"
Joerg Sonnenberger39d7cae2011-04-04 16:25:38 +000019#include "llvm/ADT/STLExtras.h"
Sean Callanan8ed9f512009-12-19 02:59:52 +000020#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/Format.h"
Craig Topper5a2c6072012-08-01 07:39:18 +000022#include <map>
Sean Callanan8ed9f512009-12-19 02:59:52 +000023
Sean Callanan8ed9f512009-12-19 02:59:52 +000024using namespace llvm;
25using namespace X86Disassembler;
Craig Topper98400092012-07-31 05:27:01 +000026
Elena Demikhovsky3062a312014-01-01 15:12:34 +000027/// stringForContext - Returns a string containing the name of a particular
28/// InstructionContext, usually for diagnostic purposes.
29///
30/// @param insnContext - The instruction class to transform to a string.
31/// @return - A statically-allocated string constant that contains the
32/// name of the instruction class.
33static inline const char* stringForContext(InstructionContext insnContext) {
34 switch (insnContext) {
35 default:
36 llvm_unreachable("Unhandled instruction class");
37#define ENUM_ENTRY(n, r, d) case n: return #n; break;
38#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) ENUM_ENTRY(n##_K_B, r, d)\
39 ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d)\
40 ENUM_ENTRY(n##_KZ_B, r, d)
41 INSTRUCTION_CONTEXTS
42#undef ENUM_ENTRY
43#undef ENUM_ENTRY_K_B
44 }
45}
46
47/// stringForOperandType - Like stringForContext, but for OperandTypes.
48static inline const char* stringForOperandType(OperandType type) {
49 switch (type) {
50 default:
51 llvm_unreachable("Unhandled type");
52#define ENUM_ENTRY(i, d) case i: return #i;
53 TYPES
54#undef ENUM_ENTRY
55 }
56}
57
58/// stringForOperandEncoding - like stringForContext, but for
59/// OperandEncodings.
60static inline const char* stringForOperandEncoding(OperandEncoding encoding) {
61 switch (encoding) {
62 default:
63 llvm_unreachable("Unhandled encoding");
64#define ENUM_ENTRY(i, d) case i: return #i;
65 ENCODINGS
66#undef ENUM_ENTRY
67 }
68}
69
Sean Callanan8ed9f512009-12-19 02:59:52 +000070/// inheritsFrom - Indicates whether all instructions in one class also belong
71/// to another class.
72///
73/// @param child - The class that may be the subset
74/// @param parent - The class that may be the superset
75/// @return - True if child is a subset of parent, false otherwise.
76static inline bool inheritsFrom(InstructionContext child,
Craig Topper8c2358a2017-10-23 16:49:26 +000077 InstructionContext parent, bool noPrefix = true,
Craig Topper3ae8f2d2017-10-22 06:18:26 +000078 bool VEX_LIG = false, bool VEX_WIG = false,
79 bool AdSize64 = false) {
Sean Callanan8ed9f512009-12-19 02:59:52 +000080 if (child == parent)
81 return true;
Craig Topper98400092012-07-31 05:27:01 +000082
Sean Callanan8ed9f512009-12-19 02:59:52 +000083 switch (parent) {
84 case IC:
Craig Topper71fc42d2015-01-02 07:02:25 +000085 return(inheritsFrom(child, IC_64BIT, AdSize64) ||
Craig Topper8c2358a2017-10-23 16:49:26 +000086 (noPrefix && inheritsFrom(child, IC_OPSIZE, noPrefix)) ||
Craig Topper930a1eb2012-02-27 01:54:29 +000087 inheritsFrom(child, IC_ADSIZE) ||
Craig Topper8c2358a2017-10-23 16:49:26 +000088 (noPrefix && inheritsFrom(child, IC_XD, noPrefix)) ||
89 (noPrefix && inheritsFrom(child, IC_XS, noPrefix)));
Sean Callanan8ed9f512009-12-19 02:59:52 +000090 case IC_64BIT:
91 return(inheritsFrom(child, IC_64BIT_REXW) ||
Craig Topper8c2358a2017-10-23 16:49:26 +000092 (noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE, noPrefix)) ||
Craig Topper71fc42d2015-01-02 07:02:25 +000093 (!AdSize64 && inheritsFrom(child, IC_64BIT_ADSIZE)) ||
Craig Topper8c2358a2017-10-23 16:49:26 +000094 (noPrefix && inheritsFrom(child, IC_64BIT_XD, noPrefix)) ||
95 (noPrefix && inheritsFrom(child, IC_64BIT_XS, noPrefix)));
Sean Callanan8ed9f512009-12-19 02:59:52 +000096 case IC_OPSIZE:
Craig Topper51f423f2014-12-31 07:07:31 +000097 return inheritsFrom(child, IC_64BIT_OPSIZE) ||
98 inheritsFrom(child, IC_OPSIZE_ADSIZE);
Craig Topper930a1eb2012-02-27 01:54:29 +000099 case IC_ADSIZE:
Craig Topper8c2358a2017-10-23 16:49:26 +0000100 return (noPrefix && inheritsFrom(child, IC_OPSIZE_ADSIZE, noPrefix));
Craig Topper51f423f2014-12-31 07:07:31 +0000101 case IC_OPSIZE_ADSIZE:
102 return false;
Craig Topper930a1eb2012-02-27 01:54:29 +0000103 case IC_64BIT_ADSIZE:
Craig Topper8c2358a2017-10-23 16:49:26 +0000104 return (noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE, noPrefix));
Craig Topper51f423f2014-12-31 07:07:31 +0000105 case IC_64BIT_OPSIZE_ADSIZE:
Craig Topper930a1eb2012-02-27 01:54:29 +0000106 return false;
Sean Callanan8ed9f512009-12-19 02:59:52 +0000107 case IC_XD:
Craig Topper5ffedb92011-09-02 04:17:54 +0000108 return inheritsFrom(child, IC_64BIT_XD);
Sean Callanan8ed9f512009-12-19 02:59:52 +0000109 case IC_XS:
Craig Topper5ffedb92011-09-02 04:17:54 +0000110 return inheritsFrom(child, IC_64BIT_XS);
Craig Toppere1b4a1a2011-10-01 19:54:56 +0000111 case IC_XD_OPSIZE:
112 return inheritsFrom(child, IC_64BIT_XD_OPSIZE);
Craig Topper29480fd2011-10-11 04:34:23 +0000113 case IC_XS_OPSIZE:
114 return inheritsFrom(child, IC_64BIT_XS_OPSIZE);
Craig Topperb3ec9a12018-04-05 18:20:14 +0000115 case IC_XD_ADSIZE:
116 return inheritsFrom(child, IC_64BIT_XD_ADSIZE);
117 case IC_XS_ADSIZE:
118 return inheritsFrom(child, IC_64BIT_XS_ADSIZE);
Sean Callanan8ed9f512009-12-19 02:59:52 +0000119 case IC_64BIT_REXW:
Craig Topper8c2358a2017-10-23 16:49:26 +0000120 return((noPrefix && inheritsFrom(child, IC_64BIT_REXW_XS, noPrefix)) ||
121 (noPrefix && inheritsFrom(child, IC_64BIT_REXW_XD, noPrefix)) ||
122 (noPrefix && inheritsFrom(child, IC_64BIT_REXW_OPSIZE, noPrefix)) ||
Craig Topper01c99892015-01-03 00:00:20 +0000123 (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE)));
Sean Callanan8ed9f512009-12-19 02:59:52 +0000124 case IC_64BIT_OPSIZE:
Craig Topper51f423f2014-12-31 07:07:31 +0000125 return inheritsFrom(child, IC_64BIT_REXW_OPSIZE) ||
Craig Topper01c99892015-01-03 00:00:20 +0000126 (!AdSize64 && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE)) ||
127 (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE));
Sean Callanan8ed9f512009-12-19 02:59:52 +0000128 case IC_64BIT_XD:
Craig Topperb3ec9a12018-04-05 18:20:14 +0000129 return(inheritsFrom(child, IC_64BIT_REXW_XD) ||
130 (!AdSize64 && inheritsFrom(child, IC_64BIT_XD_ADSIZE)));
Sean Callanan8ed9f512009-12-19 02:59:52 +0000131 case IC_64BIT_XS:
Craig Topperb3ec9a12018-04-05 18:20:14 +0000132 return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
133 (!AdSize64 && inheritsFrom(child, IC_64BIT_XS_ADSIZE)));
Craig Toppere1b4a1a2011-10-01 19:54:56 +0000134 case IC_64BIT_XD_OPSIZE:
Craig Topper29480fd2011-10-11 04:34:23 +0000135 case IC_64BIT_XS_OPSIZE:
Craig Toppere1b4a1a2011-10-01 19:54:56 +0000136 return false;
Craig Topperb3ec9a12018-04-05 18:20:14 +0000137 case IC_64BIT_XD_ADSIZE:
138 case IC_64BIT_XS_ADSIZE:
139 return false;
Sean Callanan8ed9f512009-12-19 02:59:52 +0000140 case IC_64BIT_REXW_XD:
Sean Callanan8ed9f512009-12-19 02:59:52 +0000141 case IC_64BIT_REXW_XS:
Sean Callanan8ed9f512009-12-19 02:59:52 +0000142 case IC_64BIT_REXW_OPSIZE:
Craig Topper01c99892015-01-03 00:00:20 +0000143 case IC_64BIT_REXW_ADSIZE:
Sean Callanan8ed9f512009-12-19 02:59:52 +0000144 return false;
Sean Callanana21e2ea2011-03-15 01:23:15 +0000145 case IC_VEX:
Craig Topper3ae8f2d2017-10-22 06:18:26 +0000146 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W)) ||
147 (VEX_WIG && inheritsFrom(child, IC_VEX_W)) ||
Craig Topper6744a172011-10-04 06:30:42 +0000148 (VEX_LIG && inheritsFrom(child, IC_VEX_L));
Sean Callanana21e2ea2011-03-15 01:23:15 +0000149 case IC_VEX_XS:
Craig Topper3ae8f2d2017-10-22 06:18:26 +0000150 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XS)) ||
151 (VEX_WIG && inheritsFrom(child, IC_VEX_W_XS)) ||
Craig Topper6744a172011-10-04 06:30:42 +0000152 (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS));
Sean Callanana21e2ea2011-03-15 01:23:15 +0000153 case IC_VEX_XD:
Craig Topper3ae8f2d2017-10-22 06:18:26 +0000154 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XD)) ||
155 (VEX_WIG && inheritsFrom(child, IC_VEX_W_XD)) ||
Craig Topper6744a172011-10-04 06:30:42 +0000156 (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD));
Craig Topper5ffedb92011-09-02 04:17:54 +0000157 case IC_VEX_OPSIZE:
Craig Topper3ae8f2d2017-10-22 06:18:26 +0000158 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) ||
159 (VEX_WIG && inheritsFrom(child, IC_VEX_W_OPSIZE)) ||
Craig Topper6744a172011-10-04 06:30:42 +0000160 (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE));
Sean Callanana21e2ea2011-03-15 01:23:15 +0000161 case IC_VEX_W:
Craig Topper92b45812013-09-30 02:46:36 +0000162 return VEX_LIG && inheritsFrom(child, IC_VEX_L_W);
Sean Callanana21e2ea2011-03-15 01:23:15 +0000163 case IC_VEX_W_XS:
Craig Topper92b45812013-09-30 02:46:36 +0000164 return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS);
Sean Callanana21e2ea2011-03-15 01:23:15 +0000165 case IC_VEX_W_XD:
Craig Topper92b45812013-09-30 02:46:36 +0000166 return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD);
Craig Topper5ffedb92011-09-02 04:17:54 +0000167 case IC_VEX_W_OPSIZE:
Craig Topper92b45812013-09-30 02:46:36 +0000168 return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);
Craig Topper5ffedb92011-09-02 04:17:54 +0000169 case IC_VEX_L:
Craig Topper3ae8f2d2017-10-22 06:18:26 +0000170 return VEX_WIG && inheritsFrom(child, IC_VEX_L_W);
Craig Topper5ffedb92011-09-02 04:17:54 +0000171 case IC_VEX_L_XS:
Craig Topper3ae8f2d2017-10-22 06:18:26 +0000172 return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XS);
Craig Topper5ffedb92011-09-02 04:17:54 +0000173 case IC_VEX_L_XD:
Craig Topper3ae8f2d2017-10-22 06:18:26 +0000174 return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XD);
Craig Topper5ffedb92011-09-02 04:17:54 +0000175 case IC_VEX_L_OPSIZE:
Craig Topper3ae8f2d2017-10-22 06:18:26 +0000176 return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000177 case IC_VEX_L_W:
178 case IC_VEX_L_W_XS:
179 case IC_VEX_L_W_XD:
Craig Topperc8eb8802011-11-06 23:04:08 +0000180 case IC_VEX_L_W_OPSIZE:
Craig Topper5ffedb92011-09-02 04:17:54 +0000181 return false;
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000182 case IC_EVEX:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000183 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W)) ||
184 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W)) ||
185 (VEX_WIG && inheritsFrom(child, IC_EVEX_W)) ||
186 (VEX_LIG && inheritsFrom(child, IC_EVEX_L)) ||
187 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2));
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000188 case IC_EVEX_XS:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000189 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS)) ||
190 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS)) ||
191 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS)) ||
192 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS)) ||
193 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS));
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000194 case IC_EVEX_XD:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000195 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD)) ||
196 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD)) ||
197 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD)) ||
198 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD)) ||
199 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD));
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000200 case IC_EVEX_OPSIZE:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000201 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE)) ||
202 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE)) ||
203 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE)) ||
204 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE)) ||
205 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE));
206 case IC_EVEX_K:
207 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K)) ||
208 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K)) ||
209 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_K)) ||
210 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_K)) ||
211 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K));
212 case IC_EVEX_XS_K:
213 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K)) ||
214 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K)) ||
215 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_K)) ||
216 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K)) ||
217 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K));
218 case IC_EVEX_XD_K:
219 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K)) ||
220 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K)) ||
221 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_K)) ||
222 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K)) ||
223 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K));
224 case IC_EVEX_OPSIZE_K:
225 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K)) ||
226 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K)) ||
227 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K)) ||
228 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K)) ||
229 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K));
230 case IC_EVEX_KZ:
231 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ)) ||
232 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ)) ||
233 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_KZ)) ||
234 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ)) ||
235 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ));
236 case IC_EVEX_XS_KZ:
237 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ)) ||
238 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ)) ||
239 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ)) ||
240 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ)) ||
241 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ));
242 case IC_EVEX_XD_KZ:
243 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ)) ||
244 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ)) ||
245 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ)) ||
246 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ)) ||
247 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ));
248 case IC_EVEX_OPSIZE_KZ:
249 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ)) ||
250 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ)) ||
251 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ)) ||
252 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ)) ||
253 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ));
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000254 case IC_EVEX_W:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000255 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W)) ||
256 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W));
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000257 case IC_EVEX_W_XS:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000258 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS)) ||
259 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS));
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000260 case IC_EVEX_W_XD:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000261 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD)) ||
262 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD));
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000263 case IC_EVEX_W_OPSIZE:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000264 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE)) ||
265 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE));
266 case IC_EVEX_W_K:
267 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K)) ||
268 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K));
269 case IC_EVEX_W_XS_K:
270 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K)) ||
271 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K));
272 case IC_EVEX_W_XD_K:
273 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K)) ||
274 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K));
275 case IC_EVEX_W_OPSIZE_K:
276 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K)) ||
277 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K));
278 case IC_EVEX_W_KZ:
279 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ)) ||
280 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ));
281 case IC_EVEX_W_XS_KZ:
282 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ)) ||
283 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ));
284 case IC_EVEX_W_XD_KZ:
285 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ)) ||
286 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ));
287 case IC_EVEX_W_OPSIZE_KZ:
288 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ)) ||
289 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ));
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000290 case IC_EVEX_L:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000291 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W);
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000292 case IC_EVEX_L_XS:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000293 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS);
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000294 case IC_EVEX_L_XD:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000295 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD);
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000296 case IC_EVEX_L_OPSIZE:
Craig Topper3dbdbd22017-10-22 17:22:29 +0000297 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE);
298 case IC_EVEX_L_K:
299 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K);
300 case IC_EVEX_L_XS_K:
301 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K);
302 case IC_EVEX_L_XD_K:
303 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K);
304 case IC_EVEX_L_OPSIZE_K:
305 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K);
306 case IC_EVEX_L_KZ:
307 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ);
308 case IC_EVEX_L_XS_KZ:
309 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ);
310 case IC_EVEX_L_XD_KZ:
311 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ);
312 case IC_EVEX_L_OPSIZE_KZ:
313 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ);
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000314 case IC_EVEX_L_W:
315 case IC_EVEX_L_W_XS:
316 case IC_EVEX_L_W_XD:
317 case IC_EVEX_L_W_OPSIZE:
318 return false;
Craig Topper3dbdbd22017-10-22 17:22:29 +0000319 case IC_EVEX_L_W_K:
320 case IC_EVEX_L_W_XS_K:
321 case IC_EVEX_L_W_XD_K:
322 case IC_EVEX_L_W_OPSIZE_K:
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000323 return false;
Craig Topper3dbdbd22017-10-22 17:22:29 +0000324 case IC_EVEX_L_W_KZ:
325 case IC_EVEX_L_W_XS_KZ:
326 case IC_EVEX_L_W_XD_KZ:
327 case IC_EVEX_L_W_OPSIZE_KZ:
328 return false;
329 case IC_EVEX_L2:
330 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W);
331 case IC_EVEX_L2_XS:
332 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS);
333 case IC_EVEX_L2_XD:
334 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD);
335 case IC_EVEX_L2_OPSIZE:
336 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE);
337 case IC_EVEX_L2_K:
338 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K);
339 case IC_EVEX_L2_XS_K:
340 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K);
341 case IC_EVEX_L2_XD_K:
342 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K);
343 case IC_EVEX_L2_OPSIZE_K:
344 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K);
345 case IC_EVEX_L2_KZ:
346 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ);
347 case IC_EVEX_L2_XS_KZ:
348 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ);
349 case IC_EVEX_L2_XD_KZ:
350 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ);
351 case IC_EVEX_L2_OPSIZE_KZ:
352 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ);
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000353 case IC_EVEX_L2_W:
354 case IC_EVEX_L2_W_XS:
355 case IC_EVEX_L2_W_XD:
356 case IC_EVEX_L2_W_OPSIZE:
357 return false;
Craig Topper3dbdbd22017-10-22 17:22:29 +0000358 case IC_EVEX_L2_W_K:
359 case IC_EVEX_L2_W_XS_K:
360 case IC_EVEX_L2_W_XD_K:
361 case IC_EVEX_L2_W_OPSIZE_K:
362 return false;
363 case IC_EVEX_L2_W_KZ:
364 case IC_EVEX_L2_W_XS_KZ:
365 case IC_EVEX_L2_W_XD_KZ:
366 case IC_EVEX_L2_W_OPSIZE_KZ:
367 return false;
368 case IC_EVEX_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000369 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_B)) ||
370 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_B)) ||
371 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_B)) ||
372 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_B)) ||
373 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_B));
Elena Demikhovsky975e9b92015-03-01 07:44:04 +0000374 case IC_EVEX_XS_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000375 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) ||
376 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B)) ||
377 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_B)) ||
378 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_B)) ||
379 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_B));
Elena Demikhovsky975e9b92015-03-01 07:44:04 +0000380 case IC_EVEX_XD_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000381 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) ||
382 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B)) ||
383 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_B)) ||
384 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_B)) ||
385 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_B));
Elena Demikhovsky1f044d42014-01-13 12:55:03 +0000386 case IC_EVEX_OPSIZE_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000387 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) ||
388 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B)) ||
389 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_B)) ||
390 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_B)) ||
391 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_B));
392 case IC_EVEX_K_B:
393 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) ||
394 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B)) ||
395 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_K_B)) ||
396 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_K_B)) ||
397 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K_B));
398 case IC_EVEX_XS_K_B:
399 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) ||
400 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B)) ||
401 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_K_B)) ||
402 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K_B)) ||
403 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K_B));
404 case IC_EVEX_XD_K_B:
405 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) ||
406 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B)) ||
407 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_K_B)) ||
408 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K_B)) ||
409 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K_B));
Robert Khasanovcc4b1232014-08-25 14:49:34 +0000410 case IC_EVEX_OPSIZE_K_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000411 return (VEX_LIG && VEX_WIG &&
412 inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) ||
413 (VEX_LIG && VEX_WIG &&
414 inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B)) ||
415 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K_B)) ||
416 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K_B)) ||
417 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K_B));
418 case IC_EVEX_KZ_B:
419 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) ||
420 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B)) ||
421 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_KZ_B)) ||
422 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ_B)) ||
423 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ_B));
424 case IC_EVEX_XS_KZ_B:
425 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) ||
426 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B)) ||
427 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ_B)) ||
428 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ_B)) ||
429 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ_B));
430 case IC_EVEX_XD_KZ_B:
431 return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) ||
432 (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B)) ||
433 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ_B)) ||
434 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ_B)) ||
435 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ_B));
Robert Khasanov340b5b92014-10-09 08:38:48 +0000436 case IC_EVEX_OPSIZE_KZ_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000437 return (VEX_LIG && VEX_WIG &&
438 inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) ||
439 (VEX_LIG && VEX_WIG &&
440 inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B)) ||
441 (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ_B)) ||
442 (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ_B)) ||
443 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ_B));
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000444 case IC_EVEX_W_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000445 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_B)) ||
446 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_B));
Elena Demikhovsky975e9b92015-03-01 07:44:04 +0000447 case IC_EVEX_W_XS_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000448 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) ||
449 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B));
Elena Demikhovsky975e9b92015-03-01 07:44:04 +0000450 case IC_EVEX_W_XD_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000451 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) ||
452 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B));
453 case IC_EVEX_W_OPSIZE_B:
454 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) ||
455 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B));
456 case IC_EVEX_W_K_B:
457 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) ||
458 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K_B));
Elena Demikhovsky975e9b92015-03-01 07:44:04 +0000459 case IC_EVEX_W_XS_K_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000460 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) ||
461 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B));
Elena Demikhovsky975e9b92015-03-01 07:44:04 +0000462 case IC_EVEX_W_XD_K_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000463 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) ||
464 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B));
465 case IC_EVEX_W_OPSIZE_K_B:
466 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) ||
467 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B));
468 case IC_EVEX_W_KZ_B:
469 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) ||
470 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B));
Elena Demikhovsky975e9b92015-03-01 07:44:04 +0000471 case IC_EVEX_W_XS_KZ_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000472 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) ||
473 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B));
Elena Demikhovsky975e9b92015-03-01 07:44:04 +0000474 case IC_EVEX_W_XD_KZ_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000475 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) ||
476 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B));
Robert Khasanov340b5b92014-10-09 08:38:48 +0000477 case IC_EVEX_W_OPSIZE_KZ_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000478 return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) ||
479 (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B));
480 case IC_EVEX_L_B:
481 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_B);
Elena Demikhovsky695922d2015-04-21 13:13:46 +0000482 case IC_EVEX_L_XS_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000483 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B);
484 case IC_EVEX_L_XD_B:
485 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B);
486 case IC_EVEX_L_OPSIZE_B:
487 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B);
488 case IC_EVEX_L_K_B:
489 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K_B);
Elena Demikhovsky695922d2015-04-21 13:13:46 +0000490 case IC_EVEX_L_XS_K_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000491 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B);
492 case IC_EVEX_L_XD_K_B:
493 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B);
494 case IC_EVEX_L_OPSIZE_K_B:
495 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B);
496 case IC_EVEX_L_KZ_B:
497 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B);
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000498 case IC_EVEX_L_XS_KZ_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000499 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B);
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000500 case IC_EVEX_L_XD_KZ_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000501 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B);
Robert Khasanov340b5b92014-10-09 08:38:48 +0000502 case IC_EVEX_L_OPSIZE_KZ_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000503 return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B);
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000504 case IC_EVEX_L_W_B:
Elena Demikhovsky695922d2015-04-21 13:13:46 +0000505 case IC_EVEX_L_W_XS_B:
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000506 case IC_EVEX_L_W_XD_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000507 case IC_EVEX_L_W_OPSIZE_B:
508 return false;
509 case IC_EVEX_L_W_K_B:
510 case IC_EVEX_L_W_XS_K_B:
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000511 case IC_EVEX_L_W_XD_K_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000512 case IC_EVEX_L_W_OPSIZE_K_B:
513 return false;
514 case IC_EVEX_L_W_KZ_B:
515 case IC_EVEX_L_W_XS_KZ_B:
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000516 case IC_EVEX_L_W_XD_KZ_B:
Robert Khasanov340b5b92014-10-09 08:38:48 +0000517 case IC_EVEX_L_W_OPSIZE_KZ_B:
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000518 return false;
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000519 case IC_EVEX_L2_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000520 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_B);
Elena Demikhovsky3062a312014-01-01 15:12:34 +0000521 case IC_EVEX_L2_XS_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000522 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B);
Elena Demikhovsky3062a312014-01-01 15:12:34 +0000523 case IC_EVEX_L2_XD_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000524 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B);
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000525 case IC_EVEX_L2_OPSIZE_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000526 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B);
527 case IC_EVEX_L2_K_B:
528 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B);
529 case IC_EVEX_L2_XS_K_B:
530 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B);
531 case IC_EVEX_L2_XD_K_B:
532 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B);
Elena Demikhovsky633f98b2013-11-03 13:46:31 +0000533 case IC_EVEX_L2_OPSIZE_K_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000534 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B);
535 case IC_EVEX_L2_KZ_B:
536 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B);
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000537 case IC_EVEX_L2_XS_KZ_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000538 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B);
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000539 case IC_EVEX_L2_XD_KZ_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000540 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B);
Elena Demikhovsky633f98b2013-11-03 13:46:31 +0000541 case IC_EVEX_L2_OPSIZE_KZ_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000542 return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B);
Elena Demikhovsky633f98b2013-11-03 13:46:31 +0000543 case IC_EVEX_L2_W_B:
Elena Demikhovsky695922d2015-04-21 13:13:46 +0000544 case IC_EVEX_L2_W_XS_B:
Elena Demikhovsky3062a312014-01-01 15:12:34 +0000545 case IC_EVEX_L2_W_XD_B:
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000546 case IC_EVEX_L2_W_OPSIZE_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000547 return false;
548 case IC_EVEX_L2_W_K_B:
549 case IC_EVEX_L2_W_XS_K_B:
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000550 case IC_EVEX_L2_W_XD_K_B:
Craig Topper0f7dce52017-10-23 02:26:24 +0000551 case IC_EVEX_L2_W_OPSIZE_K_B:
552 return false;
553 case IC_EVEX_L2_W_KZ_B:
554 case IC_EVEX_L2_W_XS_KZ_B:
Elena Demikhovskya0a51732015-07-13 13:26:20 +0000555 case IC_EVEX_L2_W_XD_KZ_B:
Elena Demikhovsky633f98b2013-11-03 13:46:31 +0000556 case IC_EVEX_L2_W_OPSIZE_KZ_B:
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000557 return false;
Sean Callanan8ed9f512009-12-19 02:59:52 +0000558 default:
Elena Demikhovsky3062a312014-01-01 15:12:34 +0000559 errs() << "Unknown instruction class: " <<
560 stringForContext((InstructionContext)parent) << "\n";
Craig Topper5ffedb92011-09-02 04:17:54 +0000561 llvm_unreachable("Unknown instruction class");
Sean Callanan8ed9f512009-12-19 02:59:52 +0000562 }
563}
564
565/// outranks - Indicates whether, if an instruction has two different applicable
566/// classes, which class should be preferred when performing decode. This
567/// imposes a total ordering (ties are resolved toward "lower")
568///
569/// @param upper - The class that may be preferable
570/// @param lower - The class that may be less preferable
571/// @return - True if upper is to be preferred, false otherwise.
Craig Topper98400092012-07-31 05:27:01 +0000572static inline bool outranks(InstructionContext upper,
Sean Callanan8ed9f512009-12-19 02:59:52 +0000573 InstructionContext lower) {
574 assert(upper < IC_max);
575 assert(lower < IC_max);
Craig Topper98400092012-07-31 05:27:01 +0000576
Sean Callanan8ed9f512009-12-19 02:59:52 +0000577#define ENUM_ENTRY(n, r, d) r,
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000578#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) \
Elena Demikhovsky633f98b2013-11-03 13:46:31 +0000579 ENUM_ENTRY(n##_K_B, r, d) ENUM_ENTRY(n##_KZ_B, r, d) \
580 ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d)
Sean Callanan8ed9f512009-12-19 02:59:52 +0000581 static int ranks[IC_max] = {
582 INSTRUCTION_CONTEXTS
583 };
584#undef ENUM_ENTRY
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000585#undef ENUM_ENTRY_K_B
Craig Topper98400092012-07-31 05:27:01 +0000586
Sean Callanan8ed9f512009-12-19 02:59:52 +0000587 return (ranks[upper] > ranks[lower]);
588}
589
Sean Callanan8ed9f512009-12-19 02:59:52 +0000590/// getDecisionType - Determines whether a ModRM decision with 255 entries can
591/// be compacted by eliminating redundant information.
592///
593/// @param decision - The decision to be compacted.
594/// @return - The compactest available representation for the decision.
Craig Toppere08789f2012-07-31 05:42:02 +0000595static ModRMDecisionType getDecisionType(ModRMDecision &decision) {
Sean Callanan8ed9f512009-12-19 02:59:52 +0000596 bool satisfiesOneEntry = true;
597 bool satisfiesSplitRM = true;
Craig Topperf41ab772012-02-09 08:58:07 +0000598 bool satisfiesSplitReg = true;
Craig Topper76b29b52012-09-13 05:45:42 +0000599 bool satisfiesSplitMisc = true;
Craig Topperf41ab772012-02-09 08:58:07 +0000600
Craig Topperde9e3332012-07-31 06:02:05 +0000601 for (unsigned index = 0; index < 256; ++index) {
Sean Callanan8ed9f512009-12-19 02:59:52 +0000602 if (decision.instructionIDs[index] != decision.instructionIDs[0])
603 satisfiesOneEntry = false;
Craig Topperf41ab772012-02-09 08:58:07 +0000604
Sean Callanan8ed9f512009-12-19 02:59:52 +0000605 if (((index & 0xc0) == 0xc0) &&
606 (decision.instructionIDs[index] != decision.instructionIDs[0xc0]))
607 satisfiesSplitRM = false;
Craig Topperf41ab772012-02-09 08:58:07 +0000608
Sean Callanan8ed9f512009-12-19 02:59:52 +0000609 if (((index & 0xc0) != 0xc0) &&
610 (decision.instructionIDs[index] != decision.instructionIDs[0x00]))
611 satisfiesSplitRM = false;
Craig Topperf41ab772012-02-09 08:58:07 +0000612
613 if (((index & 0xc0) == 0xc0) &&
614 (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8]))
615 satisfiesSplitReg = false;
616
617 if (((index & 0xc0) != 0xc0) &&
618 (decision.instructionIDs[index] != decision.instructionIDs[index&0x38]))
Craig Topper76b29b52012-09-13 05:45:42 +0000619 satisfiesSplitMisc = false;
Sean Callanan8ed9f512009-12-19 02:59:52 +0000620 }
Craig Topperf41ab772012-02-09 08:58:07 +0000621
Sean Callanan8ed9f512009-12-19 02:59:52 +0000622 if (satisfiesOneEntry)
623 return MODRM_ONEENTRY;
Craig Topperf41ab772012-02-09 08:58:07 +0000624
Sean Callanan8ed9f512009-12-19 02:59:52 +0000625 if (satisfiesSplitRM)
626 return MODRM_SPLITRM;
Craig Topperf41ab772012-02-09 08:58:07 +0000627
Craig Topper76b29b52012-09-13 05:45:42 +0000628 if (satisfiesSplitReg && satisfiesSplitMisc)
Craig Topperf41ab772012-02-09 08:58:07 +0000629 return MODRM_SPLITREG;
630
Craig Topper76b29b52012-09-13 05:45:42 +0000631 if (satisfiesSplitMisc)
632 return MODRM_SPLITMISC;
633
Sean Callanan8ed9f512009-12-19 02:59:52 +0000634 return MODRM_FULL;
635}
636
637/// stringForDecisionType - Returns a statically-allocated string corresponding
638/// to a particular decision type.
639///
640/// @param dt - The decision type.
Craig Topper98400092012-07-31 05:27:01 +0000641/// @return - A pointer to the statically-allocated string (e.g.,
Sean Callanan8ed9f512009-12-19 02:59:52 +0000642/// "MODRM_ONEENTRY" for MODRM_ONEENTRY).
Craig Toppere08789f2012-07-31 05:42:02 +0000643static const char* stringForDecisionType(ModRMDecisionType dt) {
Sean Callanan8ed9f512009-12-19 02:59:52 +0000644#define ENUM_ENTRY(n) case n: return #n;
645 switch (dt) {
646 default:
Craig Topper98400092012-07-31 05:27:01 +0000647 llvm_unreachable("Unknown decision type");
Sean Callanan8ed9f512009-12-19 02:59:52 +0000648 MODRMTYPES
Craig Topper98400092012-07-31 05:27:01 +0000649 };
Sean Callanan8ed9f512009-12-19 02:59:52 +0000650#undef ENUM_ENTRY
651}
Craig Topper98400092012-07-31 05:27:01 +0000652
Sean Callanan8ed9f512009-12-19 02:59:52 +0000653DisassemblerTables::DisassemblerTables() {
Craig Topper2280dbe2018-03-24 07:15:47 +0000654 for (unsigned i = 0; i < array_lengthof(Tables); i++)
655 Tables[i] = llvm::make_unique<ContextDecision>();
Craig Topper98400092012-07-31 05:27:01 +0000656
Sean Callanan8ed9f512009-12-19 02:59:52 +0000657 HasConflicts = false;
658}
Craig Topper98400092012-07-31 05:27:01 +0000659
Sean Callanan8ed9f512009-12-19 02:59:52 +0000660DisassemblerTables::~DisassemblerTables() {
Sean Callanan8ed9f512009-12-19 02:59:52 +0000661}
Craig Topper98400092012-07-31 05:27:01 +0000662
Craig Toppere08789f2012-07-31 05:42:02 +0000663void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
Craig Topperde9e3332012-07-31 06:02:05 +0000664 unsigned &i1, unsigned &i2,
Craig Topper39004b52013-09-30 06:23:19 +0000665 unsigned &ModRMTableNum,
Craig Toppere08789f2012-07-31 05:42:02 +0000666 ModRMDecision &decision) const {
Craig Topperde9e3332012-07-31 06:02:05 +0000667 static uint32_t sTableNumber = 0;
668 static uint32_t sEntryNumber = 1;
Sean Callanan8ed9f512009-12-19 02:59:52 +0000669 ModRMDecisionType dt = getDecisionType(decision);
Craig Topperce8f4c52012-02-09 07:45:30 +0000670
Sean Callanan8ed9f512009-12-19 02:59:52 +0000671 if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)
672 {
673 o2.indent(i2) << "{ /* ModRMDecision */" << "\n";
674 i2++;
Craig Topperce8f4c52012-02-09 07:45:30 +0000675
Sean Callanan8ed9f512009-12-19 02:59:52 +0000676 o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
Craig Topperce8f4c52012-02-09 07:45:30 +0000677 o2.indent(i2) << 0 << " /* EmptyTable */\n";
678
Sean Callanan8ed9f512009-12-19 02:59:52 +0000679 i2--;
680 o2.indent(i2) << "}";
681 return;
682 }
Sean Callanan8ed9f512009-12-19 02:59:52 +0000683
Craig Topper39004b52013-09-30 06:23:19 +0000684 std::vector<unsigned> ModRMDecision;
Craig Topperce8f4c52012-02-09 07:45:30 +0000685
Sean Callanan8ed9f512009-12-19 02:59:52 +0000686 switch (dt) {
687 default:
688 llvm_unreachable("Unknown decision type");
689 case MODRM_ONEENTRY:
Craig Topper39004b52013-09-30 06:23:19 +0000690 ModRMDecision.push_back(decision.instructionIDs[0]);
Sean Callanan8ed9f512009-12-19 02:59:52 +0000691 break;
692 case MODRM_SPLITRM:
Craig Topper39004b52013-09-30 06:23:19 +0000693 ModRMDecision.push_back(decision.instructionIDs[0x00]);
694 ModRMDecision.push_back(decision.instructionIDs[0xc0]);
Sean Callanan8ed9f512009-12-19 02:59:52 +0000695 break;
Craig Topperf41ab772012-02-09 08:58:07 +0000696 case MODRM_SPLITREG:
Craig Topperde9e3332012-07-31 06:02:05 +0000697 for (unsigned index = 0; index < 64; index += 8)
Craig Topper39004b52013-09-30 06:23:19 +0000698 ModRMDecision.push_back(decision.instructionIDs[index]);
Craig Topperde9e3332012-07-31 06:02:05 +0000699 for (unsigned index = 0xc0; index < 256; index += 8)
Craig Topper39004b52013-09-30 06:23:19 +0000700 ModRMDecision.push_back(decision.instructionIDs[index]);
Craig Topperf41ab772012-02-09 08:58:07 +0000701 break;
Craig Topper76b29b52012-09-13 05:45:42 +0000702 case MODRM_SPLITMISC:
703 for (unsigned index = 0; index < 64; index += 8)
Craig Topper39004b52013-09-30 06:23:19 +0000704 ModRMDecision.push_back(decision.instructionIDs[index]);
Craig Topper76b29b52012-09-13 05:45:42 +0000705 for (unsigned index = 0xc0; index < 256; ++index)
Craig Topper39004b52013-09-30 06:23:19 +0000706 ModRMDecision.push_back(decision.instructionIDs[index]);
Craig Topper76b29b52012-09-13 05:45:42 +0000707 break;
Sean Callanan8ed9f512009-12-19 02:59:52 +0000708 case MODRM_FULL:
Craig Topperde9e3332012-07-31 06:02:05 +0000709 for (unsigned index = 0; index < 256; ++index)
Craig Topper39004b52013-09-30 06:23:19 +0000710 ModRMDecision.push_back(decision.instructionIDs[index]);
Sean Callanan8ed9f512009-12-19 02:59:52 +0000711 break;
712 }
Craig Topperce8f4c52012-02-09 07:45:30 +0000713
Craig Topper39004b52013-09-30 06:23:19 +0000714 unsigned &EntryNumber = ModRMTable[ModRMDecision];
715 if (EntryNumber == 0) {
716 EntryNumber = ModRMTableNum;
717
718 ModRMTableNum += ModRMDecision.size();
719 o1 << "/* Table" << EntryNumber << " */\n";
720 i1++;
721 for (std::vector<unsigned>::const_iterator I = ModRMDecision.begin(),
722 E = ModRMDecision.end(); I != E; ++I) {
723 o1.indent(i1 * 2) << format("0x%hx", *I) << ", /* "
724 << InstructionSpecifiers[*I].name << " */\n";
725 }
726 i1--;
727 }
Craig Topperce8f4c52012-02-09 07:45:30 +0000728
Sean Callanan8ed9f512009-12-19 02:59:52 +0000729 o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n";
730 i2++;
Craig Topperce8f4c52012-02-09 07:45:30 +0000731
Sean Callanan8ed9f512009-12-19 02:59:52 +0000732 o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
Craig Topper39004b52013-09-30 06:23:19 +0000733 o2.indent(i2) << EntryNumber << " /* Table" << EntryNumber << " */\n";
Craig Topperce8f4c52012-02-09 07:45:30 +0000734
Sean Callanan8ed9f512009-12-19 02:59:52 +0000735 i2--;
736 o2.indent(i2) << "}";
Craig Topperce8f4c52012-02-09 07:45:30 +0000737
738 switch (dt) {
739 default:
740 llvm_unreachable("Unknown decision type");
741 case MODRM_ONEENTRY:
742 sEntryNumber += 1;
743 break;
744 case MODRM_SPLITRM:
745 sEntryNumber += 2;
746 break;
Craig Topperf41ab772012-02-09 08:58:07 +0000747 case MODRM_SPLITREG:
748 sEntryNumber += 16;
749 break;
Craig Topper76b29b52012-09-13 05:45:42 +0000750 case MODRM_SPLITMISC:
751 sEntryNumber += 8 + 64;
752 break;
Craig Topperce8f4c52012-02-09 07:45:30 +0000753 case MODRM_FULL:
754 sEntryNumber += 256;
755 break;
756 }
757
Craig Topper9e6dc8b2012-09-11 04:19:21 +0000758 // We assume that the index can fit into uint16_t.
759 assert(sEntryNumber < 65536U &&
760 "Index into ModRMDecision is too large for uint16_t!");
761
Sean Callanan8ed9f512009-12-19 02:59:52 +0000762 ++sTableNumber;
763}
764
Craig Toppere08789f2012-07-31 05:42:02 +0000765void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2,
Craig Topperde9e3332012-07-31 06:02:05 +0000766 unsigned &i1, unsigned &i2,
Craig Topper39004b52013-09-30 06:23:19 +0000767 unsigned &ModRMTableNum,
Craig Toppere08789f2012-07-31 05:42:02 +0000768 OpcodeDecision &decision) const {
Sean Callanan8ed9f512009-12-19 02:59:52 +0000769 o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n";
770 i2++;
771 o2.indent(i2) << "{" << "\n";
772 i2++;
773
Craig Topperde9e3332012-07-31 06:02:05 +0000774 for (unsigned index = 0; index < 256; ++index) {
Sean Callanan8ed9f512009-12-19 02:59:52 +0000775 o2.indent(i2);
776
777 o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n";
778
Craig Topper39004b52013-09-30 06:23:19 +0000779 emitModRMDecision(o1, o2, i1, i2, ModRMTableNum,
780 decision.modRMDecisions[index]);
Sean Callanan8ed9f512009-12-19 02:59:52 +0000781
782 if (index < 255)
783 o2 << ",";
784
785 o2 << "\n";
786 }
787
788 i2--;
789 o2.indent(i2) << "}" << "\n";
790 i2--;
791 o2.indent(i2) << "}" << "\n";
792}
793
Craig Toppere08789f2012-07-31 05:42:02 +0000794void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2,
Craig Topperde9e3332012-07-31 06:02:05 +0000795 unsigned &i1, unsigned &i2,
Craig Topper39004b52013-09-30 06:23:19 +0000796 unsigned &ModRMTableNum,
Craig Toppere08789f2012-07-31 05:42:02 +0000797 ContextDecision &decision,
798 const char* name) const {
Benjamin Kramer4d1dca92010-10-23 09:10:44 +0000799 o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n";
Sean Callanan8ed9f512009-12-19 02:59:52 +0000800 i2++;
801 o2.indent(i2) << "{ /* opcodeDecisions */" << "\n";
802 i2++;
803
Craig Topperde9e3332012-07-31 06:02:05 +0000804 for (unsigned index = 0; index < IC_max; ++index) {
Sean Callanan8ed9f512009-12-19 02:59:52 +0000805 o2.indent(i2) << "/* ";
806 o2 << stringForContext((InstructionContext)index);
807 o2 << " */";
808 o2 << "\n";
809
Craig Topper39004b52013-09-30 06:23:19 +0000810 emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum,
811 decision.opcodeDecisions[index]);
Sean Callanan8ed9f512009-12-19 02:59:52 +0000812
813 if (index + 1 < IC_max)
814 o2 << ", ";
815 }
816
817 i2--;
818 o2.indent(i2) << "}" << "\n";
819 i2--;
820 o2.indent(i2) << "};" << "\n";
821}
822
Craig Topperde9e3332012-07-31 06:02:05 +0000823void DisassemblerTables::emitInstructionInfo(raw_ostream &o,
824 unsigned &i) const {
Craig Topper5a2c6072012-08-01 07:39:18 +0000825 unsigned NumInstructions = InstructionSpecifiers.size();
826
827 o << "static const struct OperandSpecifier x86OperandSets[]["
828 << X86_MAX_OPERANDS << "] = {\n";
829
Craig Topperb82d5472015-04-09 04:08:48 +0000830 typedef SmallVector<std::pair<OperandEncoding, OperandType>,
831 X86_MAX_OPERANDS> OperandListTy;
Craig Topper5a2c6072012-08-01 07:39:18 +0000832 std::map<OperandListTy, unsigned> OperandSets;
833
834 unsigned OperandSetNum = 0;
835 for (unsigned Index = 0; Index < NumInstructions; ++Index) {
836 OperandListTy OperandList;
837
838 for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
839 ++OperandIndex) {
Craig Topper684de882015-04-09 04:08:42 +0000840 OperandEncoding Encoding = (OperandEncoding)InstructionSpecifiers[Index]
841 .operands[OperandIndex].encoding;
842 OperandType Type = (OperandType)InstructionSpecifiers[Index]
843 .operands[OperandIndex].type;
Craig Topper5a2c6072012-08-01 07:39:18 +0000844 OperandList.push_back(std::make_pair(Encoding, Type));
845 }
846 unsigned &N = OperandSets[OperandList];
847 if (N != 0) continue;
848
849 N = ++OperandSetNum;
850
851 o << " { /* " << (OperandSetNum - 1) << " */\n";
852 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) {
Craig Topper684de882015-04-09 04:08:42 +0000853 const char *Encoding = stringForOperandEncoding(OperandList[i].first);
854 const char *Type = stringForOperandType(OperandList[i].second);
855 o << " { " << Encoding << ", " << Type << " },\n";
Craig Topper5a2c6072012-08-01 07:39:18 +0000856 }
857 o << " },\n";
858 }
859 o << "};" << "\n\n";
860
Benjamin Kramer4d1dca92010-10-23 09:10:44 +0000861 o.indent(i * 2) << "static const struct InstructionSpecifier ";
862 o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n";
Craig Topper98400092012-07-31 05:27:01 +0000863
Sean Callanan8ed9f512009-12-19 02:59:52 +0000864 i++;
865
Craig Topper5a2c6072012-08-01 07:39:18 +0000866 for (unsigned index = 0; index < NumInstructions; ++index) {
Craig Topper13154ac2015-04-09 04:08:46 +0000867 o.indent(i * 2) << "{ /* " << index << " */\n";
Sean Callanan8ed9f512009-12-19 02:59:52 +0000868 i++;
Craig Topper991271d2012-03-04 02:16:41 +0000869
Craig Topper5a2c6072012-08-01 07:39:18 +0000870 OperandListTy OperandList;
871 for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
872 ++OperandIndex) {
Craig Topper684de882015-04-09 04:08:42 +0000873 OperandEncoding Encoding = (OperandEncoding)InstructionSpecifiers[index]
874 .operands[OperandIndex].encoding;
875 OperandType Type = (OperandType)InstructionSpecifiers[index]
876 .operands[OperandIndex].type;
Craig Topper5a2c6072012-08-01 07:39:18 +0000877 OperandList.push_back(std::make_pair(Encoding, Type));
Sean Callanan8ed9f512009-12-19 02:59:52 +0000878 }
Craig Topper5a2c6072012-08-01 07:39:18 +0000879 o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n";
Craig Topper98400092012-07-31 05:27:01 +0000880
Craig Topper13154ac2015-04-09 04:08:46 +0000881 o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */\n";
Sean Callanan8ed9f512009-12-19 02:59:52 +0000882
883 i--;
Craig Topper13154ac2015-04-09 04:08:46 +0000884 o.indent(i * 2) << "},\n";
Sean Callanan8ed9f512009-12-19 02:59:52 +0000885 }
886
887 i--;
888 o.indent(i * 2) << "};" << "\n";
889}
890
Craig Topperde9e3332012-07-31 06:02:05 +0000891void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
Craig Topper7cff4112018-03-24 07:48:54 +0000892 const unsigned int tableSize = 16384;
Craig Topper19dbe2f2012-07-31 06:15:39 +0000893 o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR
Elena Demikhovsky09a63712013-12-25 11:40:51 +0000894 "[" << tableSize << "] = {\n";
Sean Callanan8ed9f512009-12-19 02:59:52 +0000895 i++;
896
Elena Demikhovsky09a63712013-12-25 11:40:51 +0000897 for (unsigned index = 0; index < tableSize; ++index) {
Sean Callanan8ed9f512009-12-19 02:59:52 +0000898 o.indent(i * 2);
899
Craig Topper7cff4112018-03-24 07:48:54 +0000900 if (index & ATTR_EVEX) {
Elena Demikhovsky09a63712013-12-25 11:40:51 +0000901 o << "IC_EVEX";
902 if (index & ATTR_EVEXL2)
903 o << "_L2";
904 else if (index & ATTR_EVEXL)
905 o << "_L";
906 if (index & ATTR_REXW)
907 o << "_W";
908 if (index & ATTR_OPSIZE)
909 o << "_OPSIZE";
910 else if (index & ATTR_XD)
911 o << "_XD";
912 else if (index & ATTR_XS)
913 o << "_XS";
914 if (index & ATTR_EVEXKZ)
915 o << "_KZ";
916 else if (index & ATTR_EVEXK)
917 o << "_K";
918 if (index & ATTR_EVEXB)
919 o << "_B";
920 }
921 else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
Craig Topperc8eb8802011-11-06 23:04:08 +0000922 o << "IC_VEX_L_W_OPSIZE";
Craig Topper92b45812013-09-30 02:46:36 +0000923 else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XD))
924 o << "IC_VEX_L_W_XD";
925 else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XS))
926 o << "IC_VEX_L_W_XS";
927 else if ((index & ATTR_VEXL) && (index & ATTR_REXW))
928 o << "IC_VEX_L_W";
Craig Topperc8eb8802011-11-06 23:04:08 +0000929 else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE))
Sean Callanana21e2ea2011-03-15 01:23:15 +0000930 o << "IC_VEX_L_OPSIZE";
931 else if ((index & ATTR_VEXL) && (index & ATTR_XD))
932 o << "IC_VEX_L_XD";
933 else if ((index & ATTR_VEXL) && (index & ATTR_XS))
934 o << "IC_VEX_L_XS";
935 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
936 o << "IC_VEX_W_OPSIZE";
937 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XD))
938 o << "IC_VEX_W_XD";
939 else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XS))
940 o << "IC_VEX_W_XS";
941 else if (index & ATTR_VEXL)
942 o << "IC_VEX_L";
943 else if ((index & ATTR_VEX) && (index & ATTR_REXW))
944 o << "IC_VEX_W";
945 else if ((index & ATTR_VEX) && (index & ATTR_OPSIZE))
946 o << "IC_VEX_OPSIZE";
947 else if ((index & ATTR_VEX) && (index & ATTR_XD))
948 o << "IC_VEX_XD";
949 else if ((index & ATTR_VEX) && (index & ATTR_XS))
950 o << "IC_VEX_XS";
Craig Topper113061d2011-08-25 07:42:00 +0000951 else if (index & ATTR_VEX)
952 o << "IC_VEX";
Sean Callanana21e2ea2011-03-15 01:23:15 +0000953 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))
Sean Callanan8ed9f512009-12-19 02:59:52 +0000954 o << "IC_64BIT_REXW_XS";
955 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD))
956 o << "IC_64BIT_REXW_XD";
Craig Topper98400092012-07-31 05:27:01 +0000957 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&
Sean Callanan8ed9f512009-12-19 02:59:52 +0000958 (index & ATTR_OPSIZE))
959 o << "IC_64BIT_REXW_OPSIZE";
Craig Topper01c99892015-01-03 00:00:20 +0000960 else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&
961 (index & ATTR_ADSIZE))
962 o << "IC_64BIT_REXW_ADSIZE";
Craig Toppere1b4a1a2011-10-01 19:54:56 +0000963 else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
964 o << "IC_64BIT_XD_OPSIZE";
Craig Topperb3ec9a12018-04-05 18:20:14 +0000965 else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_ADSIZE))
966 o << "IC_64BIT_XD_ADSIZE";
Craig Topper29480fd2011-10-11 04:34:23 +0000967 else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE))
968 o << "IC_64BIT_XS_OPSIZE";
Craig Topperb3ec9a12018-04-05 18:20:14 +0000969 else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_ADSIZE))
970 o << "IC_64BIT_XS_ADSIZE";
Sean Callanan8ed9f512009-12-19 02:59:52 +0000971 else if ((index & ATTR_64BIT) && (index & ATTR_XS))
972 o << "IC_64BIT_XS";
973 else if ((index & ATTR_64BIT) && (index & ATTR_XD))
974 o << "IC_64BIT_XD";
Craig Topper51f423f2014-12-31 07:07:31 +0000975 else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE) &&
976 (index & ATTR_ADSIZE))
977 o << "IC_64BIT_OPSIZE_ADSIZE";
Sean Callanan8ed9f512009-12-19 02:59:52 +0000978 else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE))
979 o << "IC_64BIT_OPSIZE";
Craig Topper930a1eb2012-02-27 01:54:29 +0000980 else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE))
981 o << "IC_64BIT_ADSIZE";
Sean Callanan8ed9f512009-12-19 02:59:52 +0000982 else if ((index & ATTR_64BIT) && (index & ATTR_REXW))
983 o << "IC_64BIT_REXW";
984 else if ((index & ATTR_64BIT))
985 o << "IC_64BIT";
Craig Topper29480fd2011-10-11 04:34:23 +0000986 else if ((index & ATTR_XS) && (index & ATTR_OPSIZE))
987 o << "IC_XS_OPSIZE";
Craig Toppere1b4a1a2011-10-01 19:54:56 +0000988 else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
989 o << "IC_XD_OPSIZE";
Craig Topperb3ec9a12018-04-05 18:20:14 +0000990 else if ((index & ATTR_XS) && (index & ATTR_ADSIZE))
991 o << "IC_XS_ADSIZE";
992 else if ((index & ATTR_XD) && (index & ATTR_ADSIZE))
993 o << "IC_XD_ADSIZE";
Sean Callanan8ed9f512009-12-19 02:59:52 +0000994 else if (index & ATTR_XS)
995 o << "IC_XS";
996 else if (index & ATTR_XD)
997 o << "IC_XD";
Craig Topper51f423f2014-12-31 07:07:31 +0000998 else if ((index & ATTR_OPSIZE) && (index & ATTR_ADSIZE))
999 o << "IC_OPSIZE_ADSIZE";
Sean Callanan8ed9f512009-12-19 02:59:52 +00001000 else if (index & ATTR_OPSIZE)
1001 o << "IC_OPSIZE";
Craig Topper930a1eb2012-02-27 01:54:29 +00001002 else if (index & ATTR_ADSIZE)
1003 o << "IC_ADSIZE";
Sean Callanan8ed9f512009-12-19 02:59:52 +00001004 else
1005 o << "IC";
1006
Elena Demikhovsky09a63712013-12-25 11:40:51 +00001007 if (index < tableSize - 1)
Sean Callanan8ed9f512009-12-19 02:59:52 +00001008 o << ",";
1009 else
1010 o << " ";
1011
1012 o << " /* " << index << " */";
1013
1014 o << "\n";
1015 }
1016
1017 i--;
1018 o.indent(i * 2) << "};" << "\n";
1019}
1020
Craig Toppere08789f2012-07-31 05:42:02 +00001021void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2,
Craig Topper39004b52013-09-30 06:23:19 +00001022 unsigned &i1, unsigned &i2,
1023 unsigned &ModRMTableNum) const {
1024 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[0], ONEBYTE_STR);
1025 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[1], TWOBYTE_STR);
1026 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[2], THREEBYTE38_STR);
1027 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[3], THREEBYTE3A_STR);
Craig Topper82a644a2014-02-19 05:34:21 +00001028 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], XOP8_MAP_STR);
1029 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], XOP9_MAP_STR);
1030 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOPA_MAP_STR);
Craig Topper7cff4112018-03-24 07:48:54 +00001031 emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[7], THREEDNOW_MAP_STR);
Sean Callanan8ed9f512009-12-19 02:59:52 +00001032}
1033
1034void DisassemblerTables::emit(raw_ostream &o) const {
Craig Topperde9e3332012-07-31 06:02:05 +00001035 unsigned i1 = 0;
1036 unsigned i2 = 0;
Craig Topper98400092012-07-31 05:27:01 +00001037
Sean Callanan8ed9f512009-12-19 02:59:52 +00001038 std::string s1;
1039 std::string s2;
Craig Topper98400092012-07-31 05:27:01 +00001040
Sean Callanan8ed9f512009-12-19 02:59:52 +00001041 raw_string_ostream o1(s1);
1042 raw_string_ostream o2(s2);
Craig Topper98400092012-07-31 05:27:01 +00001043
Sean Callanan8ed9f512009-12-19 02:59:52 +00001044 emitInstructionInfo(o, i2);
1045 o << "\n";
1046
1047 emitContextTable(o, i2);
1048 o << "\n";
Craig Topperce8f4c52012-02-09 07:45:30 +00001049
Craig Topper39004b52013-09-30 06:23:19 +00001050 unsigned ModRMTableNum = 0;
1051
Craig Topperce8f4c52012-02-09 07:45:30 +00001052 o << "static const InstrUID modRMTable[] = {\n";
1053 i1++;
Craig Topper39004b52013-09-30 06:23:19 +00001054 std::vector<unsigned> EmptyTable(1, 0);
1055 ModRMTable[EmptyTable] = ModRMTableNum;
1056 ModRMTableNum += EmptyTable.size();
1057 o1 << "/* EmptyTable */\n";
1058 o1.indent(i1 * 2) << "0x0,\n";
Craig Topperce8f4c52012-02-09 07:45:30 +00001059 i1--;
Craig Topper39004b52013-09-30 06:23:19 +00001060 emitContextDecisions(o1, o2, i1, i2, ModRMTableNum);
Craig Topperce8f4c52012-02-09 07:45:30 +00001061
Sean Callanan8ed9f512009-12-19 02:59:52 +00001062 o << o1.str();
Craig Topperce8f4c52012-02-09 07:45:30 +00001063 o << " 0x0\n";
1064 o << "};\n";
Sean Callanan8ed9f512009-12-19 02:59:52 +00001065 o << "\n";
1066 o << o2.str();
1067 o << "\n";
1068 o << "\n";
1069}
1070
1071void DisassemblerTables::setTableFields(ModRMDecision &decision,
1072 const ModRMFilter &filter,
1073 InstrUID uid,
1074 uint8_t opcode) {
Craig Topperde9e3332012-07-31 06:02:05 +00001075 for (unsigned index = 0; index < 256; ++index) {
Sean Callanan8ed9f512009-12-19 02:59:52 +00001076 if (filter.accepts(index)) {
1077 if (decision.instructionIDs[index] == uid)
1078 continue;
1079
1080 if (decision.instructionIDs[index] != 0) {
1081 InstructionSpecifier &newInfo =
1082 InstructionSpecifiers[uid];
1083 InstructionSpecifier &previousInfo =
1084 InstructionSpecifiers[decision.instructionIDs[index]];
Craig Topper98400092012-07-31 05:27:01 +00001085
Craig Topper842f58f2011-09-11 20:23:20 +00001086 if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" ||
1087 newInfo.name == "XCHG32ar" ||
1088 newInfo.name == "XCHG64ar"))
1089 continue; // special case for XCHG*ar and NOOP
Sean Callanan8ed9f512009-12-19 02:59:52 +00001090
1091 if (outranks(previousInfo.insnContext, newInfo.insnContext))
1092 continue;
Craig Topper98400092012-07-31 05:27:01 +00001093
Craig Topper1ee7e392014-02-13 07:07:16 +00001094 if (previousInfo.insnContext == newInfo.insnContext) {
Sean Callanan8ed9f512009-12-19 02:59:52 +00001095 errs() << "Error: Primary decode conflict: ";
1096 errs() << newInfo.name << " would overwrite " << previousInfo.name;
1097 errs() << "\n";
1098 errs() << "ModRM " << index << "\n";
1099 errs() << "Opcode " << (uint16_t)opcode << "\n";
1100 errs() << "Context " << stringForContext(newInfo.insnContext) << "\n";
1101 HasConflicts = true;
1102 }
1103 }
1104
1105 decision.instructionIDs[index] = uid;
1106 }
1107 }
1108}
1109
1110void DisassemblerTables::setTableFields(OpcodeType type,
1111 InstructionContext insnContext,
1112 uint8_t opcode,
1113 const ModRMFilter &filter,
Craig Topper4da632e2011-09-23 06:57:25 +00001114 InstrUID uid,
Craig Topper6744a172011-10-04 06:30:42 +00001115 bool is32bit,
Craig Topper8c2358a2017-10-23 16:49:26 +00001116 bool noPrefix,
Craig Topper71fc42d2015-01-02 07:02:25 +00001117 bool ignoresVEX_L,
Craig Topper3ae8f2d2017-10-22 06:18:26 +00001118 bool ignoresVEX_W,
Craig Topper71fc42d2015-01-02 07:02:25 +00001119 unsigned addressSize) {
Sean Callanan8ed9f512009-12-19 02:59:52 +00001120 ContextDecision &decision = *Tables[type];
1121
Craig Topperde9e3332012-07-31 06:02:05 +00001122 for (unsigned index = 0; index < IC_max; ++index) {
Craig Topper71fc42d2015-01-02 07:02:25 +00001123 if ((is32bit || addressSize == 16) &&
1124 inheritsFrom((InstructionContext)index, IC_64BIT))
Craig Topper4da632e2011-09-23 06:57:25 +00001125 continue;
1126
Craig Topper71fc42d2015-01-02 07:02:25 +00001127 bool adSize64 = addressSize == 64;
Craig Topper98400092012-07-31 05:27:01 +00001128 if (inheritsFrom((InstructionContext)index,
Craig Topper8c2358a2017-10-23 16:49:26 +00001129 InstructionSpecifiers[uid].insnContext, noPrefix,
1130 ignoresVEX_L, ignoresVEX_W, adSize64))
Craig Topper98400092012-07-31 05:27:01 +00001131 setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode],
Sean Callanan8ed9f512009-12-19 02:59:52 +00001132 filter,
1133 uid,
1134 opcode);
1135 }
1136}