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