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