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