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