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|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",
260 static initializer operand_type_init[] =
262 { "OPERAND_TYPE_NONE",
264 { "OPERAND_TYPE_REG8",
266 { "OPERAND_TYPE_REG16",
268 { "OPERAND_TYPE_REG32",
270 { "OPERAND_TYPE_REG64",
272 { "OPERAND_TYPE_IMM1",
274 { "OPERAND_TYPE_IMM8",
276 { "OPERAND_TYPE_IMM8S",
278 { "OPERAND_TYPE_IMM16",
280 { "OPERAND_TYPE_IMM32",
282 { "OPERAND_TYPE_IMM32S",
284 { "OPERAND_TYPE_IMM64",
286 { "OPERAND_TYPE_BASEINDEX",
288 { "OPERAND_TYPE_DISP8",
290 { "OPERAND_TYPE_DISP16",
292 { "OPERAND_TYPE_DISP32",
294 { "OPERAND_TYPE_DISP32S",
296 { "OPERAND_TYPE_DISP64",
298 { "OPERAND_TYPE_INOUTPORTREG",
300 { "OPERAND_TYPE_SHIFTCOUNT",
302 { "OPERAND_TYPE_CONTROL",
304 { "OPERAND_TYPE_TEST",
306 { "OPERAND_TYPE_DEBUG",
308 { "OPERAND_TYPE_FLOATREG",
310 { "OPERAND_TYPE_FLOATACC",
312 { "OPERAND_TYPE_SREG2",
314 { "OPERAND_TYPE_SREG3",
316 { "OPERAND_TYPE_ACC",
318 { "OPERAND_TYPE_JUMPABSOLUTE",
320 { "OPERAND_TYPE_REGMMX",
322 { "OPERAND_TYPE_REGXMM",
324 { "OPERAND_TYPE_REGYMM",
326 { "OPERAND_TYPE_REGZMM",
328 { "OPERAND_TYPE_REGMASK",
330 { "OPERAND_TYPE_ESSEG",
332 { "OPERAND_TYPE_ACC32",
334 { "OPERAND_TYPE_ACC64",
336 { "OPERAND_TYPE_INOUTPORTREG",
338 { "OPERAND_TYPE_REG16_INOUTPORTREG",
339 "Reg16|InOutPortReg" },
340 { "OPERAND_TYPE_DISP16_32",
342 { "OPERAND_TYPE_ANYDISP",
343 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
344 { "OPERAND_TYPE_IMM16_32",
346 { "OPERAND_TYPE_IMM16_32S",
348 { "OPERAND_TYPE_IMM16_32_32S",
349 "Imm16|Imm32|Imm32S" },
350 { "OPERAND_TYPE_IMM32_64",
352 { "OPERAND_TYPE_IMM32_32S_DISP32",
353 "Imm32|Imm32S|Disp32" },
354 { "OPERAND_TYPE_IMM64_DISP64",
356 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
357 "Imm32|Imm32S|Imm64|Disp32" },
358 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
359 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
360 { "OPERAND_TYPE_VEC_IMM4",
362 { "OPERAND_TYPE_REGBND",
364 { "OPERAND_TYPE_VEC_DISP8",
368 typedef struct bitfield
375 #define BITFIELD(n) { n, 0, #n }
377 static bitfield cpu_flags[] =
385 BITFIELD (CpuClflush),
387 BITFIELD (CpuSYSCALL),
392 BITFIELD (CpuFISTTP),
398 BITFIELD (CpuSSE4_1),
399 BITFIELD (CpuSSE4_2),
402 BITFIELD (CpuAVX512F),
403 BITFIELD (CpuAVX512CD),
404 BITFIELD (CpuAVX512ER),
405 BITFIELD (CpuAVX512PF),
406 BITFIELD (CpuAVX512VL),
407 BITFIELD (CpuAVX512DQ),
408 BITFIELD (CpuAVX512BW),
414 BITFIELD (Cpu3dnowA),
415 BITFIELD (CpuPadLock),
421 BITFIELD (CpuXsaveopt),
423 BITFIELD (CpuPCLMUL),
434 BITFIELD (CpuRdtscp),
435 BITFIELD (CpuFSGSBase),
442 BITFIELD (CpuINVPCID),
443 BITFIELD (CpuVMFUNC),
444 BITFIELD (CpuRDSEED),
446 BITFIELD (CpuPRFCHW),
450 BITFIELD (CpuClflushOpt),
451 BITFIELD (CpuXSAVES),
452 BITFIELD (CpuXSAVEC),
453 BITFIELD (CpuPREFETCHWT1),
456 BITFIELD (CpuPCOMMIT),
460 BITFIELD (CpuAVX512IFMA),
461 BITFIELD (CpuAVX512VBMI),
462 BITFIELD (CpuMWAITX),
463 BITFIELD (CpuCLZERO),
465 BITFIELD (CpuIntel64),
467 BITFIELD (CpuUnused),
471 static bitfield opcode_modifiers[] =
477 BITFIELD (ShortForm),
479 BITFIELD (JumpDword),
481 BITFIELD (JumpInterSegment),
488 BITFIELD (CheckRegSize),
489 BITFIELD (IgnoreSize),
490 BITFIELD (DefaultSize),
499 BITFIELD (BNDPrefixOk),
500 BITFIELD (IsLockable),
501 BITFIELD (RegKludge),
502 BITFIELD (FirstXmm0),
503 BITFIELD (Implicit1stXmm0),
504 BITFIELD (RepPrefixOk),
505 BITFIELD (HLEPrefixOk),
508 BITFIELD (AddrPrefixOp0),
517 BITFIELD (VexOpcode),
518 BITFIELD (VexSources),
519 BITFIELD (VexImmExt),
526 BITFIELD (Broadcast),
527 BITFIELD (StaticRounding),
529 BITFIELD (Disp8MemShift),
530 BITFIELD (NoDefMask),
532 BITFIELD (ATTMnemonic),
533 BITFIELD (ATTSyntax),
534 BITFIELD (IntelSyntax),
537 static bitfield operand_types[] =
556 BITFIELD (BaseIndex),
562 BITFIELD (InOutPortReg),
563 BITFIELD (ShiftCount),
571 BITFIELD (JumpAbsolute),
584 BITFIELD (Unspecified),
588 BITFIELD (Vec_Disp8),
594 static const char *filename;
597 compare (const void *x, const void *y)
599 const bitfield *xp = (const bitfield *) x;
600 const bitfield *yp = (const bitfield *) y;
601 return xp->position - yp->position;
605 fail (const char *message, ...)
609 va_start (args, message);
610 fprintf (stderr, _("%s: Error: "), program_name);
611 vfprintf (stderr, message, args);
617 process_copyright (FILE *fp)
619 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
620 /* Copyright (C) 2007-2015 Free Software Foundation, Inc.\n\
622 This file is part of the GNU opcodes library.\n\
624 This library is free software; you can redistribute it and/or modify\n\
625 it under the terms of the GNU General Public License as published by\n\
626 the Free Software Foundation; either version 3, or (at your option)\n\
627 any later version.\n\
629 It is distributed in the hope that it will be useful, but WITHOUT\n\
630 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
631 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
632 License for more details.\n\
634 You should have received a copy of the GNU General Public License\n\
635 along with this program; if not, write to the Free Software\n\
636 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
637 MA 02110-1301, USA. */\n");
640 /* Remove leading white spaces. */
643 remove_leading_whitespaces (char *str)
645 while (ISSPACE (*str))
650 /* Remove trailing white spaces. */
653 remove_trailing_whitespaces (char *str)
655 size_t last = strlen (str);
663 if (ISSPACE (str [last]))
671 /* Find next field separated by SEP and terminate it. Return a
672 pointer to the one after it. */
675 next_field (char *str, char sep, char **next, char *last)
679 p = remove_leading_whitespaces (str);
680 for (str = p; *str != sep && *str != '\0'; str++);
683 remove_trailing_whitespaces (p);
694 set_bitfield (const char *f, bitfield *array, int value,
695 unsigned int size, int lineno)
699 if (strcmp (f, "CpuFP") == 0)
701 set_bitfield("Cpu387", array, value, size, lineno);
702 set_bitfield("Cpu287", array, value, size, lineno);
705 else if (strcmp (f, "Mmword") == 0)
707 else if (strcmp (f, "Oword") == 0)
710 for (i = 0; i < size; i++)
711 if (strcasecmp (array[i].name, f) == 0)
713 array[i].value = value;
719 const char *v = strchr (f, '=');
726 for (i = 0; i < size; i++)
727 if (strncasecmp (array[i].name, f, n) == 0)
729 value = strtol (v + 1, &end, 0);
732 array[i].value = value;
741 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
743 fail (_("Unknown bitfield: %s\n"), f);
747 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
748 int macro, const char *comma, const char *indent)
752 fprintf (table, "%s{ { ", indent);
754 for (i = 0; i < size - 1; i++)
756 if (((i + 1) % 20) != 0)
757 fprintf (table, "%d, ", flags[i].value);
759 fprintf (table, "%d,", flags[i].value);
760 if (((i + 1) % 20) == 0)
762 /* We need \\ for macro. */
764 fprintf (table, " \\\n %s", indent);
766 fprintf (table, "\n %s", indent);
770 fprintf (table, "%d } }%s\n", flags[i].value, comma);
774 process_i386_cpu_flag (FILE *table, char *flag, int macro,
775 const char *comma, const char *indent,
778 char *str, *next, *last;
780 bitfield flags [ARRAY_SIZE (cpu_flags)];
782 /* Copy the default cpu flags. */
783 memcpy (flags, cpu_flags, sizeof (cpu_flags));
785 if (strcasecmp (flag, "unknown") == 0)
787 /* We turn on everything except for cpu64 in case of
788 CPU_UNKNOWN_FLAGS. */
789 for (i = 0; i < ARRAY_SIZE (flags); i++)
790 if (flags[i].position != Cpu64)
793 else if (flag[0] == '~')
795 last = flag + strlen (flag);
802 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
809 /* First we turn on everything except for cpu64. */
810 for (i = 0; i < ARRAY_SIZE (flags); i++)
811 if (flags[i].position != Cpu64)
814 /* Turn off selective bits. */
815 for (; next && next < last; )
817 str = next_field (next, '|', &next, last);
819 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
822 else if (strcmp (flag, "0"))
824 /* Turn on selective bits. */
825 last = flag + strlen (flag);
826 for (next = flag; next && next < last; )
828 str = next_field (next, '|', &next, last);
830 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
834 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
839 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
843 fprintf (table, " { ");
845 for (i = 0; i < size - 1; i++)
847 if (((i + 1) % 20) != 0)
848 fprintf (table, "%d, ", modifier[i].value);
850 fprintf (table, "%d,", modifier[i].value);
851 if (((i + 1) % 20) == 0)
852 fprintf (table, "\n ");
855 fprintf (table, "%d },\n", modifier[i].value);
859 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
861 char *str, *next, *last;
862 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
864 /* Copy the default opcode modifier. */
865 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
867 if (strcmp (mod, "0"))
869 last = mod + strlen (mod);
870 for (next = mod; next && next < last; )
872 str = next_field (next, '|', &next, last);
874 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
878 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
882 output_operand_type (FILE *table, bitfield *types, unsigned int size,
883 int macro, const char *indent)
887 fprintf (table, "{ { ");
889 for (i = 0; i < size - 1; i++)
891 if (((i + 1) % 20) != 0)
892 fprintf (table, "%d, ", types[i].value);
894 fprintf (table, "%d,", types[i].value);
895 if (((i + 1) % 20) == 0)
897 /* We need \\ for macro. */
899 fprintf (table, " \\\n%s", indent);
901 fprintf (table, "\n%s", indent);
905 fprintf (table, "%d } }", types[i].value);
909 process_i386_operand_type (FILE *table, char *op, int macro,
910 const char *indent, int lineno)
912 char *str, *next, *last;
913 bitfield types [ARRAY_SIZE (operand_types)];
915 /* Copy the default operand type. */
916 memcpy (types, operand_types, sizeof (types));
918 if (strcmp (op, "0"))
920 last = op + strlen (op);
921 for (next = op; next && next < last; )
923 str = next_field (next, '|', &next, last);
925 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
928 output_operand_type (table, types, ARRAY_SIZE (types), macro,
933 output_i386_opcode (FILE *table, const char *name, char *str,
934 char *last, int lineno)
937 char *operands, *base_opcode, *extension_opcode, *opcode_length;
938 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
940 /* Find number of operands. */
941 operands = next_field (str, ',', &str, last);
943 /* Find base_opcode. */
944 base_opcode = next_field (str, ',', &str, last);
946 /* Find extension_opcode. */
947 extension_opcode = next_field (str, ',', &str, last);
949 /* Find opcode_length. */
950 opcode_length = next_field (str, ',', &str, last);
952 /* Find cpu_flags. */
953 cpu_flags = next_field (str, ',', &str, last);
955 /* Find opcode_modifier. */
956 opcode_modifier = next_field (str, ',', &str, last);
958 /* Remove the first {. */
959 str = remove_leading_whitespaces (str);
962 str = remove_leading_whitespaces (str + 1);
966 /* There are at least "X}". */
970 /* Remove trailing white spaces and }. */
974 if (ISSPACE (str[i]) || str[i] == '}')
983 /* Find operand_types. */
984 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
988 operand_types [i] = NULL;
992 operand_types [i] = next_field (str, ',', &str, last);
993 if (*operand_types[i] == '0')
996 operand_types[i] = NULL;
1001 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1002 name, operands, base_opcode, extension_opcode,
1005 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1007 process_i386_opcode_modifier (table, opcode_modifier, lineno);
1009 fprintf (table, " { ");
1011 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1013 if (operand_types[i] == NULL || *operand_types[i] == '0')
1016 process_i386_operand_type (table, "0", 0, "\t ", lineno);
1021 fprintf (table, ",\n ");
1023 process_i386_operand_type (table, operand_types[i], 0,
1026 fprintf (table, " } },\n");
1029 struct opcode_hash_entry
1031 struct opcode_hash_entry *next;
1037 /* Calculate the hash value of an opcode hash entry P. */
1040 opcode_hash_hash (const void *p)
1042 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1043 return htab_hash_string (entry->name);
1046 /* Compare a string Q against an opcode hash entry P. */
1049 opcode_hash_eq (const void *p, const void *q)
1051 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1052 const char *name = (const char *) q;
1053 return strcmp (name, entry->name) == 0;
1057 process_i386_opcodes (FILE *table)
1062 char *str, *p, *last, *name;
1063 struct opcode_hash_entry **hash_slot, **entry, *next;
1064 htab_t opcode_hash_table;
1065 struct opcode_hash_entry **opcode_array;
1066 unsigned int opcode_array_size = 1024;
1069 filename = "i386-opc.tbl";
1070 fp = fopen (filename, "r");
1073 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1077 opcode_array = (struct opcode_hash_entry **)
1078 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1080 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1081 opcode_hash_eq, NULL,
1084 fprintf (table, "\n/* i386 opcode table. */\n\n");
1085 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1087 /* Put everything on opcode array. */
1090 if (fgets (buf, sizeof (buf), fp) == NULL)
1095 p = remove_leading_whitespaces (buf);
1097 /* Skip comments. */
1098 str = strstr (p, "//");
1102 /* Remove trailing white spaces. */
1103 remove_trailing_whitespaces (p);
1108 /* Ignore comments. */
1116 last = p + strlen (p);
1119 name = next_field (p, ',', &str, last);
1121 /* Get the slot in hash table. */
1122 hash_slot = (struct opcode_hash_entry **)
1123 htab_find_slot_with_hash (opcode_hash_table, name,
1124 htab_hash_string (name),
1127 if (*hash_slot == NULL)
1129 /* It is the new one. Put it on opcode array. */
1130 if (i >= opcode_array_size)
1132 /* Grow the opcode array when needed. */
1133 opcode_array_size += 1024;
1134 opcode_array = (struct opcode_hash_entry **)
1135 xrealloc (opcode_array,
1136 sizeof (*opcode_array) * opcode_array_size);
1139 opcode_array[i] = (struct opcode_hash_entry *)
1140 xmalloc (sizeof (struct opcode_hash_entry));
1141 opcode_array[i]->next = NULL;
1142 opcode_array[i]->name = xstrdup (name);
1143 opcode_array[i]->opcode = xstrdup (str);
1144 opcode_array[i]->lineno = lineno;
1145 *hash_slot = opcode_array[i];
1150 /* Append it to the existing one. */
1152 while ((*entry) != NULL)
1153 entry = &(*entry)->next;
1154 *entry = (struct opcode_hash_entry *)
1155 xmalloc (sizeof (struct opcode_hash_entry));
1156 (*entry)->next = NULL;
1157 (*entry)->name = (*hash_slot)->name;
1158 (*entry)->opcode = xstrdup (str);
1159 (*entry)->lineno = lineno;
1163 /* Process opcode array. */
1164 for (j = 0; j < i; j++)
1166 for (next = opcode_array[j]; next; next = next->next)
1170 lineno = next->lineno;
1171 last = str + strlen (str);
1172 output_i386_opcode (table, name, str, last, lineno);
1178 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1180 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1182 process_i386_opcode_modifier (table, "0", -1);
1184 fprintf (table, " { ");
1185 process_i386_operand_type (table, "0", 0, "\t ", -1);
1186 fprintf (table, " } }\n");
1188 fprintf (table, "};\n");
1192 process_i386_registers (FILE *table)
1196 char *str, *p, *last;
1197 char *reg_name, *reg_type, *reg_flags, *reg_num;
1198 char *dw2_32_num, *dw2_64_num;
1201 filename = "i386-reg.tbl";
1202 fp = fopen (filename, "r");
1204 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1207 fprintf (table, "\n/* i386 register table. */\n\n");
1208 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1212 if (fgets (buf, sizeof (buf), fp) == NULL)
1217 p = remove_leading_whitespaces (buf);
1219 /* Skip comments. */
1220 str = strstr (p, "//");
1224 /* Remove trailing white spaces. */
1225 remove_trailing_whitespaces (p);
1230 fprintf (table, "%s\n", p);
1238 last = p + strlen (p);
1240 /* Find reg_name. */
1241 reg_name = next_field (p, ',', &str, last);
1243 /* Find reg_type. */
1244 reg_type = next_field (str, ',', &str, last);
1246 /* Find reg_flags. */
1247 reg_flags = next_field (str, ',', &str, last);
1250 reg_num = next_field (str, ',', &str, last);
1252 fprintf (table, " { \"%s\",\n ", reg_name);
1254 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1256 /* Find 32-bit Dwarf2 register number. */
1257 dw2_32_num = next_field (str, ',', &str, last);
1259 /* Find 64-bit Dwarf2 register number. */
1260 dw2_64_num = next_field (str, ',', &str, last);
1262 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1263 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1268 fprintf (table, "};\n");
1270 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1274 process_i386_initializers (void)
1277 FILE *fp = fopen ("i386-init.h", "w");
1281 fail (_("can't create i386-init.h, errno = %s\n"),
1284 process_copyright (fp);
1286 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1288 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1289 init = xstrdup (cpu_flag_init[i].init);
1290 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1294 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1296 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1297 init = xstrdup (operand_type_init[i].init);
1298 process_i386_operand_type (fp, init, 1, " ", -1);
1306 /* Program options. */
1307 #define OPTION_SRCDIR 200
1309 struct option long_options[] =
1311 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1312 {"debug", no_argument, NULL, 'd'},
1313 {"version", no_argument, NULL, 'V'},
1314 {"help", no_argument, NULL, 'h'},
1315 {0, no_argument, NULL, 0}
1319 print_version (void)
1321 printf ("%s: version 1.0\n", program_name);
1326 usage (FILE * stream, int status)
1328 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1334 main (int argc, char **argv)
1336 extern int chdir (char *);
1337 char *srcdir = NULL;
1341 program_name = *argv;
1342 xmalloc_set_program_name (program_name);
1344 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1369 if (chdir (srcdir) != 0)
1370 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1371 srcdir, xstrerror (errno));
1373 /* Check the unused bitfield in i386_cpu_flags. */
1375 c = CpuNumOfBits - CpuMax - 1;
1377 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1380 /* Check the unused bitfield in i386_operand_type. */
1382 c = OTNumOfBits - OTMax - 1;
1384 fail (_("%d unused bits in i386_operand_type.\n"), c);
1387 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1390 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1391 sizeof (opcode_modifiers [0]), compare);
1393 qsort (operand_types, ARRAY_SIZE (operand_types),
1394 sizeof (operand_types [0]), compare);
1396 table = fopen ("i386-tbl.h", "w");
1398 fail (_("can't create i386-tbl.h, errno = %s\n"),
1401 process_copyright (table);
1403 process_i386_opcodes (table);
1404 process_i386_registers (table);
1405 process_i386_initializers ();