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