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