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