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