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