x86: support VMGEXIT
[deliverable/binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.
2
3 This file is part of the GNU opcodes library.
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
19
20 #include "sysdep.h"
21 #include <stdio.h>
22 #include <errno.h>
23 #include "getopt.h"
24 #include "libiberty.h"
25 #include "hashtab.h"
26 #include "safe-ctype.h"
27
28 #include "i386-opc.h"
29
30 #include <libintl.h>
31 #define _(String) gettext (String)
32
33 /* Build-time checks are preferrable over runtime ones. Use this construct
34 in preference where possible. */
35 #define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
36
37 static const char *program_name = NULL;
38 static int debug = 0;
39
40 typedef struct initializer
41 {
42 const char *name;
43 const char *init;
44 } initializer;
45
46 static initializer cpu_flag_init[] =
47 {
48 { "CPU_UNKNOWN_FLAGS",
49 "~(CpuL1OM|CpuK1OM)" },
50 { "CPU_GENERIC32_FLAGS",
51 "Cpu186|Cpu286|Cpu386" },
52 { "CPU_GENERIC64_FLAGS",
53 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
54 { "CPU_NONE_FLAGS",
55 "0" },
56 { "CPU_I186_FLAGS",
57 "Cpu186" },
58 { "CPU_I286_FLAGS",
59 "CPU_I186_FLAGS|Cpu286" },
60 { "CPU_I386_FLAGS",
61 "CPU_I286_FLAGS|Cpu386" },
62 { "CPU_I486_FLAGS",
63 "CPU_I386_FLAGS|Cpu486" },
64 { "CPU_I586_FLAGS",
65 "CPU_I486_FLAGS|Cpu387|Cpu586" },
66 { "CPU_I686_FLAGS",
67 "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" },
68 { "CPU_PENTIUMPRO_FLAGS",
69 "CPU_I686_FLAGS|CpuNop" },
70 { "CPU_P2_FLAGS",
71 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
72 { "CPU_P3_FLAGS",
73 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
74 { "CPU_P4_FLAGS",
75 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
76 { "CPU_NOCONA_FLAGS",
77 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
78 { "CPU_CORE_FLAGS",
79 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
80 { "CPU_CORE2_FLAGS",
81 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
82 { "CPU_COREI7_FLAGS",
83 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
84 { "CPU_K6_FLAGS",
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
86 { "CPU_K6_2_FLAGS",
87 "CPU_K6_FLAGS|Cpu3dnow" },
88 { "CPU_ATHLON_FLAGS",
89 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
90 { "CPU_K8_FLAGS",
91 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
92 { "CPU_AMDFAM10_FLAGS",
93 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuLZCNT|CpuPOPCNT" },
94 { "CPU_BDVER1_FLAGS",
95 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuLZCNT|CpuPOPCNT|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuPRFCHW" },
96 { "CPU_BDVER2_FLAGS",
97 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
98 { "CPU_BDVER3_FLAGS",
99 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
100 { "CPU_BDVER4_FLAGS",
101 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
102 { "CPU_ZNVER1_FLAGS",
103 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuSVME|CpuAES|CpuPCLMUL|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
104 { "CPU_ZNVER2_FLAGS",
105 "CPU_ZNVER1_FLAGS|CpuCLWB|CpuRDPID|CpuRDPRU|CpuMCOMMIT|CpuWBNOINVD" },
106 { "CPU_BTVER1_FLAGS",
107 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME" },
108 { "CPU_BTVER2_FLAGS",
109 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
110 { "CPU_8087_FLAGS",
111 "Cpu8087" },
112 { "CPU_287_FLAGS",
113 "Cpu287" },
114 { "CPU_387_FLAGS",
115 "Cpu387" },
116 { "CPU_687_FLAGS",
117 "CPU_387_FLAGS|Cpu687" },
118 { "CPU_CMOV_FLAGS",
119 "CpuCMOV" },
120 { "CPU_FXSR_FLAGS",
121 "CpuFXSR" },
122 { "CPU_CLFLUSH_FLAGS",
123 "CpuClflush" },
124 { "CPU_NOP_FLAGS",
125 "CpuNop" },
126 { "CPU_SYSCALL_FLAGS",
127 "CpuSYSCALL" },
128 { "CPU_MMX_FLAGS",
129 "CpuMMX" },
130 { "CPU_SSE_FLAGS",
131 "CpuSSE" },
132 { "CPU_SSE2_FLAGS",
133 "CPU_SSE_FLAGS|CpuSSE2" },
134 { "CPU_SSE3_FLAGS",
135 "CPU_SSE2_FLAGS|CpuSSE3" },
136 { "CPU_SSSE3_FLAGS",
137 "CPU_SSE3_FLAGS|CpuSSSE3" },
138 { "CPU_SSE4_1_FLAGS",
139 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
140 { "CPU_SSE4_2_FLAGS",
141 "CPU_SSE4_1_FLAGS|CpuSSE4_2|CpuPOPCNT" },
142 { "CPU_VMX_FLAGS",
143 "CpuVMX" },
144 { "CPU_SMX_FLAGS",
145 "CpuSMX" },
146 { "CPU_XSAVE_FLAGS",
147 "CpuXsave" },
148 { "CPU_XSAVEOPT_FLAGS",
149 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
150 { "CPU_AES_FLAGS",
151 "CPU_SSE2_FLAGS|CpuAES" },
152 { "CPU_PCLMUL_FLAGS",
153 "CPU_SSE2_FLAGS|CpuPCLMUL" },
154 { "CPU_FMA_FLAGS",
155 "CPU_AVX_FLAGS|CpuFMA" },
156 { "CPU_FMA4_FLAGS",
157 "CPU_AVX_FLAGS|CpuFMA4" },
158 { "CPU_XOP_FLAGS",
159 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
160 { "CPU_LWP_FLAGS",
161 "CPU_XSAVE_FLAGS|CpuLWP" },
162 { "CPU_BMI_FLAGS",
163 "CpuBMI" },
164 { "CPU_TBM_FLAGS",
165 "CpuTBM" },
166 { "CPU_MOVBE_FLAGS",
167 "CpuMovbe" },
168 { "CPU_CX16_FLAGS",
169 "CpuCX16" },
170 { "CPU_RDTSCP_FLAGS",
171 "CpuRdtscp" },
172 { "CPU_EPT_FLAGS",
173 "CpuEPT" },
174 { "CPU_FSGSBASE_FLAGS",
175 "CpuFSGSBase" },
176 { "CPU_RDRND_FLAGS",
177 "CpuRdRnd" },
178 { "CPU_F16C_FLAGS",
179 "CPU_AVX_FLAGS|CpuF16C" },
180 { "CPU_BMI2_FLAGS",
181 "CpuBMI2" },
182 { "CPU_LZCNT_FLAGS",
183 "CpuLZCNT" },
184 { "CPU_POPCNT_FLAGS",
185 "CpuPOPCNT" },
186 { "CPU_HLE_FLAGS",
187 "CpuHLE" },
188 { "CPU_RTM_FLAGS",
189 "CpuRTM" },
190 { "CPU_INVPCID_FLAGS",
191 "CpuINVPCID" },
192 { "CPU_VMFUNC_FLAGS",
193 "CpuVMFUNC" },
194 { "CPU_3DNOW_FLAGS",
195 "CPU_MMX_FLAGS|Cpu3dnow" },
196 { "CPU_3DNOWA_FLAGS",
197 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
198 { "CPU_PADLOCK_FLAGS",
199 "CpuPadLock" },
200 { "CPU_SVME_FLAGS",
201 "CpuSVME" },
202 { "CPU_SSE4A_FLAGS",
203 "CPU_SSE3_FLAGS|CpuSSE4a" },
204 { "CPU_ABM_FLAGS",
205 "CpuLZCNT|CpuPOPCNT" },
206 { "CPU_AVX_FLAGS",
207 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
208 { "CPU_AVX2_FLAGS",
209 "CPU_AVX_FLAGS|CpuAVX2" },
210 { "CPU_AVX512F_FLAGS",
211 "CPU_AVX2_FLAGS|CpuAVX512F" },
212 { "CPU_AVX512CD_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
214 { "CPU_AVX512ER_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
216 { "CPU_AVX512PF_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
218 { "CPU_AVX512DQ_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
220 { "CPU_AVX512BW_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
222 { "CPU_AVX512VL_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
224 { "CPU_AVX512IFMA_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
226 { "CPU_AVX512VBMI_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
228 { "CPU_AVX512_4FMAPS_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
230 { "CPU_AVX512_4VNNIW_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
232 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
234 { "CPU_AVX512_VBMI2_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
236 { "CPU_AVX512_VNNI_FLAGS",
237 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
238 { "CPU_AVX512_BITALG_FLAGS",
239 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
240 { "CPU_AVX512_BF16_FLAGS",
241 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
242 { "CPU_L1OM_FLAGS",
243 "unknown" },
244 { "CPU_K1OM_FLAGS",
245 "unknown" },
246 { "CPU_IAMCU_FLAGS",
247 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
248 { "CPU_ADX_FLAGS",
249 "CpuADX" },
250 { "CPU_RDSEED_FLAGS",
251 "CpuRdSeed" },
252 { "CPU_PRFCHW_FLAGS",
253 "CpuPRFCHW" },
254 { "CPU_SMAP_FLAGS",
255 "CpuSMAP" },
256 { "CPU_MPX_FLAGS",
257 "CPU_XSAVE_FLAGS|CpuMPX" },
258 { "CPU_SHA_FLAGS",
259 "CPU_SSE2_FLAGS|CpuSHA" },
260 { "CPU_CLFLUSHOPT_FLAGS",
261 "CpuClflushOpt" },
262 { "CPU_XSAVES_FLAGS",
263 "CPU_XSAVE_FLAGS|CpuXSAVES" },
264 { "CPU_XSAVEC_FLAGS",
265 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
266 { "CPU_PREFETCHWT1_FLAGS",
267 "CpuPREFETCHWT1" },
268 { "CPU_SE1_FLAGS",
269 "CpuSE1" },
270 { "CPU_CLWB_FLAGS",
271 "CpuCLWB" },
272 { "CPU_CLZERO_FLAGS",
273 "CpuCLZERO" },
274 { "CPU_MWAITX_FLAGS",
275 "CpuMWAITX" },
276 { "CPU_OSPKE_FLAGS",
277 "CPU_XSAVE_FLAGS|CpuOSPKE" },
278 { "CPU_RDPID_FLAGS",
279 "CpuRDPID" },
280 { "CPU_PTWRITE_FLAGS",
281 "CpuPTWRITE" },
282 { "CPU_IBT_FLAGS",
283 "CpuIBT" },
284 { "CPU_SHSTK_FLAGS",
285 "CpuSHSTK" },
286 { "CPU_GFNI_FLAGS",
287 "CpuGFNI" },
288 { "CPU_VAES_FLAGS",
289 "CpuVAES" },
290 { "CPU_VPCLMULQDQ_FLAGS",
291 "CpuVPCLMULQDQ" },
292 { "CPU_WBNOINVD_FLAGS",
293 "CpuWBNOINVD" },
294 { "CPU_PCONFIG_FLAGS",
295 "CpuPCONFIG" },
296 { "CPU_WAITPKG_FLAGS",
297 "CpuWAITPKG" },
298 { "CPU_CLDEMOTE_FLAGS",
299 "CpuCLDEMOTE" },
300 { "CPU_MOVDIRI_FLAGS",
301 "CpuMOVDIRI" },
302 { "CPU_MOVDIR64B_FLAGS",
303 "CpuMOVDIR64B" },
304 { "CPU_ENQCMD_FLAGS",
305 "CpuENQCMD" },
306 { "CPU_AVX512_VP2INTERSECT_FLAGS",
307 "CpuAVX512_VP2INTERSECT" },
308 { "CPU_RDPRU_FLAGS",
309 "CpuRDPRU" },
310 { "CPU_MCOMMIT_FLAGS",
311 "CpuMCOMMIT" },
312 { "CPU_SEV_ES_FLAGS",
313 "CpuSEV_ES" },
314 { "CPU_ANY_X87_FLAGS",
315 "CPU_ANY_287_FLAGS|Cpu8087" },
316 { "CPU_ANY_287_FLAGS",
317 "CPU_ANY_387_FLAGS|Cpu287" },
318 { "CPU_ANY_387_FLAGS",
319 "CPU_ANY_687_FLAGS|Cpu387" },
320 { "CPU_ANY_687_FLAGS",
321 "Cpu687|CpuFISTTP" },
322 { "CPU_ANY_CMOV_FLAGS",
323 "CpuCMOV" },
324 { "CPU_ANY_FXSR_FLAGS",
325 "CpuFXSR" },
326 { "CPU_ANY_MMX_FLAGS",
327 "CPU_3DNOWA_FLAGS" },
328 { "CPU_ANY_SSE_FLAGS",
329 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
330 { "CPU_ANY_SSE2_FLAGS",
331 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
332 { "CPU_ANY_SSE3_FLAGS",
333 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
334 { "CPU_ANY_SSSE3_FLAGS",
335 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
336 { "CPU_ANY_SSE4_1_FLAGS",
337 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
338 { "CPU_ANY_SSE4_2_FLAGS",
339 "CpuSSE4_2" },
340 { "CPU_ANY_SSE4A_FLAGS",
341 "CpuSSE4a" },
342 { "CPU_ANY_AVX_FLAGS",
343 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
344 { "CPU_ANY_AVX2_FLAGS",
345 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
346 { "CPU_ANY_AVX512F_FLAGS",
347 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
348 { "CPU_ANY_AVX512CD_FLAGS",
349 "CpuAVX512CD" },
350 { "CPU_ANY_AVX512ER_FLAGS",
351 "CpuAVX512ER" },
352 { "CPU_ANY_AVX512PF_FLAGS",
353 "CpuAVX512PF" },
354 { "CPU_ANY_AVX512DQ_FLAGS",
355 "CpuAVX512DQ" },
356 { "CPU_ANY_AVX512BW_FLAGS",
357 "CpuAVX512BW" },
358 { "CPU_ANY_AVX512VL_FLAGS",
359 "CpuAVX512VL" },
360 { "CPU_ANY_AVX512IFMA_FLAGS",
361 "CpuAVX512IFMA" },
362 { "CPU_ANY_AVX512VBMI_FLAGS",
363 "CpuAVX512VBMI" },
364 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
365 "CpuAVX512_4FMAPS" },
366 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
367 "CpuAVX512_4VNNIW" },
368 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
369 "CpuAVX512_VPOPCNTDQ" },
370 { "CPU_ANY_IBT_FLAGS",
371 "CpuIBT" },
372 { "CPU_ANY_SHSTK_FLAGS",
373 "CpuSHSTK" },
374 { "CPU_ANY_AVX512_VBMI2_FLAGS",
375 "CpuAVX512_VBMI2" },
376 { "CPU_ANY_AVX512_VNNI_FLAGS",
377 "CpuAVX512_VNNI" },
378 { "CPU_ANY_AVX512_BITALG_FLAGS",
379 "CpuAVX512_BITALG" },
380 { "CPU_ANY_AVX512_BF16_FLAGS",
381 "CpuAVX512_BF16" },
382 { "CPU_ANY_MOVDIRI_FLAGS",
383 "CpuMOVDIRI" },
384 { "CPU_ANY_MOVDIR64B_FLAGS",
385 "CpuMOVDIR64B" },
386 { "CPU_ANY_ENQCMD_FLAGS",
387 "CpuENQCMD" },
388 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
389 "CpuAVX512_VP2INTERSECT" },
390 };
391
392 static initializer operand_type_init[] =
393 {
394 { "OPERAND_TYPE_NONE",
395 "0" },
396 { "OPERAND_TYPE_REG8",
397 "Class=Reg|Byte" },
398 { "OPERAND_TYPE_REG16",
399 "Class=Reg|Word" },
400 { "OPERAND_TYPE_REG32",
401 "Class=Reg|Dword" },
402 { "OPERAND_TYPE_REG64",
403 "Class=Reg|Qword" },
404 { "OPERAND_TYPE_IMM1",
405 "Imm1" },
406 { "OPERAND_TYPE_IMM8",
407 "Imm8" },
408 { "OPERAND_TYPE_IMM8S",
409 "Imm8S" },
410 { "OPERAND_TYPE_IMM16",
411 "Imm16" },
412 { "OPERAND_TYPE_IMM32",
413 "Imm32" },
414 { "OPERAND_TYPE_IMM32S",
415 "Imm32S" },
416 { "OPERAND_TYPE_IMM64",
417 "Imm64" },
418 { "OPERAND_TYPE_BASEINDEX",
419 "BaseIndex" },
420 { "OPERAND_TYPE_DISP8",
421 "Disp8" },
422 { "OPERAND_TYPE_DISP16",
423 "Disp16" },
424 { "OPERAND_TYPE_DISP32",
425 "Disp32" },
426 { "OPERAND_TYPE_DISP32S",
427 "Disp32S" },
428 { "OPERAND_TYPE_DISP64",
429 "Disp64" },
430 { "OPERAND_TYPE_INOUTPORTREG",
431 "Instance=RegD|Word" },
432 { "OPERAND_TYPE_SHIFTCOUNT",
433 "Instance=RegC|Byte" },
434 { "OPERAND_TYPE_CONTROL",
435 "Class=RegCR" },
436 { "OPERAND_TYPE_TEST",
437 "Class=RegTR" },
438 { "OPERAND_TYPE_DEBUG",
439 "Class=RegDR" },
440 { "OPERAND_TYPE_FLOATREG",
441 "Class=Reg|Tbyte" },
442 { "OPERAND_TYPE_FLOATACC",
443 "Instance=Accum|Tbyte" },
444 { "OPERAND_TYPE_SREG",
445 "Class=SReg" },
446 { "OPERAND_TYPE_REGMMX",
447 "Class=RegMMX" },
448 { "OPERAND_TYPE_REGXMM",
449 "Class=RegSIMD|Xmmword" },
450 { "OPERAND_TYPE_REGYMM",
451 "Class=RegSIMD|Ymmword" },
452 { "OPERAND_TYPE_REGZMM",
453 "Class=RegSIMD|Zmmword" },
454 { "OPERAND_TYPE_REGMASK",
455 "Class=RegMask" },
456 { "OPERAND_TYPE_REGBND",
457 "Class=RegBND" },
458 { "OPERAND_TYPE_ACC8",
459 "Instance=Accum|Byte" },
460 { "OPERAND_TYPE_ACC16",
461 "Instance=Accum|Word" },
462 { "OPERAND_TYPE_ACC32",
463 "Instance=Accum|Dword" },
464 { "OPERAND_TYPE_ACC64",
465 "Instance=Accum|Qword" },
466 { "OPERAND_TYPE_DISP16_32",
467 "Disp16|Disp32" },
468 { "OPERAND_TYPE_ANYDISP",
469 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
470 { "OPERAND_TYPE_IMM16_32",
471 "Imm16|Imm32" },
472 { "OPERAND_TYPE_IMM16_32S",
473 "Imm16|Imm32S" },
474 { "OPERAND_TYPE_IMM16_32_32S",
475 "Imm16|Imm32|Imm32S" },
476 { "OPERAND_TYPE_IMM32_64",
477 "Imm32|Imm64" },
478 { "OPERAND_TYPE_IMM32_32S_DISP32",
479 "Imm32|Imm32S|Disp32" },
480 { "OPERAND_TYPE_IMM64_DISP64",
481 "Imm64|Disp64" },
482 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
483 "Imm32|Imm32S|Imm64|Disp32" },
484 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
485 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
486 { "OPERAND_TYPE_ANYIMM",
487 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
488 };
489
490 typedef struct bitfield
491 {
492 int position;
493 int value;
494 const char *name;
495 } bitfield;
496
497 #define BITFIELD(n) { n, 0, #n }
498
499 static bitfield cpu_flags[] =
500 {
501 BITFIELD (Cpu186),
502 BITFIELD (Cpu286),
503 BITFIELD (Cpu386),
504 BITFIELD (Cpu486),
505 BITFIELD (Cpu586),
506 BITFIELD (Cpu686),
507 BITFIELD (CpuCMOV),
508 BITFIELD (CpuFXSR),
509 BITFIELD (CpuClflush),
510 BITFIELD (CpuNop),
511 BITFIELD (CpuSYSCALL),
512 BITFIELD (Cpu8087),
513 BITFIELD (Cpu287),
514 BITFIELD (Cpu387),
515 BITFIELD (Cpu687),
516 BITFIELD (CpuFISTTP),
517 BITFIELD (CpuMMX),
518 BITFIELD (CpuSSE),
519 BITFIELD (CpuSSE2),
520 BITFIELD (CpuSSE3),
521 BITFIELD (CpuSSSE3),
522 BITFIELD (CpuSSE4_1),
523 BITFIELD (CpuSSE4_2),
524 BITFIELD (CpuAVX),
525 BITFIELD (CpuAVX2),
526 BITFIELD (CpuAVX512F),
527 BITFIELD (CpuAVX512CD),
528 BITFIELD (CpuAVX512ER),
529 BITFIELD (CpuAVX512PF),
530 BITFIELD (CpuAVX512VL),
531 BITFIELD (CpuAVX512DQ),
532 BITFIELD (CpuAVX512BW),
533 BITFIELD (CpuL1OM),
534 BITFIELD (CpuK1OM),
535 BITFIELD (CpuIAMCU),
536 BITFIELD (CpuSSE4a),
537 BITFIELD (Cpu3dnow),
538 BITFIELD (Cpu3dnowA),
539 BITFIELD (CpuPadLock),
540 BITFIELD (CpuSVME),
541 BITFIELD (CpuVMX),
542 BITFIELD (CpuSMX),
543 BITFIELD (CpuXsave),
544 BITFIELD (CpuXsaveopt),
545 BITFIELD (CpuAES),
546 BITFIELD (CpuPCLMUL),
547 BITFIELD (CpuFMA),
548 BITFIELD (CpuFMA4),
549 BITFIELD (CpuXOP),
550 BITFIELD (CpuLWP),
551 BITFIELD (CpuBMI),
552 BITFIELD (CpuTBM),
553 BITFIELD (CpuLM),
554 BITFIELD (CpuMovbe),
555 BITFIELD (CpuCX16),
556 BITFIELD (CpuEPT),
557 BITFIELD (CpuRdtscp),
558 BITFIELD (CpuFSGSBase),
559 BITFIELD (CpuRdRnd),
560 BITFIELD (CpuF16C),
561 BITFIELD (CpuBMI2),
562 BITFIELD (CpuLZCNT),
563 BITFIELD (CpuPOPCNT),
564 BITFIELD (CpuHLE),
565 BITFIELD (CpuRTM),
566 BITFIELD (CpuINVPCID),
567 BITFIELD (CpuVMFUNC),
568 BITFIELD (CpuRDSEED),
569 BITFIELD (CpuADX),
570 BITFIELD (CpuPRFCHW),
571 BITFIELD (CpuSMAP),
572 BITFIELD (CpuSHA),
573 BITFIELD (CpuClflushOpt),
574 BITFIELD (CpuXSAVES),
575 BITFIELD (CpuXSAVEC),
576 BITFIELD (CpuPREFETCHWT1),
577 BITFIELD (CpuSE1),
578 BITFIELD (CpuCLWB),
579 BITFIELD (Cpu64),
580 BITFIELD (CpuNo64),
581 BITFIELD (CpuMPX),
582 BITFIELD (CpuAVX512IFMA),
583 BITFIELD (CpuAVX512VBMI),
584 BITFIELD (CpuAVX512_4FMAPS),
585 BITFIELD (CpuAVX512_4VNNIW),
586 BITFIELD (CpuAVX512_VPOPCNTDQ),
587 BITFIELD (CpuAVX512_VBMI2),
588 BITFIELD (CpuAVX512_VNNI),
589 BITFIELD (CpuAVX512_BITALG),
590 BITFIELD (CpuAVX512_BF16),
591 BITFIELD (CpuAVX512_VP2INTERSECT),
592 BITFIELD (CpuMWAITX),
593 BITFIELD (CpuCLZERO),
594 BITFIELD (CpuOSPKE),
595 BITFIELD (CpuRDPID),
596 BITFIELD (CpuPTWRITE),
597 BITFIELD (CpuIBT),
598 BITFIELD (CpuSHSTK),
599 BITFIELD (CpuGFNI),
600 BITFIELD (CpuVAES),
601 BITFIELD (CpuVPCLMULQDQ),
602 BITFIELD (CpuWBNOINVD),
603 BITFIELD (CpuPCONFIG),
604 BITFIELD (CpuWAITPKG),
605 BITFIELD (CpuCLDEMOTE),
606 BITFIELD (CpuMOVDIRI),
607 BITFIELD (CpuMOVDIR64B),
608 BITFIELD (CpuENQCMD),
609 BITFIELD (CpuRDPRU),
610 BITFIELD (CpuMCOMMIT),
611 BITFIELD (CpuSEV_ES),
612 #ifdef CpuUnused
613 BITFIELD (CpuUnused),
614 #endif
615 };
616
617 static bitfield opcode_modifiers[] =
618 {
619 BITFIELD (D),
620 BITFIELD (W),
621 BITFIELD (Load),
622 BITFIELD (Modrm),
623 BITFIELD (Jump),
624 BITFIELD (FloatMF),
625 BITFIELD (FloatR),
626 BITFIELD (Size),
627 BITFIELD (CheckRegSize),
628 BITFIELD (MnemonicSize),
629 BITFIELD (Anysize),
630 BITFIELD (No_bSuf),
631 BITFIELD (No_wSuf),
632 BITFIELD (No_lSuf),
633 BITFIELD (No_sSuf),
634 BITFIELD (No_qSuf),
635 BITFIELD (No_ldSuf),
636 BITFIELD (FWait),
637 BITFIELD (IsString),
638 BITFIELD (RegMem),
639 BITFIELD (BNDPrefixOk),
640 BITFIELD (NoTrackPrefixOk),
641 BITFIELD (IsLockable),
642 BITFIELD (RegKludge),
643 BITFIELD (Implicit1stXmm0),
644 BITFIELD (RepPrefixOk),
645 BITFIELD (HLEPrefixOk),
646 BITFIELD (ToDword),
647 BITFIELD (ToQword),
648 BITFIELD (AddrPrefixOpReg),
649 BITFIELD (IsPrefix),
650 BITFIELD (ImmExt),
651 BITFIELD (NoRex64),
652 BITFIELD (Rex64),
653 BITFIELD (Ugh),
654 BITFIELD (Vex),
655 BITFIELD (VexVVVV),
656 BITFIELD (VexW),
657 BITFIELD (VexOpcode),
658 BITFIELD (VexSources),
659 BITFIELD (VecSIB),
660 BITFIELD (SSE2AVX),
661 BITFIELD (NoAVX),
662 BITFIELD (EVex),
663 BITFIELD (Masking),
664 BITFIELD (Broadcast),
665 BITFIELD (StaticRounding),
666 BITFIELD (SAE),
667 BITFIELD (Disp8MemShift),
668 BITFIELD (NoDefMask),
669 BITFIELD (ImplicitQuadGroup),
670 BITFIELD (Optimize),
671 BITFIELD (ATTMnemonic),
672 BITFIELD (ATTSyntax),
673 BITFIELD (IntelSyntax),
674 BITFIELD (ISA64),
675 };
676
677 #define CLASS(n) #n, n
678
679 static const struct {
680 const char *name;
681 enum operand_class value;
682 } operand_classes[] = {
683 CLASS (Reg),
684 CLASS (SReg),
685 CLASS (RegCR),
686 CLASS (RegDR),
687 CLASS (RegTR),
688 CLASS (RegMMX),
689 CLASS (RegSIMD),
690 CLASS (RegMask),
691 CLASS (RegBND),
692 };
693
694 #undef CLASS
695
696 #define INSTANCE(n) #n, n
697
698 static const struct {
699 const char *name;
700 enum operand_instance value;
701 } operand_instances[] = {
702 INSTANCE (Accum),
703 INSTANCE (RegC),
704 INSTANCE (RegD),
705 INSTANCE (RegB),
706 };
707
708 #undef INSTANCE
709
710 static bitfield operand_types[] =
711 {
712 BITFIELD (Imm1),
713 BITFIELD (Imm8),
714 BITFIELD (Imm8S),
715 BITFIELD (Imm16),
716 BITFIELD (Imm32),
717 BITFIELD (Imm32S),
718 BITFIELD (Imm64),
719 BITFIELD (BaseIndex),
720 BITFIELD (Disp8),
721 BITFIELD (Disp16),
722 BITFIELD (Disp32),
723 BITFIELD (Disp32S),
724 BITFIELD (Disp64),
725 BITFIELD (Byte),
726 BITFIELD (Word),
727 BITFIELD (Dword),
728 BITFIELD (Fword),
729 BITFIELD (Qword),
730 BITFIELD (Tbyte),
731 BITFIELD (Xmmword),
732 BITFIELD (Ymmword),
733 BITFIELD (Zmmword),
734 BITFIELD (Unspecified),
735 #ifdef OTUnused
736 BITFIELD (OTUnused),
737 #endif
738 };
739
740 static const char *filename;
741 static i386_cpu_flags active_cpu_flags;
742 static int active_isstring;
743
744 static int
745 compare (const void *x, const void *y)
746 {
747 const bitfield *xp = (const bitfield *) x;
748 const bitfield *yp = (const bitfield *) y;
749 return xp->position - yp->position;
750 }
751
752 static void
753 fail (const char *message, ...)
754 {
755 va_list args;
756
757 va_start (args, message);
758 fprintf (stderr, _("%s: error: "), program_name);
759 vfprintf (stderr, message, args);
760 va_end (args);
761 xexit (1);
762 }
763
764 static void
765 process_copyright (FILE *fp)
766 {
767 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
768 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
769 \n\
770 This file is part of the GNU opcodes library.\n\
771 \n\
772 This library is free software; you can redistribute it and/or modify\n\
773 it under the terms of the GNU General Public License as published by\n\
774 the Free Software Foundation; either version 3, or (at your option)\n\
775 any later version.\n\
776 \n\
777 It is distributed in the hope that it will be useful, but WITHOUT\n\
778 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
779 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
780 License for more details.\n\
781 \n\
782 You should have received a copy of the GNU General Public License\n\
783 along with this program; if not, write to the Free Software\n\
784 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
785 MA 02110-1301, USA. */\n");
786 }
787
788 /* Remove leading white spaces. */
789
790 static char *
791 remove_leading_whitespaces (char *str)
792 {
793 while (ISSPACE (*str))
794 str++;
795 return str;
796 }
797
798 /* Remove trailing white spaces. */
799
800 static void
801 remove_trailing_whitespaces (char *str)
802 {
803 size_t last = strlen (str);
804
805 if (last == 0)
806 return;
807
808 do
809 {
810 last--;
811 if (ISSPACE (str [last]))
812 str[last] = '\0';
813 else
814 break;
815 }
816 while (last != 0);
817 }
818
819 /* Find next field separated by SEP and terminate it. Return a
820 pointer to the one after it. */
821
822 static char *
823 next_field (char *str, char sep, char **next, char *last)
824 {
825 char *p;
826
827 p = remove_leading_whitespaces (str);
828 for (str = p; *str != sep && *str != '\0'; str++);
829
830 *str = '\0';
831 remove_trailing_whitespaces (p);
832
833 *next = str + 1;
834
835 if (p >= last)
836 abort ();
837
838 return p;
839 }
840
841 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
842
843 static int
844 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
845 int lineno)
846 {
847 char *str, *next, *last;
848 unsigned int i;
849
850 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
851 if (strcmp (cpu_flag_init[i].name, f) == 0)
852 {
853 /* Turn on selective bits. */
854 char *init = xstrdup (cpu_flag_init[i].init);
855 last = init + strlen (init);
856 for (next = init; next && next < last; )
857 {
858 str = next_field (next, '|', &next, last);
859 if (str)
860 set_bitfield (str, array, 1, size, lineno);
861 }
862 free (init);
863 return 0;
864 }
865
866 return -1;
867 }
868
869 static void
870 set_bitfield (char *f, bitfield *array, int value,
871 unsigned int size, int lineno)
872 {
873 unsigned int i;
874
875 if (strcmp (f, "CpuFP") == 0)
876 {
877 set_bitfield("Cpu387", array, value, size, lineno);
878 set_bitfield("Cpu287", array, value, size, lineno);
879 f = "Cpu8087";
880 }
881 else if (strcmp (f, "Mmword") == 0)
882 f= "Qword";
883 else if (strcmp (f, "Oword") == 0)
884 f= "Xmmword";
885
886 for (i = 0; i < size; i++)
887 if (strcasecmp (array[i].name, f) == 0)
888 {
889 array[i].value = value;
890 return;
891 }
892
893 if (value)
894 {
895 const char *v = strchr (f, '=');
896
897 if (v)
898 {
899 size_t n = v - f;
900 char *end;
901
902 for (i = 0; i < size; i++)
903 if (strncasecmp (array[i].name, f, n) == 0)
904 {
905 value = strtol (v + 1, &end, 0);
906 if (*end == '\0')
907 {
908 array[i].value = value;
909 return;
910 }
911 break;
912 }
913 }
914 }
915
916 /* Handle CPU_XXX_FLAGS. */
917 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
918 return;
919
920 if (lineno != -1)
921 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
922 else
923 fail (_("unknown bitfield: %s\n"), f);
924 }
925
926 static void
927 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
928 int macro, const char *comma, const char *indent)
929 {
930 unsigned int i;
931
932 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
933
934 fprintf (table, "%s{ { ", indent);
935
936 for (i = 0; i < size - 1; i++)
937 {
938 if (((i + 1) % 20) != 0)
939 fprintf (table, "%d, ", flags[i].value);
940 else
941 fprintf (table, "%d,", flags[i].value);
942 if (((i + 1) % 20) == 0)
943 {
944 /* We need \\ for macro. */
945 if (macro)
946 fprintf (table, " \\\n %s", indent);
947 else
948 fprintf (table, "\n %s", indent);
949 }
950 if (flags[i].value)
951 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
952 }
953
954 fprintf (table, "%d } }%s\n", flags[i].value, comma);
955 }
956
957 static void
958 process_i386_cpu_flag (FILE *table, char *flag, int macro,
959 const char *comma, const char *indent,
960 int lineno)
961 {
962 char *str, *next, *last;
963 unsigned int i;
964 bitfield flags [ARRAY_SIZE (cpu_flags)];
965
966 /* Copy the default cpu flags. */
967 memcpy (flags, cpu_flags, sizeof (cpu_flags));
968
969 if (strcasecmp (flag, "unknown") == 0)
970 {
971 /* We turn on everything except for cpu64 in case of
972 CPU_UNKNOWN_FLAGS. */
973 for (i = 0; i < ARRAY_SIZE (flags); i++)
974 if (flags[i].position != Cpu64)
975 flags[i].value = 1;
976 }
977 else if (flag[0] == '~')
978 {
979 last = flag + strlen (flag);
980
981 if (flag[1] == '(')
982 {
983 last -= 1;
984 next = flag + 2;
985 if (*last != ')')
986 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
987 lineno, flag);
988 *last = '\0';
989 }
990 else
991 next = flag + 1;
992
993 /* First we turn on everything except for cpu64. */
994 for (i = 0; i < ARRAY_SIZE (flags); i++)
995 if (flags[i].position != Cpu64)
996 flags[i].value = 1;
997
998 /* Turn off selective bits. */
999 for (; next && next < last; )
1000 {
1001 str = next_field (next, '|', &next, last);
1002 if (str)
1003 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1004 }
1005 }
1006 else if (strcmp (flag, "0"))
1007 {
1008 /* Turn on selective bits. */
1009 last = flag + strlen (flag);
1010 for (next = flag; next && next < last; )
1011 {
1012 str = next_field (next, '|', &next, last);
1013 if (str)
1014 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1015 }
1016 }
1017
1018 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1019 comma, indent);
1020 }
1021
1022 static void
1023 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1024 {
1025 unsigned int i;
1026
1027 fprintf (table, " { ");
1028
1029 for (i = 0; i < size - 1; i++)
1030 {
1031 if (((i + 1) % 20) != 0)
1032 fprintf (table, "%d, ", modifier[i].value);
1033 else
1034 fprintf (table, "%d,", modifier[i].value);
1035 if (((i + 1) % 20) == 0)
1036 fprintf (table, "\n ");
1037 }
1038
1039 fprintf (table, "%d },\n", modifier[i].value);
1040 }
1041
1042 static int
1043 adjust_broadcast_modifier (char **opnd)
1044 {
1045 char *str, *next, *last, *op;
1046 int bcst_type = INT_MAX;
1047
1048 /* Skip the immediate operand. */
1049 op = opnd[0];
1050 if (strcasecmp(op, "Imm8") == 0)
1051 op = opnd[1];
1052
1053 op = xstrdup (op);
1054 last = op + strlen (op);
1055 for (next = op; next && next < last; )
1056 {
1057 str = next_field (next, '|', &next, last);
1058 if (str)
1059 {
1060 if (strcasecmp(str, "Byte") == 0)
1061 {
1062 /* The smalest broadcast type, no need to check
1063 further. */
1064 bcst_type = BYTE_BROADCAST;
1065 break;
1066 }
1067 else if (strcasecmp(str, "Word") == 0)
1068 {
1069 if (bcst_type > WORD_BROADCAST)
1070 bcst_type = WORD_BROADCAST;
1071 }
1072 else if (strcasecmp(str, "Dword") == 0)
1073 {
1074 if (bcst_type > DWORD_BROADCAST)
1075 bcst_type = DWORD_BROADCAST;
1076 }
1077 else if (strcasecmp(str, "Qword") == 0)
1078 {
1079 if (bcst_type > QWORD_BROADCAST)
1080 bcst_type = QWORD_BROADCAST;
1081 }
1082 }
1083 }
1084 free (op);
1085
1086 if (bcst_type == INT_MAX)
1087 fail (_("unknown broadcast operand: %s\n"), op);
1088
1089 return bcst_type;
1090 }
1091
1092 static void
1093 process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
1094 {
1095 char *str, *next, *last;
1096 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1097
1098 active_isstring = 0;
1099
1100 /* Copy the default opcode modifier. */
1101 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1102
1103 if (strcmp (mod, "0"))
1104 {
1105 unsigned int have_w = 0, bwlq_suf = 0xf;
1106
1107 last = mod + strlen (mod);
1108 for (next = mod; next && next < last; )
1109 {
1110 str = next_field (next, '|', &next, last);
1111 if (str)
1112 {
1113 int val = 1;
1114 if (strcasecmp(str, "Broadcast") == 0)
1115 val = adjust_broadcast_modifier (opnd);
1116 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1117 lineno);
1118 if (strcasecmp(str, "IsString") == 0)
1119 active_isstring = 1;
1120
1121 if (strcasecmp(str, "W") == 0)
1122 have_w = 1;
1123
1124 if (strcasecmp(str, "No_bSuf") == 0)
1125 bwlq_suf &= ~1;
1126 if (strcasecmp(str, "No_wSuf") == 0)
1127 bwlq_suf &= ~2;
1128 if (strcasecmp(str, "No_lSuf") == 0)
1129 bwlq_suf &= ~4;
1130 if (strcasecmp(str, "No_qSuf") == 0)
1131 bwlq_suf &= ~8;
1132 }
1133 }
1134
1135 if (have_w && !bwlq_suf)
1136 fail ("%s: %d: stray W modifier\n", filename, lineno);
1137 if (have_w && !(bwlq_suf & 1))
1138 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1139 filename, lineno);
1140 if (have_w && !(bwlq_suf & ~1))
1141 fprintf (stderr,
1142 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1143 filename, lineno);
1144 }
1145 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1146 }
1147
1148 enum stage {
1149 stage_macros,
1150 stage_opcodes,
1151 stage_registers,
1152 };
1153
1154 static void
1155 output_operand_type (FILE *table, enum operand_class class,
1156 enum operand_instance instance,
1157 const bitfield *types, unsigned int size,
1158 enum stage stage, const char *indent)
1159 {
1160 unsigned int i;
1161
1162 fprintf (table, "{ { %d, %d, ", class, instance);
1163
1164 for (i = 0; i < size - 1; i++)
1165 {
1166 if (((i + 3) % 20) != 0)
1167 fprintf (table, "%d, ", types[i].value);
1168 else
1169 fprintf (table, "%d,", types[i].value);
1170 if (((i + 3) % 20) == 0)
1171 {
1172 /* We need \\ for macro. */
1173 if (stage == stage_macros)
1174 fprintf (table, " \\\n%s", indent);
1175 else
1176 fprintf (table, "\n%s", indent);
1177 }
1178 }
1179
1180 fprintf (table, "%d } }", types[i].value);
1181 }
1182
1183 static void
1184 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1185 const char *indent, int lineno)
1186 {
1187 char *str, *next, *last;
1188 enum operand_class class = ClassNone;
1189 enum operand_instance instance = InstanceNone;
1190 bitfield types [ARRAY_SIZE (operand_types)];
1191
1192 /* Copy the default operand type. */
1193 memcpy (types, operand_types, sizeof (types));
1194
1195 if (strcmp (op, "0"))
1196 {
1197 int baseindex = 0;
1198
1199 last = op + strlen (op);
1200 for (next = op; next && next < last; )
1201 {
1202 str = next_field (next, '|', &next, last);
1203 if (str)
1204 {
1205 unsigned int i;
1206
1207 if (!strncmp(str, "Class=", 6))
1208 {
1209 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1210 if (!strcmp(str + 6, operand_classes[i].name))
1211 {
1212 class = operand_classes[i].value;
1213 str = NULL;
1214 break;
1215 }
1216 }
1217
1218 if (str && !strncmp(str, "Instance=", 9))
1219 {
1220 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1221 if (!strcmp(str + 9, operand_instances[i].name))
1222 {
1223 instance = operand_instances[i].value;
1224 str = NULL;
1225 break;
1226 }
1227 }
1228 }
1229 if (str)
1230 {
1231 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1232 if (strcasecmp(str, "BaseIndex") == 0)
1233 baseindex = 1;
1234 }
1235 }
1236
1237 if (stage == stage_opcodes && baseindex && !active_isstring)
1238 {
1239 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1240 if (!active_cpu_flags.bitfield.cpu64
1241 && !active_cpu_flags.bitfield.cpumpx)
1242 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1243 if (!active_cpu_flags.bitfield.cpu64)
1244 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1245 if (!active_cpu_flags.bitfield.cpuno64)
1246 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1247 }
1248 }
1249 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1250 stage, indent);
1251 }
1252
1253 static void
1254 output_i386_opcode (FILE *table, const char *name, char *str,
1255 char *last, int lineno)
1256 {
1257 unsigned int i;
1258 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1259 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1260
1261 /* Find number of operands. */
1262 operands = next_field (str, ',', &str, last);
1263
1264 /* Find base_opcode. */
1265 base_opcode = next_field (str, ',', &str, last);
1266
1267 /* Find extension_opcode. */
1268 extension_opcode = next_field (str, ',', &str, last);
1269
1270 /* Find opcode_length. */
1271 opcode_length = next_field (str, ',', &str, last);
1272
1273 /* Find cpu_flags. */
1274 cpu_flags = next_field (str, ',', &str, last);
1275
1276 /* Find opcode_modifier. */
1277 opcode_modifier = next_field (str, ',', &str, last);
1278
1279 /* Remove the first {. */
1280 str = remove_leading_whitespaces (str);
1281 if (*str != '{')
1282 abort ();
1283 str = remove_leading_whitespaces (str + 1);
1284
1285 i = strlen (str);
1286
1287 /* There are at least "X}". */
1288 if (i < 2)
1289 abort ();
1290
1291 /* Remove trailing white spaces and }. */
1292 do
1293 {
1294 i--;
1295 if (ISSPACE (str[i]) || str[i] == '}')
1296 str[i] = '\0';
1297 else
1298 break;
1299 }
1300 while (i != 0);
1301
1302 last = str + i;
1303
1304 /* Find operand_types. */
1305 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1306 {
1307 if (str >= last)
1308 {
1309 operand_types [i] = NULL;
1310 break;
1311 }
1312
1313 operand_types [i] = next_field (str, ',', &str, last);
1314 if (*operand_types[i] == '0')
1315 {
1316 if (i != 0)
1317 operand_types[i] = NULL;
1318 break;
1319 }
1320 }
1321
1322 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1323 name, base_opcode, extension_opcode, opcode_length, operands);
1324
1325 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1326
1327 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
1328
1329 fprintf (table, " { ");
1330
1331 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1332 {
1333 if (operand_types[i] == NULL || *operand_types[i] == '0')
1334 {
1335 if (i == 0)
1336 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1337 lineno);
1338 break;
1339 }
1340
1341 if (i != 0)
1342 fprintf (table, ",\n ");
1343
1344 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1345 "\t ", lineno);
1346 }
1347 fprintf (table, " } },\n");
1348 }
1349
1350 struct opcode_hash_entry
1351 {
1352 struct opcode_hash_entry *next;
1353 char *name;
1354 char *opcode;
1355 int lineno;
1356 };
1357
1358 /* Calculate the hash value of an opcode hash entry P. */
1359
1360 static hashval_t
1361 opcode_hash_hash (const void *p)
1362 {
1363 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1364 return htab_hash_string (entry->name);
1365 }
1366
1367 /* Compare a string Q against an opcode hash entry P. */
1368
1369 static int
1370 opcode_hash_eq (const void *p, const void *q)
1371 {
1372 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1373 const char *name = (const char *) q;
1374 return strcmp (name, entry->name) == 0;
1375 }
1376
1377 static void
1378 process_i386_opcodes (FILE *table)
1379 {
1380 FILE *fp;
1381 char buf[2048];
1382 unsigned int i, j;
1383 char *str, *p, *last, *name;
1384 struct opcode_hash_entry **hash_slot, **entry, *next;
1385 htab_t opcode_hash_table;
1386 struct opcode_hash_entry **opcode_array;
1387 unsigned int opcode_array_size = 1024;
1388 int lineno = 0, marker = 0;
1389
1390 filename = "i386-opc.tbl";
1391 fp = stdin;
1392
1393 i = 0;
1394 opcode_array = (struct opcode_hash_entry **)
1395 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1396
1397 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1398 opcode_hash_eq, NULL,
1399 xcalloc, free);
1400
1401 fprintf (table, "\n/* i386 opcode table. */\n\n");
1402 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1403
1404 /* Put everything on opcode array. */
1405 while (!feof (fp))
1406 {
1407 if (fgets (buf, sizeof (buf), fp) == NULL)
1408 break;
1409
1410 lineno++;
1411
1412 p = remove_leading_whitespaces (buf);
1413
1414 /* Skip comments. */
1415 str = strstr (p, "//");
1416 if (str != NULL)
1417 str[0] = '\0';
1418
1419 /* Remove trailing white spaces. */
1420 remove_trailing_whitespaces (p);
1421
1422 switch (p[0])
1423 {
1424 case '#':
1425 if (!strcmp("### MARKER ###", buf))
1426 marker = 1;
1427 else
1428 {
1429 /* Since we ignore all included files (we only care about their
1430 #define-s here), we don't need to monitor filenames. The final
1431 line number directive is going to refer to the main source file
1432 again. */
1433 char *end;
1434 unsigned long ln;
1435
1436 p = remove_leading_whitespaces (p + 1);
1437 if (!strncmp(p, "line", 4))
1438 p += 4;
1439 ln = strtoul (p, &end, 10);
1440 if (ln > 1 && ln < INT_MAX
1441 && *remove_leading_whitespaces (end) == '"')
1442 lineno = ln - 1;
1443 }
1444 /* Ignore comments. */
1445 case '\0':
1446 continue;
1447 break;
1448 default:
1449 if (!marker)
1450 continue;
1451 break;
1452 }
1453
1454 last = p + strlen (p);
1455
1456 /* Find name. */
1457 name = next_field (p, ',', &str, last);
1458
1459 /* Get the slot in hash table. */
1460 hash_slot = (struct opcode_hash_entry **)
1461 htab_find_slot_with_hash (opcode_hash_table, name,
1462 htab_hash_string (name),
1463 INSERT);
1464
1465 if (*hash_slot == NULL)
1466 {
1467 /* It is the new one. Put it on opcode array. */
1468 if (i >= opcode_array_size)
1469 {
1470 /* Grow the opcode array when needed. */
1471 opcode_array_size += 1024;
1472 opcode_array = (struct opcode_hash_entry **)
1473 xrealloc (opcode_array,
1474 sizeof (*opcode_array) * opcode_array_size);
1475 }
1476
1477 opcode_array[i] = (struct opcode_hash_entry *)
1478 xmalloc (sizeof (struct opcode_hash_entry));
1479 opcode_array[i]->next = NULL;
1480 opcode_array[i]->name = xstrdup (name);
1481 opcode_array[i]->opcode = xstrdup (str);
1482 opcode_array[i]->lineno = lineno;
1483 *hash_slot = opcode_array[i];
1484 i++;
1485 }
1486 else
1487 {
1488 /* Append it to the existing one. */
1489 entry = hash_slot;
1490 while ((*entry) != NULL)
1491 entry = &(*entry)->next;
1492 *entry = (struct opcode_hash_entry *)
1493 xmalloc (sizeof (struct opcode_hash_entry));
1494 (*entry)->next = NULL;
1495 (*entry)->name = (*hash_slot)->name;
1496 (*entry)->opcode = xstrdup (str);
1497 (*entry)->lineno = lineno;
1498 }
1499 }
1500
1501 /* Process opcode array. */
1502 for (j = 0; j < i; j++)
1503 {
1504 for (next = opcode_array[j]; next; next = next->next)
1505 {
1506 name = next->name;
1507 str = next->opcode;
1508 lineno = next->lineno;
1509 last = str + strlen (str);
1510 output_i386_opcode (table, name, str, last, lineno);
1511 }
1512 }
1513
1514 fclose (fp);
1515
1516 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1517
1518 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1519
1520 process_i386_opcode_modifier (table, "0", NULL, -1);
1521
1522 fprintf (table, " { ");
1523 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1524 fprintf (table, " } }\n");
1525
1526 fprintf (table, "};\n");
1527 }
1528
1529 static void
1530 process_i386_registers (FILE *table)
1531 {
1532 FILE *fp;
1533 char buf[2048];
1534 char *str, *p, *last;
1535 char *reg_name, *reg_type, *reg_flags, *reg_num;
1536 char *dw2_32_num, *dw2_64_num;
1537 int lineno = 0;
1538
1539 filename = "i386-reg.tbl";
1540 fp = fopen (filename, "r");
1541 if (fp == NULL)
1542 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1543 xstrerror (errno));
1544
1545 fprintf (table, "\n/* i386 register table. */\n\n");
1546 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1547
1548 while (!feof (fp))
1549 {
1550 if (fgets (buf, sizeof (buf), fp) == NULL)
1551 break;
1552
1553 lineno++;
1554
1555 p = remove_leading_whitespaces (buf);
1556
1557 /* Skip comments. */
1558 str = strstr (p, "//");
1559 if (str != NULL)
1560 str[0] = '\0';
1561
1562 /* Remove trailing white spaces. */
1563 remove_trailing_whitespaces (p);
1564
1565 switch (p[0])
1566 {
1567 case '#':
1568 fprintf (table, "%s\n", p);
1569 case '\0':
1570 continue;
1571 break;
1572 default:
1573 break;
1574 }
1575
1576 last = p + strlen (p);
1577
1578 /* Find reg_name. */
1579 reg_name = next_field (p, ',', &str, last);
1580
1581 /* Find reg_type. */
1582 reg_type = next_field (str, ',', &str, last);
1583
1584 /* Find reg_flags. */
1585 reg_flags = next_field (str, ',', &str, last);
1586
1587 /* Find reg_num. */
1588 reg_num = next_field (str, ',', &str, last);
1589
1590 fprintf (table, " { \"%s\",\n ", reg_name);
1591
1592 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1593 lineno);
1594
1595 /* Find 32-bit Dwarf2 register number. */
1596 dw2_32_num = next_field (str, ',', &str, last);
1597
1598 /* Find 64-bit Dwarf2 register number. */
1599 dw2_64_num = next_field (str, ',', &str, last);
1600
1601 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1602 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1603 }
1604
1605 fclose (fp);
1606
1607 fprintf (table, "};\n");
1608
1609 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1610 }
1611
1612 static void
1613 process_i386_initializers (void)
1614 {
1615 unsigned int i;
1616 FILE *fp = fopen ("i386-init.h", "w");
1617 char *init;
1618
1619 if (fp == NULL)
1620 fail (_("can't create i386-init.h, errno = %s\n"),
1621 xstrerror (errno));
1622
1623 process_copyright (fp);
1624
1625 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1626 {
1627 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1628 init = xstrdup (cpu_flag_init[i].init);
1629 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1630 free (init);
1631 }
1632
1633 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1634 {
1635 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1636 init = xstrdup (operand_type_init[i].init);
1637 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1638 free (init);
1639 }
1640 fprintf (fp, "\n");
1641
1642 fclose (fp);
1643 }
1644
1645 /* Program options. */
1646 #define OPTION_SRCDIR 200
1647
1648 struct option long_options[] =
1649 {
1650 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1651 {"debug", no_argument, NULL, 'd'},
1652 {"version", no_argument, NULL, 'V'},
1653 {"help", no_argument, NULL, 'h'},
1654 {0, no_argument, NULL, 0}
1655 };
1656
1657 static void
1658 print_version (void)
1659 {
1660 printf ("%s: version 1.0\n", program_name);
1661 xexit (0);
1662 }
1663
1664 static void
1665 usage (FILE * stream, int status)
1666 {
1667 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1668 program_name);
1669 xexit (status);
1670 }
1671
1672 int
1673 main (int argc, char **argv)
1674 {
1675 extern int chdir (char *);
1676 char *srcdir = NULL;
1677 int c;
1678 unsigned int i, cpumax;
1679 FILE *table;
1680
1681 program_name = *argv;
1682 xmalloc_set_program_name (program_name);
1683
1684 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1685 switch (c)
1686 {
1687 case OPTION_SRCDIR:
1688 srcdir = optarg;
1689 break;
1690 case 'V':
1691 case 'v':
1692 print_version ();
1693 break;
1694 case 'd':
1695 debug = 1;
1696 break;
1697 case 'h':
1698 case '?':
1699 usage (stderr, 0);
1700 default:
1701 case 0:
1702 break;
1703 }
1704
1705 if (optind != argc)
1706 usage (stdout, 1);
1707
1708 if (srcdir != NULL)
1709 if (chdir (srcdir) != 0)
1710 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1711 srcdir, xstrerror (errno));
1712
1713 /* cpu_flags isn't sorted by position. */
1714 cpumax = 0;
1715 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1716 if (cpu_flags[i].position > cpumax)
1717 cpumax = cpu_flags[i].position;
1718
1719 /* Check the unused bitfield in i386_cpu_flags. */
1720 #ifdef CpuUnused
1721 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1722
1723 if ((cpumax - 1) != CpuMax)
1724 fail (_("CpuMax != %d!\n"), cpumax);
1725 #else
1726 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1727
1728 if (cpumax != CpuMax)
1729 fail (_("CpuMax != %d!\n"), cpumax);
1730
1731 c = CpuNumOfBits - CpuMax - 1;
1732 if (c)
1733 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1734 #endif
1735
1736 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1737
1738 /* Check the unused bitfield in i386_operand_type. */
1739 #ifdef OTUnused
1740 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1741 == OTNum + 1);
1742 #else
1743 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1744 == OTNum);
1745
1746 c = OTNumOfBits - OTNum;
1747 if (c)
1748 fail (_("%d unused bits in i386_operand_type.\n"), c);
1749 #endif
1750
1751 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1752 compare);
1753
1754 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1755 sizeof (opcode_modifiers [0]), compare);
1756
1757 qsort (operand_types, ARRAY_SIZE (operand_types),
1758 sizeof (operand_types [0]), compare);
1759
1760 table = fopen ("i386-tbl.h", "w");
1761 if (table == NULL)
1762 fail (_("can't create i386-tbl.h, errno = %s\n"),
1763 xstrerror (errno));
1764
1765 process_copyright (table);
1766
1767 process_i386_opcodes (table);
1768 process_i386_registers (table);
1769 process_i386_initializers ();
1770
1771 fclose (table);
1772
1773 exit (0);
1774 }
This page took 0.130353 seconds and 5 git commands to generate.