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