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