1 /* Copyright (C) 2007-2015 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" },
99 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|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" },
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" },
216 { "CPU_RDSEED_FLAGS",
218 { "CPU_PRFCHW_FLAGS",
226 { "CPU_CLFLUSHOPT_FLAGS",
228 { "CPU_XSAVES_FLAGS",
230 { "CPU_XSAVEC_FLAGS",
232 { "CPU_PREFETCHWT1_FLAGS",
236 { "CPU_AVX512DQ_FLAGS",
237 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512DQ" },
238 { "CPU_AVX512BW_FLAGS",
239 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512BW" },
240 { "CPU_AVX512VL_FLAGS",
241 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VL" },
244 { "CPU_PCOMMIT_FLAGS",
246 { "CPU_AVX512IFMA_FLAGS",
247 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512IFMA" },
248 { "CPU_AVX512VBMI_FLAGS",
249 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512VBMI" },
250 { "CPU_CLZERO_FLAGS",
254 static initializer operand_type_init
[] =
256 { "OPERAND_TYPE_NONE",
258 { "OPERAND_TYPE_REG8",
260 { "OPERAND_TYPE_REG16",
262 { "OPERAND_TYPE_REG32",
264 { "OPERAND_TYPE_REG64",
266 { "OPERAND_TYPE_IMM1",
268 { "OPERAND_TYPE_IMM8",
270 { "OPERAND_TYPE_IMM8S",
272 { "OPERAND_TYPE_IMM16",
274 { "OPERAND_TYPE_IMM32",
276 { "OPERAND_TYPE_IMM32S",
278 { "OPERAND_TYPE_IMM64",
280 { "OPERAND_TYPE_BASEINDEX",
282 { "OPERAND_TYPE_DISP8",
284 { "OPERAND_TYPE_DISP16",
286 { "OPERAND_TYPE_DISP32",
288 { "OPERAND_TYPE_DISP32S",
290 { "OPERAND_TYPE_DISP64",
292 { "OPERAND_TYPE_INOUTPORTREG",
294 { "OPERAND_TYPE_SHIFTCOUNT",
296 { "OPERAND_TYPE_CONTROL",
298 { "OPERAND_TYPE_TEST",
300 { "OPERAND_TYPE_DEBUG",
302 { "OPERAND_TYPE_FLOATREG",
304 { "OPERAND_TYPE_FLOATACC",
306 { "OPERAND_TYPE_SREG2",
308 { "OPERAND_TYPE_SREG3",
310 { "OPERAND_TYPE_ACC",
312 { "OPERAND_TYPE_JUMPABSOLUTE",
314 { "OPERAND_TYPE_REGMMX",
316 { "OPERAND_TYPE_REGXMM",
318 { "OPERAND_TYPE_REGYMM",
320 { "OPERAND_TYPE_REGZMM",
322 { "OPERAND_TYPE_REGMASK",
324 { "OPERAND_TYPE_ESSEG",
326 { "OPERAND_TYPE_ACC32",
328 { "OPERAND_TYPE_ACC64",
330 { "OPERAND_TYPE_INOUTPORTREG",
332 { "OPERAND_TYPE_REG16_INOUTPORTREG",
333 "Reg16|InOutPortReg" },
334 { "OPERAND_TYPE_DISP16_32",
336 { "OPERAND_TYPE_ANYDISP",
337 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
338 { "OPERAND_TYPE_IMM16_32",
340 { "OPERAND_TYPE_IMM16_32S",
342 { "OPERAND_TYPE_IMM16_32_32S",
343 "Imm16|Imm32|Imm32S" },
344 { "OPERAND_TYPE_IMM32_64",
346 { "OPERAND_TYPE_IMM32_32S_DISP32",
347 "Imm32|Imm32S|Disp32" },
348 { "OPERAND_TYPE_IMM64_DISP64",
350 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
351 "Imm32|Imm32S|Imm64|Disp32" },
352 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
353 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
354 { "OPERAND_TYPE_VEC_IMM4",
356 { "OPERAND_TYPE_REGBND",
358 { "OPERAND_TYPE_VEC_DISP8",
362 typedef struct bitfield
369 #define BITFIELD(n) { n, 0, #n }
371 static bitfield cpu_flags
[] =
379 BITFIELD (CpuClflush
),
381 BITFIELD (CpuSYSCALL
),
386 BITFIELD (CpuFISTTP
),
392 BITFIELD (CpuSSE4_1
),
393 BITFIELD (CpuSSE4_2
),
396 BITFIELD (CpuAVX512F
),
397 BITFIELD (CpuAVX512CD
),
398 BITFIELD (CpuAVX512ER
),
399 BITFIELD (CpuAVX512PF
),
400 BITFIELD (CpuAVX512VL
),
401 BITFIELD (CpuAVX512DQ
),
402 BITFIELD (CpuAVX512BW
),
407 BITFIELD (Cpu3dnowA
),
408 BITFIELD (CpuPadLock
),
414 BITFIELD (CpuXsaveopt
),
416 BITFIELD (CpuPCLMUL
),
427 BITFIELD (CpuRdtscp
),
428 BITFIELD (CpuFSGSBase
),
435 BITFIELD (CpuINVPCID
),
436 BITFIELD (CpuVMFUNC
),
437 BITFIELD (CpuRDSEED
),
439 BITFIELD (CpuPRFCHW
),
443 BITFIELD (CpuClflushOpt
),
444 BITFIELD (CpuXSAVES
),
445 BITFIELD (CpuXSAVEC
),
446 BITFIELD (CpuPREFETCHWT1
),
449 BITFIELD (CpuPCOMMIT
),
453 BITFIELD (CpuAVX512IFMA
),
454 BITFIELD (CpuAVX512VBMI
),
455 BITFIELD (CpuCLZERO
),
457 BITFIELD (CpuUnused
),
461 static bitfield opcode_modifiers
[] =
467 BITFIELD (ShortForm
),
469 BITFIELD (JumpDword
),
471 BITFIELD (JumpInterSegment
),
478 BITFIELD (CheckRegSize
),
479 BITFIELD (IgnoreSize
),
480 BITFIELD (DefaultSize
),
489 BITFIELD (BNDPrefixOk
),
490 BITFIELD (IsLockable
),
491 BITFIELD (RegKludge
),
492 BITFIELD (FirstXmm0
),
493 BITFIELD (Implicit1stXmm0
),
494 BITFIELD (RepPrefixOk
),
495 BITFIELD (HLEPrefixOk
),
498 BITFIELD (AddrPrefixOp0
),
507 BITFIELD (VexOpcode
),
508 BITFIELD (VexSources
),
509 BITFIELD (VexImmExt
),
516 BITFIELD (Broadcast
),
517 BITFIELD (StaticRounding
),
519 BITFIELD (Disp8MemShift
),
520 BITFIELD (NoDefMask
),
522 BITFIELD (ATTMnemonic
),
523 BITFIELD (ATTSyntax
),
524 BITFIELD (IntelSyntax
),
527 static bitfield operand_types
[] =
546 BITFIELD (BaseIndex
),
552 BITFIELD (InOutPortReg
),
553 BITFIELD (ShiftCount
),
561 BITFIELD (JumpAbsolute
),
574 BITFIELD (Unspecified
),
578 BITFIELD (Vec_Disp8
),
584 static const char *filename
;
587 compare (const void *x
, const void *y
)
589 const bitfield
*xp
= (const bitfield
*) x
;
590 const bitfield
*yp
= (const bitfield
*) y
;
591 return xp
->position
- yp
->position
;
595 fail (const char *message
, ...)
599 va_start (args
, message
);
600 fprintf (stderr
, _("%s: Error: "), program_name
);
601 vfprintf (stderr
, message
, args
);
607 process_copyright (FILE *fp
)
609 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
610 /* Copyright (C) 2007-2015 Free Software Foundation, Inc.\n\
612 This file is part of the GNU opcodes library.\n\
614 This library is free software; you can redistribute it and/or modify\n\
615 it under the terms of the GNU General Public License as published by\n\
616 the Free Software Foundation; either version 3, or (at your option)\n\
617 any later version.\n\
619 It is distributed in the hope that it will be useful, but WITHOUT\n\
620 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
621 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
622 License for more details.\n\
624 You should have received a copy of the GNU General Public License\n\
625 along with this program; if not, write to the Free Software\n\
626 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
627 MA 02110-1301, USA. */\n");
630 /* Remove leading white spaces. */
633 remove_leading_whitespaces (char *str
)
635 while (ISSPACE (*str
))
640 /* Remove trailing white spaces. */
643 remove_trailing_whitespaces (char *str
)
645 size_t last
= strlen (str
);
653 if (ISSPACE (str
[last
]))
661 /* Find next field separated by SEP and terminate it. Return a
662 pointer to the one after it. */
665 next_field (char *str
, char sep
, char **next
, char *last
)
669 p
= remove_leading_whitespaces (str
);
670 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
673 remove_trailing_whitespaces (p
);
684 set_bitfield (const char *f
, bitfield
*array
, int value
,
685 unsigned int size
, int lineno
)
689 if (strcmp (f
, "CpuFP") == 0)
691 set_bitfield("Cpu387", array
, value
, size
, lineno
);
692 set_bitfield("Cpu287", array
, value
, size
, lineno
);
695 else if (strcmp (f
, "Mmword") == 0)
697 else if (strcmp (f
, "Oword") == 0)
700 for (i
= 0; i
< size
; i
++)
701 if (strcasecmp (array
[i
].name
, f
) == 0)
703 array
[i
].value
= value
;
709 const char *v
= strchr (f
, '=');
716 for (i
= 0; i
< size
; i
++)
717 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
719 value
= strtol (v
+ 1, &end
, 0);
722 array
[i
].value
= value
;
731 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
733 fail (_("Unknown bitfield: %s\n"), f
);
737 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
738 int macro
, const char *comma
, const char *indent
)
742 fprintf (table
, "%s{ { ", indent
);
744 for (i
= 0; i
< size
- 1; i
++)
746 if (((i
+ 1) % 20) != 0)
747 fprintf (table
, "%d, ", flags
[i
].value
);
749 fprintf (table
, "%d,", flags
[i
].value
);
750 if (((i
+ 1) % 20) == 0)
752 /* We need \\ for macro. */
754 fprintf (table
, " \\\n %s", indent
);
756 fprintf (table
, "\n %s", indent
);
760 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
764 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
765 const char *comma
, const char *indent
,
768 char *str
, *next
, *last
;
770 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
772 /* Copy the default cpu flags. */
773 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
775 if (strcasecmp (flag
, "unknown") == 0)
777 /* We turn on everything except for cpu64 in case of
778 CPU_UNKNOWN_FLAGS. */
779 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
780 if (flags
[i
].position
!= Cpu64
)
783 else if (flag
[0] == '~')
785 last
= flag
+ strlen (flag
);
792 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
799 /* First we turn on everything except for cpu64. */
800 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
801 if (flags
[i
].position
!= Cpu64
)
804 /* Turn off selective bits. */
805 for (; next
&& next
< last
; )
807 str
= next_field (next
, '|', &next
, last
);
809 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
812 else if (strcmp (flag
, "0"))
814 /* Turn on selective bits. */
815 last
= flag
+ strlen (flag
);
816 for (next
= flag
; next
&& next
< last
; )
818 str
= next_field (next
, '|', &next
, last
);
820 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
824 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
829 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
833 fprintf (table
, " { ");
835 for (i
= 0; i
< size
- 1; i
++)
837 if (((i
+ 1) % 20) != 0)
838 fprintf (table
, "%d, ", modifier
[i
].value
);
840 fprintf (table
, "%d,", modifier
[i
].value
);
841 if (((i
+ 1) % 20) == 0)
842 fprintf (table
, "\n ");
845 fprintf (table
, "%d },\n", modifier
[i
].value
);
849 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
851 char *str
, *next
, *last
;
852 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
854 /* Copy the default opcode modifier. */
855 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
857 if (strcmp (mod
, "0"))
859 last
= mod
+ strlen (mod
);
860 for (next
= mod
; next
&& next
< last
; )
862 str
= next_field (next
, '|', &next
, last
);
864 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
868 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
872 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
873 int macro
, const char *indent
)
877 fprintf (table
, "{ { ");
879 for (i
= 0; i
< size
- 1; i
++)
881 if (((i
+ 1) % 20) != 0)
882 fprintf (table
, "%d, ", types
[i
].value
);
884 fprintf (table
, "%d,", types
[i
].value
);
885 if (((i
+ 1) % 20) == 0)
887 /* We need \\ for macro. */
889 fprintf (table
, " \\\n%s", indent
);
891 fprintf (table
, "\n%s", indent
);
895 fprintf (table
, "%d } }", types
[i
].value
);
899 process_i386_operand_type (FILE *table
, char *op
, int macro
,
900 const char *indent
, int lineno
)
902 char *str
, *next
, *last
;
903 bitfield types
[ARRAY_SIZE (operand_types
)];
905 /* Copy the default operand type. */
906 memcpy (types
, operand_types
, sizeof (types
));
908 if (strcmp (op
, "0"))
910 last
= op
+ strlen (op
);
911 for (next
= op
; next
&& next
< last
; )
913 str
= next_field (next
, '|', &next
, last
);
915 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
918 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
923 output_i386_opcode (FILE *table
, const char *name
, char *str
,
924 char *last
, int lineno
)
927 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
928 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
930 /* Find number of operands. */
931 operands
= next_field (str
, ',', &str
, last
);
933 /* Find base_opcode. */
934 base_opcode
= next_field (str
, ',', &str
, last
);
936 /* Find extension_opcode. */
937 extension_opcode
= next_field (str
, ',', &str
, last
);
939 /* Find opcode_length. */
940 opcode_length
= next_field (str
, ',', &str
, last
);
942 /* Find cpu_flags. */
943 cpu_flags
= next_field (str
, ',', &str
, last
);
945 /* Find opcode_modifier. */
946 opcode_modifier
= next_field (str
, ',', &str
, last
);
948 /* Remove the first {. */
949 str
= remove_leading_whitespaces (str
);
952 str
= remove_leading_whitespaces (str
+ 1);
956 /* There are at least "X}". */
960 /* Remove trailing white spaces and }. */
964 if (ISSPACE (str
[i
]) || str
[i
] == '}')
973 /* Find operand_types. */
974 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
978 operand_types
[i
] = NULL
;
982 operand_types
[i
] = next_field (str
, ',', &str
, last
);
983 if (*operand_types
[i
] == '0')
986 operand_types
[i
] = NULL
;
991 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
992 name
, operands
, base_opcode
, extension_opcode
,
995 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
997 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
999 fprintf (table
, " { ");
1001 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1003 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1006 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1011 fprintf (table
, ",\n ");
1013 process_i386_operand_type (table
, operand_types
[i
], 0,
1016 fprintf (table
, " } },\n");
1019 struct opcode_hash_entry
1021 struct opcode_hash_entry
*next
;
1027 /* Calculate the hash value of an opcode hash entry P. */
1030 opcode_hash_hash (const void *p
)
1032 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1033 return htab_hash_string (entry
->name
);
1036 /* Compare a string Q against an opcode hash entry P. */
1039 opcode_hash_eq (const void *p
, const void *q
)
1041 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1042 const char *name
= (const char *) q
;
1043 return strcmp (name
, entry
->name
) == 0;
1047 process_i386_opcodes (FILE *table
)
1052 char *str
, *p
, *last
, *name
;
1053 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1054 htab_t opcode_hash_table
;
1055 struct opcode_hash_entry
**opcode_array
;
1056 unsigned int opcode_array_size
= 1024;
1059 filename
= "i386-opc.tbl";
1060 fp
= fopen (filename
, "r");
1063 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1067 opcode_array
= (struct opcode_hash_entry
**)
1068 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1070 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1071 opcode_hash_eq
, NULL
,
1074 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1075 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1077 /* Put everything on opcode array. */
1080 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1085 p
= remove_leading_whitespaces (buf
);
1087 /* Skip comments. */
1088 str
= strstr (p
, "//");
1092 /* Remove trailing white spaces. */
1093 remove_trailing_whitespaces (p
);
1098 /* Ignore comments. */
1106 last
= p
+ strlen (p
);
1109 name
= next_field (p
, ',', &str
, last
);
1111 /* Get the slot in hash table. */
1112 hash_slot
= (struct opcode_hash_entry
**)
1113 htab_find_slot_with_hash (opcode_hash_table
, name
,
1114 htab_hash_string (name
),
1117 if (*hash_slot
== NULL
)
1119 /* It is the new one. Put it on opcode array. */
1120 if (i
>= opcode_array_size
)
1122 /* Grow the opcode array when needed. */
1123 opcode_array_size
+= 1024;
1124 opcode_array
= (struct opcode_hash_entry
**)
1125 xrealloc (opcode_array
,
1126 sizeof (*opcode_array
) * opcode_array_size
);
1129 opcode_array
[i
] = (struct opcode_hash_entry
*)
1130 xmalloc (sizeof (struct opcode_hash_entry
));
1131 opcode_array
[i
]->next
= NULL
;
1132 opcode_array
[i
]->name
= xstrdup (name
);
1133 opcode_array
[i
]->opcode
= xstrdup (str
);
1134 opcode_array
[i
]->lineno
= lineno
;
1135 *hash_slot
= opcode_array
[i
];
1140 /* Append it to the existing one. */
1142 while ((*entry
) != NULL
)
1143 entry
= &(*entry
)->next
;
1144 *entry
= (struct opcode_hash_entry
*)
1145 xmalloc (sizeof (struct opcode_hash_entry
));
1146 (*entry
)->next
= NULL
;
1147 (*entry
)->name
= (*hash_slot
)->name
;
1148 (*entry
)->opcode
= xstrdup (str
);
1149 (*entry
)->lineno
= lineno
;
1153 /* Process opcode array. */
1154 for (j
= 0; j
< i
; j
++)
1156 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1160 lineno
= next
->lineno
;
1161 last
= str
+ strlen (str
);
1162 output_i386_opcode (table
, name
, str
, last
, lineno
);
1168 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1170 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1172 process_i386_opcode_modifier (table
, "0", -1);
1174 fprintf (table
, " { ");
1175 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1176 fprintf (table
, " } }\n");
1178 fprintf (table
, "};\n");
1182 process_i386_registers (FILE *table
)
1186 char *str
, *p
, *last
;
1187 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1188 char *dw2_32_num
, *dw2_64_num
;
1191 filename
= "i386-reg.tbl";
1192 fp
= fopen (filename
, "r");
1194 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1197 fprintf (table
, "\n/* i386 register table. */\n\n");
1198 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1202 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1207 p
= remove_leading_whitespaces (buf
);
1209 /* Skip comments. */
1210 str
= strstr (p
, "//");
1214 /* Remove trailing white spaces. */
1215 remove_trailing_whitespaces (p
);
1220 fprintf (table
, "%s\n", p
);
1228 last
= p
+ strlen (p
);
1230 /* Find reg_name. */
1231 reg_name
= next_field (p
, ',', &str
, last
);
1233 /* Find reg_type. */
1234 reg_type
= next_field (str
, ',', &str
, last
);
1236 /* Find reg_flags. */
1237 reg_flags
= next_field (str
, ',', &str
, last
);
1240 reg_num
= next_field (str
, ',', &str
, last
);
1242 fprintf (table
, " { \"%s\",\n ", reg_name
);
1244 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1246 /* Find 32-bit Dwarf2 register number. */
1247 dw2_32_num
= next_field (str
, ',', &str
, last
);
1249 /* Find 64-bit Dwarf2 register number. */
1250 dw2_64_num
= next_field (str
, ',', &str
, last
);
1252 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1253 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1258 fprintf (table
, "};\n");
1260 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1264 process_i386_initializers (void)
1267 FILE *fp
= fopen ("i386-init.h", "w");
1271 fail (_("can't create i386-init.h, errno = %s\n"),
1274 process_copyright (fp
);
1276 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1278 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1279 init
= xstrdup (cpu_flag_init
[i
].init
);
1280 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1284 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1286 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1287 init
= xstrdup (operand_type_init
[i
].init
);
1288 process_i386_operand_type (fp
, init
, 1, " ", -1);
1296 /* Program options. */
1297 #define OPTION_SRCDIR 200
1299 struct option long_options
[] =
1301 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1302 {"debug", no_argument
, NULL
, 'd'},
1303 {"version", no_argument
, NULL
, 'V'},
1304 {"help", no_argument
, NULL
, 'h'},
1305 {0, no_argument
, NULL
, 0}
1309 print_version (void)
1311 printf ("%s: version 1.0\n", program_name
);
1316 usage (FILE * stream
, int status
)
1318 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1324 main (int argc
, char **argv
)
1326 extern int chdir (char *);
1327 char *srcdir
= NULL
;
1331 program_name
= *argv
;
1332 xmalloc_set_program_name (program_name
);
1334 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1359 if (chdir (srcdir
) != 0)
1360 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1361 srcdir
, xstrerror (errno
));
1363 /* Check the unused bitfield in i386_cpu_flags. */
1365 c
= CpuNumOfBits
- CpuMax
- 1;
1367 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1370 /* Check the unused bitfield in i386_operand_type. */
1372 c
= OTNumOfBits
- OTMax
- 1;
1374 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1377 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1380 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1381 sizeof (opcode_modifiers
[0]), compare
);
1383 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1384 sizeof (operand_types
[0]), compare
);
1386 table
= fopen ("i386-tbl.h", "w");
1388 fail (_("can't create i386-tbl.h, errno = %s\n"),
1391 process_copyright (table
);
1393 process_i386_opcodes (table
);
1394 process_i386_registers (table
);
1395 process_i386_initializers ();