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