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