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