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" },
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_PADLOCK_FLAGS",
193 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
197 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
199 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
200 { "CPU_AVX512F_FLAGS",
201 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F" },
202 { "CPU_AVX512CD_FLAGS",
203 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD" },
204 { "CPU_AVX512ER_FLAGS",
205 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512ER" },
206 { "CPU_AVX512PF_FLAGS",
207 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512PF" },
208 { "CPU_ANY_AVX_FLAGS",
209 "CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
215 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
216 { "CPU_IAMCU_COMPAT_FLAGS",
217 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuNo64|CpuNop" },
220 { "CPU_RDSEED_FLAGS",
222 { "CPU_PRFCHW_FLAGS",
230 { "CPU_CLFLUSHOPT_FLAGS",
232 { "CPU_XSAVES_FLAGS",
234 { "CPU_XSAVEC_FLAGS",
236 { "CPU_PREFETCHWT1_FLAGS",
240 { "CPU_AVX512DQ_FLAGS",
241 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512DQ" },
242 { "CPU_AVX512BW_FLAGS",
243 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512BW" },
244 { "CPU_AVX512VL_FLAGS",
245 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VL" },
248 { "CPU_PCOMMIT_FLAGS",
250 { "CPU_AVX512IFMA_FLAGS",
251 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512IFMA" },
252 { "CPU_AVX512VBMI_FLAGS",
253 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VBMI" },
254 { "CPU_CLZERO_FLAGS",
256 { "CPU_MWAITX_FLAGS",
264 static initializer operand_type_init
[] =
266 { "OPERAND_TYPE_NONE",
268 { "OPERAND_TYPE_REG8",
270 { "OPERAND_TYPE_REG16",
272 { "OPERAND_TYPE_REG32",
274 { "OPERAND_TYPE_REG64",
276 { "OPERAND_TYPE_IMM1",
278 { "OPERAND_TYPE_IMM8",
280 { "OPERAND_TYPE_IMM8S",
282 { "OPERAND_TYPE_IMM16",
284 { "OPERAND_TYPE_IMM32",
286 { "OPERAND_TYPE_IMM32S",
288 { "OPERAND_TYPE_IMM64",
290 { "OPERAND_TYPE_BASEINDEX",
292 { "OPERAND_TYPE_DISP8",
294 { "OPERAND_TYPE_DISP16",
296 { "OPERAND_TYPE_DISP32",
298 { "OPERAND_TYPE_DISP32S",
300 { "OPERAND_TYPE_DISP64",
302 { "OPERAND_TYPE_INOUTPORTREG",
304 { "OPERAND_TYPE_SHIFTCOUNT",
306 { "OPERAND_TYPE_CONTROL",
308 { "OPERAND_TYPE_TEST",
310 { "OPERAND_TYPE_DEBUG",
312 { "OPERAND_TYPE_FLOATREG",
314 { "OPERAND_TYPE_FLOATACC",
316 { "OPERAND_TYPE_SREG2",
318 { "OPERAND_TYPE_SREG3",
320 { "OPERAND_TYPE_ACC",
322 { "OPERAND_TYPE_JUMPABSOLUTE",
324 { "OPERAND_TYPE_REGMMX",
326 { "OPERAND_TYPE_REGXMM",
328 { "OPERAND_TYPE_REGYMM",
330 { "OPERAND_TYPE_REGZMM",
332 { "OPERAND_TYPE_REGMASK",
334 { "OPERAND_TYPE_ESSEG",
336 { "OPERAND_TYPE_ACC32",
338 { "OPERAND_TYPE_ACC64",
340 { "OPERAND_TYPE_INOUTPORTREG",
342 { "OPERAND_TYPE_REG16_INOUTPORTREG",
343 "Reg16|InOutPortReg" },
344 { "OPERAND_TYPE_DISP16_32",
346 { "OPERAND_TYPE_ANYDISP",
347 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
348 { "OPERAND_TYPE_IMM16_32",
350 { "OPERAND_TYPE_IMM16_32S",
352 { "OPERAND_TYPE_IMM16_32_32S",
353 "Imm16|Imm32|Imm32S" },
354 { "OPERAND_TYPE_IMM32_64",
356 { "OPERAND_TYPE_IMM32_32S_DISP32",
357 "Imm32|Imm32S|Disp32" },
358 { "OPERAND_TYPE_IMM64_DISP64",
360 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
361 "Imm32|Imm32S|Imm64|Disp32" },
362 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
363 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
364 { "OPERAND_TYPE_VEC_IMM4",
366 { "OPERAND_TYPE_REGBND",
368 { "OPERAND_TYPE_VEC_DISP8",
372 typedef struct bitfield
379 #define BITFIELD(n) { n, 0, #n }
381 static bitfield cpu_flags
[] =
389 BITFIELD (CpuClflush
),
391 BITFIELD (CpuSYSCALL
),
396 BITFIELD (CpuFISTTP
),
402 BITFIELD (CpuSSE4_1
),
403 BITFIELD (CpuSSE4_2
),
406 BITFIELD (CpuAVX512F
),
407 BITFIELD (CpuAVX512CD
),
408 BITFIELD (CpuAVX512ER
),
409 BITFIELD (CpuAVX512PF
),
410 BITFIELD (CpuAVX512VL
),
411 BITFIELD (CpuAVX512DQ
),
412 BITFIELD (CpuAVX512BW
),
418 BITFIELD (Cpu3dnowA
),
419 BITFIELD (CpuPadLock
),
425 BITFIELD (CpuXsaveopt
),
427 BITFIELD (CpuPCLMUL
),
438 BITFIELD (CpuRdtscp
),
439 BITFIELD (CpuFSGSBase
),
446 BITFIELD (CpuINVPCID
),
447 BITFIELD (CpuVMFUNC
),
448 BITFIELD (CpuRDSEED
),
450 BITFIELD (CpuPRFCHW
),
454 BITFIELD (CpuClflushOpt
),
455 BITFIELD (CpuXSAVES
),
456 BITFIELD (CpuXSAVEC
),
457 BITFIELD (CpuPREFETCHWT1
),
460 BITFIELD (CpuPCOMMIT
),
464 BITFIELD (CpuAVX512IFMA
),
465 BITFIELD (CpuAVX512VBMI
),
466 BITFIELD (CpuMWAITX
),
467 BITFIELD (CpuCLZERO
),
471 BITFIELD (CpuIntel64
),
473 BITFIELD (CpuUnused
),
477 static bitfield opcode_modifiers
[] =
483 BITFIELD (ShortForm
),
485 BITFIELD (JumpDword
),
487 BITFIELD (JumpInterSegment
),
494 BITFIELD (CheckRegSize
),
495 BITFIELD (IgnoreSize
),
496 BITFIELD (DefaultSize
),
505 BITFIELD (BNDPrefixOk
),
506 BITFIELD (IsLockable
),
507 BITFIELD (RegKludge
),
508 BITFIELD (FirstXmm0
),
509 BITFIELD (Implicit1stXmm0
),
510 BITFIELD (RepPrefixOk
),
511 BITFIELD (HLEPrefixOk
),
514 BITFIELD (AddrPrefixOp0
),
523 BITFIELD (VexOpcode
),
524 BITFIELD (VexSources
),
525 BITFIELD (VexImmExt
),
532 BITFIELD (Broadcast
),
533 BITFIELD (StaticRounding
),
535 BITFIELD (Disp8MemShift
),
536 BITFIELD (NoDefMask
),
538 BITFIELD (ATTMnemonic
),
539 BITFIELD (ATTSyntax
),
540 BITFIELD (IntelSyntax
),
543 static bitfield operand_types
[] =
562 BITFIELD (BaseIndex
),
568 BITFIELD (InOutPortReg
),
569 BITFIELD (ShiftCount
),
577 BITFIELD (JumpAbsolute
),
590 BITFIELD (Unspecified
),
594 BITFIELD (Vec_Disp8
),
600 static const char *filename
;
603 compare (const void *x
, const void *y
)
605 const bitfield
*xp
= (const bitfield
*) x
;
606 const bitfield
*yp
= (const bitfield
*) y
;
607 return xp
->position
- yp
->position
;
611 fail (const char *message
, ...)
615 va_start (args
, message
);
616 fprintf (stderr
, _("%s: Error: "), program_name
);
617 vfprintf (stderr
, message
, args
);
623 process_copyright (FILE *fp
)
625 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
626 /* Copyright (C) 2007-2016 Free Software Foundation, Inc.\n\
628 This file is part of the GNU opcodes library.\n\
630 This library is free software; you can redistribute it and/or modify\n\
631 it under the terms of the GNU General Public License as published by\n\
632 the Free Software Foundation; either version 3, or (at your option)\n\
633 any later version.\n\
635 It is distributed in the hope that it will be useful, but WITHOUT\n\
636 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
637 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
638 License for more details.\n\
640 You should have received a copy of the GNU General Public License\n\
641 along with this program; if not, write to the Free Software\n\
642 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
643 MA 02110-1301, USA. */\n");
646 /* Remove leading white spaces. */
649 remove_leading_whitespaces (char *str
)
651 while (ISSPACE (*str
))
656 /* Remove trailing white spaces. */
659 remove_trailing_whitespaces (char *str
)
661 size_t last
= strlen (str
);
669 if (ISSPACE (str
[last
]))
677 /* Find next field separated by SEP and terminate it. Return a
678 pointer to the one after it. */
681 next_field (char *str
, char sep
, char **next
, char *last
)
685 p
= remove_leading_whitespaces (str
);
686 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
689 remove_trailing_whitespaces (p
);
700 set_bitfield (const char *f
, bitfield
*array
, int value
,
701 unsigned int size
, int lineno
)
705 if (strcmp (f
, "CpuFP") == 0)
707 set_bitfield("Cpu387", array
, value
, size
, lineno
);
708 set_bitfield("Cpu287", array
, value
, size
, lineno
);
711 else if (strcmp (f
, "Mmword") == 0)
713 else if (strcmp (f
, "Oword") == 0)
716 for (i
= 0; i
< size
; i
++)
717 if (strcasecmp (array
[i
].name
, f
) == 0)
719 array
[i
].value
= value
;
725 const char *v
= strchr (f
, '=');
732 for (i
= 0; i
< size
; i
++)
733 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
735 value
= strtol (v
+ 1, &end
, 0);
738 array
[i
].value
= value
;
747 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
749 fail (_("Unknown bitfield: %s\n"), f
);
753 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
754 int macro
, const char *comma
, const char *indent
)
758 fprintf (table
, "%s{ { ", indent
);
760 for (i
= 0; i
< size
- 1; i
++)
762 if (((i
+ 1) % 20) != 0)
763 fprintf (table
, "%d, ", flags
[i
].value
);
765 fprintf (table
, "%d,", flags
[i
].value
);
766 if (((i
+ 1) % 20) == 0)
768 /* We need \\ for macro. */
770 fprintf (table
, " \\\n %s", indent
);
772 fprintf (table
, "\n %s", indent
);
776 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
780 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
781 const char *comma
, const char *indent
,
784 char *str
, *next
, *last
;
786 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
788 /* Copy the default cpu flags. */
789 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
791 if (strcasecmp (flag
, "unknown") == 0)
793 /* We turn on everything except for cpu64 in case of
794 CPU_UNKNOWN_FLAGS. */
795 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
796 if (flags
[i
].position
!= Cpu64
)
799 else if (flag
[0] == '~')
801 last
= flag
+ strlen (flag
);
808 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
815 /* First we turn on everything except for cpu64. */
816 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
817 if (flags
[i
].position
!= Cpu64
)
820 /* Turn off selective bits. */
821 for (; next
&& next
< last
; )
823 str
= next_field (next
, '|', &next
, last
);
825 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
828 else if (strcmp (flag
, "0"))
830 /* Turn on selective bits. */
831 last
= flag
+ strlen (flag
);
832 for (next
= flag
; next
&& next
< last
; )
834 str
= next_field (next
, '|', &next
, last
);
836 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
840 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
845 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
849 fprintf (table
, " { ");
851 for (i
= 0; i
< size
- 1; i
++)
853 if (((i
+ 1) % 20) != 0)
854 fprintf (table
, "%d, ", modifier
[i
].value
);
856 fprintf (table
, "%d,", modifier
[i
].value
);
857 if (((i
+ 1) % 20) == 0)
858 fprintf (table
, "\n ");
861 fprintf (table
, "%d },\n", modifier
[i
].value
);
865 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
867 char *str
, *next
, *last
;
868 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
870 /* Copy the default opcode modifier. */
871 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
873 if (strcmp (mod
, "0"))
875 last
= mod
+ strlen (mod
);
876 for (next
= mod
; next
&& next
< last
; )
878 str
= next_field (next
, '|', &next
, last
);
880 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
884 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
888 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
889 int macro
, const char *indent
)
893 fprintf (table
, "{ { ");
895 for (i
= 0; i
< size
- 1; i
++)
897 if (((i
+ 1) % 20) != 0)
898 fprintf (table
, "%d, ", types
[i
].value
);
900 fprintf (table
, "%d,", types
[i
].value
);
901 if (((i
+ 1) % 20) == 0)
903 /* We need \\ for macro. */
905 fprintf (table
, " \\\n%s", indent
);
907 fprintf (table
, "\n%s", indent
);
911 fprintf (table
, "%d } }", types
[i
].value
);
915 process_i386_operand_type (FILE *table
, char *op
, int macro
,
916 const char *indent
, int lineno
)
918 char *str
, *next
, *last
;
919 bitfield types
[ARRAY_SIZE (operand_types
)];
921 /* Copy the default operand type. */
922 memcpy (types
, operand_types
, sizeof (types
));
924 if (strcmp (op
, "0"))
926 last
= op
+ strlen (op
);
927 for (next
= op
; next
&& next
< last
; )
929 str
= next_field (next
, '|', &next
, last
);
931 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
934 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
939 output_i386_opcode (FILE *table
, const char *name
, char *str
,
940 char *last
, int lineno
)
943 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
944 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
946 /* Find number of operands. */
947 operands
= next_field (str
, ',', &str
, last
);
949 /* Find base_opcode. */
950 base_opcode
= next_field (str
, ',', &str
, last
);
952 /* Find extension_opcode. */
953 extension_opcode
= next_field (str
, ',', &str
, last
);
955 /* Find opcode_length. */
956 opcode_length
= next_field (str
, ',', &str
, last
);
958 /* Find cpu_flags. */
959 cpu_flags
= next_field (str
, ',', &str
, last
);
961 /* Find opcode_modifier. */
962 opcode_modifier
= next_field (str
, ',', &str
, last
);
964 /* Remove the first {. */
965 str
= remove_leading_whitespaces (str
);
968 str
= remove_leading_whitespaces (str
+ 1);
972 /* There are at least "X}". */
976 /* Remove trailing white spaces and }. */
980 if (ISSPACE (str
[i
]) || str
[i
] == '}')
989 /* Find operand_types. */
990 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
994 operand_types
[i
] = NULL
;
998 operand_types
[i
] = next_field (str
, ',', &str
, last
);
999 if (*operand_types
[i
] == '0')
1002 operand_types
[i
] = NULL
;
1007 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1008 name
, operands
, base_opcode
, extension_opcode
,
1011 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1013 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1015 fprintf (table
, " { ");
1017 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1019 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1022 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1027 fprintf (table
, ",\n ");
1029 process_i386_operand_type (table
, operand_types
[i
], 0,
1032 fprintf (table
, " } },\n");
1035 struct opcode_hash_entry
1037 struct opcode_hash_entry
*next
;
1043 /* Calculate the hash value of an opcode hash entry P. */
1046 opcode_hash_hash (const void *p
)
1048 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1049 return htab_hash_string (entry
->name
);
1052 /* Compare a string Q against an opcode hash entry P. */
1055 opcode_hash_eq (const void *p
, const void *q
)
1057 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1058 const char *name
= (const char *) q
;
1059 return strcmp (name
, entry
->name
) == 0;
1063 process_i386_opcodes (FILE *table
)
1068 char *str
, *p
, *last
, *name
;
1069 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1070 htab_t opcode_hash_table
;
1071 struct opcode_hash_entry
**opcode_array
;
1072 unsigned int opcode_array_size
= 1024;
1075 filename
= "i386-opc.tbl";
1076 fp
= fopen (filename
, "r");
1079 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1083 opcode_array
= (struct opcode_hash_entry
**)
1084 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1086 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1087 opcode_hash_eq
, NULL
,
1090 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1091 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1093 /* Put everything on opcode array. */
1096 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1101 p
= remove_leading_whitespaces (buf
);
1103 /* Skip comments. */
1104 str
= strstr (p
, "//");
1108 /* Remove trailing white spaces. */
1109 remove_trailing_whitespaces (p
);
1114 /* Ignore comments. */
1122 last
= p
+ strlen (p
);
1125 name
= next_field (p
, ',', &str
, last
);
1127 /* Get the slot in hash table. */
1128 hash_slot
= (struct opcode_hash_entry
**)
1129 htab_find_slot_with_hash (opcode_hash_table
, name
,
1130 htab_hash_string (name
),
1133 if (*hash_slot
== NULL
)
1135 /* It is the new one. Put it on opcode array. */
1136 if (i
>= opcode_array_size
)
1138 /* Grow the opcode array when needed. */
1139 opcode_array_size
+= 1024;
1140 opcode_array
= (struct opcode_hash_entry
**)
1141 xrealloc (opcode_array
,
1142 sizeof (*opcode_array
) * opcode_array_size
);
1145 opcode_array
[i
] = (struct opcode_hash_entry
*)
1146 xmalloc (sizeof (struct opcode_hash_entry
));
1147 opcode_array
[i
]->next
= NULL
;
1148 opcode_array
[i
]->name
= xstrdup (name
);
1149 opcode_array
[i
]->opcode
= xstrdup (str
);
1150 opcode_array
[i
]->lineno
= lineno
;
1151 *hash_slot
= opcode_array
[i
];
1156 /* Append it to the existing one. */
1158 while ((*entry
) != NULL
)
1159 entry
= &(*entry
)->next
;
1160 *entry
= (struct opcode_hash_entry
*)
1161 xmalloc (sizeof (struct opcode_hash_entry
));
1162 (*entry
)->next
= NULL
;
1163 (*entry
)->name
= (*hash_slot
)->name
;
1164 (*entry
)->opcode
= xstrdup (str
);
1165 (*entry
)->lineno
= lineno
;
1169 /* Process opcode array. */
1170 for (j
= 0; j
< i
; j
++)
1172 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1176 lineno
= next
->lineno
;
1177 last
= str
+ strlen (str
);
1178 output_i386_opcode (table
, name
, str
, last
, lineno
);
1184 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1186 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1188 process_i386_opcode_modifier (table
, "0", -1);
1190 fprintf (table
, " { ");
1191 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1192 fprintf (table
, " } }\n");
1194 fprintf (table
, "};\n");
1198 process_i386_registers (FILE *table
)
1202 char *str
, *p
, *last
;
1203 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1204 char *dw2_32_num
, *dw2_64_num
;
1207 filename
= "i386-reg.tbl";
1208 fp
= fopen (filename
, "r");
1210 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1213 fprintf (table
, "\n/* i386 register table. */\n\n");
1214 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1218 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1223 p
= remove_leading_whitespaces (buf
);
1225 /* Skip comments. */
1226 str
= strstr (p
, "//");
1230 /* Remove trailing white spaces. */
1231 remove_trailing_whitespaces (p
);
1236 fprintf (table
, "%s\n", p
);
1244 last
= p
+ strlen (p
);
1246 /* Find reg_name. */
1247 reg_name
= next_field (p
, ',', &str
, last
);
1249 /* Find reg_type. */
1250 reg_type
= next_field (str
, ',', &str
, last
);
1252 /* Find reg_flags. */
1253 reg_flags
= next_field (str
, ',', &str
, last
);
1256 reg_num
= next_field (str
, ',', &str
, last
);
1258 fprintf (table
, " { \"%s\",\n ", reg_name
);
1260 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1262 /* Find 32-bit Dwarf2 register number. */
1263 dw2_32_num
= next_field (str
, ',', &str
, last
);
1265 /* Find 64-bit Dwarf2 register number. */
1266 dw2_64_num
= next_field (str
, ',', &str
, last
);
1268 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1269 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1274 fprintf (table
, "};\n");
1276 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1280 process_i386_initializers (void)
1283 FILE *fp
= fopen ("i386-init.h", "w");
1287 fail (_("can't create i386-init.h, errno = %s\n"),
1290 process_copyright (fp
);
1292 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1294 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1295 init
= xstrdup (cpu_flag_init
[i
].init
);
1296 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1300 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1302 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1303 init
= xstrdup (operand_type_init
[i
].init
);
1304 process_i386_operand_type (fp
, init
, 1, " ", -1);
1312 /* Program options. */
1313 #define OPTION_SRCDIR 200
1315 struct option long_options
[] =
1317 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1318 {"debug", no_argument
, NULL
, 'd'},
1319 {"version", no_argument
, NULL
, 'V'},
1320 {"help", no_argument
, NULL
, 'h'},
1321 {0, no_argument
, NULL
, 0}
1325 print_version (void)
1327 printf ("%s: version 1.0\n", program_name
);
1332 usage (FILE * stream
, int status
)
1334 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1340 main (int argc
, char **argv
)
1342 extern int chdir (char *);
1343 char *srcdir
= NULL
;
1347 program_name
= *argv
;
1348 xmalloc_set_program_name (program_name
);
1350 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1375 if (chdir (srcdir
) != 0)
1376 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1377 srcdir
, xstrerror (errno
));
1379 /* Check the unused bitfield in i386_cpu_flags. */
1381 c
= CpuNumOfBits
- CpuMax
- 1;
1383 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1386 /* Check the unused bitfield in i386_operand_type. */
1388 c
= OTNumOfBits
- OTMax
- 1;
1390 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1393 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1396 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1397 sizeof (opcode_modifiers
[0]), compare
);
1399 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1400 sizeof (operand_types
[0]), compare
);
1402 table
= fopen ("i386-tbl.h", "w");
1404 fail (_("can't create i386-tbl.h, errno = %s\n"),
1407 process_copyright (table
);
1409 process_i386_opcodes (table
);
1410 process_i386_registers (table
);
1411 process_i386_initializers ();