gdb/gdbserver:
[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" },
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),
42164a71 401 BITFIELD (HLEPrefixOk),
ca61edf2
L
402 BITFIELD (ToDword),
403 BITFIELD (ToQword),
404 BITFIELD (AddrPrefixOp0),
40fb9820
L
405 BITFIELD (IsPrefix),
406 BITFIELD (ImmExt),
407 BITFIELD (NoRex64),
408 BITFIELD (Rex64),
409 BITFIELD (Ugh),
c0f3af97 410 BITFIELD (Vex),
2426c15f 411 BITFIELD (VexVVVV),
1ef99a7b 412 BITFIELD (VexW),
7f399153 413 BITFIELD (VexOpcode),
8cd7925b 414 BITFIELD (VexSources),
c0f3af97 415 BITFIELD (VexImmExt),
6c30d220 416 BITFIELD (VecSIB),
c0f3af97 417 BITFIELD (SSE2AVX),
81f8a913 418 BITFIELD (NoAVX),
1efbbeb4
L
419 BITFIELD (OldGcc),
420 BITFIELD (ATTMnemonic),
e1d4d893 421 BITFIELD (ATTSyntax),
5c07affc 422 BITFIELD (IntelSyntax),
40fb9820
L
423};
424
425static bitfield operand_types[] =
426{
427 BITFIELD (Reg8),
428 BITFIELD (Reg16),
429 BITFIELD (Reg32),
430 BITFIELD (Reg64),
431 BITFIELD (FloatReg),
432 BITFIELD (RegMMX),
433 BITFIELD (RegXMM),
c0f3af97 434 BITFIELD (RegYMM),
94ff3a50 435 BITFIELD (Imm1),
40fb9820
L
436 BITFIELD (Imm8),
437 BITFIELD (Imm8S),
438 BITFIELD (Imm16),
439 BITFIELD (Imm32),
440 BITFIELD (Imm32S),
441 BITFIELD (Imm64),
40fb9820
L
442 BITFIELD (BaseIndex),
443 BITFIELD (Disp8),
444 BITFIELD (Disp16),
445 BITFIELD (Disp32),
446 BITFIELD (Disp32S),
447 BITFIELD (Disp64),
448 BITFIELD (InOutPortReg),
449 BITFIELD (ShiftCount),
450 BITFIELD (Control),
451 BITFIELD (Debug),
452 BITFIELD (Test),
453 BITFIELD (SReg2),
454 BITFIELD (SReg3),
455 BITFIELD (Acc),
456 BITFIELD (FloatAcc),
457 BITFIELD (JumpAbsolute),
458 BITFIELD (EsSeg),
459 BITFIELD (RegMem),
5c07affc 460 BITFIELD (Mem),
7d5e4556
L
461 BITFIELD (Byte),
462 BITFIELD (Word),
463 BITFIELD (Dword),
464 BITFIELD (Fword),
465 BITFIELD (Qword),
466 BITFIELD (Tbyte),
467 BITFIELD (Xmmword),
c0f3af97 468 BITFIELD (Ymmword),
7d5e4556
L
469 BITFIELD (Unspecified),
470 BITFIELD (Anysize),
a683cc34 471 BITFIELD (Vec_Imm4),
40fb9820
L
472#ifdef OTUnused
473 BITFIELD (OTUnused),
474#endif
475};
476
3d4d5afa
L
477static const char *filename;
478
40fb9820
L
479static int
480compare (const void *x, const void *y)
481{
482 const bitfield *xp = (const bitfield *) x;
483 const bitfield *yp = (const bitfield *) y;
484 return xp->position - yp->position;
485}
486
40b8e679
L
487static void
488fail (const char *message, ...)
489{
490 va_list args;
491
492 va_start (args, message);
493 fprintf (stderr, _("%s: Error: "), program_name);
494 vfprintf (stderr, message, args);
495 va_end (args);
496 xexit (1);
497}
498
72ffa0fb
L
499static void
500process_copyright (FILE *fp)
501{
502 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
4fb3aee2 503/* Copyright 2007, 2008, 2009, 2010, 2011\n\
22da050b 504 Free Software Foundation, Inc.\n\
72ffa0fb
L
505\n\
506 This file is part of the GNU opcodes library.\n\
507\n\
508 This library is free software; you can redistribute it and/or modify\n\
509 it under the terms of the GNU General Public License as published by\n\
510 the Free Software Foundation; either version 3, or (at your option)\n\
511 any later version.\n\
512\n\
513 It is distributed in the hope that it will be useful, but WITHOUT\n\
514 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
515 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
516 License for more details.\n\
517\n\
518 You should have received a copy of the GNU General Public License\n\
519 along with this program; if not, write to the Free Software\n\
520 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
521 MA 02110-1301, USA. */\n");
522}
523
40b8e679
L
524/* Remove leading white spaces. */
525
526static char *
527remove_leading_whitespaces (char *str)
528{
529 while (ISSPACE (*str))
530 str++;
531 return str;
532}
533
534/* Remove trailing white spaces. */
535
536static void
537remove_trailing_whitespaces (char *str)
538{
539 size_t last = strlen (str);
540
541 if (last == 0)
542 return;
543
544 do
545 {
546 last--;
547 if (ISSPACE (str [last]))
548 str[last] = '\0';
549 else
550 break;
551 }
552 while (last != 0);
553}
554
93b1ec2c 555/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
556 pointer to the one after it. */
557
558static char *
c587b3f9 559next_field (char *str, char sep, char **next, char *last)
40b8e679
L
560{
561 char *p;
562
563 p = remove_leading_whitespaces (str);
93b1ec2c 564 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
565
566 *str = '\0';
567 remove_trailing_whitespaces (p);
568
569 *next = str + 1;
570
c587b3f9
L
571 if (p >= last)
572 abort ();
573
40b8e679
L
574 return p;
575}
576
40fb9820 577static void
8a9036a4
L
578set_bitfield (const char *f, bitfield *array, int value,
579 unsigned int size, int lineno)
40fb9820
L
580{
581 unsigned int i;
582
309d3373
JB
583 if (strcmp (f, "CpuFP") == 0)
584 {
8a9036a4
L
585 set_bitfield("Cpu387", array, value, size, lineno);
586 set_bitfield("Cpu287", array, value, size, lineno);
309d3373
JB
587 f = "Cpu8087";
588 }
589 else if (strcmp (f, "Mmword") == 0)
7d5e4556
L
590 f= "Qword";
591 else if (strcmp (f, "Oword") == 0)
592 f= "Xmmword";
40fb9820
L
593
594 for (i = 0; i < size; i++)
595 if (strcasecmp (array[i].name, f) == 0)
596 {
8a9036a4 597 array[i].value = value;
40fb9820
L
598 return;
599 }
600
2bf05e57
L
601 if (value)
602 {
603 const char *v = strchr (f, '=');
604
605 if (v)
606 {
607 size_t n = v - f;
608 char *end;
609
610 for (i = 0; i < size; i++)
611 if (strncasecmp (array[i].name, f, n) == 0)
612 {
613 value = strtol (v + 1, &end, 0);
614 if (*end == '\0')
615 {
616 array[i].value = value;
617 return;
618 }
619 break;
620 }
621 }
622 }
623
bd5295b2
L
624 if (lineno != -1)
625 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
626 else
627 fail (_("Unknown bitfield: %s\n"), f);
40fb9820
L
628}
629
630static void
631output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
632 int macro, const char *comma, const char *indent)
633{
634 unsigned int i;
635
636 fprintf (table, "%s{ { ", indent);
637
638 for (i = 0; i < size - 1; i++)
639 {
640 fprintf (table, "%d, ", flags[i].value);
641 if (((i + 1) % 20) == 0)
642 {
643 /* We need \\ for macro. */
644 if (macro)
645 fprintf (table, " \\\n %s", indent);
646 else
647 fprintf (table, "\n %s", indent);
648 }
649 }
650
651 fprintf (table, "%d } }%s\n", flags[i].value, comma);
652}
653
654static void
655process_i386_cpu_flag (FILE *table, char *flag, int macro,
bd5295b2
L
656 const char *comma, const char *indent,
657 int lineno)
40fb9820
L
658{
659 char *str, *next, *last;
8a9036a4 660 unsigned int i;
40fb9820
L
661 bitfield flags [ARRAY_SIZE (cpu_flags)];
662
663 /* Copy the default cpu flags. */
664 memcpy (flags, cpu_flags, sizeof (cpu_flags));
665
666 if (strcasecmp (flag, "unknown") == 0)
667 {
40fb9820 668 /* We turn on everything except for cpu64 in case of
8a9036a4
L
669 CPU_UNKNOWN_FLAGS. */
670 for (i = 0; i < ARRAY_SIZE (flags); i++)
671 if (flags[i].position != Cpu64)
672 flags[i].value = 1;
673 }
674 else if (flag[0] == '~')
675 {
676 last = flag + strlen (flag);
677
678 if (flag[1] == '(')
679 {
680 last -= 1;
681 next = flag + 2;
682 if (*last != ')')
683 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
684 lineno, flag);
685 *last = '\0';
686 }
687 else
688 next = flag + 1;
689
690 /* First we turn on everything except for cpu64. */
40fb9820
L
691 for (i = 0; i < ARRAY_SIZE (flags); i++)
692 if (flags[i].position != Cpu64)
693 flags[i].value = 1;
8a9036a4
L
694
695 /* Turn off selective bits. */
696 for (; next && next < last; )
697 {
698 str = next_field (next, '|', &next, last);
699 if (str)
700 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
701 }
40fb9820
L
702 }
703 else if (strcmp (flag, "0"))
704 {
8a9036a4 705 /* Turn on selective bits. */
40fb9820
L
706 last = flag + strlen (flag);
707 for (next = flag; next && next < last; )
708 {
c587b3f9 709 str = next_field (next, '|', &next, last);
40fb9820 710 if (str)
8a9036a4 711 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
40fb9820
L
712 }
713 }
714
715 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
716 comma, indent);
717}
718
719static void
720output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
721{
722 unsigned int i;
723
724 fprintf (table, " { ");
725
726 for (i = 0; i < size - 1; i++)
727 {
728 fprintf (table, "%d, ", modifier[i].value);
729 if (((i + 1) % 20) == 0)
730 fprintf (table, "\n ");
731 }
732
733 fprintf (table, "%d },\n", modifier[i].value);
734}
735
736static void
bd5295b2 737process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
40fb9820
L
738{
739 char *str, *next, *last;
740 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
741
742 /* Copy the default opcode modifier. */
743 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
744
745 if (strcmp (mod, "0"))
746 {
747 last = mod + strlen (mod);
748 for (next = mod; next && next < last; )
749 {
c587b3f9 750 str = next_field (next, '|', &next, last);
40fb9820 751 if (str)
8a9036a4
L
752 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
753 lineno);
40fb9820
L
754 }
755 }
756 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
757}
758
759static void
760output_operand_type (FILE *table, bitfield *types, unsigned int size,
761 int macro, const char *indent)
762{
763 unsigned int i;
764
765 fprintf (table, "{ { ");
766
767 for (i = 0; i < size - 1; i++)
768 {
769 fprintf (table, "%d, ", types[i].value);
770 if (((i + 1) % 20) == 0)
771 {
772 /* We need \\ for macro. */
773 if (macro)
774 fprintf (table, "\\\n%s", indent);
775 else
776 fprintf (table, "\n%s", indent);
777 }
778 }
779
780 fprintf (table, "%d } }", types[i].value);
781}
782
783static void
784process_i386_operand_type (FILE *table, char *op, int macro,
bd5295b2 785 const char *indent, int lineno)
40fb9820
L
786{
787 char *str, *next, *last;
788 bitfield types [ARRAY_SIZE (operand_types)];
789
790 /* Copy the default operand type. */
791 memcpy (types, operand_types, sizeof (types));
792
793 if (strcmp (op, "0"))
794 {
795 last = op + strlen (op);
796 for (next = op; next && next < last; )
797 {
c587b3f9 798 str = next_field (next, '|', &next, last);
40fb9820 799 if (str)
8a9036a4 800 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
801 }
802 }
803 output_operand_type (table, types, ARRAY_SIZE (types), macro,
804 indent);
805}
806
c587b3f9
L
807static void
808output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 809 char *last, int lineno)
c587b3f9
L
810{
811 unsigned int i;
812 char *operands, *base_opcode, *extension_opcode, *opcode_length;
813 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
814
815 /* Find number of operands. */
816 operands = next_field (str, ',', &str, last);
817
818 /* Find base_opcode. */
819 base_opcode = next_field (str, ',', &str, last);
820
821 /* Find extension_opcode. */
822 extension_opcode = next_field (str, ',', &str, last);
823
824 /* Find opcode_length. */
825 opcode_length = next_field (str, ',', &str, last);
826
827 /* Find cpu_flags. */
828 cpu_flags = next_field (str, ',', &str, last);
829
830 /* Find opcode_modifier. */
831 opcode_modifier = next_field (str, ',', &str, last);
832
833 /* Remove the first {. */
834 str = remove_leading_whitespaces (str);
835 if (*str != '{')
836 abort ();
837 str = remove_leading_whitespaces (str + 1);
838
839 i = strlen (str);
840
841 /* There are at least "X}". */
842 if (i < 2)
843 abort ();
844
845 /* Remove trailing white spaces and }. */
846 do
847 {
848 i--;
849 if (ISSPACE (str[i]) || str[i] == '}')
850 str[i] = '\0';
851 else
852 break;
853 }
854 while (i != 0);
855
856 last = str + i;
857
858 /* Find operand_types. */
859 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
860 {
861 if (str >= last)
862 {
863 operand_types [i] = NULL;
864 break;
865 }
866
867 operand_types [i] = next_field (str, ',', &str, last);
868 if (*operand_types[i] == '0')
869 {
870 if (i != 0)
871 operand_types[i] = NULL;
872 break;
873 }
874 }
875
876 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
877 name, operands, base_opcode, extension_opcode,
878 opcode_length);
879
bd5295b2 880 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
c587b3f9 881
bd5295b2 882 process_i386_opcode_modifier (table, opcode_modifier, lineno);
c587b3f9
L
883
884 fprintf (table, " { ");
885
886 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
887 {
888 if (operand_types[i] == NULL || *operand_types[i] == '0')
889 {
890 if (i == 0)
bd5295b2 891 process_i386_operand_type (table, "0", 0, "\t ", lineno);
c587b3f9
L
892 break;
893 }
894
895 if (i != 0)
896 fprintf (table, ",\n ");
897
898 process_i386_operand_type (table, operand_types[i], 0,
bd5295b2 899 "\t ", lineno);
c587b3f9
L
900 }
901 fprintf (table, " } },\n");
902}
903
904struct opcode_hash_entry
905{
906 struct opcode_hash_entry *next;
907 char *name;
908 char *opcode;
bd5295b2 909 int lineno;
c587b3f9
L
910};
911
912/* Calculate the hash value of an opcode hash entry P. */
913
914static hashval_t
915opcode_hash_hash (const void *p)
916{
917 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
918 return htab_hash_string (entry->name);
919}
920
921/* Compare a string Q against an opcode hash entry P. */
922
923static int
924opcode_hash_eq (const void *p, const void *q)
925{
926 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
927 const char *name = (const char *) q;
928 return strcmp (name, entry->name) == 0;
929}
930
40b8e679 931static void
72ffa0fb 932process_i386_opcodes (FILE *table)
40b8e679 933{
3d4d5afa 934 FILE *fp;
40b8e679 935 char buf[2048];
c587b3f9
L
936 unsigned int i, j;
937 char *str, *p, *last, *name;
938 struct opcode_hash_entry **hash_slot, **entry, *next;
939 htab_t opcode_hash_table;
940 struct opcode_hash_entry **opcode_array;
941 unsigned int opcode_array_size = 1024;
bd5295b2 942 int lineno = 0;
40b8e679 943
3d4d5afa
L
944 filename = "i386-opc.tbl";
945 fp = fopen (filename, "r");
946
40b8e679 947 if (fp == NULL)
34edb9ad 948 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
40fb9820 949 xstrerror (errno));
40b8e679 950
c587b3f9
L
951 i = 0;
952 opcode_array = (struct opcode_hash_entry **)
953 xmalloc (sizeof (*opcode_array) * opcode_array_size);
954
955 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
956 opcode_hash_eq, NULL,
957 xcalloc, free);
958
34edb9ad 959 fprintf (table, "\n/* i386 opcode table. */\n\n");
d3ce72d0 960 fprintf (table, "const insn_template i386_optab[] =\n{\n");
40b8e679 961
c587b3f9 962 /* Put everything on opcode array. */
40b8e679
L
963 while (!feof (fp))
964 {
965 if (fgets (buf, sizeof (buf), fp) == NULL)
966 break;
967
3d4d5afa
L
968 lineno++;
969
40b8e679
L
970 p = remove_leading_whitespaces (buf);
971
972 /* Skip comments. */
973 str = strstr (p, "//");
974 if (str != NULL)
975 str[0] = '\0';
976
977 /* Remove trailing white spaces. */
978 remove_trailing_whitespaces (p);
979
980 switch (p[0])
981 {
982 case '#':
c587b3f9 983 /* Ignore comments. */
40b8e679
L
984 case '\0':
985 continue;
986 break;
987 default:
988 break;
989 }
990
991 last = p + strlen (p);
992
993 /* Find name. */
c587b3f9 994 name = next_field (p, ',', &str, last);
40b8e679 995
c587b3f9
L
996 /* Get the slot in hash table. */
997 hash_slot = (struct opcode_hash_entry **)
998 htab_find_slot_with_hash (opcode_hash_table, name,
999 htab_hash_string (name),
1000 INSERT);
40b8e679 1001
c587b3f9 1002 if (*hash_slot == NULL)
40b8e679 1003 {
c587b3f9
L
1004 /* It is the new one. Put it on opcode array. */
1005 if (i >= opcode_array_size)
40b8e679 1006 {
c587b3f9
L
1007 /* Grow the opcode array when needed. */
1008 opcode_array_size += 1024;
1009 opcode_array = (struct opcode_hash_entry **)
1010 xrealloc (opcode_array,
1011 sizeof (*opcode_array) * opcode_array_size);
40b8e679
L
1012 }
1013
c587b3f9
L
1014 opcode_array[i] = (struct opcode_hash_entry *)
1015 xmalloc (sizeof (struct opcode_hash_entry));
1016 opcode_array[i]->next = NULL;
1017 opcode_array[i]->name = xstrdup (name);
1018 opcode_array[i]->opcode = xstrdup (str);
bd5295b2 1019 opcode_array[i]->lineno = lineno;
c587b3f9
L
1020 *hash_slot = opcode_array[i];
1021 i++;
40b8e679 1022 }
c587b3f9 1023 else
40b8e679 1024 {
c587b3f9
L
1025 /* Append it to the existing one. */
1026 entry = hash_slot;
1027 while ((*entry) != NULL)
1028 entry = &(*entry)->next;
1029 *entry = (struct opcode_hash_entry *)
1030 xmalloc (sizeof (struct opcode_hash_entry));
1031 (*entry)->next = NULL;
1032 (*entry)->name = (*hash_slot)->name;
1033 (*entry)->opcode = xstrdup (str);
bd5295b2 1034 (*entry)->lineno = lineno;
c587b3f9
L
1035 }
1036 }
40b8e679 1037
c587b3f9
L
1038 /* Process opcode array. */
1039 for (j = 0; j < i; j++)
1040 {
1041 for (next = opcode_array[j]; next; next = next->next)
1042 {
1043 name = next->name;
1044 str = next->opcode;
bd5295b2 1045 lineno = next->lineno;
c587b3f9 1046 last = str + strlen (str);
bd5295b2 1047 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1048 }
40b8e679
L
1049 }
1050
34edb9ad
L
1051 fclose (fp);
1052
4dffcebc 1053 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820 1054
bd5295b2 1055 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
40fb9820 1056
bd5295b2 1057 process_i386_opcode_modifier (table, "0", -1);
40fb9820
L
1058
1059 fprintf (table, " { ");
bd5295b2 1060 process_i386_operand_type (table, "0", 0, "\t ", -1);
40fb9820
L
1061 fprintf (table, " } }\n");
1062
34edb9ad 1063 fprintf (table, "};\n");
40b8e679
L
1064}
1065
1066static void
72ffa0fb 1067process_i386_registers (FILE *table)
40b8e679 1068{
3d4d5afa 1069 FILE *fp;
40b8e679
L
1070 char buf[2048];
1071 char *str, *p, *last;
1072 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1073 char *dw2_32_num, *dw2_64_num;
bd5295b2 1074 int lineno = 0;
40b8e679 1075
3d4d5afa
L
1076 filename = "i386-reg.tbl";
1077 fp = fopen (filename, "r");
40b8e679 1078 if (fp == NULL)
34edb9ad 1079 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1080 xstrerror (errno));
40b8e679 1081
34edb9ad
L
1082 fprintf (table, "\n/* i386 register table. */\n\n");
1083 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1084
1085 while (!feof (fp))
1086 {
1087 if (fgets (buf, sizeof (buf), fp) == NULL)
1088 break;
1089
3d4d5afa
L
1090 lineno++;
1091
40b8e679
L
1092 p = remove_leading_whitespaces (buf);
1093
1094 /* Skip comments. */
1095 str = strstr (p, "//");
1096 if (str != NULL)
1097 str[0] = '\0';
1098
1099 /* Remove trailing white spaces. */
1100 remove_trailing_whitespaces (p);
1101
1102 switch (p[0])
1103 {
1104 case '#':
34edb9ad 1105 fprintf (table, "%s\n", p);
40b8e679
L
1106 case '\0':
1107 continue;
1108 break;
1109 default:
1110 break;
1111 }
1112
1113 last = p + strlen (p);
1114
1115 /* Find reg_name. */
c587b3f9 1116 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1117
1118 /* Find reg_type. */
c587b3f9 1119 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1120
1121 /* Find reg_flags. */
c587b3f9 1122 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1123
1124 /* Find reg_num. */
c587b3f9 1125 reg_num = next_field (str, ',', &str, last);
a60de03c 1126
40fb9820
L
1127 fprintf (table, " { \"%s\",\n ", reg_name);
1128
bd5295b2 1129 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
40fb9820 1130
a60de03c 1131 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1132 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1133
1134 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1135 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1136
1137 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1138 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1139 }
1140
34edb9ad
L
1141 fclose (fp);
1142
1143 fprintf (table, "};\n");
40b8e679 1144
34edb9ad 1145 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1146}
1147
40fb9820
L
1148static void
1149process_i386_initializers (void)
1150{
1151 unsigned int i;
1152 FILE *fp = fopen ("i386-init.h", "w");
1153 char *init;
1154
1155 if (fp == NULL)
1156 fail (_("can't create i386-init.h, errno = %s\n"),
1157 xstrerror (errno));
1158
1159 process_copyright (fp);
1160
1161 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1162 {
1163 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1164 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1165 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1166 free (init);
1167 }
1168
1169 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1170 {
1171 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1172 init = xstrdup (operand_type_init[i].init);
bd5295b2 1173 process_i386_operand_type (fp, init, 1, " ", -1);
40fb9820
L
1174 free (init);
1175 }
1176 fprintf (fp, "\n");
1177
1178 fclose (fp);
1179}
1180
40b8e679
L
1181/* Program options. */
1182#define OPTION_SRCDIR 200
1183
1184struct option long_options[] =
1185{
1186 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1187 {"debug", no_argument, NULL, 'd'},
1188 {"version", no_argument, NULL, 'V'},
1189 {"help", no_argument, NULL, 'h'},
1190 {0, no_argument, NULL, 0}
1191};
1192
1193static void
1194print_version (void)
1195{
1196 printf ("%s: version 1.0\n", program_name);
1197 xexit (0);
1198}
1199
1200static void
1201usage (FILE * stream, int status)
1202{
1203 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1204 program_name);
1205 xexit (status);
1206}
1207
1208int
1209main (int argc, char **argv)
1210{
1211 extern int chdir (char *);
1212 char *srcdir = NULL;
8b40d594 1213 int c;
72ffa0fb 1214 FILE *table;
40b8e679
L
1215
1216 program_name = *argv;
1217 xmalloc_set_program_name (program_name);
1218
1219 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1220 switch (c)
1221 {
1222 case OPTION_SRCDIR:
1223 srcdir = optarg;
1224 break;
1225 case 'V':
1226 case 'v':
1227 print_version ();
1228 break;
1229 case 'd':
1230 debug = 1;
1231 break;
1232 case 'h':
1233 case '?':
1234 usage (stderr, 0);
1235 default:
1236 case 0:
1237 break;
1238 }
1239
1240 if (optind != argc)
1241 usage (stdout, 1);
1242
1243 if (srcdir != NULL)
1244 if (chdir (srcdir) != 0)
1245 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
1246 srcdir, xstrerror (errno));
1247
1248 /* Check the unused bitfield in i386_cpu_flags. */
1249#ifndef CpuUnused
8b40d594
L
1250 c = CpuNumOfBits - CpuMax - 1;
1251 if (c)
1252 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
1253#endif
1254
1255 /* Check the unused bitfield in i386_operand_type. */
1256#ifndef OTUnused
8b40d594
L
1257 c = OTNumOfBits - OTMax - 1;
1258 if (c)
1259 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
1260#endif
1261
1262 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1263 compare);
1264
1265 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1266 sizeof (opcode_modifiers [0]), compare);
1267
1268 qsort (operand_types, ARRAY_SIZE (operand_types),
1269 sizeof (operand_types [0]), compare);
40b8e679 1270
34edb9ad
L
1271 table = fopen ("i386-tbl.h", "w");
1272 if (table == NULL)
40fb9820
L
1273 fail (_("can't create i386-tbl.h, errno = %s\n"),
1274 xstrerror (errno));
34edb9ad 1275
72ffa0fb 1276 process_copyright (table);
40b8e679 1277
72ffa0fb
L
1278 process_i386_opcodes (table);
1279 process_i386_registers (table);
40fb9820 1280 process_i386_initializers ();
40b8e679 1281
34edb9ad
L
1282 fclose (table);
1283
40b8e679
L
1284 exit (0);
1285}
This page took 0.287353 seconds and 4 git commands to generate.