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