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