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