1 /* Copyright (C) 2007-2016 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
24 #include "libiberty.h"
26 #include "safe-ctype.h"
31 #define _(String) gettext (String)
33 static const char *program_name
= NULL
;
36 typedef struct initializer
42 static initializer cpu_flag_init
[] =
44 { "CPU_UNKNOWN_FLAGS",
45 "~(CpuL1OM|CpuK1OM)" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
57 "Cpu186|Cpu286|Cpu386" },
59 "Cpu186|Cpu286|Cpu386|Cpu486" },
61 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu387" },
63 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
67 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
69 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
71 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
73 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM|CpuCX16" },
75 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuCX16" },
77 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM|CpuCX16" },
79 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM|CpuCX16" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
83 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
87 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
91 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "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|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
95 "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|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase" },
97 "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|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
99 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuBMI|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_BTVER1_FLAGS",
101 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
102 { "CPU_BTVER2_FLAGS",
103 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuSSE4_1|CpuSSE4_2|CpuABM|CpuLM|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
110 { "CPU_ANY_X87_FLAGS",
111 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
112 { "CPU_CLFLUSH_FLAGS",
116 { "CPU_SYSCALL_FLAGS",
123 "CpuMMX|CpuSSE|CpuSSE2" },
125 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
127 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
128 { "CPU_SSE4_1_FLAGS",
129 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
130 { "CPU_SSE4_2_FLAGS",
131 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
132 { "CPU_ANY_SSE_FLAGS",
133 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
140 { "CPU_XSAVEOPT_FLAGS",
143 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
144 { "CPU_PCLMUL_FLAGS",
145 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
147 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
149 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
151 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
162 { "CPU_RDTSCP_FLAGS",
166 { "CPU_FSGSBASE_FLAGS",
180 { "CPU_INVPCID_FLAGS",
182 { "CPU_VMFUNC_FLAGS",
186 { "CPU_3DNOWA_FLAGS",
187 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
188 { "CPU_ANY_MMX_FLAGS",
189 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
190 { "CPU_PADLOCK_FLAGS",
195 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
199 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
201 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
202 { "CPU_AVX512F_FLAGS",
203 "CpuVREX|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F" },
204 { "CPU_AVX512CD_FLAGS",
205 "CpuVREX|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD" },
206 { "CPU_AVX512ER_FLAGS",
207 "CpuVREX|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512ER" },
208 { "CPU_AVX512PF_FLAGS",
209 "CpuVREX|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512PF" },
210 { "CPU_AVX512DQ_FLAGS",
211 "CpuVREX|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512DQ" },
212 { "CPU_AVX512BW_FLAGS",
213 "CpuVREX|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512BW" },
214 { "CPU_AVX512VL_FLAGS",
215 "CpuVREX|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VL" },
216 { "CPU_AVX512IFMA_FLAGS",
217 "CpuVREX|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512IFMA" },
218 { "CPU_AVX512VBMI_FLAGS",
219 "CpuVREX|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VBMI" },
220 { "CPU_ANY_AVX_FLAGS",
221 "CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI" },
227 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
228 { "CPU_IAMCU_COMPAT_FLAGS",
229 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuNo64|CpuNop" },
232 { "CPU_RDSEED_FLAGS",
234 { "CPU_PRFCHW_FLAGS",
242 { "CPU_CLFLUSHOPT_FLAGS",
244 { "CPU_XSAVES_FLAGS",
246 { "CPU_XSAVEC_FLAGS",
248 { "CPU_PREFETCHWT1_FLAGS",
254 { "CPU_PCOMMIT_FLAGS",
256 { "CPU_CLZERO_FLAGS",
258 { "CPU_MWAITX_FLAGS",
266 static initializer operand_type_init
[] =
268 { "OPERAND_TYPE_NONE",
270 { "OPERAND_TYPE_REG8",
272 { "OPERAND_TYPE_REG16",
274 { "OPERAND_TYPE_REG32",
276 { "OPERAND_TYPE_REG64",
278 { "OPERAND_TYPE_IMM1",
280 { "OPERAND_TYPE_IMM8",
282 { "OPERAND_TYPE_IMM8S",
284 { "OPERAND_TYPE_IMM16",
286 { "OPERAND_TYPE_IMM32",
288 { "OPERAND_TYPE_IMM32S",
290 { "OPERAND_TYPE_IMM64",
292 { "OPERAND_TYPE_BASEINDEX",
294 { "OPERAND_TYPE_DISP8",
296 { "OPERAND_TYPE_DISP16",
298 { "OPERAND_TYPE_DISP32",
300 { "OPERAND_TYPE_DISP32S",
302 { "OPERAND_TYPE_DISP64",
304 { "OPERAND_TYPE_INOUTPORTREG",
306 { "OPERAND_TYPE_SHIFTCOUNT",
308 { "OPERAND_TYPE_CONTROL",
310 { "OPERAND_TYPE_TEST",
312 { "OPERAND_TYPE_DEBUG",
314 { "OPERAND_TYPE_FLOATREG",
316 { "OPERAND_TYPE_FLOATACC",
318 { "OPERAND_TYPE_SREG2",
320 { "OPERAND_TYPE_SREG3",
322 { "OPERAND_TYPE_ACC",
324 { "OPERAND_TYPE_JUMPABSOLUTE",
326 { "OPERAND_TYPE_REGMMX",
328 { "OPERAND_TYPE_REGXMM",
330 { "OPERAND_TYPE_REGYMM",
332 { "OPERAND_TYPE_REGZMM",
334 { "OPERAND_TYPE_REGMASK",
336 { "OPERAND_TYPE_ESSEG",
338 { "OPERAND_TYPE_ACC32",
340 { "OPERAND_TYPE_ACC64",
342 { "OPERAND_TYPE_INOUTPORTREG",
344 { "OPERAND_TYPE_REG16_INOUTPORTREG",
345 "Reg16|InOutPortReg" },
346 { "OPERAND_TYPE_DISP16_32",
348 { "OPERAND_TYPE_ANYDISP",
349 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
350 { "OPERAND_TYPE_IMM16_32",
352 { "OPERAND_TYPE_IMM16_32S",
354 { "OPERAND_TYPE_IMM16_32_32S",
355 "Imm16|Imm32|Imm32S" },
356 { "OPERAND_TYPE_IMM32_64",
358 { "OPERAND_TYPE_IMM32_32S_DISP32",
359 "Imm32|Imm32S|Disp32" },
360 { "OPERAND_TYPE_IMM64_DISP64",
362 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
363 "Imm32|Imm32S|Imm64|Disp32" },
364 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
365 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
366 { "OPERAND_TYPE_VEC_IMM4",
368 { "OPERAND_TYPE_REGBND",
370 { "OPERAND_TYPE_VEC_DISP8",
374 typedef struct bitfield
381 #define BITFIELD(n) { n, 0, #n }
383 static bitfield cpu_flags
[] =
391 BITFIELD (CpuClflush
),
393 BITFIELD (CpuSYSCALL
),
398 BITFIELD (CpuFISTTP
),
404 BITFIELD (CpuSSE4_1
),
405 BITFIELD (CpuSSE4_2
),
408 BITFIELD (CpuAVX512F
),
409 BITFIELD (CpuAVX512CD
),
410 BITFIELD (CpuAVX512ER
),
411 BITFIELD (CpuAVX512PF
),
412 BITFIELD (CpuAVX512VL
),
413 BITFIELD (CpuAVX512DQ
),
414 BITFIELD (CpuAVX512BW
),
420 BITFIELD (Cpu3dnowA
),
421 BITFIELD (CpuPadLock
),
427 BITFIELD (CpuXsaveopt
),
429 BITFIELD (CpuPCLMUL
),
440 BITFIELD (CpuRdtscp
),
441 BITFIELD (CpuFSGSBase
),
448 BITFIELD (CpuINVPCID
),
449 BITFIELD (CpuVMFUNC
),
450 BITFIELD (CpuRDSEED
),
452 BITFIELD (CpuPRFCHW
),
456 BITFIELD (CpuClflushOpt
),
457 BITFIELD (CpuXSAVES
),
458 BITFIELD (CpuXSAVEC
),
459 BITFIELD (CpuPREFETCHWT1
),
462 BITFIELD (CpuPCOMMIT
),
466 BITFIELD (CpuAVX512IFMA
),
467 BITFIELD (CpuAVX512VBMI
),
468 BITFIELD (CpuMWAITX
),
469 BITFIELD (CpuCLZERO
),
473 BITFIELD (CpuIntel64
),
475 BITFIELD (CpuUnused
),
479 static bitfield opcode_modifiers
[] =
485 BITFIELD (ShortForm
),
487 BITFIELD (JumpDword
),
489 BITFIELD (JumpInterSegment
),
496 BITFIELD (CheckRegSize
),
497 BITFIELD (IgnoreSize
),
498 BITFIELD (DefaultSize
),
507 BITFIELD (BNDPrefixOk
),
508 BITFIELD (IsLockable
),
509 BITFIELD (RegKludge
),
510 BITFIELD (FirstXmm0
),
511 BITFIELD (Implicit1stXmm0
),
512 BITFIELD (RepPrefixOk
),
513 BITFIELD (HLEPrefixOk
),
516 BITFIELD (AddrPrefixOp0
),
525 BITFIELD (VexOpcode
),
526 BITFIELD (VexSources
),
527 BITFIELD (VexImmExt
),
534 BITFIELD (Broadcast
),
535 BITFIELD (StaticRounding
),
537 BITFIELD (Disp8MemShift
),
538 BITFIELD (NoDefMask
),
540 BITFIELD (ATTMnemonic
),
541 BITFIELD (ATTSyntax
),
542 BITFIELD (IntelSyntax
),
545 static bitfield operand_types
[] =
564 BITFIELD (BaseIndex
),
570 BITFIELD (InOutPortReg
),
571 BITFIELD (ShiftCount
),
579 BITFIELD (JumpAbsolute
),
592 BITFIELD (Unspecified
),
596 BITFIELD (Vec_Disp8
),
602 static const char *filename
;
605 compare (const void *x
, const void *y
)
607 const bitfield
*xp
= (const bitfield
*) x
;
608 const bitfield
*yp
= (const bitfield
*) y
;
609 return xp
->position
- yp
->position
;
613 fail (const char *message
, ...)
617 va_start (args
, message
);
618 fprintf (stderr
, _("%s: Error: "), program_name
);
619 vfprintf (stderr
, message
, args
);
625 process_copyright (FILE *fp
)
627 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
628 /* Copyright (C) 2007-2016 Free Software Foundation, Inc.\n\
630 This file is part of the GNU opcodes library.\n\
632 This library is free software; you can redistribute it and/or modify\n\
633 it under the terms of the GNU General Public License as published by\n\
634 the Free Software Foundation; either version 3, or (at your option)\n\
635 any later version.\n\
637 It is distributed in the hope that it will be useful, but WITHOUT\n\
638 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
639 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
640 License for more details.\n\
642 You should have received a copy of the GNU General Public License\n\
643 along with this program; if not, write to the Free Software\n\
644 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
645 MA 02110-1301, USA. */\n");
648 /* Remove leading white spaces. */
651 remove_leading_whitespaces (char *str
)
653 while (ISSPACE (*str
))
658 /* Remove trailing white spaces. */
661 remove_trailing_whitespaces (char *str
)
663 size_t last
= strlen (str
);
671 if (ISSPACE (str
[last
]))
679 /* Find next field separated by SEP and terminate it. Return a
680 pointer to the one after it. */
683 next_field (char *str
, char sep
, char **next
, char *last
)
687 p
= remove_leading_whitespaces (str
);
688 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
691 remove_trailing_whitespaces (p
);
702 set_bitfield (const char *f
, bitfield
*array
, int value
,
703 unsigned int size
, int lineno
)
707 if (strcmp (f
, "CpuFP") == 0)
709 set_bitfield("Cpu387", array
, value
, size
, lineno
);
710 set_bitfield("Cpu287", array
, value
, size
, lineno
);
713 else if (strcmp (f
, "Mmword") == 0)
715 else if (strcmp (f
, "Oword") == 0)
718 for (i
= 0; i
< size
; i
++)
719 if (strcasecmp (array
[i
].name
, f
) == 0)
721 array
[i
].value
= value
;
727 const char *v
= strchr (f
, '=');
734 for (i
= 0; i
< size
; i
++)
735 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
737 value
= strtol (v
+ 1, &end
, 0);
740 array
[i
].value
= value
;
749 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
751 fail (_("Unknown bitfield: %s\n"), f
);
755 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
756 int macro
, const char *comma
, const char *indent
)
760 fprintf (table
, "%s{ { ", indent
);
762 for (i
= 0; i
< size
- 1; i
++)
764 if (((i
+ 1) % 20) != 0)
765 fprintf (table
, "%d, ", flags
[i
].value
);
767 fprintf (table
, "%d,", flags
[i
].value
);
768 if (((i
+ 1) % 20) == 0)
770 /* We need \\ for macro. */
772 fprintf (table
, " \\\n %s", indent
);
774 fprintf (table
, "\n %s", indent
);
778 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
782 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
783 const char *comma
, const char *indent
,
786 char *str
, *next
, *last
;
788 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
790 /* Copy the default cpu flags. */
791 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
793 if (strcasecmp (flag
, "unknown") == 0)
795 /* We turn on everything except for cpu64 in case of
796 CPU_UNKNOWN_FLAGS. */
797 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
798 if (flags
[i
].position
!= Cpu64
)
801 else if (flag
[0] == '~')
803 last
= flag
+ strlen (flag
);
810 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
817 /* First we turn on everything except for cpu64. */
818 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
819 if (flags
[i
].position
!= Cpu64
)
822 /* Turn off selective bits. */
823 for (; next
&& next
< last
; )
825 str
= next_field (next
, '|', &next
, last
);
827 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
830 else if (strcmp (flag
, "0"))
832 /* Turn on selective bits. */
833 last
= flag
+ strlen (flag
);
834 for (next
= flag
; next
&& next
< last
; )
836 str
= next_field (next
, '|', &next
, last
);
838 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
842 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
847 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
851 fprintf (table
, " { ");
853 for (i
= 0; i
< size
- 1; i
++)
855 if (((i
+ 1) % 20) != 0)
856 fprintf (table
, "%d, ", modifier
[i
].value
);
858 fprintf (table
, "%d,", modifier
[i
].value
);
859 if (((i
+ 1) % 20) == 0)
860 fprintf (table
, "\n ");
863 fprintf (table
, "%d },\n", modifier
[i
].value
);
867 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
869 char *str
, *next
, *last
;
870 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
872 /* Copy the default opcode modifier. */
873 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
875 if (strcmp (mod
, "0"))
877 last
= mod
+ strlen (mod
);
878 for (next
= mod
; next
&& next
< last
; )
880 str
= next_field (next
, '|', &next
, last
);
882 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
886 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
890 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
891 int macro
, const char *indent
)
895 fprintf (table
, "{ { ");
897 for (i
= 0; i
< size
- 1; i
++)
899 if (((i
+ 1) % 20) != 0)
900 fprintf (table
, "%d, ", types
[i
].value
);
902 fprintf (table
, "%d,", types
[i
].value
);
903 if (((i
+ 1) % 20) == 0)
905 /* We need \\ for macro. */
907 fprintf (table
, " \\\n%s", indent
);
909 fprintf (table
, "\n%s", indent
);
913 fprintf (table
, "%d } }", types
[i
].value
);
917 process_i386_operand_type (FILE *table
, char *op
, int macro
,
918 const char *indent
, int lineno
)
920 char *str
, *next
, *last
;
921 bitfield types
[ARRAY_SIZE (operand_types
)];
923 /* Copy the default operand type. */
924 memcpy (types
, operand_types
, sizeof (types
));
926 if (strcmp (op
, "0"))
928 last
= op
+ strlen (op
);
929 for (next
= op
; next
&& next
< last
; )
931 str
= next_field (next
, '|', &next
, last
);
933 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
936 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
941 output_i386_opcode (FILE *table
, const char *name
, char *str
,
942 char *last
, int lineno
)
945 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
946 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
948 /* Find number of operands. */
949 operands
= next_field (str
, ',', &str
, last
);
951 /* Find base_opcode. */
952 base_opcode
= next_field (str
, ',', &str
, last
);
954 /* Find extension_opcode. */
955 extension_opcode
= next_field (str
, ',', &str
, last
);
957 /* Find opcode_length. */
958 opcode_length
= next_field (str
, ',', &str
, last
);
960 /* Find cpu_flags. */
961 cpu_flags
= next_field (str
, ',', &str
, last
);
963 /* Find opcode_modifier. */
964 opcode_modifier
= next_field (str
, ',', &str
, last
);
966 /* Remove the first {. */
967 str
= remove_leading_whitespaces (str
);
970 str
= remove_leading_whitespaces (str
+ 1);
974 /* There are at least "X}". */
978 /* Remove trailing white spaces and }. */
982 if (ISSPACE (str
[i
]) || str
[i
] == '}')
991 /* Find operand_types. */
992 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
996 operand_types
[i
] = NULL
;
1000 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1001 if (*operand_types
[i
] == '0')
1004 operand_types
[i
] = NULL
;
1009 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1010 name
, operands
, base_opcode
, extension_opcode
,
1013 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1015 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1017 fprintf (table
, " { ");
1019 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1021 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1024 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1029 fprintf (table
, ",\n ");
1031 process_i386_operand_type (table
, operand_types
[i
], 0,
1034 fprintf (table
, " } },\n");
1037 struct opcode_hash_entry
1039 struct opcode_hash_entry
*next
;
1045 /* Calculate the hash value of an opcode hash entry P. */
1048 opcode_hash_hash (const void *p
)
1050 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1051 return htab_hash_string (entry
->name
);
1054 /* Compare a string Q against an opcode hash entry P. */
1057 opcode_hash_eq (const void *p
, const void *q
)
1059 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1060 const char *name
= (const char *) q
;
1061 return strcmp (name
, entry
->name
) == 0;
1065 process_i386_opcodes (FILE *table
)
1070 char *str
, *p
, *last
, *name
;
1071 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1072 htab_t opcode_hash_table
;
1073 struct opcode_hash_entry
**opcode_array
;
1074 unsigned int opcode_array_size
= 1024;
1077 filename
= "i386-opc.tbl";
1078 fp
= fopen (filename
, "r");
1081 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1085 opcode_array
= (struct opcode_hash_entry
**)
1086 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1088 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1089 opcode_hash_eq
, NULL
,
1092 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1093 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1095 /* Put everything on opcode array. */
1098 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1103 p
= remove_leading_whitespaces (buf
);
1105 /* Skip comments. */
1106 str
= strstr (p
, "//");
1110 /* Remove trailing white spaces. */
1111 remove_trailing_whitespaces (p
);
1116 /* Ignore comments. */
1124 last
= p
+ strlen (p
);
1127 name
= next_field (p
, ',', &str
, last
);
1129 /* Get the slot in hash table. */
1130 hash_slot
= (struct opcode_hash_entry
**)
1131 htab_find_slot_with_hash (opcode_hash_table
, name
,
1132 htab_hash_string (name
),
1135 if (*hash_slot
== NULL
)
1137 /* It is the new one. Put it on opcode array. */
1138 if (i
>= opcode_array_size
)
1140 /* Grow the opcode array when needed. */
1141 opcode_array_size
+= 1024;
1142 opcode_array
= (struct opcode_hash_entry
**)
1143 xrealloc (opcode_array
,
1144 sizeof (*opcode_array
) * opcode_array_size
);
1147 opcode_array
[i
] = (struct opcode_hash_entry
*)
1148 xmalloc (sizeof (struct opcode_hash_entry
));
1149 opcode_array
[i
]->next
= NULL
;
1150 opcode_array
[i
]->name
= xstrdup (name
);
1151 opcode_array
[i
]->opcode
= xstrdup (str
);
1152 opcode_array
[i
]->lineno
= lineno
;
1153 *hash_slot
= opcode_array
[i
];
1158 /* Append it to the existing one. */
1160 while ((*entry
) != NULL
)
1161 entry
= &(*entry
)->next
;
1162 *entry
= (struct opcode_hash_entry
*)
1163 xmalloc (sizeof (struct opcode_hash_entry
));
1164 (*entry
)->next
= NULL
;
1165 (*entry
)->name
= (*hash_slot
)->name
;
1166 (*entry
)->opcode
= xstrdup (str
);
1167 (*entry
)->lineno
= lineno
;
1171 /* Process opcode array. */
1172 for (j
= 0; j
< i
; j
++)
1174 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1178 lineno
= next
->lineno
;
1179 last
= str
+ strlen (str
);
1180 output_i386_opcode (table
, name
, str
, last
, lineno
);
1186 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1188 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1190 process_i386_opcode_modifier (table
, "0", -1);
1192 fprintf (table
, " { ");
1193 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1194 fprintf (table
, " } }\n");
1196 fprintf (table
, "};\n");
1200 process_i386_registers (FILE *table
)
1204 char *str
, *p
, *last
;
1205 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1206 char *dw2_32_num
, *dw2_64_num
;
1209 filename
= "i386-reg.tbl";
1210 fp
= fopen (filename
, "r");
1212 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1215 fprintf (table
, "\n/* i386 register table. */\n\n");
1216 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1220 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1225 p
= remove_leading_whitespaces (buf
);
1227 /* Skip comments. */
1228 str
= strstr (p
, "//");
1232 /* Remove trailing white spaces. */
1233 remove_trailing_whitespaces (p
);
1238 fprintf (table
, "%s\n", p
);
1246 last
= p
+ strlen (p
);
1248 /* Find reg_name. */
1249 reg_name
= next_field (p
, ',', &str
, last
);
1251 /* Find reg_type. */
1252 reg_type
= next_field (str
, ',', &str
, last
);
1254 /* Find reg_flags. */
1255 reg_flags
= next_field (str
, ',', &str
, last
);
1258 reg_num
= next_field (str
, ',', &str
, last
);
1260 fprintf (table
, " { \"%s\",\n ", reg_name
);
1262 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1264 /* Find 32-bit Dwarf2 register number. */
1265 dw2_32_num
= next_field (str
, ',', &str
, last
);
1267 /* Find 64-bit Dwarf2 register number. */
1268 dw2_64_num
= next_field (str
, ',', &str
, last
);
1270 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1271 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1276 fprintf (table
, "};\n");
1278 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1282 process_i386_initializers (void)
1285 FILE *fp
= fopen ("i386-init.h", "w");
1289 fail (_("can't create i386-init.h, errno = %s\n"),
1292 process_copyright (fp
);
1294 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1296 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1297 init
= xstrdup (cpu_flag_init
[i
].init
);
1298 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1302 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1304 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1305 init
= xstrdup (operand_type_init
[i
].init
);
1306 process_i386_operand_type (fp
, init
, 1, " ", -1);
1314 /* Program options. */
1315 #define OPTION_SRCDIR 200
1317 struct option long_options
[] =
1319 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1320 {"debug", no_argument
, NULL
, 'd'},
1321 {"version", no_argument
, NULL
, 'V'},
1322 {"help", no_argument
, NULL
, 'h'},
1323 {0, no_argument
, NULL
, 0}
1327 print_version (void)
1329 printf ("%s: version 1.0\n", program_name
);
1334 usage (FILE * stream
, int status
)
1336 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1342 main (int argc
, char **argv
)
1344 extern int chdir (char *);
1345 char *srcdir
= NULL
;
1349 program_name
= *argv
;
1350 xmalloc_set_program_name (program_name
);
1352 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1377 if (chdir (srcdir
) != 0)
1378 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1379 srcdir
, xstrerror (errno
));
1381 /* Check the unused bitfield in i386_cpu_flags. */
1383 c
= CpuNumOfBits
- CpuMax
- 1;
1385 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1388 /* Check the unused bitfield in i386_operand_type. */
1390 c
= OTNumOfBits
- OTMax
- 1;
1392 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1395 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1398 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1399 sizeof (opcode_modifiers
[0]), compare
);
1401 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1402 sizeof (operand_types
[0]), compare
);
1404 table
= fopen ("i386-tbl.h", "w");
1406 fail (_("can't create i386-tbl.h, errno = %s\n"),
1409 process_copyright (table
);
1411 process_i386_opcodes (table
);
1412 process_i386_registers (table
);
1413 process_i386_initializers ();