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