xref: /netbsd-src/external/gpl3/gdb.old/dist/opcodes/i386-gen.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Copyright (C) 2007-2022 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     "~CpuIAMCU" },
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_ZNVER3_FLAGS",
107     "CPU_ZNVER2_FLAGS|CpuINVLPGB|CpuTLBSYNC|CpuVAES|CpuVPCLMULQDQ|CpuINVPCID|CpuSNP|CpuOSPKE" },
108   { "CPU_ZNVER4_FLAGS",
109     "CPU_ZNVER3_FLAGS|CpuAVX512F|CpuAVX512DQ|CpuAVX512IFMA|CpuAVX512CD|CpuAVX512BW|CpuAVX512VL|CpuAVX512_BF16|CpuAVX512VBMI|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_VPOPCNTDQ|CpuGFNI|CpuRMPQUERY" },
110   { "CPU_BTVER1_FLAGS",
111     "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME" },
112   { "CPU_BTVER2_FLAGS",
113     "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
114   { "CPU_8087_FLAGS",
115     "Cpu8087" },
116   { "CPU_287_FLAGS",
117     "Cpu287" },
118   { "CPU_387_FLAGS",
119     "Cpu387" },
120   { "CPU_687_FLAGS",
121     "CPU_387_FLAGS|Cpu687" },
122   { "CPU_CMOV_FLAGS",
123     "CpuCMOV" },
124   { "CPU_FXSR_FLAGS",
125     "CpuFXSR" },
126   { "CPU_CLFLUSH_FLAGS",
127     "CpuClflush" },
128   { "CPU_NOP_FLAGS",
129     "CpuNop" },
130   { "CPU_SYSCALL_FLAGS",
131     "CpuSYSCALL" },
132   { "CPU_MMX_FLAGS",
133     "CpuMMX" },
134   { "CPU_SSE_FLAGS",
135     "CpuSSE" },
136   { "CPU_SSE2_FLAGS",
137     "CPU_SSE_FLAGS|CpuSSE2" },
138   { "CPU_SSE3_FLAGS",
139     "CPU_SSE2_FLAGS|CpuSSE3" },
140   { "CPU_SSSE3_FLAGS",
141     "CPU_SSE3_FLAGS|CpuSSSE3" },
142   { "CPU_SSE4_1_FLAGS",
143     "CPU_SSSE3_FLAGS|CpuSSE4_1" },
144   { "CPU_SSE4_2_FLAGS",
145     "CPU_SSE4_1_FLAGS|CpuSSE4_2|CpuPOPCNT" },
146   { "CPU_VMX_FLAGS",
147     "CpuVMX" },
148   { "CPU_SMX_FLAGS",
149     "CpuSMX" },
150   { "CPU_XSAVE_FLAGS",
151     "CpuXsave" },
152   { "CPU_XSAVEOPT_FLAGS",
153     "CPU_XSAVE_FLAGS|CpuXsaveopt" },
154   { "CPU_AES_FLAGS",
155     "CPU_SSE2_FLAGS|CpuAES" },
156   { "CPU_PCLMUL_FLAGS",
157     "CPU_SSE2_FLAGS|CpuPCLMUL" },
158   { "CPU_FMA_FLAGS",
159     "CPU_AVX_FLAGS|CpuFMA" },
160   { "CPU_FMA4_FLAGS",
161     "CPU_AVX_FLAGS|CpuFMA4" },
162   { "CPU_XOP_FLAGS",
163     "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
164   { "CPU_LWP_FLAGS",
165     "CPU_XSAVE_FLAGS|CpuLWP" },
166   { "CPU_BMI_FLAGS",
167     "CpuBMI" },
168   { "CPU_TBM_FLAGS",
169     "CpuTBM" },
170   { "CPU_MOVBE_FLAGS",
171     "CpuMovbe" },
172   { "CPU_CX16_FLAGS",
173     "CpuCX16" },
174   { "CPU_RDTSCP_FLAGS",
175     "CpuRdtscp" },
176   { "CPU_EPT_FLAGS",
177     "CpuEPT" },
178   { "CPU_FSGSBASE_FLAGS",
179     "CpuFSGSBase" },
180   { "CPU_RDRND_FLAGS",
181     "CpuRdRnd" },
182   { "CPU_F16C_FLAGS",
183     "CPU_AVX_FLAGS|CpuF16C" },
184   { "CPU_BMI2_FLAGS",
185     "CpuBMI2" },
186   { "CPU_LZCNT_FLAGS",
187     "CpuLZCNT" },
188   { "CPU_POPCNT_FLAGS",
189     "CpuPOPCNT" },
190   { "CPU_HLE_FLAGS",
191     "CpuHLE" },
192   { "CPU_RTM_FLAGS",
193     "CpuRTM" },
194   { "CPU_INVPCID_FLAGS",
195     "CpuINVPCID" },
196   { "CPU_VMFUNC_FLAGS",
197     "CpuVMFUNC" },
198   { "CPU_3DNOW_FLAGS",
199     "CPU_MMX_FLAGS|Cpu3dnow" },
200   { "CPU_3DNOWA_FLAGS",
201     "CPU_3DNOW_FLAGS|Cpu3dnowA" },
202   { "CPU_PADLOCK_FLAGS",
203     "CpuPadLock" },
204   { "CPU_SVME_FLAGS",
205     "CpuSVME" },
206   { "CPU_SSE4A_FLAGS",
207     "CPU_SSE3_FLAGS|CpuSSE4a" },
208   { "CPU_ABM_FLAGS",
209     "CpuLZCNT|CpuPOPCNT" },
210   { "CPU_AVX_FLAGS",
211     "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
212   { "CPU_AVX2_FLAGS",
213     "CPU_AVX_FLAGS|CpuAVX2" },
214   { "CPU_AVX_VNNI_FLAGS",
215     "CPU_AVX2_FLAGS|CpuAVX_VNNI" },
216   { "CPU_AVX512F_FLAGS",
217     "CPU_AVX2_FLAGS|CpuAVX512F" },
218   { "CPU_AVX512CD_FLAGS",
219     "CPU_AVX512F_FLAGS|CpuAVX512CD" },
220   { "CPU_AVX512ER_FLAGS",
221     "CPU_AVX512F_FLAGS|CpuAVX512ER" },
222   { "CPU_AVX512PF_FLAGS",
223     "CPU_AVX512F_FLAGS|CpuAVX512PF" },
224   { "CPU_AVX512DQ_FLAGS",
225     "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
226   { "CPU_AVX512BW_FLAGS",
227     "CPU_AVX512F_FLAGS|CpuAVX512BW" },
228   { "CPU_AVX512VL_FLAGS",
229     "CPU_AVX512F_FLAGS|CpuAVX512VL" },
230   { "CPU_AVX512IFMA_FLAGS",
231     "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
232   { "CPU_AVX512VBMI_FLAGS",
233     "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
234   { "CPU_AVX512_4FMAPS_FLAGS",
235     "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
236   { "CPU_AVX512_4VNNIW_FLAGS",
237     "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
238   { "CPU_AVX512_VPOPCNTDQ_FLAGS",
239     "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
240   { "CPU_AVX512_VBMI2_FLAGS",
241     "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
242   { "CPU_AVX512_VNNI_FLAGS",
243     "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
244   { "CPU_AVX512_BITALG_FLAGS",
245     "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
246   { "CPU_AVX512_BF16_FLAGS",
247     "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
248   { "CPU_AVX512_FP16_FLAGS",
249     "CPU_AVX512BW_FLAGS|CpuAVX512_FP16" },
250   { "CPU_PREFETCHI_FLAGS",
251     "CpuPREFETCHI"},
252   { "CPU_AVX_IFMA_FLAGS",
253     "CPU_AVX2_FLAGS|CpuAVX_IFMA" },
254   { "CPU_AVX_VNNI_INT8_FLAGS",
255     "CPU_AVX2_FLAGS|CpuAVX_VNNI_INT8" },
256   { "CPU_CMPCCXADD_FLAGS",
257     "CpuCMPCCXADD" },
258   { "CPU_WRMSRNS_FLAGS",
259     "CpuWRMSRNS" },
260   { "CPU_MSRLIST_FLAGS",
261     "CpuMSRLIST" },
262   { "CPU_AVX_NE_CONVERT_FLAGS",
263     "CPU_AVX2_FLAGS|CpuAVX_NE_CONVERT" },
264   { "CPU_RAO_INT_FLAGS",
265     "CpuRAO_INT" },
266   { "CPU_IAMCU_FLAGS",
267     "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuIAMCU" },
268   { "CPU_ADX_FLAGS",
269     "CpuADX" },
270   { "CPU_RDSEED_FLAGS",
271     "CpuRdSeed" },
272   { "CPU_PRFCHW_FLAGS",
273     "CpuPRFCHW" },
274   { "CPU_SMAP_FLAGS",
275     "CpuSMAP" },
276   { "CPU_MPX_FLAGS",
277     "CPU_XSAVE_FLAGS|CpuMPX" },
278   { "CPU_SHA_FLAGS",
279     "CPU_SSE2_FLAGS|CpuSHA" },
280   { "CPU_CLFLUSHOPT_FLAGS",
281     "CpuClflushOpt" },
282   { "CPU_XSAVES_FLAGS",
283     "CPU_XSAVE_FLAGS|CpuXSAVES" },
284   { "CPU_XSAVEC_FLAGS",
285     "CPU_XSAVE_FLAGS|CpuXSAVEC" },
286   { "CPU_PREFETCHWT1_FLAGS",
287     "CpuPREFETCHWT1" },
288   { "CPU_SE1_FLAGS",
289     "CpuSE1" },
290   { "CPU_CLWB_FLAGS",
291     "CpuCLWB" },
292   { "CPU_CLZERO_FLAGS",
293     "CpuCLZERO" },
294   { "CPU_MWAITX_FLAGS",
295     "CpuMWAITX" },
296   { "CPU_OSPKE_FLAGS",
297     "CPU_XSAVE_FLAGS|CpuOSPKE" },
298   { "CPU_RDPID_FLAGS",
299     "CpuRDPID" },
300   { "CPU_PTWRITE_FLAGS",
301     "CpuPTWRITE" },
302   { "CPU_IBT_FLAGS",
303     "CpuIBT" },
304   { "CPU_SHSTK_FLAGS",
305     "CpuSHSTK" },
306   { "CPU_GFNI_FLAGS",
307     "CpuGFNI" },
308   { "CPU_VAES_FLAGS",
309     "CpuVAES" },
310   { "CPU_VPCLMULQDQ_FLAGS",
311     "CpuVPCLMULQDQ" },
312   { "CPU_WBNOINVD_FLAGS",
313     "CpuWBNOINVD" },
314   { "CPU_PCONFIG_FLAGS",
315     "CpuPCONFIG" },
316   { "CPU_WAITPKG_FLAGS",
317     "CpuWAITPKG" },
318   { "CPU_UINTR_FLAGS",
319     "CpuUINTR" },
320   { "CPU_CLDEMOTE_FLAGS",
321     "CpuCLDEMOTE" },
322   { "CPU_AMX_INT8_FLAGS",
323     "CPU_AMX_TILE_FLAGS|CpuAMX_INT8" },
324   { "CPU_AMX_BF16_FLAGS",
325     "CPU_AMX_TILE_FLAGS|CpuAMX_BF16" },
326   { "CPU_AMX_FP16_FLAGS",
327     "CPU_AMX_TILE_FLAGS|CpuAMX_FP16" },
328   { "CPU_AMX_TILE_FLAGS",
329     "CpuAMX_TILE" },
330   { "CPU_MOVDIRI_FLAGS",
331     "CpuMOVDIRI" },
332   { "CPU_MOVDIR64B_FLAGS",
333     "CpuMOVDIR64B" },
334   { "CPU_ENQCMD_FLAGS",
335     "CpuENQCMD" },
336   { "CPU_SERIALIZE_FLAGS",
337     "CpuSERIALIZE" },
338   { "CPU_AVX512_VP2INTERSECT_FLAGS",
339     "CpuAVX512_VP2INTERSECT" },
340   { "CPU_TDX_FLAGS",
341     "CpuTDX" },
342   { "CPU_RDPRU_FLAGS",
343     "CpuRDPRU" },
344   { "CPU_MCOMMIT_FLAGS",
345     "CpuMCOMMIT" },
346   { "CPU_SEV_ES_FLAGS",
347     "CpuSEV_ES" },
348   { "CPU_TSXLDTRK_FLAGS",
349     "CpuTSXLDTRK"},
350   { "CPU_KL_FLAGS",
351     "CpuKL" },
352   { "CPU_WIDEKL_FLAGS",
353     "CpuWideKL" },
354   { "CPU_HRESET_FLAGS",
355     "CpuHRESET"},
356   { "CPU_INVLPGB_FLAGS",
357     "CpuINVLPGB" },
358   { "CPU_TLBSYNC_FLAGS",
359     "CpuTLBSYNC" },
360   { "CPU_SNP_FLAGS",
361     "CpuSNP" },
362   { "CPU_RMPQUERY_FLAGS",
363     "CpuRMPQUERY" },
364   { "CPU_ANY_X87_FLAGS",
365     "CPU_ANY_287_FLAGS|Cpu8087" },
366   { "CPU_ANY_287_FLAGS",
367     "CPU_ANY_387_FLAGS|Cpu287" },
368   { "CPU_ANY_387_FLAGS",
369     "CPU_ANY_687_FLAGS|Cpu387" },
370   { "CPU_ANY_687_FLAGS",
371     "Cpu687|CpuFISTTP" },
372   { "CPU_ANY_CMOV_FLAGS",
373     "CpuCMOV" },
374   { "CPU_ANY_FXSR_FLAGS",
375     "CpuFXSR" },
376   { "CPU_ANY_MMX_FLAGS",
377     "CPU_3DNOWA_FLAGS" },
378   { "CPU_ANY_SSE_FLAGS",
379     "CPU_ANY_SSE2_FLAGS|CpuSSE" },
380   { "CPU_ANY_SSE2_FLAGS",
381     "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
382   { "CPU_ANY_SSE3_FLAGS",
383     "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
384   { "CPU_ANY_SSSE3_FLAGS",
385     "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
386   { "CPU_ANY_SSE4_1_FLAGS",
387     "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
388   { "CPU_ANY_SSE4_2_FLAGS",
389     "CpuSSE4_2" },
390   { "CPU_ANY_SSE4A_FLAGS",
391     "CpuSSE4a" },
392   { "CPU_ANY_AVX_FLAGS",
393     "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
394   { "CPU_ANY_AVX2_FLAGS",
395     "CPU_ANY_AVX512F_FLAGS|CpuAVX2|CpuAVX_VNNI|CpuAVX_IFMA|CpuAVX_VNNI_INT8|CpuAVX_NE_CONVERT" },
396   { "CPU_ANY_AVX512F_FLAGS",
397     "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CPU_ANY_AVX512BW_FLAGS|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
398   { "CPU_ANY_AVX512CD_FLAGS",
399     "CpuAVX512CD" },
400   { "CPU_ANY_AVX512ER_FLAGS",
401     "CpuAVX512ER" },
402   { "CPU_ANY_AVX512PF_FLAGS",
403     "CpuAVX512PF" },
404   { "CPU_ANY_AVX512DQ_FLAGS",
405     "CpuAVX512DQ" },
406   { "CPU_ANY_AVX512BW_FLAGS",
407     "CpuAVX512BW|CPU_ANY_AVX512_FP16_FLAGS" },
408   { "CPU_ANY_AVX512VL_FLAGS",
409     "CpuAVX512VL" },
410   { "CPU_ANY_AVX512IFMA_FLAGS",
411     "CpuAVX512IFMA" },
412   { "CPU_ANY_AVX512VBMI_FLAGS",
413     "CpuAVX512VBMI" },
414   { "CPU_ANY_AVX512_4FMAPS_FLAGS",
415     "CpuAVX512_4FMAPS" },
416   { "CPU_ANY_AVX512_4VNNIW_FLAGS",
417     "CpuAVX512_4VNNIW" },
418   { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
419     "CpuAVX512_VPOPCNTDQ" },
420   { "CPU_ANY_IBT_FLAGS",
421     "CpuIBT" },
422   { "CPU_ANY_SHSTK_FLAGS",
423     "CpuSHSTK" },
424   { "CPU_ANY_AVX512_VBMI2_FLAGS",
425     "CpuAVX512_VBMI2" },
426   { "CPU_ANY_AVX512_VNNI_FLAGS",
427     "CpuAVX512_VNNI" },
428   { "CPU_ANY_AVX512_BITALG_FLAGS",
429     "CpuAVX512_BITALG" },
430   { "CPU_ANY_AVX512_BF16_FLAGS",
431     "CpuAVX512_BF16" },
432   { "CPU_ANY_AMX_INT8_FLAGS",
433     "CpuAMX_INT8" },
434   { "CPU_ANY_AMX_BF16_FLAGS",
435     "CpuAMX_BF16" },
436   { "CPU_ANY_AMX_TILE_FLAGS",
437     "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16|CpuAMX_FP16" },
438   { "CPU_ANY_AVX_VNNI_FLAGS",
439     "CpuAVX_VNNI" },
440   { "CPU_ANY_MOVDIRI_FLAGS",
441     "CpuMOVDIRI" },
442   { "CPU_ANY_UINTR_FLAGS",
443     "CpuUINTR" },
444   { "CPU_ANY_MOVDIR64B_FLAGS",
445     "CpuMOVDIR64B" },
446   { "CPU_ANY_ENQCMD_FLAGS",
447     "CpuENQCMD" },
448   { "CPU_ANY_SERIALIZE_FLAGS",
449     "CpuSERIALIZE" },
450   { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
451     "CpuAVX512_VP2INTERSECT" },
452   { "CPU_ANY_TDX_FLAGS",
453     "CpuTDX" },
454   { "CPU_ANY_TSXLDTRK_FLAGS",
455     "CpuTSXLDTRK" },
456   { "CPU_ANY_KL_FLAGS",
457     "CpuKL|CpuWideKL" },
458   { "CPU_ANY_WIDEKL_FLAGS",
459     "CpuWideKL" },
460   { "CPU_ANY_HRESET_FLAGS",
461     "CpuHRESET" },
462   { "CPU_ANY_AVX512_FP16_FLAGS",
463     "CpuAVX512_FP16" },
464   { "CPU_ANY_AVX_IFMA_FLAGS",
465     "CpuAVX_IFMA" },
466   { "CPU_ANY_AVX_VNNI_INT8_FLAGS",
467     "CpuAVX_VNNI_INT8" },
468   { "CPU_ANY_CMPCCXADD_FLAGS",
469     "CpuCMPCCXADD" },
470   { "CPU_ANY_WRMSRNS_FLAGS",
471     "CpuWRMSRNS" },
472   { "CPU_ANY_MSRLIST_FLAGS",
473     "CpuMSRLIST" },
474   { "CPU_ANY_AVX_NE_CONVERT_FLAGS",
475     "CpuAVX_NE_CONVERT" },
476   { "CPU_ANY_RAO_INT_FLAGS",
477     "CpuRAO_INT"},
478 };
479 
480 typedef struct bitfield
481 {
482   int position;
483   int value;
484   const char *name;
485 } bitfield;
486 
487 #define BITFIELD(n) { n, 0, #n }
488 
489 static bitfield cpu_flags[] =
490 {
491   BITFIELD (Cpu186),
492   BITFIELD (Cpu286),
493   BITFIELD (Cpu386),
494   BITFIELD (Cpu486),
495   BITFIELD (Cpu586),
496   BITFIELD (Cpu686),
497   BITFIELD (CpuCMOV),
498   BITFIELD (CpuFXSR),
499   BITFIELD (CpuClflush),
500   BITFIELD (CpuNop),
501   BITFIELD (CpuSYSCALL),
502   BITFIELD (Cpu8087),
503   BITFIELD (Cpu287),
504   BITFIELD (Cpu387),
505   BITFIELD (Cpu687),
506   BITFIELD (CpuFISTTP),
507   BITFIELD (CpuMMX),
508   BITFIELD (CpuSSE),
509   BITFIELD (CpuSSE2),
510   BITFIELD (CpuSSE3),
511   BITFIELD (CpuSSSE3),
512   BITFIELD (CpuSSE4_1),
513   BITFIELD (CpuSSE4_2),
514   BITFIELD (CpuAVX),
515   BITFIELD (CpuAVX2),
516   BITFIELD (CpuAVX512F),
517   BITFIELD (CpuAVX512CD),
518   BITFIELD (CpuAVX512ER),
519   BITFIELD (CpuAVX512PF),
520   BITFIELD (CpuAVX512VL),
521   BITFIELD (CpuAVX512DQ),
522   BITFIELD (CpuAVX512BW),
523   BITFIELD (CpuIAMCU),
524   BITFIELD (CpuSSE4a),
525   BITFIELD (Cpu3dnow),
526   BITFIELD (Cpu3dnowA),
527   BITFIELD (CpuPadLock),
528   BITFIELD (CpuSVME),
529   BITFIELD (CpuVMX),
530   BITFIELD (CpuSMX),
531   BITFIELD (CpuXsave),
532   BITFIELD (CpuXsaveopt),
533   BITFIELD (CpuAES),
534   BITFIELD (CpuPCLMUL),
535   BITFIELD (CpuFMA),
536   BITFIELD (CpuFMA4),
537   BITFIELD (CpuXOP),
538   BITFIELD (CpuLWP),
539   BITFIELD (CpuBMI),
540   BITFIELD (CpuTBM),
541   BITFIELD (CpuLM),
542   BITFIELD (CpuMovbe),
543   BITFIELD (CpuCX16),
544   BITFIELD (CpuEPT),
545   BITFIELD (CpuRdtscp),
546   BITFIELD (CpuFSGSBase),
547   BITFIELD (CpuRdRnd),
548   BITFIELD (CpuF16C),
549   BITFIELD (CpuBMI2),
550   BITFIELD (CpuLZCNT),
551   BITFIELD (CpuPOPCNT),
552   BITFIELD (CpuHLE),
553   BITFIELD (CpuRTM),
554   BITFIELD (CpuINVPCID),
555   BITFIELD (CpuVMFUNC),
556   BITFIELD (CpuRDSEED),
557   BITFIELD (CpuADX),
558   BITFIELD (CpuPRFCHW),
559   BITFIELD (CpuSMAP),
560   BITFIELD (CpuSHA),
561   BITFIELD (CpuClflushOpt),
562   BITFIELD (CpuXSAVES),
563   BITFIELD (CpuXSAVEC),
564   BITFIELD (CpuPREFETCHWT1),
565   BITFIELD (CpuSE1),
566   BITFIELD (CpuCLWB),
567   BITFIELD (CpuMPX),
568   BITFIELD (CpuAVX512IFMA),
569   BITFIELD (CpuAVX512VBMI),
570   BITFIELD (CpuAVX512_4FMAPS),
571   BITFIELD (CpuAVX512_4VNNIW),
572   BITFIELD (CpuAVX512_VPOPCNTDQ),
573   BITFIELD (CpuAVX512_VBMI2),
574   BITFIELD (CpuAVX512_VNNI),
575   BITFIELD (CpuAVX512_BITALG),
576   BITFIELD (CpuAVX512_BF16),
577   BITFIELD (CpuAVX512_VP2INTERSECT),
578   BITFIELD (CpuTDX),
579   BITFIELD (CpuAVX_VNNI),
580   BITFIELD (CpuAVX512_FP16),
581   BITFIELD (CpuPREFETCHI),
582   BITFIELD (CpuAVX_IFMA),
583   BITFIELD (CpuAVX_VNNI_INT8),
584   BITFIELD (CpuCMPCCXADD),
585   BITFIELD (CpuWRMSRNS),
586   BITFIELD (CpuMSRLIST),
587   BITFIELD (CpuAVX_NE_CONVERT),
588   BITFIELD (CpuRAO_INT),
589   BITFIELD (CpuMWAITX),
590   BITFIELD (CpuCLZERO),
591   BITFIELD (CpuOSPKE),
592   BITFIELD (CpuRDPID),
593   BITFIELD (CpuPTWRITE),
594   BITFIELD (CpuIBT),
595   BITFIELD (CpuSHSTK),
596   BITFIELD (CpuGFNI),
597   BITFIELD (CpuVAES),
598   BITFIELD (CpuVPCLMULQDQ),
599   BITFIELD (CpuWBNOINVD),
600   BITFIELD (CpuPCONFIG),
601   BITFIELD (CpuWAITPKG),
602   BITFIELD (CpuUINTR),
603   BITFIELD (CpuCLDEMOTE),
604   BITFIELD (CpuAMX_INT8),
605   BITFIELD (CpuAMX_BF16),
606   BITFIELD (CpuAMX_FP16),
607   BITFIELD (CpuAMX_TILE),
608   BITFIELD (CpuMOVDIRI),
609   BITFIELD (CpuMOVDIR64B),
610   BITFIELD (CpuENQCMD),
611   BITFIELD (CpuSERIALIZE),
612   BITFIELD (CpuRDPRU),
613   BITFIELD (CpuMCOMMIT),
614   BITFIELD (CpuSEV_ES),
615   BITFIELD (CpuTSXLDTRK),
616   BITFIELD (CpuKL),
617   BITFIELD (CpuWideKL),
618   BITFIELD (CpuHRESET),
619   BITFIELD (CpuINVLPGB),
620   BITFIELD (CpuTLBSYNC),
621   BITFIELD (CpuSNP),
622   BITFIELD (CpuRMPQUERY),
623   BITFIELD (Cpu64),
624   BITFIELD (CpuNo64),
625 #ifdef CpuUnused
626   BITFIELD (CpuUnused),
627 #endif
628 };
629 
630 static bitfield opcode_modifiers[] =
631 {
632   BITFIELD (D),
633   BITFIELD (W),
634   BITFIELD (Load),
635   BITFIELD (Modrm),
636   BITFIELD (Jump),
637   BITFIELD (FloatMF),
638   BITFIELD (Size),
639   BITFIELD (CheckRegSize),
640   BITFIELD (OperandConstraint),
641   BITFIELD (MnemonicSize),
642   BITFIELD (No_bSuf),
643   BITFIELD (No_wSuf),
644   BITFIELD (No_lSuf),
645   BITFIELD (No_sSuf),
646   BITFIELD (No_qSuf),
647   BITFIELD (FWait),
648   BITFIELD (IsString),
649   BITFIELD (RegMem),
650   BITFIELD (BNDPrefixOk),
651   BITFIELD (PrefixOk),
652   BITFIELD (IsPrefix),
653   BITFIELD (ImmExt),
654   BITFIELD (NoRex64),
655   BITFIELD (Vex),
656   BITFIELD (VexVVVV),
657   BITFIELD (VexW),
658   BITFIELD (OpcodeSpace),
659   BITFIELD (OpcodePrefix),
660   BITFIELD (VexSources),
661   BITFIELD (SIB),
662   BITFIELD (SSE2AVX),
663   BITFIELD (EVex),
664   BITFIELD (Masking),
665   BITFIELD (Broadcast),
666   BITFIELD (StaticRounding),
667   BITFIELD (SAE),
668   BITFIELD (Disp8MemShift),
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 (Disp64),
723   BITFIELD (Byte),
724   BITFIELD (Word),
725   BITFIELD (Dword),
726   BITFIELD (Fword),
727   BITFIELD (Qword),
728   BITFIELD (Tbyte),
729   BITFIELD (Xmmword),
730   BITFIELD (Ymmword),
731   BITFIELD (Zmmword),
732   BITFIELD (Tmmword),
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 struct template_arg {
744   const struct template_arg *next;
745   const char *val;
746 };
747 
748 struct template_instance {
749   const struct template_instance *next;
750   const char *name;
751   const struct template_arg *args;
752 };
753 
754 struct template_param {
755   const struct template_param *next;
756   const char *name;
757 };
758 
759 struct template {
760   struct template *next;
761   const char *name;
762   const struct template_instance *instances;
763   const struct template_param *params;
764 };
765 
766 static struct template *templates;
767 
768 static int
769 compare (const void *x, const void *y)
770 {
771   const bitfield *xp = (const bitfield *) x;
772   const bitfield *yp = (const bitfield *) y;
773   return xp->position - yp->position;
774 }
775 
776 static void
777 fail (const char *message, ...)
778 {
779   va_list args;
780 
781   va_start (args, message);
782   fprintf (stderr, _("%s: error: "), program_name);
783   vfprintf (stderr, message, args);
784   va_end (args);
785   xexit (1);
786 }
787 
788 static void
789 process_copyright (FILE *fp)
790 {
791   fprintf (fp, "/* This file is automatically generated by i386-gen.  Do not edit!  */\n\
792 /* Copyright (C) 2007-2022 Free Software Foundation, Inc.\n\
793 \n\
794    This file is part of the GNU opcodes library.\n\
795 \n\
796    This library is free software; you can redistribute it and/or modify\n\
797    it under the terms of the GNU General Public License as published by\n\
798    the Free Software Foundation; either version 3, or (at your option)\n\
799    any later version.\n\
800 \n\
801    It is distributed in the hope that it will be useful, but WITHOUT\n\
802    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
803    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\n\
804    License for more details.\n\
805 \n\
806    You should have received a copy of the GNU General Public License\n\
807    along with this program; if not, write to the Free Software\n\
808    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
809    MA 02110-1301, USA.  */\n");
810 }
811 
812 /* Remove leading white spaces.  */
813 
814 static char *
815 remove_leading_whitespaces (char *str)
816 {
817   while (ISSPACE (*str))
818     str++;
819   return str;
820 }
821 
822 /* Remove trailing white spaces.  */
823 
824 static void
825 remove_trailing_whitespaces (char *str)
826 {
827   size_t last = strlen (str);
828 
829   if (last == 0)
830     return;
831 
832   do
833     {
834       last--;
835       if (ISSPACE (str [last]))
836 	str[last] = '\0';
837       else
838 	break;
839     }
840   while (last != 0);
841 }
842 
843 /* Find next field separated by SEP and terminate it. Return a
844    pointer to the one after it.  */
845 
846 static char *
847 next_field (char *str, char sep, char **next, char *last)
848 {
849   char *p;
850 
851   p = remove_leading_whitespaces (str);
852   for (str = p; *str != sep && *str != '\0'; str++);
853 
854   *str = '\0';
855   remove_trailing_whitespaces (p);
856 
857   *next = str + 1;
858 
859   if (p >= last)
860     abort ();
861 
862   return p;
863 }
864 
865 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
866 
867 static int
868 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
869 				 int lineno)
870 {
871   char *str, *next, *last;
872   unsigned int i;
873 
874   for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
875     if (strcmp (cpu_flag_init[i].name, f) == 0)
876       {
877 	/* Turn on selective bits.  */
878 	char *init = xstrdup (cpu_flag_init[i].init);
879 	last = init + strlen (init);
880 	for (next = init; next && next < last; )
881 	  {
882 	    str = next_field (next, '|', &next, last);
883 	    if (str)
884 	      set_bitfield (str, array, 1, size, lineno);
885 	  }
886 	free (init);
887 	return 0;
888       }
889 
890   return -1;
891 }
892 
893 static void
894 set_bitfield (char *f, bitfield *array, int value,
895 	      unsigned int size, int lineno)
896 {
897   unsigned int i;
898 
899   /* Ignore empty fields; they may result from template expansions.  */
900   if (*f == '\0')
901     return;
902 
903   for (i = 0; i < size; i++)
904     if (strcasecmp (array[i].name, f) == 0)
905       {
906 	array[i].value = value;
907 	return;
908       }
909 
910   if (value)
911     {
912       const char *v = strchr (f, '=');
913 
914       if (v)
915 	{
916 	  size_t n = v - f;
917 	  char *end;
918 
919 	  for (i = 0; i < size; i++)
920 	    if (strncasecmp (array[i].name, f, n) == 0)
921 	      {
922 		value = strtol (v + 1, &end, 0);
923 		if (*end == '\0')
924 		  {
925 		    array[i].value = value;
926 		    return;
927 		  }
928 		break;
929 	      }
930 	}
931     }
932 
933   /* Handle CPU_XXX_FLAGS.  */
934   if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
935     return;
936 
937   if (lineno != -1)
938     fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
939   else
940     fail (_("unknown bitfield: %s\n"), f);
941 }
942 
943 static void
944 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
945 		  int macro, const char *comma, const char *indent)
946 {
947   unsigned int i;
948 
949   memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
950 
951   fprintf (table, "%s{ { ", indent);
952 
953   for (i = 0; i < size - 1; i++)
954     {
955       if (((i + 1) % 20) != 0)
956 	fprintf (table, "%d, ", flags[i].value);
957       else
958 	fprintf (table, "%d,", flags[i].value);
959       if (((i + 1) % 20) == 0)
960 	{
961 	  /* We need \\ for macro.  */
962 	  if (macro)
963 	    fprintf (table, " \\\n    %s", indent);
964 	  else
965 	    fprintf (table, "\n    %s", indent);
966 	}
967       if (flags[i].value)
968 	active_cpu_flags.array[i / 32] |= 1U << (i % 32);
969     }
970 
971   fprintf (table, "%d } }%s\n", flags[i].value, comma);
972 }
973 
974 static void
975 process_i386_cpu_flag (FILE *table, char *flag, int macro,
976 		       const char *comma, const char *indent,
977 		       int lineno)
978 {
979   char *str, *next = flag, *last;
980   unsigned int i;
981   int value = 1;
982   bitfield flags [ARRAY_SIZE (cpu_flags)];
983 
984   /* Copy the default cpu flags.  */
985   memcpy (flags, cpu_flags, sizeof (cpu_flags));
986 
987   if (flag[0] == '~')
988     {
989       last = flag + strlen (flag);
990 
991       if (flag[1] == '(')
992 	{
993 	  last -= 1;
994 	  next = flag + 2;
995 	  if (*last != ')')
996 	    fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
997 		  lineno, flag);
998 	  *last = '\0';
999 	}
1000       else
1001 	next = flag + 1;
1002 
1003       /* First we turn on everything except for cpu64, cpuno64, and - if
1004          present - the padding field.  */
1005       for (i = 0; i < ARRAY_SIZE (flags); i++)
1006 	if (flags[i].position < Cpu64)
1007 	  flags[i].value = 1;
1008 
1009       /* Turn off selective bits.  */
1010       value = 0;
1011     }
1012 
1013   if (strcmp (flag, "0"))
1014     {
1015       /* Turn on/off selective bits.  */
1016       last = flag + strlen (flag);
1017       for (; next && next < last; )
1018 	{
1019 	  str = next_field (next, '|', &next, last);
1020 	  if (str)
1021 	    set_bitfield (str, flags, value, ARRAY_SIZE (flags), lineno);
1022 	}
1023     }
1024 
1025   output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1026 		    comma, indent);
1027 }
1028 
1029 static void
1030 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1031 {
1032   unsigned int i;
1033 
1034   fprintf (table, "    { ");
1035 
1036   for (i = 0; i < size - 1; i++)
1037     {
1038       if (((i + 1) % 20) != 0)
1039         fprintf (table, "%d, ", modifier[i].value);
1040       else
1041         fprintf (table, "%d,", modifier[i].value);
1042       if (((i + 1) % 20) == 0)
1043 	fprintf (table, "\n      ");
1044     }
1045 
1046   fprintf (table, "%d },\n", modifier[i].value);
1047 }
1048 
1049 /* Returns LOG2 of element size.  */
1050 static int
1051 get_element_size (char **opnd, int lineno)
1052 {
1053   char *str, *next, *last, *op;
1054   const char *full = opnd[0];
1055   int elem_size = INT_MAX;
1056 
1057   /* Find the memory operand.  */
1058   while (full != NULL && strstr(full, "BaseIndex") == NULL)
1059     full = *++opnd;
1060   if (full == NULL)
1061     fail (_("%s: %d: no memory operand\n"), filename, lineno);
1062 
1063   op = xstrdup (full);
1064   last = op + strlen (op);
1065   for (next = op; next && next < last; )
1066     {
1067       str = next_field (next, '|', &next, last);
1068       if (str)
1069 	{
1070 	  if (strcasecmp(str, "Byte") == 0)
1071 	    {
1072 	      /* The smallest element size, no need to check
1073 		 further.  */
1074 	      elem_size = 0;
1075 	      break;
1076 	    }
1077 	  else if (strcasecmp(str, "Word") == 0)
1078 	    {
1079 	      if (elem_size > 1)
1080 		elem_size = 1;
1081 	    }
1082 	  else if (strcasecmp(str, "Dword") == 0)
1083 	    {
1084 	      if (elem_size > 2)
1085 		elem_size = 2;
1086 	    }
1087 	  else if (strcasecmp(str, "Qword") == 0)
1088 	    {
1089 	      if (elem_size > 3)
1090 		elem_size = 3;
1091 	    }
1092 	}
1093     }
1094   free (op);
1095 
1096   if (elem_size == INT_MAX)
1097     fail (_("%s: %d: unknown element size: %s\n"), filename, lineno, full);
1098 
1099   return elem_size;
1100 }
1101 
1102 static void
1103 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1104 			      unsigned int prefix, char **opnd, int lineno)
1105 {
1106   char *str, *next, *last;
1107   bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1108 
1109   active_isstring = 0;
1110 
1111   /* Copy the default opcode modifier.  */
1112   memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1113 
1114   if (strcmp (mod, "0"))
1115     {
1116       unsigned int have_w = 0, bwlq_suf = 0xf;
1117 
1118       last = mod + strlen (mod);
1119       for (next = mod; next && next < last; )
1120 	{
1121 	  str = next_field (next, '|', &next, last);
1122 	  if (str)
1123 	    {
1124 	      int val = 1;
1125 	      if (strcasecmp(str, "Broadcast") == 0)
1126 		val = get_element_size (opnd, lineno) + BYTE_BROADCAST;
1127 	      else if (strcasecmp(str, "Disp8MemShift") == 0)
1128 		val = get_element_size (opnd, lineno);
1129 
1130 	      set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1131 			    lineno);
1132 	      if (strcasecmp(str, "IsString") == 0)
1133 		active_isstring = 1;
1134 
1135 	      if (strcasecmp(str, "W") == 0)
1136 		have_w = 1;
1137 
1138 	      if (strcasecmp(str, "No_bSuf") == 0)
1139 		bwlq_suf &= ~1;
1140 	      if (strcasecmp(str, "No_wSuf") == 0)
1141 		bwlq_suf &= ~2;
1142 	      if (strcasecmp(str, "No_lSuf") == 0)
1143 		bwlq_suf &= ~4;
1144 	      if (strcasecmp(str, "No_qSuf") == 0)
1145 		bwlq_suf &= ~8;
1146 	    }
1147 	}
1148 
1149       if (space)
1150 	{
1151 	  if (!modifiers[OpcodeSpace].value)
1152 	    modifiers[OpcodeSpace].value = space;
1153 	  else if (modifiers[OpcodeSpace].value != space)
1154 	    fail (_("%s:%d: Conflicting opcode space specifications\n"),
1155 		  filename, lineno);
1156 	  else
1157 	    fprintf (stderr,
1158 		     _("%s:%d: Warning: redundant opcode space specification\n"),
1159 		     filename, lineno);
1160 	}
1161 
1162       if (prefix)
1163 	{
1164 	  if (!modifiers[OpcodePrefix].value)
1165 	    modifiers[OpcodePrefix].value = prefix;
1166 	  else if (modifiers[OpcodePrefix].value != prefix)
1167 	    fail (_("%s:%d: Conflicting prefix specifications\n"),
1168 		  filename, lineno);
1169 	  else
1170 	    fprintf (stderr,
1171 		     _("%s:%d: Warning: redundant prefix specification\n"),
1172 		     filename, lineno);
1173 	}
1174 
1175       if (have_w && !bwlq_suf)
1176 	fail ("%s: %d: stray W modifier\n", filename, lineno);
1177       if (have_w && !(bwlq_suf & 1))
1178 	fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1179 		 filename, lineno);
1180       if (have_w && !(bwlq_suf & ~1))
1181 	fprintf (stderr,
1182 		 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1183 		 filename, lineno);
1184     }
1185   output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1186 }
1187 
1188 enum stage {
1189   stage_macros,
1190   stage_opcodes,
1191   stage_registers,
1192 };
1193 
1194 static void
1195 output_operand_type (FILE *table, enum operand_class class,
1196 		     enum operand_instance instance,
1197 		     const bitfield *types, unsigned int size,
1198 		     enum stage stage, const char *indent)
1199 {
1200   unsigned int i;
1201 
1202   fprintf (table, "{ { %d, %d, ", class, instance);
1203 
1204   for (i = 0; i < size - 1; i++)
1205     {
1206       if (((i + 3) % 20) != 0)
1207 	fprintf (table, "%d, ", types[i].value);
1208       else
1209 	fprintf (table, "%d,", types[i].value);
1210       if (((i + 3) % 20) == 0)
1211 	{
1212 	  /* We need \\ for macro.  */
1213 	  if (stage == stage_macros)
1214 	    fprintf (table, " \\\n%s", indent);
1215 	  else
1216 	    fprintf (table, "\n%s", indent);
1217 	}
1218     }
1219 
1220   fprintf (table, "%d } }", types[i].value);
1221 }
1222 
1223 static void
1224 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1225 			   const char *indent, int lineno)
1226 {
1227   char *str, *next, *last;
1228   enum operand_class class = ClassNone;
1229   enum operand_instance instance = InstanceNone;
1230   bitfield types [ARRAY_SIZE (operand_types)];
1231 
1232   /* Copy the default operand type.  */
1233   memcpy (types, operand_types, sizeof (types));
1234 
1235   if (strcmp (op, "0"))
1236     {
1237       int baseindex = 0;
1238 
1239       last = op + strlen (op);
1240       for (next = op; next && next < last; )
1241 	{
1242 	  str = next_field (next, '|', &next, last);
1243 	  if (str)
1244 	    {
1245 	      unsigned int i;
1246 
1247 	      if (!strncmp(str, "Class=", 6))
1248 		{
1249 		  for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1250 		    if (!strcmp(str + 6, operand_classes[i].name))
1251 		      {
1252 			class = operand_classes[i].value;
1253 			str = NULL;
1254 			break;
1255 		      }
1256 		}
1257 
1258 	      if (str && !strncmp(str, "Instance=", 9))
1259 		{
1260 		  for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1261 		    if (!strcmp(str + 9, operand_instances[i].name))
1262 		      {
1263 			instance = operand_instances[i].value;
1264 			str = NULL;
1265 			break;
1266 		      }
1267 		}
1268 	    }
1269 	  if (str)
1270 	    {
1271 	      set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1272 	      if (strcasecmp(str, "BaseIndex") == 0)
1273 		baseindex = 1;
1274 	    }
1275 	}
1276 
1277       if (stage == stage_opcodes && baseindex && !active_isstring)
1278 	{
1279 	  set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1280 	  if (!active_cpu_flags.bitfield.cpu64
1281 	      && !active_cpu_flags.bitfield.cpumpx)
1282 	    set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1283 	  set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1284 	}
1285     }
1286   output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1287 		       stage, indent);
1288 }
1289 
1290 static void
1291 output_i386_opcode (FILE *table, const char *name, char *str,
1292 		    char *last, int lineno)
1293 {
1294   unsigned int i, length, prefix = 0, space = 0;
1295   char *base_opcode, *extension_opcode, *end;
1296   char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1297   unsigned long long opcode;
1298 
1299   /* Find base_opcode.  */
1300   base_opcode = next_field (str, ',', &str, last);
1301 
1302   /* Find extension_opcode, if any.  */
1303   extension_opcode = strchr (base_opcode, '/');
1304   if (extension_opcode)
1305     *extension_opcode++ = '\0';
1306 
1307   /* Find cpu_flags.  */
1308   cpu_flags = next_field (str, ',', &str, last);
1309 
1310   /* Find opcode_modifier.  */
1311   opcode_modifier = next_field (str, ',', &str, last);
1312 
1313   /* Remove the first {.  */
1314   str = remove_leading_whitespaces (str);
1315   if (*str != '{')
1316     abort ();
1317   str = remove_leading_whitespaces (str + 1);
1318   remove_trailing_whitespaces (str);
1319 
1320   /* Remove } and trailing white space. */
1321   i = strlen (str);
1322   if (!i || str[i - 1] != '}')
1323     abort ();
1324   str[--i] = '\0';
1325   remove_trailing_whitespaces (str);
1326 
1327   if (!*str)
1328     operand_types [i = 0] = NULL;
1329   else
1330     {
1331       last = str + strlen (str);
1332 
1333       /* Find operand_types.  */
1334       for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1335 	{
1336 	  if (str >= last)
1337 	    {
1338 	      operand_types [i] = NULL;
1339 	      break;
1340 	    }
1341 
1342 	  operand_types [i] = next_field (str, ',', &str, last);
1343 	}
1344     }
1345 
1346   opcode = strtoull (base_opcode, &end, 0);
1347 
1348   /* Determine opcode length.  */
1349   for (length = 1; length < 8; ++length)
1350     if (!(opcode >> (8 * length)))
1351        break;
1352 
1353   /* Transform prefixes encoded in the opcode into opcode modifier
1354      representation.  */
1355   if (length > 1)
1356     {
1357       switch (opcode >> (8 * length - 8))
1358 	{
1359 	case 0x66: prefix = PREFIX_0X66; break;
1360 	case 0xF3: prefix = PREFIX_0XF3; break;
1361 	case 0xF2: prefix = PREFIX_0XF2; break;
1362 	}
1363 
1364       if (prefix)
1365 	opcode &= (1ULL << (8 * --length)) - 1;
1366     }
1367 
1368   /* Transform opcode space encoded in the opcode into opcode modifier
1369      representation.  */
1370   if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1371     {
1372       switch ((opcode >> (8 * length - 16)) & 0xff)
1373 	{
1374 	default:   space = SPACE_0F;   break;
1375 	case 0x38: space = SPACE_0F38; break;
1376 	case 0x3A: space = SPACE_0F3A; break;
1377 	}
1378 
1379       if (space != SPACE_0F && --length == 1)
1380 	fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1381 	      filename, lineno, name);
1382       opcode &= (1ULL << (8 * --length)) - 1;
1383     }
1384 
1385   if (length > 2)
1386     fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1387 	  filename, lineno, name, 2 * length, opcode);
1388 
1389   fprintf (table, "  { \"%s\", 0x%0*llx%s, %lu, %s,\n",
1390 	   name, 2 * (int)length, opcode, end, i,
1391 	   extension_opcode ? extension_opcode : "None");
1392 
1393   process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1394 				operand_types, lineno);
1395 
1396   process_i386_cpu_flag (table, cpu_flags, 0, ",", "    ", lineno);
1397 
1398   fprintf (table, "    { ");
1399 
1400   for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1401     {
1402       if (!operand_types[i])
1403 	{
1404 	  if (i == 0)
1405 	    process_i386_operand_type (table, "0", stage_opcodes, "\t  ",
1406 				       lineno);
1407 	  break;
1408 	}
1409 
1410       if (i != 0)
1411 	fprintf (table, ",\n      ");
1412 
1413       process_i386_operand_type (table, operand_types[i], stage_opcodes,
1414 				 "\t  ", lineno);
1415     }
1416   fprintf (table, " } },\n");
1417 }
1418 
1419 struct opcode_hash_entry
1420 {
1421   struct opcode_hash_entry *next;
1422   char *name;
1423   char *opcode;
1424   int lineno;
1425 };
1426 
1427 /* Calculate the hash value of an opcode hash entry P.  */
1428 
1429 static hashval_t
1430 opcode_hash_hash (const void *p)
1431 {
1432   struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1433   return htab_hash_string (entry->name);
1434 }
1435 
1436 /* Compare a string Q against an opcode hash entry P.  */
1437 
1438 static int
1439 opcode_hash_eq (const void *p, const void *q)
1440 {
1441   struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1442   const char *name = (const char *) q;
1443   return strcmp (name, entry->name) == 0;
1444 }
1445 
1446 static void
1447 parse_template (char *buf, int lineno)
1448 {
1449   char sep, *end, *name;
1450   struct template *tmpl;
1451   struct template_instance *last_inst = NULL;
1452 
1453   buf = remove_leading_whitespaces (buf + 1);
1454   end = strchr (buf, ':');
1455   if (end == NULL)
1456     {
1457       struct template *prev = NULL;
1458 
1459       end = strchr (buf, '>');
1460       if (end == NULL)
1461 	fail ("%s: %d: missing ':' or '>'\n", filename, lineno);
1462       if (*remove_leading_whitespaces (end + 1))
1463 	fail ("%s: %d: malformed template purge\n", filename, lineno);
1464       *end = '\0';
1465       remove_trailing_whitespaces (buf);
1466       /* Don't bother freeing the various structures.  */
1467       for (tmpl = templates; tmpl != NULL; tmpl = (prev = tmpl)->next)
1468 	if (!strcmp (buf, tmpl->name))
1469 	  break;
1470       if (tmpl == NULL)
1471 	fail ("%s: %d: no template '%s'\n", filename, lineno, buf);
1472       if (prev)
1473 	prev->next = tmpl->next;
1474       else
1475 	templates = tmpl->next;
1476       return;
1477     }
1478   *end++ = '\0';
1479   remove_trailing_whitespaces (buf);
1480 
1481   if (*buf == '\0')
1482     fail ("%s: %d: missing template identifier\n", filename, lineno);
1483   tmpl = xmalloc (sizeof (*tmpl));
1484   tmpl->name = xstrdup (buf);
1485 
1486   tmpl->params = NULL;
1487   do {
1488       struct template_param *param;
1489 
1490       buf = remove_leading_whitespaces (end);
1491       end = strpbrk (buf, ":,");
1492       if (end == NULL)
1493         fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1494 
1495       sep = *end;
1496       *end++ = '\0';
1497       remove_trailing_whitespaces (buf);
1498 
1499       param = xmalloc (sizeof (*param));
1500       param->name = xstrdup (buf);
1501       param->next = tmpl->params;
1502       tmpl->params = param;
1503   } while (sep == ':');
1504 
1505   tmpl->instances = NULL;
1506   do {
1507       struct template_instance *inst;
1508       char *cur, *next;
1509       const struct template_param *param;
1510 
1511       buf = remove_leading_whitespaces (end);
1512       end = strpbrk (buf, ",>");
1513       if (end == NULL)
1514         fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1515 
1516       sep = *end;
1517       *end++ = '\0';
1518 
1519       inst = xmalloc (sizeof (*inst));
1520       inst->next = NULL;
1521       inst->args = NULL;
1522 
1523       cur = next_field (buf, ':', &next, end);
1524       inst->name = *cur != '$' ? xstrdup (cur) : "";
1525 
1526       for (param = tmpl->params; param; param = param->next)
1527 	{
1528 	  struct template_arg *arg = xmalloc (sizeof (*arg));
1529 
1530 	  cur = next_field (next, ':', &next, end);
1531 	  if (next > end)
1532 	    fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1533 	  arg->val = xstrdup (cur);
1534 	  arg->next = inst->args;
1535 	  inst->args = arg;
1536 	}
1537 
1538       if (tmpl->instances)
1539 	last_inst->next = inst;
1540       else
1541 	tmpl->instances = inst;
1542       last_inst = inst;
1543   } while (sep == ',');
1544 
1545   buf = remove_leading_whitespaces (end);
1546   if (*buf)
1547     fprintf(stderr, "%s: %d: excess characters '%s'\n",
1548 	    filename, lineno, buf);
1549 
1550   tmpl->next = templates;
1551   templates = tmpl;
1552 }
1553 
1554 static unsigned int
1555 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1556 		  struct opcode_hash_entry ***opcode_array_p, int lineno)
1557 {
1558   static unsigned int idx, opcode_array_size;
1559   struct opcode_hash_entry **opcode_array = *opcode_array_p;
1560   struct opcode_hash_entry **hash_slot, **entry;
1561   char *ptr1 = strchr(name, '<'), *ptr2;
1562 
1563   if (ptr1 == NULL)
1564     {
1565       /* Get the slot in hash table.  */
1566       hash_slot = (struct opcode_hash_entry **)
1567 	htab_find_slot_with_hash (opcode_hash_table, name,
1568 				  htab_hash_string (name),
1569 				  INSERT);
1570 
1571       if (*hash_slot == NULL)
1572 	{
1573 	  /* It is the new one.  Put it on opcode array.  */
1574 	  if (idx >= opcode_array_size)
1575 	    {
1576 	      /* Grow the opcode array when needed.  */
1577 	      opcode_array_size += 1024;
1578 	      opcode_array = (struct opcode_hash_entry **)
1579 		xrealloc (opcode_array,
1580 			  sizeof (*opcode_array) * opcode_array_size);
1581 		*opcode_array_p = opcode_array;
1582 	    }
1583 
1584 	  opcode_array[idx] = (struct opcode_hash_entry *)
1585 	    xmalloc (sizeof (struct opcode_hash_entry));
1586 	  opcode_array[idx]->next = NULL;
1587 	  opcode_array[idx]->name = xstrdup (name);
1588 	  opcode_array[idx]->opcode = xstrdup (str);
1589 	  opcode_array[idx]->lineno = lineno;
1590 	  *hash_slot = opcode_array[idx];
1591 	  idx++;
1592 	}
1593       else
1594 	{
1595 	  /* Append it to the existing one.  */
1596 	  entry = hash_slot;
1597 	  while ((*entry) != NULL)
1598 	    entry = &(*entry)->next;
1599 	  *entry = (struct opcode_hash_entry *)
1600 	    xmalloc (sizeof (struct opcode_hash_entry));
1601 	  (*entry)->next = NULL;
1602 	  (*entry)->name = (*hash_slot)->name;
1603 	  (*entry)->opcode = xstrdup (str);
1604 	  (*entry)->lineno = lineno;
1605 	}
1606     }
1607   else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1608     fail ("%s: %d: missing '>'\n", filename, lineno);
1609   else
1610     {
1611       const struct template *tmpl;
1612       const struct template_instance *inst;
1613 
1614       *ptr1 = '\0';
1615       ptr1 = remove_leading_whitespaces (ptr1 + 1);
1616       remove_trailing_whitespaces (ptr1);
1617 
1618       *ptr2++ = '\0';
1619 
1620       for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1621 	if (!strcmp(ptr1, tmpl->name))
1622 	  break;
1623       if (!tmpl)
1624 	fail ("reference to unknown template '%s'\n", ptr1);
1625 
1626       for (inst = tmpl->instances; inst; inst = inst->next)
1627 	{
1628 	  char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1629 	  char *str2 = xmalloc(2 * strlen(str));
1630 	  const char *src;
1631 
1632 	  strcpy (name2, name);
1633 	  strcat (name2, inst->name);
1634 	  strcat (name2, ptr2);
1635 
1636 	  for (ptr1 = str2, src = str; *src; )
1637 	    {
1638 	      const char *ident = tmpl->name, *end;
1639 	      const struct template_param *param;
1640 	      const struct template_arg *arg;
1641 
1642 	      if ((*ptr1 = *src++) != '<')
1643 		{
1644 		  ++ptr1;
1645 		  continue;
1646 		}
1647 	      while (ISSPACE(*src))
1648 		++src;
1649 	      while (*ident && *src == *ident)
1650 		++src, ++ident;
1651 	      while (ISSPACE(*src))
1652 		++src;
1653 	      if (*src != ':' || *ident != '\0')
1654 		{
1655 		  memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1656 		  ptr1 += ident - tmpl->name;
1657 		  continue;
1658 		}
1659 	      while (ISSPACE(*++src))
1660 		;
1661 
1662 	      end = src;
1663 	      while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1664 		++end;
1665 
1666 	      for (param = tmpl->params, arg = inst->args; param;
1667 		   param = param->next, arg = arg->next)
1668 		{
1669 		  if (end - src == strlen (param->name)
1670 		      && !memcmp (src, param->name, end - src))
1671 		    {
1672 		      src = end;
1673 		      break;
1674 		    }
1675 		}
1676 
1677 	      if (param == NULL)
1678 		fail ("template '%s' has no parameter '%.*s'\n",
1679 		      tmpl->name, (int)(end - src), src);
1680 
1681 	      while (ISSPACE(*src))
1682 		++src;
1683 	      if (*src != '>')
1684 		fail ("%s: %d: missing '>'\n", filename, lineno);
1685 
1686 	      memcpy(ptr1, arg->val, strlen(arg->val));
1687 	      ptr1 += strlen(arg->val);
1688 	      ++src;
1689 	    }
1690 
1691 	  *ptr1 = '\0';
1692 
1693 	  expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1694 			    lineno);
1695 
1696 	  free (str2);
1697 	  free (name2);
1698 	}
1699     }
1700 
1701   return idx;
1702 }
1703 
1704 static void
1705 process_i386_opcodes (FILE *table)
1706 {
1707   FILE *fp;
1708   char buf[2048];
1709   unsigned int i, j, nr;
1710   char *str, *p, *last, *name;
1711   htab_t opcode_hash_table;
1712   struct opcode_hash_entry **opcode_array = NULL;
1713   int lineno = 0, marker = 0;
1714 
1715   filename = "i386-opc.tbl";
1716   fp = stdin;
1717 
1718   i = 0;
1719   opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1720 					 opcode_hash_eq, NULL,
1721 					 xcalloc, free);
1722 
1723   fprintf (table, "\n/* i386 opcode table.  */\n\n");
1724   fprintf (table, "static const insn_template i386_optab[] =\n{\n");
1725 
1726   /* Put everything on opcode array.  */
1727   while (!feof (fp))
1728     {
1729       if (fgets (buf, sizeof (buf), fp) == NULL)
1730 	break;
1731 
1732       p = remove_leading_whitespaces (buf);
1733 
1734       for ( ; ; )
1735 	{
1736 	  lineno++;
1737 
1738 	  /* Skip comments.  */
1739 	  str = strstr (p, "//");
1740 	  if (str != NULL)
1741 	    {
1742 	      str[0] = '\0';
1743 	      remove_trailing_whitespaces (p);
1744 	      break;
1745 	    }
1746 
1747 	  /* Look for line continuation character.  */
1748 	  remove_trailing_whitespaces (p);
1749 	  j = strlen (buf);
1750 	  if (!j || buf[j - 1] != '+')
1751 	    break;
1752 	  if (j >= sizeof (buf) - 1)
1753 	    fail (_("%s: %d: (continued) line too long\n"), filename, lineno);
1754 
1755 	  if (fgets (buf + j - 1, sizeof (buf) - j + 1, fp) == NULL)
1756 	    {
1757 	      fprintf (stderr, "%s: Line continuation on last line?\n",
1758 		       filename);
1759 	      break;
1760 	    }
1761 	}
1762 
1763       switch (p[0])
1764 	{
1765 	case '#':
1766 	  if (!strcmp("### MARKER ###", buf))
1767 	    marker = 1;
1768 	  else
1769 	    {
1770 	      /* Since we ignore all included files (we only care about their
1771 		 #define-s here), we don't need to monitor filenames.  The final
1772 		 line number directive is going to refer to the main source file
1773 		 again.  */
1774 	      char *end;
1775 	      unsigned long ln;
1776 
1777 	      p = remove_leading_whitespaces (p + 1);
1778 	      if (!strncmp(p, "line", 4))
1779 		p += 4;
1780 	      ln = strtoul (p, &end, 10);
1781 	      if (ln > 1 && ln < INT_MAX
1782 		  && *remove_leading_whitespaces (end) == '"')
1783 		lineno = ln - 1;
1784 	    }
1785 	  /* Ignore comments.  */
1786 	case '\0':
1787 	  continue;
1788 	  break;
1789 	case '<':
1790 	  parse_template (p, lineno);
1791 	  continue;
1792 	default:
1793 	  if (!marker)
1794 	    continue;
1795 	  break;
1796 	}
1797 
1798       last = p + strlen (p);
1799 
1800       /* Find name.  */
1801       name = next_field (p, ',', &str, last);
1802 
1803       i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1804 			    lineno);
1805     }
1806 
1807   /* Process opcode array.  */
1808   for (j = 0; j < i; j++)
1809     {
1810       struct opcode_hash_entry *next;
1811 
1812       for (next = opcode_array[j]; next; next = next->next)
1813 	{
1814 	  name = next->name;
1815 	  str = next->opcode;
1816 	  lineno = next->lineno;
1817 	  last = str + strlen (str);
1818 	  output_i386_opcode (table, name, str, last, lineno);
1819 	}
1820     }
1821 
1822   fclose (fp);
1823 
1824   fprintf (table, "};\n");
1825 
1826   /* Generate opcode sets array.  */
1827   fprintf (table, "\n/* i386 opcode sets table.  */\n\n");
1828   fprintf (table, "static const insn_template *const i386_op_sets[] =\n{\n");
1829   fprintf (table, "  i386_optab,\n");
1830 
1831   for (nr = j = 0; j < i; j++)
1832     {
1833       struct opcode_hash_entry *next = opcode_array[j];
1834 
1835       do
1836 	{
1837 	  ++nr;
1838 	  next = next->next;
1839 	}
1840       while (next);
1841       fprintf (table, "  i386_optab + %u,\n", nr);
1842     }
1843 
1844   fprintf (table, "};\n");
1845 }
1846 
1847 static void
1848 process_i386_registers (FILE *table)
1849 {
1850   FILE *fp;
1851   char buf[2048];
1852   char *str, *p, *last;
1853   char *reg_name, *reg_type, *reg_flags, *reg_num;
1854   char *dw2_32_num, *dw2_64_num;
1855   int lineno = 0;
1856 
1857   filename = "i386-reg.tbl";
1858   fp = fopen (filename, "r");
1859   if (fp == NULL)
1860     fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1861 	  xstrerror (errno));
1862 
1863   fprintf (table, "\n/* i386 register table.  */\n\n");
1864   fprintf (table, "static const reg_entry i386_regtab[] =\n{\n");
1865 
1866   while (!feof (fp))
1867     {
1868       if (fgets (buf, sizeof (buf), fp) == NULL)
1869 	break;
1870 
1871       lineno++;
1872 
1873       p = remove_leading_whitespaces (buf);
1874 
1875       /* Skip comments.  */
1876       str = strstr (p, "//");
1877       if (str != NULL)
1878 	str[0] = '\0';
1879 
1880       /* Remove trailing white spaces.  */
1881       remove_trailing_whitespaces (p);
1882 
1883       switch (p[0])
1884 	{
1885 	case '#':
1886 	  fprintf (table, "%s\n", p);
1887 	case '\0':
1888 	  continue;
1889 	  break;
1890 	default:
1891 	  break;
1892 	}
1893 
1894       last = p + strlen (p);
1895 
1896       /* Find reg_name.  */
1897       reg_name = next_field (p, ',', &str, last);
1898 
1899       /* Find reg_type.  */
1900       reg_type = next_field (str, ',', &str, last);
1901 
1902       /* Find reg_flags.  */
1903       reg_flags = next_field (str, ',', &str, last);
1904 
1905       /* Find reg_num.  */
1906       reg_num = next_field (str, ',', &str, last);
1907 
1908       fprintf (table, "  { \"%s\",\n    ", reg_name);
1909 
1910       process_i386_operand_type (table, reg_type, stage_registers, "\t",
1911 				 lineno);
1912 
1913       /* Find 32-bit Dwarf2 register number.  */
1914       dw2_32_num = next_field (str, ',', &str, last);
1915 
1916       /* Find 64-bit Dwarf2 register number.  */
1917       dw2_64_num = next_field (str, ',', &str, last);
1918 
1919       fprintf (table, ",\n    %s, %s, { %s, %s } },\n",
1920 	       reg_flags, reg_num, dw2_32_num, dw2_64_num);
1921     }
1922 
1923   fclose (fp);
1924 
1925   fprintf (table, "};\n");
1926 
1927   fprintf (table, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1928 }
1929 
1930 static void
1931 process_i386_initializers (void)
1932 {
1933   unsigned int i;
1934   FILE *fp = fopen ("i386-init.h", "w");
1935   char *init;
1936 
1937   if (fp == NULL)
1938     fail (_("can't create i386-init.h, errno = %s\n"),
1939 	  xstrerror (errno));
1940 
1941   process_copyright (fp);
1942 
1943   for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1944     {
1945       fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1946       init = xstrdup (cpu_flag_init[i].init);
1947       process_i386_cpu_flag (fp, init, 1, "", "  ", -1);
1948       free (init);
1949     }
1950 
1951   fprintf (fp, "\n");
1952 
1953   fclose (fp);
1954 }
1955 
1956 /* Program options.  */
1957 #define OPTION_SRCDIR	200
1958 
1959 struct option long_options[] =
1960 {
1961   {"srcdir",  required_argument, NULL, OPTION_SRCDIR},
1962   {"debug",   no_argument,       NULL, 'd'},
1963   {"version", no_argument,       NULL, 'V'},
1964   {"help",    no_argument,       NULL, 'h'},
1965   {0,         no_argument,       NULL, 0}
1966 };
1967 
1968 static void
1969 print_version (void)
1970 {
1971   printf ("%s: version 1.0\n", program_name);
1972   xexit (0);
1973 }
1974 
1975 static void
1976 usage (FILE * stream, int status)
1977 {
1978   fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1979 	   program_name);
1980   xexit (status);
1981 }
1982 
1983 int
1984 main (int argc, char **argv)
1985 {
1986   extern int chdir (char *);
1987   char *srcdir = NULL;
1988   int c;
1989   unsigned int i, cpumax;
1990   FILE *table;
1991 
1992   program_name = *argv;
1993   xmalloc_set_program_name (program_name);
1994 
1995   while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1996     switch (c)
1997       {
1998       case OPTION_SRCDIR:
1999 	srcdir = optarg;
2000 	break;
2001       case 'V':
2002       case 'v':
2003 	print_version ();
2004 	break;
2005       case 'd':
2006 	debug = 1;
2007 	break;
2008       case 'h':
2009       case '?':
2010 	usage (stderr, 0);
2011       default:
2012       case 0:
2013 	break;
2014       }
2015 
2016   if (optind != argc)
2017     usage (stdout, 1);
2018 
2019   if (srcdir != NULL)
2020     if (chdir (srcdir) != 0)
2021       fail (_("unable to change directory to \"%s\", errno = %s\n"),
2022 	    srcdir, xstrerror (errno));
2023 
2024   /* cpu_flags isn't sorted by position.  */
2025   cpumax = 0;
2026   for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2027     if (cpu_flags[i].position > cpumax)
2028       cpumax = cpu_flags[i].position;
2029 
2030   /* Check the unused bitfield in i386_cpu_flags.  */
2031 #ifdef CpuUnused
2032   static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2033 
2034   if ((cpumax - 1) != CpuMax)
2035     fail (_("CpuMax != %d!\n"), cpumax);
2036 #else
2037   static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2038 
2039   if (cpumax != CpuMax)
2040     fail (_("CpuMax != %d!\n"), cpumax);
2041 
2042   c = CpuNumOfBits - CpuMax - 1;
2043   if (c)
2044     fail (_("%d unused bits in i386_cpu_flags.\n"), c);
2045 #endif
2046 
2047   static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2048 
2049   /* Check the unused bitfield in i386_operand_type.  */
2050 #ifdef OTUnused
2051   static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2052 		 == OTNum + 1);
2053 #else
2054   static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2055 		 == OTNum);
2056 
2057   c = OTNumOfBits - OTNum;
2058   if (c)
2059     fail (_("%d unused bits in i386_operand_type.\n"), c);
2060 #endif
2061 
2062   qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2063 	 compare);
2064 
2065   qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2066 	 sizeof (opcode_modifiers [0]), compare);
2067 
2068   qsort (operand_types, ARRAY_SIZE (operand_types),
2069 	 sizeof (operand_types [0]), compare);
2070 
2071   table = fopen ("i386-tbl.h", "w");
2072   if (table == NULL)
2073     fail (_("can't create i386-tbl.h, errno = %s\n"),
2074 	  xstrerror (errno));
2075 
2076   process_copyright (table);
2077 
2078   process_i386_opcodes (table);
2079   process_i386_registers (table);
2080   process_i386_initializers ();
2081 
2082   fclose (table);
2083 
2084   exit (0);
2085 }
2086