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