x86: drop/replace IgnoreSize
[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 (Ugh),
653 BITFIELD (Vex),
654 BITFIELD (VexVVVV),
655 BITFIELD (VexW),
656 BITFIELD (VexOpcode),
657 BITFIELD (VexSources),
658 BITFIELD (VecSIB),
659 BITFIELD (SSE2AVX),
660 BITFIELD (NoAVX),
661 BITFIELD (EVex),
662 BITFIELD (Masking),
663 BITFIELD (Broadcast),
664 BITFIELD (StaticRounding),
665 BITFIELD (SAE),
666 BITFIELD (Disp8MemShift),
667 BITFIELD (NoDefMask),
668 BITFIELD (ImplicitQuadGroup),
669 BITFIELD (Optimize),
670 BITFIELD (ATTMnemonic),
671 BITFIELD (ATTSyntax),
672 BITFIELD (IntelSyntax),
673 BITFIELD (ISA64),
674 };
675
676 #define CLASS(n) #n, n
677
678 static const struct {
679 const char *name;
680 enum operand_class value;
681 } operand_classes[] = {
682 CLASS (Reg),
683 CLASS (SReg),
684 CLASS (RegCR),
685 CLASS (RegDR),
686 CLASS (RegTR),
687 CLASS (RegMMX),
688 CLASS (RegSIMD),
689 CLASS (RegMask),
690 CLASS (RegBND),
691 };
692
693 #undef CLASS
694
695 #define INSTANCE(n) #n, n
696
697 static const struct {
698 const char *name;
699 enum operand_instance value;
700 } operand_instances[] = {
701 INSTANCE (Accum),
702 INSTANCE (RegC),
703 INSTANCE (RegD),
704 INSTANCE (RegB),
705 };
706
707 #undef INSTANCE
708
709 static bitfield operand_types[] =
710 {
711 BITFIELD (Imm1),
712 BITFIELD (Imm8),
713 BITFIELD (Imm8S),
714 BITFIELD (Imm16),
715 BITFIELD (Imm32),
716 BITFIELD (Imm32S),
717 BITFIELD (Imm64),
718 BITFIELD (BaseIndex),
719 BITFIELD (Disp8),
720 BITFIELD (Disp16),
721 BITFIELD (Disp32),
722 BITFIELD (Disp32S),
723 BITFIELD (Disp64),
724 BITFIELD (Byte),
725 BITFIELD (Word),
726 BITFIELD (Dword),
727 BITFIELD (Fword),
728 BITFIELD (Qword),
729 BITFIELD (Tbyte),
730 BITFIELD (Xmmword),
731 BITFIELD (Ymmword),
732 BITFIELD (Zmmword),
733 BITFIELD (Unspecified),
734 #ifdef OTUnused
735 BITFIELD (OTUnused),
736 #endif
737 };
738
739 static const char *filename;
740 static i386_cpu_flags active_cpu_flags;
741 static int active_isstring;
742
743 static int
744 compare (const void *x, const void *y)
745 {
746 const bitfield *xp = (const bitfield *) x;
747 const bitfield *yp = (const bitfield *) y;
748 return xp->position - yp->position;
749 }
750
751 static void
752 fail (const char *message, ...)
753 {
754 va_list args;
755
756 va_start (args, message);
757 fprintf (stderr, _("%s: error: "), program_name);
758 vfprintf (stderr, message, args);
759 va_end (args);
760 xexit (1);
761 }
762
763 static void
764 process_copyright (FILE *fp)
765 {
766 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
767 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
768 \n\
769 This file is part of the GNU opcodes library.\n\
770 \n\
771 This library is free software; you can redistribute it and/or modify\n\
772 it under the terms of the GNU General Public License as published by\n\
773 the Free Software Foundation; either version 3, or (at your option)\n\
774 any later version.\n\
775 \n\
776 It is distributed in the hope that it will be useful, but WITHOUT\n\
777 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
778 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
779 License for more details.\n\
780 \n\
781 You should have received a copy of the GNU General Public License\n\
782 along with this program; if not, write to the Free Software\n\
783 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
784 MA 02110-1301, USA. */\n");
785 }
786
787 /* Remove leading white spaces. */
788
789 static char *
790 remove_leading_whitespaces (char *str)
791 {
792 while (ISSPACE (*str))
793 str++;
794 return str;
795 }
796
797 /* Remove trailing white spaces. */
798
799 static void
800 remove_trailing_whitespaces (char *str)
801 {
802 size_t last = strlen (str);
803
804 if (last == 0)
805 return;
806
807 do
808 {
809 last--;
810 if (ISSPACE (str [last]))
811 str[last] = '\0';
812 else
813 break;
814 }
815 while (last != 0);
816 }
817
818 /* Find next field separated by SEP and terminate it. Return a
819 pointer to the one after it. */
820
821 static char *
822 next_field (char *str, char sep, char **next, char *last)
823 {
824 char *p;
825
826 p = remove_leading_whitespaces (str);
827 for (str = p; *str != sep && *str != '\0'; str++);
828
829 *str = '\0';
830 remove_trailing_whitespaces (p);
831
832 *next = str + 1;
833
834 if (p >= last)
835 abort ();
836
837 return p;
838 }
839
840 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
841
842 static int
843 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
844 int lineno)
845 {
846 char *str, *next, *last;
847 unsigned int i;
848
849 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
850 if (strcmp (cpu_flag_init[i].name, f) == 0)
851 {
852 /* Turn on selective bits. */
853 char *init = xstrdup (cpu_flag_init[i].init);
854 last = init + strlen (init);
855 for (next = init; next && next < last; )
856 {
857 str = next_field (next, '|', &next, last);
858 if (str)
859 set_bitfield (str, array, 1, size, lineno);
860 }
861 free (init);
862 return 0;
863 }
864
865 return -1;
866 }
867
868 static void
869 set_bitfield (char *f, bitfield *array, int value,
870 unsigned int size, int lineno)
871 {
872 unsigned int i;
873
874 if (strcmp (f, "CpuFP") == 0)
875 {
876 set_bitfield("Cpu387", array, value, size, lineno);
877 set_bitfield("Cpu287", array, value, size, lineno);
878 f = "Cpu8087";
879 }
880 else if (strcmp (f, "Mmword") == 0)
881 f= "Qword";
882 else if (strcmp (f, "Oword") == 0)
883 f= "Xmmword";
884
885 for (i = 0; i < size; i++)
886 if (strcasecmp (array[i].name, f) == 0)
887 {
888 array[i].value = value;
889 return;
890 }
891
892 if (value)
893 {
894 const char *v = strchr (f, '=');
895
896 if (v)
897 {
898 size_t n = v - f;
899 char *end;
900
901 for (i = 0; i < size; i++)
902 if (strncasecmp (array[i].name, f, n) == 0)
903 {
904 value = strtol (v + 1, &end, 0);
905 if (*end == '\0')
906 {
907 array[i].value = value;
908 return;
909 }
910 break;
911 }
912 }
913 }
914
915 /* Handle CPU_XXX_FLAGS. */
916 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
917 return;
918
919 if (lineno != -1)
920 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
921 else
922 fail (_("unknown bitfield: %s\n"), f);
923 }
924
925 static void
926 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
927 int macro, const char *comma, const char *indent)
928 {
929 unsigned int i;
930
931 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
932
933 fprintf (table, "%s{ { ", indent);
934
935 for (i = 0; i < size - 1; i++)
936 {
937 if (((i + 1) % 20) != 0)
938 fprintf (table, "%d, ", flags[i].value);
939 else
940 fprintf (table, "%d,", flags[i].value);
941 if (((i + 1) % 20) == 0)
942 {
943 /* We need \\ for macro. */
944 if (macro)
945 fprintf (table, " \\\n %s", indent);
946 else
947 fprintf (table, "\n %s", indent);
948 }
949 if (flags[i].value)
950 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
951 }
952
953 fprintf (table, "%d } }%s\n", flags[i].value, comma);
954 }
955
956 static void
957 process_i386_cpu_flag (FILE *table, char *flag, int macro,
958 const char *comma, const char *indent,
959 int lineno)
960 {
961 char *str, *next, *last;
962 unsigned int i;
963 bitfield flags [ARRAY_SIZE (cpu_flags)];
964
965 /* Copy the default cpu flags. */
966 memcpy (flags, cpu_flags, sizeof (cpu_flags));
967
968 if (strcasecmp (flag, "unknown") == 0)
969 {
970 /* We turn on everything except for cpu64 in case of
971 CPU_UNKNOWN_FLAGS. */
972 for (i = 0; i < ARRAY_SIZE (flags); i++)
973 if (flags[i].position != Cpu64)
974 flags[i].value = 1;
975 }
976 else if (flag[0] == '~')
977 {
978 last = flag + strlen (flag);
979
980 if (flag[1] == '(')
981 {
982 last -= 1;
983 next = flag + 2;
984 if (*last != ')')
985 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
986 lineno, flag);
987 *last = '\0';
988 }
989 else
990 next = flag + 1;
991
992 /* First we turn on everything except for cpu64. */
993 for (i = 0; i < ARRAY_SIZE (flags); i++)
994 if (flags[i].position != Cpu64)
995 flags[i].value = 1;
996
997 /* Turn off selective bits. */
998 for (; next && next < last; )
999 {
1000 str = next_field (next, '|', &next, last);
1001 if (str)
1002 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1003 }
1004 }
1005 else if (strcmp (flag, "0"))
1006 {
1007 /* Turn on selective bits. */
1008 last = flag + strlen (flag);
1009 for (next = flag; next && next < last; )
1010 {
1011 str = next_field (next, '|', &next, last);
1012 if (str)
1013 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1014 }
1015 }
1016
1017 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1018 comma, indent);
1019 }
1020
1021 static void
1022 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1023 {
1024 unsigned int i;
1025
1026 fprintf (table, " { ");
1027
1028 for (i = 0; i < size - 1; i++)
1029 {
1030 if (((i + 1) % 20) != 0)
1031 fprintf (table, "%d, ", modifier[i].value);
1032 else
1033 fprintf (table, "%d,", modifier[i].value);
1034 if (((i + 1) % 20) == 0)
1035 fprintf (table, "\n ");
1036 }
1037
1038 fprintf (table, "%d },\n", modifier[i].value);
1039 }
1040
1041 static int
1042 adjust_broadcast_modifier (char **opnd)
1043 {
1044 char *str, *next, *last, *op;
1045 int bcst_type = INT_MAX;
1046
1047 /* Skip the immediate operand. */
1048 op = opnd[0];
1049 if (strcasecmp(op, "Imm8") == 0)
1050 op = opnd[1];
1051
1052 op = xstrdup (op);
1053 last = op + strlen (op);
1054 for (next = op; next && next < last; )
1055 {
1056 str = next_field (next, '|', &next, last);
1057 if (str)
1058 {
1059 if (strcasecmp(str, "Byte") == 0)
1060 {
1061 /* The smalest broadcast type, no need to check
1062 further. */
1063 bcst_type = BYTE_BROADCAST;
1064 break;
1065 }
1066 else if (strcasecmp(str, "Word") == 0)
1067 {
1068 if (bcst_type > WORD_BROADCAST)
1069 bcst_type = WORD_BROADCAST;
1070 }
1071 else if (strcasecmp(str, "Dword") == 0)
1072 {
1073 if (bcst_type > DWORD_BROADCAST)
1074 bcst_type = DWORD_BROADCAST;
1075 }
1076 else if (strcasecmp(str, "Qword") == 0)
1077 {
1078 if (bcst_type > QWORD_BROADCAST)
1079 bcst_type = QWORD_BROADCAST;
1080 }
1081 }
1082 }
1083 free (op);
1084
1085 if (bcst_type == INT_MAX)
1086 fail (_("unknown broadcast operand: %s\n"), op);
1087
1088 return bcst_type;
1089 }
1090
1091 static void
1092 process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
1093 {
1094 char *str, *next, *last;
1095 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1096
1097 active_isstring = 0;
1098
1099 /* Copy the default opcode modifier. */
1100 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1101
1102 if (strcmp (mod, "0"))
1103 {
1104 unsigned int have_w = 0, bwlq_suf = 0xf;
1105
1106 last = mod + strlen (mod);
1107 for (next = mod; next && next < last; )
1108 {
1109 str = next_field (next, '|', &next, last);
1110 if (str)
1111 {
1112 int val = 1;
1113 if (strcasecmp(str, "Broadcast") == 0)
1114 val = adjust_broadcast_modifier (opnd);
1115 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1116 lineno);
1117 if (strcasecmp(str, "IsString") == 0)
1118 active_isstring = 1;
1119
1120 if (strcasecmp(str, "W") == 0)
1121 have_w = 1;
1122
1123 if (strcasecmp(str, "No_bSuf") == 0)
1124 bwlq_suf &= ~1;
1125 if (strcasecmp(str, "No_wSuf") == 0)
1126 bwlq_suf &= ~2;
1127 if (strcasecmp(str, "No_lSuf") == 0)
1128 bwlq_suf &= ~4;
1129 if (strcasecmp(str, "No_qSuf") == 0)
1130 bwlq_suf &= ~8;
1131 }
1132 }
1133
1134 if (have_w && !bwlq_suf)
1135 fail ("%s: %d: stray W modifier\n", filename, lineno);
1136 if (have_w && !(bwlq_suf & 1))
1137 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1138 filename, lineno);
1139 if (have_w && !(bwlq_suf & ~1))
1140 fprintf (stderr,
1141 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1142 filename, lineno);
1143 }
1144 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1145 }
1146
1147 enum stage {
1148 stage_macros,
1149 stage_opcodes,
1150 stage_registers,
1151 };
1152
1153 static void
1154 output_operand_type (FILE *table, enum operand_class class,
1155 enum operand_instance instance,
1156 const bitfield *types, unsigned int size,
1157 enum stage stage, const char *indent)
1158 {
1159 unsigned int i;
1160
1161 fprintf (table, "{ { %d, %d, ", class, instance);
1162
1163 for (i = 0; i < size - 1; i++)
1164 {
1165 if (((i + 3) % 20) != 0)
1166 fprintf (table, "%d, ", types[i].value);
1167 else
1168 fprintf (table, "%d,", types[i].value);
1169 if (((i + 3) % 20) == 0)
1170 {
1171 /* We need \\ for macro. */
1172 if (stage == stage_macros)
1173 fprintf (table, " \\\n%s", indent);
1174 else
1175 fprintf (table, "\n%s", indent);
1176 }
1177 }
1178
1179 fprintf (table, "%d } }", types[i].value);
1180 }
1181
1182 static void
1183 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1184 const char *indent, int lineno)
1185 {
1186 char *str, *next, *last;
1187 enum operand_class class = ClassNone;
1188 enum operand_instance instance = InstanceNone;
1189 bitfield types [ARRAY_SIZE (operand_types)];
1190
1191 /* Copy the default operand type. */
1192 memcpy (types, operand_types, sizeof (types));
1193
1194 if (strcmp (op, "0"))
1195 {
1196 int baseindex = 0;
1197
1198 last = op + strlen (op);
1199 for (next = op; next && next < last; )
1200 {
1201 str = next_field (next, '|', &next, last);
1202 if (str)
1203 {
1204 unsigned int i;
1205
1206 if (!strncmp(str, "Class=", 6))
1207 {
1208 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1209 if (!strcmp(str + 6, operand_classes[i].name))
1210 {
1211 class = operand_classes[i].value;
1212 str = NULL;
1213 break;
1214 }
1215 }
1216
1217 if (str && !strncmp(str, "Instance=", 9))
1218 {
1219 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1220 if (!strcmp(str + 9, operand_instances[i].name))
1221 {
1222 instance = operand_instances[i].value;
1223 str = NULL;
1224 break;
1225 }
1226 }
1227 }
1228 if (str)
1229 {
1230 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1231 if (strcasecmp(str, "BaseIndex") == 0)
1232 baseindex = 1;
1233 }
1234 }
1235
1236 if (stage == stage_opcodes && baseindex && !active_isstring)
1237 {
1238 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1239 if (!active_cpu_flags.bitfield.cpu64
1240 && !active_cpu_flags.bitfield.cpumpx)
1241 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1242 if (!active_cpu_flags.bitfield.cpu64)
1243 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1244 if (!active_cpu_flags.bitfield.cpuno64)
1245 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1246 }
1247 }
1248 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1249 stage, indent);
1250 }
1251
1252 static void
1253 output_i386_opcode (FILE *table, const char *name, char *str,
1254 char *last, int lineno)
1255 {
1256 unsigned int i;
1257 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1258 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1259
1260 /* Find number of operands. */
1261 operands = next_field (str, ',', &str, last);
1262
1263 /* Find base_opcode. */
1264 base_opcode = next_field (str, ',', &str, last);
1265
1266 /* Find extension_opcode. */
1267 extension_opcode = next_field (str, ',', &str, last);
1268
1269 /* Find opcode_length. */
1270 opcode_length = next_field (str, ',', &str, last);
1271
1272 /* Find cpu_flags. */
1273 cpu_flags = next_field (str, ',', &str, last);
1274
1275 /* Find opcode_modifier. */
1276 opcode_modifier = next_field (str, ',', &str, last);
1277
1278 /* Remove the first {. */
1279 str = remove_leading_whitespaces (str);
1280 if (*str != '{')
1281 abort ();
1282 str = remove_leading_whitespaces (str + 1);
1283
1284 i = strlen (str);
1285
1286 /* There are at least "X}". */
1287 if (i < 2)
1288 abort ();
1289
1290 /* Remove trailing white spaces and }. */
1291 do
1292 {
1293 i--;
1294 if (ISSPACE (str[i]) || str[i] == '}')
1295 str[i] = '\0';
1296 else
1297 break;
1298 }
1299 while (i != 0);
1300
1301 last = str + i;
1302
1303 /* Find operand_types. */
1304 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1305 {
1306 if (str >= last)
1307 {
1308 operand_types [i] = NULL;
1309 break;
1310 }
1311
1312 operand_types [i] = next_field (str, ',', &str, last);
1313 if (*operand_types[i] == '0')
1314 {
1315 if (i != 0)
1316 operand_types[i] = NULL;
1317 break;
1318 }
1319 }
1320
1321 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1322 name, base_opcode, extension_opcode, opcode_length, operands);
1323
1324 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1325
1326 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
1327
1328 fprintf (table, " { ");
1329
1330 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1331 {
1332 if (operand_types[i] == NULL || *operand_types[i] == '0')
1333 {
1334 if (i == 0)
1335 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1336 lineno);
1337 break;
1338 }
1339
1340 if (i != 0)
1341 fprintf (table, ",\n ");
1342
1343 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1344 "\t ", lineno);
1345 }
1346 fprintf (table, " } },\n");
1347 }
1348
1349 struct opcode_hash_entry
1350 {
1351 struct opcode_hash_entry *next;
1352 char *name;
1353 char *opcode;
1354 int lineno;
1355 };
1356
1357 /* Calculate the hash value of an opcode hash entry P. */
1358
1359 static hashval_t
1360 opcode_hash_hash (const void *p)
1361 {
1362 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1363 return htab_hash_string (entry->name);
1364 }
1365
1366 /* Compare a string Q against an opcode hash entry P. */
1367
1368 static int
1369 opcode_hash_eq (const void *p, const void *q)
1370 {
1371 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1372 const char *name = (const char *) q;
1373 return strcmp (name, entry->name) == 0;
1374 }
1375
1376 static void
1377 process_i386_opcodes (FILE *table)
1378 {
1379 FILE *fp;
1380 char buf[2048];
1381 unsigned int i, j;
1382 char *str, *p, *last, *name;
1383 struct opcode_hash_entry **hash_slot, **entry, *next;
1384 htab_t opcode_hash_table;
1385 struct opcode_hash_entry **opcode_array;
1386 unsigned int opcode_array_size = 1024;
1387 int lineno = 0, marker = 0;
1388
1389 filename = "i386-opc.tbl";
1390 fp = stdin;
1391
1392 i = 0;
1393 opcode_array = (struct opcode_hash_entry **)
1394 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1395
1396 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1397 opcode_hash_eq, NULL,
1398 xcalloc, free);
1399
1400 fprintf (table, "\n/* i386 opcode table. */\n\n");
1401 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1402
1403 /* Put everything on opcode array. */
1404 while (!feof (fp))
1405 {
1406 if (fgets (buf, sizeof (buf), fp) == NULL)
1407 break;
1408
1409 lineno++;
1410
1411 p = remove_leading_whitespaces (buf);
1412
1413 /* Skip comments. */
1414 str = strstr (p, "//");
1415 if (str != NULL)
1416 str[0] = '\0';
1417
1418 /* Remove trailing white spaces. */
1419 remove_trailing_whitespaces (p);
1420
1421 switch (p[0])
1422 {
1423 case '#':
1424 if (!strcmp("### MARKER ###", buf))
1425 marker = 1;
1426 else
1427 {
1428 /* Since we ignore all included files (we only care about their
1429 #define-s here), we don't need to monitor filenames. The final
1430 line number directive is going to refer to the main source file
1431 again. */
1432 char *end;
1433 unsigned long ln;
1434
1435 p = remove_leading_whitespaces (p + 1);
1436 if (!strncmp(p, "line", 4))
1437 p += 4;
1438 ln = strtoul (p, &end, 10);
1439 if (ln > 1 && ln < INT_MAX
1440 && *remove_leading_whitespaces (end) == '"')
1441 lineno = ln - 1;
1442 }
1443 /* Ignore comments. */
1444 case '\0':
1445 continue;
1446 break;
1447 default:
1448 if (!marker)
1449 continue;
1450 break;
1451 }
1452
1453 last = p + strlen (p);
1454
1455 /* Find name. */
1456 name = next_field (p, ',', &str, last);
1457
1458 /* Get the slot in hash table. */
1459 hash_slot = (struct opcode_hash_entry **)
1460 htab_find_slot_with_hash (opcode_hash_table, name,
1461 htab_hash_string (name),
1462 INSERT);
1463
1464 if (*hash_slot == NULL)
1465 {
1466 /* It is the new one. Put it on opcode array. */
1467 if (i >= opcode_array_size)
1468 {
1469 /* Grow the opcode array when needed. */
1470 opcode_array_size += 1024;
1471 opcode_array = (struct opcode_hash_entry **)
1472 xrealloc (opcode_array,
1473 sizeof (*opcode_array) * opcode_array_size);
1474 }
1475
1476 opcode_array[i] = (struct opcode_hash_entry *)
1477 xmalloc (sizeof (struct opcode_hash_entry));
1478 opcode_array[i]->next = NULL;
1479 opcode_array[i]->name = xstrdup (name);
1480 opcode_array[i]->opcode = xstrdup (str);
1481 opcode_array[i]->lineno = lineno;
1482 *hash_slot = opcode_array[i];
1483 i++;
1484 }
1485 else
1486 {
1487 /* Append it to the existing one. */
1488 entry = hash_slot;
1489 while ((*entry) != NULL)
1490 entry = &(*entry)->next;
1491 *entry = (struct opcode_hash_entry *)
1492 xmalloc (sizeof (struct opcode_hash_entry));
1493 (*entry)->next = NULL;
1494 (*entry)->name = (*hash_slot)->name;
1495 (*entry)->opcode = xstrdup (str);
1496 (*entry)->lineno = lineno;
1497 }
1498 }
1499
1500 /* Process opcode array. */
1501 for (j = 0; j < i; j++)
1502 {
1503 for (next = opcode_array[j]; next; next = next->next)
1504 {
1505 name = next->name;
1506 str = next->opcode;
1507 lineno = next->lineno;
1508 last = str + strlen (str);
1509 output_i386_opcode (table, name, str, last, lineno);
1510 }
1511 }
1512
1513 fclose (fp);
1514
1515 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1516
1517 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1518
1519 process_i386_opcode_modifier (table, "0", NULL, -1);
1520
1521 fprintf (table, " { ");
1522 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1523 fprintf (table, " } }\n");
1524
1525 fprintf (table, "};\n");
1526 }
1527
1528 static void
1529 process_i386_registers (FILE *table)
1530 {
1531 FILE *fp;
1532 char buf[2048];
1533 char *str, *p, *last;
1534 char *reg_name, *reg_type, *reg_flags, *reg_num;
1535 char *dw2_32_num, *dw2_64_num;
1536 int lineno = 0;
1537
1538 filename = "i386-reg.tbl";
1539 fp = fopen (filename, "r");
1540 if (fp == NULL)
1541 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1542 xstrerror (errno));
1543
1544 fprintf (table, "\n/* i386 register table. */\n\n");
1545 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1546
1547 while (!feof (fp))
1548 {
1549 if (fgets (buf, sizeof (buf), fp) == NULL)
1550 break;
1551
1552 lineno++;
1553
1554 p = remove_leading_whitespaces (buf);
1555
1556 /* Skip comments. */
1557 str = strstr (p, "//");
1558 if (str != NULL)
1559 str[0] = '\0';
1560
1561 /* Remove trailing white spaces. */
1562 remove_trailing_whitespaces (p);
1563
1564 switch (p[0])
1565 {
1566 case '#':
1567 fprintf (table, "%s\n", p);
1568 case '\0':
1569 continue;
1570 break;
1571 default:
1572 break;
1573 }
1574
1575 last = p + strlen (p);
1576
1577 /* Find reg_name. */
1578 reg_name = next_field (p, ',', &str, last);
1579
1580 /* Find reg_type. */
1581 reg_type = next_field (str, ',', &str, last);
1582
1583 /* Find reg_flags. */
1584 reg_flags = next_field (str, ',', &str, last);
1585
1586 /* Find reg_num. */
1587 reg_num = next_field (str, ',', &str, last);
1588
1589 fprintf (table, " { \"%s\",\n ", reg_name);
1590
1591 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1592 lineno);
1593
1594 /* Find 32-bit Dwarf2 register number. */
1595 dw2_32_num = next_field (str, ',', &str, last);
1596
1597 /* Find 64-bit Dwarf2 register number. */
1598 dw2_64_num = next_field (str, ',', &str, last);
1599
1600 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1601 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1602 }
1603
1604 fclose (fp);
1605
1606 fprintf (table, "};\n");
1607
1608 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1609 }
1610
1611 static void
1612 process_i386_initializers (void)
1613 {
1614 unsigned int i;
1615 FILE *fp = fopen ("i386-init.h", "w");
1616 char *init;
1617
1618 if (fp == NULL)
1619 fail (_("can't create i386-init.h, errno = %s\n"),
1620 xstrerror (errno));
1621
1622 process_copyright (fp);
1623
1624 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1625 {
1626 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1627 init = xstrdup (cpu_flag_init[i].init);
1628 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1629 free (init);
1630 }
1631
1632 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1633 {
1634 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1635 init = xstrdup (operand_type_init[i].init);
1636 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1637 free (init);
1638 }
1639 fprintf (fp, "\n");
1640
1641 fclose (fp);
1642 }
1643
1644 /* Program options. */
1645 #define OPTION_SRCDIR 200
1646
1647 struct option long_options[] =
1648 {
1649 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1650 {"debug", no_argument, NULL, 'd'},
1651 {"version", no_argument, NULL, 'V'},
1652 {"help", no_argument, NULL, 'h'},
1653 {0, no_argument, NULL, 0}
1654 };
1655
1656 static void
1657 print_version (void)
1658 {
1659 printf ("%s: version 1.0\n", program_name);
1660 xexit (0);
1661 }
1662
1663 static void
1664 usage (FILE * stream, int status)
1665 {
1666 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1667 program_name);
1668 xexit (status);
1669 }
1670
1671 int
1672 main (int argc, char **argv)
1673 {
1674 extern int chdir (char *);
1675 char *srcdir = NULL;
1676 int c;
1677 unsigned int i, cpumax;
1678 FILE *table;
1679
1680 program_name = *argv;
1681 xmalloc_set_program_name (program_name);
1682
1683 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1684 switch (c)
1685 {
1686 case OPTION_SRCDIR:
1687 srcdir = optarg;
1688 break;
1689 case 'V':
1690 case 'v':
1691 print_version ();
1692 break;
1693 case 'd':
1694 debug = 1;
1695 break;
1696 case 'h':
1697 case '?':
1698 usage (stderr, 0);
1699 default:
1700 case 0:
1701 break;
1702 }
1703
1704 if (optind != argc)
1705 usage (stdout, 1);
1706
1707 if (srcdir != NULL)
1708 if (chdir (srcdir) != 0)
1709 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1710 srcdir, xstrerror (errno));
1711
1712 /* cpu_flags isn't sorted by position. */
1713 cpumax = 0;
1714 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1715 if (cpu_flags[i].position > cpumax)
1716 cpumax = cpu_flags[i].position;
1717
1718 /* Check the unused bitfield in i386_cpu_flags. */
1719 #ifdef CpuUnused
1720 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1721
1722 if ((cpumax - 1) != CpuMax)
1723 fail (_("CpuMax != %d!\n"), cpumax);
1724 #else
1725 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1726
1727 if (cpumax != CpuMax)
1728 fail (_("CpuMax != %d!\n"), cpumax);
1729
1730 c = CpuNumOfBits - CpuMax - 1;
1731 if (c)
1732 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1733 #endif
1734
1735 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1736
1737 /* Check the unused bitfield in i386_operand_type. */
1738 #ifdef OTUnused
1739 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1740 == OTNum + 1);
1741 #else
1742 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1743 == OTNum);
1744
1745 c = OTNumOfBits - OTNum;
1746 if (c)
1747 fail (_("%d unused bits in i386_operand_type.\n"), c);
1748 #endif
1749
1750 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1751 compare);
1752
1753 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1754 sizeof (opcode_modifiers [0]), compare);
1755
1756 qsort (operand_types, ARRAY_SIZE (operand_types),
1757 sizeof (operand_types [0]), compare);
1758
1759 table = fopen ("i386-tbl.h", "w");
1760 if (table == NULL)
1761 fail (_("can't create i386-tbl.h, errno = %s\n"),
1762 xstrerror (errno));
1763
1764 process_copyright (table);
1765
1766 process_i386_opcodes (table);
1767 process_i386_registers (table);
1768 process_i386_initializers ();
1769
1770 fclose (table);
1771
1772 exit (0);
1773 }
This page took 0.067503 seconds and 4 git commands to generate.