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" },
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",
258 static initializer operand_type_init
[] =
260 { "OPERAND_TYPE_NONE",
262 { "OPERAND_TYPE_REG8",
264 { "OPERAND_TYPE_REG16",
266 { "OPERAND_TYPE_REG32",
268 { "OPERAND_TYPE_REG64",
270 { "OPERAND_TYPE_IMM1",
272 { "OPERAND_TYPE_IMM8",
274 { "OPERAND_TYPE_IMM8S",
276 { "OPERAND_TYPE_IMM16",
278 { "OPERAND_TYPE_IMM32",
280 { "OPERAND_TYPE_IMM32S",
282 { "OPERAND_TYPE_IMM64",
284 { "OPERAND_TYPE_BASEINDEX",
286 { "OPERAND_TYPE_DISP8",
288 { "OPERAND_TYPE_DISP16",
290 { "OPERAND_TYPE_DISP32",
292 { "OPERAND_TYPE_DISP32S",
294 { "OPERAND_TYPE_DISP64",
296 { "OPERAND_TYPE_INOUTPORTREG",
298 { "OPERAND_TYPE_SHIFTCOUNT",
300 { "OPERAND_TYPE_CONTROL",
302 { "OPERAND_TYPE_TEST",
304 { "OPERAND_TYPE_DEBUG",
306 { "OPERAND_TYPE_FLOATREG",
308 { "OPERAND_TYPE_FLOATACC",
310 { "OPERAND_TYPE_SREG2",
312 { "OPERAND_TYPE_SREG3",
314 { "OPERAND_TYPE_ACC",
316 { "OPERAND_TYPE_JUMPABSOLUTE",
318 { "OPERAND_TYPE_REGMMX",
320 { "OPERAND_TYPE_REGXMM",
322 { "OPERAND_TYPE_REGYMM",
324 { "OPERAND_TYPE_REGZMM",
326 { "OPERAND_TYPE_REGMASK",
328 { "OPERAND_TYPE_ESSEG",
330 { "OPERAND_TYPE_ACC32",
332 { "OPERAND_TYPE_ACC64",
334 { "OPERAND_TYPE_INOUTPORTREG",
336 { "OPERAND_TYPE_REG16_INOUTPORTREG",
337 "Reg16|InOutPortReg" },
338 { "OPERAND_TYPE_DISP16_32",
340 { "OPERAND_TYPE_ANYDISP",
341 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
342 { "OPERAND_TYPE_IMM16_32",
344 { "OPERAND_TYPE_IMM16_32S",
346 { "OPERAND_TYPE_IMM16_32_32S",
347 "Imm16|Imm32|Imm32S" },
348 { "OPERAND_TYPE_IMM32_64",
350 { "OPERAND_TYPE_IMM32_32S_DISP32",
351 "Imm32|Imm32S|Disp32" },
352 { "OPERAND_TYPE_IMM64_DISP64",
354 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
355 "Imm32|Imm32S|Imm64|Disp32" },
356 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
357 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
358 { "OPERAND_TYPE_VEC_IMM4",
360 { "OPERAND_TYPE_REGBND",
362 { "OPERAND_TYPE_VEC_DISP8",
366 typedef struct bitfield
373 #define BITFIELD(n) { n, 0, #n }
375 static bitfield cpu_flags
[] =
383 BITFIELD (CpuClflush
),
385 BITFIELD (CpuSYSCALL
),
390 BITFIELD (CpuFISTTP
),
396 BITFIELD (CpuSSE4_1
),
397 BITFIELD (CpuSSE4_2
),
400 BITFIELD (CpuAVX512F
),
401 BITFIELD (CpuAVX512CD
),
402 BITFIELD (CpuAVX512ER
),
403 BITFIELD (CpuAVX512PF
),
404 BITFIELD (CpuAVX512VL
),
405 BITFIELD (CpuAVX512DQ
),
406 BITFIELD (CpuAVX512BW
),
412 BITFIELD (Cpu3dnowA
),
413 BITFIELD (CpuPadLock
),
419 BITFIELD (CpuXsaveopt
),
421 BITFIELD (CpuPCLMUL
),
432 BITFIELD (CpuRdtscp
),
433 BITFIELD (CpuFSGSBase
),
440 BITFIELD (CpuINVPCID
),
441 BITFIELD (CpuVMFUNC
),
442 BITFIELD (CpuRDSEED
),
444 BITFIELD (CpuPRFCHW
),
448 BITFIELD (CpuClflushOpt
),
449 BITFIELD (CpuXSAVES
),
450 BITFIELD (CpuXSAVEC
),
451 BITFIELD (CpuPREFETCHWT1
),
454 BITFIELD (CpuPCOMMIT
),
458 BITFIELD (CpuAVX512IFMA
),
459 BITFIELD (CpuAVX512VBMI
),
460 BITFIELD (CpuCLZERO
),
462 BITFIELD (CpuIntel64
),
464 BITFIELD (CpuUnused
),
468 static bitfield opcode_modifiers
[] =
474 BITFIELD (ShortForm
),
476 BITFIELD (JumpDword
),
478 BITFIELD (JumpInterSegment
),
485 BITFIELD (CheckRegSize
),
486 BITFIELD (IgnoreSize
),
487 BITFIELD (DefaultSize
),
496 BITFIELD (BNDPrefixOk
),
497 BITFIELD (IsLockable
),
498 BITFIELD (RegKludge
),
499 BITFIELD (FirstXmm0
),
500 BITFIELD (Implicit1stXmm0
),
501 BITFIELD (RepPrefixOk
),
502 BITFIELD (HLEPrefixOk
),
505 BITFIELD (AddrPrefixOp0
),
514 BITFIELD (VexOpcode
),
515 BITFIELD (VexSources
),
516 BITFIELD (VexImmExt
),
523 BITFIELD (Broadcast
),
524 BITFIELD (StaticRounding
),
526 BITFIELD (Disp8MemShift
),
527 BITFIELD (NoDefMask
),
529 BITFIELD (ATTMnemonic
),
530 BITFIELD (ATTSyntax
),
531 BITFIELD (IntelSyntax
),
534 static bitfield operand_types
[] =
553 BITFIELD (BaseIndex
),
559 BITFIELD (InOutPortReg
),
560 BITFIELD (ShiftCount
),
568 BITFIELD (JumpAbsolute
),
581 BITFIELD (Unspecified
),
585 BITFIELD (Vec_Disp8
),
591 static const char *filename
;
594 compare (const void *x
, const void *y
)
596 const bitfield
*xp
= (const bitfield
*) x
;
597 const bitfield
*yp
= (const bitfield
*) y
;
598 return xp
->position
- yp
->position
;
602 fail (const char *message
, ...)
606 va_start (args
, message
);
607 fprintf (stderr
, _("%s: Error: "), program_name
);
608 vfprintf (stderr
, message
, args
);
614 process_copyright (FILE *fp
)
616 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
617 /* Copyright (C) 2007-2015 Free Software Foundation, Inc.\n\
619 This file is part of the GNU opcodes library.\n\
621 This library is free software; you can redistribute it and/or modify\n\
622 it under the terms of the GNU General Public License as published by\n\
623 the Free Software Foundation; either version 3, or (at your option)\n\
624 any later version.\n\
626 It is distributed in the hope that it will be useful, but WITHOUT\n\
627 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
628 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
629 License for more details.\n\
631 You should have received a copy of the GNU General Public License\n\
632 along with this program; if not, write to the Free Software\n\
633 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
634 MA 02110-1301, USA. */\n");
637 /* Remove leading white spaces. */
640 remove_leading_whitespaces (char *str
)
642 while (ISSPACE (*str
))
647 /* Remove trailing white spaces. */
650 remove_trailing_whitespaces (char *str
)
652 size_t last
= strlen (str
);
660 if (ISSPACE (str
[last
]))
668 /* Find next field separated by SEP and terminate it. Return a
669 pointer to the one after it. */
672 next_field (char *str
, char sep
, char **next
, char *last
)
676 p
= remove_leading_whitespaces (str
);
677 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
680 remove_trailing_whitespaces (p
);
691 set_bitfield (const char *f
, bitfield
*array
, int value
,
692 unsigned int size
, int lineno
)
696 if (strcmp (f
, "CpuFP") == 0)
698 set_bitfield("Cpu387", array
, value
, size
, lineno
);
699 set_bitfield("Cpu287", array
, value
, size
, lineno
);
702 else if (strcmp (f
, "Mmword") == 0)
704 else if (strcmp (f
, "Oword") == 0)
707 for (i
= 0; i
< size
; i
++)
708 if (strcasecmp (array
[i
].name
, f
) == 0)
710 array
[i
].value
= value
;
716 const char *v
= strchr (f
, '=');
723 for (i
= 0; i
< size
; i
++)
724 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
726 value
= strtol (v
+ 1, &end
, 0);
729 array
[i
].value
= value
;
738 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
740 fail (_("Unknown bitfield: %s\n"), f
);
744 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
745 int macro
, const char *comma
, const char *indent
)
749 fprintf (table
, "%s{ { ", indent
);
751 for (i
= 0; i
< size
- 1; i
++)
753 if (((i
+ 1) % 20) != 0)
754 fprintf (table
, "%d, ", flags
[i
].value
);
756 fprintf (table
, "%d,", flags
[i
].value
);
757 if (((i
+ 1) % 20) == 0)
759 /* We need \\ for macro. */
761 fprintf (table
, " \\\n %s", indent
);
763 fprintf (table
, "\n %s", indent
);
767 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
771 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
772 const char *comma
, const char *indent
,
775 char *str
, *next
, *last
;
777 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
779 /* Copy the default cpu flags. */
780 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
782 if (strcasecmp (flag
, "unknown") == 0)
784 /* We turn on everything except for cpu64 in case of
785 CPU_UNKNOWN_FLAGS. */
786 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
787 if (flags
[i
].position
!= Cpu64
)
790 else if (flag
[0] == '~')
792 last
= flag
+ strlen (flag
);
799 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
806 /* First we turn on everything except for cpu64. */
807 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
808 if (flags
[i
].position
!= Cpu64
)
811 /* Turn off selective bits. */
812 for (; next
&& next
< last
; )
814 str
= next_field (next
, '|', &next
, last
);
816 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
819 else if (strcmp (flag
, "0"))
821 /* Turn on selective bits. */
822 last
= flag
+ strlen (flag
);
823 for (next
= flag
; next
&& next
< last
; )
825 str
= next_field (next
, '|', &next
, last
);
827 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
831 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
836 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
840 fprintf (table
, " { ");
842 for (i
= 0; i
< size
- 1; i
++)
844 if (((i
+ 1) % 20) != 0)
845 fprintf (table
, "%d, ", modifier
[i
].value
);
847 fprintf (table
, "%d,", modifier
[i
].value
);
848 if (((i
+ 1) % 20) == 0)
849 fprintf (table
, "\n ");
852 fprintf (table
, "%d },\n", modifier
[i
].value
);
856 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
858 char *str
, *next
, *last
;
859 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
861 /* Copy the default opcode modifier. */
862 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
864 if (strcmp (mod
, "0"))
866 last
= mod
+ strlen (mod
);
867 for (next
= mod
; next
&& next
< last
; )
869 str
= next_field (next
, '|', &next
, last
);
871 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
875 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
879 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
880 int macro
, const char *indent
)
884 fprintf (table
, "{ { ");
886 for (i
= 0; i
< size
- 1; i
++)
888 if (((i
+ 1) % 20) != 0)
889 fprintf (table
, "%d, ", types
[i
].value
);
891 fprintf (table
, "%d,", types
[i
].value
);
892 if (((i
+ 1) % 20) == 0)
894 /* We need \\ for macro. */
896 fprintf (table
, " \\\n%s", indent
);
898 fprintf (table
, "\n%s", indent
);
902 fprintf (table
, "%d } }", types
[i
].value
);
906 process_i386_operand_type (FILE *table
, char *op
, int macro
,
907 const char *indent
, int lineno
)
909 char *str
, *next
, *last
;
910 bitfield types
[ARRAY_SIZE (operand_types
)];
912 /* Copy the default operand type. */
913 memcpy (types
, operand_types
, sizeof (types
));
915 if (strcmp (op
, "0"))
917 last
= op
+ strlen (op
);
918 for (next
= op
; next
&& next
< last
; )
920 str
= next_field (next
, '|', &next
, last
);
922 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
925 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
930 output_i386_opcode (FILE *table
, const char *name
, char *str
,
931 char *last
, int lineno
)
934 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
935 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
937 /* Find number of operands. */
938 operands
= next_field (str
, ',', &str
, last
);
940 /* Find base_opcode. */
941 base_opcode
= next_field (str
, ',', &str
, last
);
943 /* Find extension_opcode. */
944 extension_opcode
= next_field (str
, ',', &str
, last
);
946 /* Find opcode_length. */
947 opcode_length
= next_field (str
, ',', &str
, last
);
949 /* Find cpu_flags. */
950 cpu_flags
= next_field (str
, ',', &str
, last
);
952 /* Find opcode_modifier. */
953 opcode_modifier
= next_field (str
, ',', &str
, last
);
955 /* Remove the first {. */
956 str
= remove_leading_whitespaces (str
);
959 str
= remove_leading_whitespaces (str
+ 1);
963 /* There are at least "X}". */
967 /* Remove trailing white spaces and }. */
971 if (ISSPACE (str
[i
]) || str
[i
] == '}')
980 /* Find operand_types. */
981 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
985 operand_types
[i
] = NULL
;
989 operand_types
[i
] = next_field (str
, ',', &str
, last
);
990 if (*operand_types
[i
] == '0')
993 operand_types
[i
] = NULL
;
998 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
999 name
, operands
, base_opcode
, extension_opcode
,
1002 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1004 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1006 fprintf (table
, " { ");
1008 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1010 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1013 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1018 fprintf (table
, ",\n ");
1020 process_i386_operand_type (table
, operand_types
[i
], 0,
1023 fprintf (table
, " } },\n");
1026 struct opcode_hash_entry
1028 struct opcode_hash_entry
*next
;
1034 /* Calculate the hash value of an opcode hash entry P. */
1037 opcode_hash_hash (const void *p
)
1039 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1040 return htab_hash_string (entry
->name
);
1043 /* Compare a string Q against an opcode hash entry P. */
1046 opcode_hash_eq (const void *p
, const void *q
)
1048 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1049 const char *name
= (const char *) q
;
1050 return strcmp (name
, entry
->name
) == 0;
1054 process_i386_opcodes (FILE *table
)
1059 char *str
, *p
, *last
, *name
;
1060 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1061 htab_t opcode_hash_table
;
1062 struct opcode_hash_entry
**opcode_array
;
1063 unsigned int opcode_array_size
= 1024;
1066 filename
= "i386-opc.tbl";
1067 fp
= fopen (filename
, "r");
1070 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1074 opcode_array
= (struct opcode_hash_entry
**)
1075 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1077 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1078 opcode_hash_eq
, NULL
,
1081 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1082 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1084 /* Put everything on opcode array. */
1087 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1092 p
= remove_leading_whitespaces (buf
);
1094 /* Skip comments. */
1095 str
= strstr (p
, "//");
1099 /* Remove trailing white spaces. */
1100 remove_trailing_whitespaces (p
);
1105 /* Ignore comments. */
1113 last
= p
+ strlen (p
);
1116 name
= next_field (p
, ',', &str
, last
);
1118 /* Get the slot in hash table. */
1119 hash_slot
= (struct opcode_hash_entry
**)
1120 htab_find_slot_with_hash (opcode_hash_table
, name
,
1121 htab_hash_string (name
),
1124 if (*hash_slot
== NULL
)
1126 /* It is the new one. Put it on opcode array. */
1127 if (i
>= opcode_array_size
)
1129 /* Grow the opcode array when needed. */
1130 opcode_array_size
+= 1024;
1131 opcode_array
= (struct opcode_hash_entry
**)
1132 xrealloc (opcode_array
,
1133 sizeof (*opcode_array
) * opcode_array_size
);
1136 opcode_array
[i
] = (struct opcode_hash_entry
*)
1137 xmalloc (sizeof (struct opcode_hash_entry
));
1138 opcode_array
[i
]->next
= NULL
;
1139 opcode_array
[i
]->name
= xstrdup (name
);
1140 opcode_array
[i
]->opcode
= xstrdup (str
);
1141 opcode_array
[i
]->lineno
= lineno
;
1142 *hash_slot
= opcode_array
[i
];
1147 /* Append it to the existing one. */
1149 while ((*entry
) != NULL
)
1150 entry
= &(*entry
)->next
;
1151 *entry
= (struct opcode_hash_entry
*)
1152 xmalloc (sizeof (struct opcode_hash_entry
));
1153 (*entry
)->next
= NULL
;
1154 (*entry
)->name
= (*hash_slot
)->name
;
1155 (*entry
)->opcode
= xstrdup (str
);
1156 (*entry
)->lineno
= lineno
;
1160 /* Process opcode array. */
1161 for (j
= 0; j
< i
; j
++)
1163 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1167 lineno
= next
->lineno
;
1168 last
= str
+ strlen (str
);
1169 output_i386_opcode (table
, name
, str
, last
, lineno
);
1175 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1177 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1179 process_i386_opcode_modifier (table
, "0", -1);
1181 fprintf (table
, " { ");
1182 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1183 fprintf (table
, " } }\n");
1185 fprintf (table
, "};\n");
1189 process_i386_registers (FILE *table
)
1193 char *str
, *p
, *last
;
1194 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1195 char *dw2_32_num
, *dw2_64_num
;
1198 filename
= "i386-reg.tbl";
1199 fp
= fopen (filename
, "r");
1201 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1204 fprintf (table
, "\n/* i386 register table. */\n\n");
1205 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1209 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1214 p
= remove_leading_whitespaces (buf
);
1216 /* Skip comments. */
1217 str
= strstr (p
, "//");
1221 /* Remove trailing white spaces. */
1222 remove_trailing_whitespaces (p
);
1227 fprintf (table
, "%s\n", p
);
1235 last
= p
+ strlen (p
);
1237 /* Find reg_name. */
1238 reg_name
= next_field (p
, ',', &str
, last
);
1240 /* Find reg_type. */
1241 reg_type
= next_field (str
, ',', &str
, last
);
1243 /* Find reg_flags. */
1244 reg_flags
= next_field (str
, ',', &str
, last
);
1247 reg_num
= next_field (str
, ',', &str
, last
);
1249 fprintf (table
, " { \"%s\",\n ", reg_name
);
1251 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1253 /* Find 32-bit Dwarf2 register number. */
1254 dw2_32_num
= next_field (str
, ',', &str
, last
);
1256 /* Find 64-bit Dwarf2 register number. */
1257 dw2_64_num
= next_field (str
, ',', &str
, last
);
1259 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1260 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1265 fprintf (table
, "};\n");
1267 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1271 process_i386_initializers (void)
1274 FILE *fp
= fopen ("i386-init.h", "w");
1278 fail (_("can't create i386-init.h, errno = %s\n"),
1281 process_copyright (fp
);
1283 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1285 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1286 init
= xstrdup (cpu_flag_init
[i
].init
);
1287 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1291 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1293 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1294 init
= xstrdup (operand_type_init
[i
].init
);
1295 process_i386_operand_type (fp
, init
, 1, " ", -1);
1303 /* Program options. */
1304 #define OPTION_SRCDIR 200
1306 struct option long_options
[] =
1308 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1309 {"debug", no_argument
, NULL
, 'd'},
1310 {"version", no_argument
, NULL
, 'V'},
1311 {"help", no_argument
, NULL
, 'h'},
1312 {0, no_argument
, NULL
, 0}
1316 print_version (void)
1318 printf ("%s: version 1.0\n", program_name
);
1323 usage (FILE * stream
, int status
)
1325 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1331 main (int argc
, char **argv
)
1333 extern int chdir (char *);
1334 char *srcdir
= NULL
;
1338 program_name
= *argv
;
1339 xmalloc_set_program_name (program_name
);
1341 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1366 if (chdir (srcdir
) != 0)
1367 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1368 srcdir
, xstrerror (errno
));
1370 /* Check the unused bitfield in i386_cpu_flags. */
1372 c
= CpuNumOfBits
- CpuMax
- 1;
1374 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1377 /* Check the unused bitfield in i386_operand_type. */
1379 c
= OTNumOfBits
- OTMax
- 1;
1381 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1384 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1387 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1388 sizeof (opcode_modifiers
[0]), compare
);
1390 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1391 sizeof (operand_types
[0]), compare
);
1393 table
= fopen ("i386-tbl.h", "w");
1395 fail (_("can't create i386-tbl.h, errno = %s\n"),
1398 process_copyright (table
);
1400 process_i386_opcodes (table
);
1401 process_i386_registers (table
);
1402 process_i386_initializers ();