2 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
25 #include "libiberty.h"
27 #include "safe-ctype.h"
32 #define _(String) gettext (String)
34 static const char *program_name = NULL;
37 typedef struct initializer
43 static initializer cpu_flag_init[] =
45 { "CPU_UNKNOWN_FLAGS",
46 "~(CpuL1OM|CpuK1OM)" },
47 { "CPU_GENERIC32_FLAGS",
48 "Cpu186|Cpu286|Cpu386" },
49 { "CPU_GENERIC64_FLAGS",
50 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
58 "Cpu186|Cpu286|Cpu386" },
60 "Cpu186|Cpu286|Cpu386|Cpu486" },
62 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu387" },
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
65 { "CPU_PENTIUMPRO_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM|CpuCX16" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuCX16" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM|CpuCX16" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM|CpuCX16" },
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
89 { "CPU_AMDFAM10_FLAGS",
90 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
92 "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" },
94 "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" },
96 "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" },
98 "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" },
100 "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" },
101 { "CPU_BTVER2_FLAGS",
102 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuSSE4_1|CpuSSE4_2|CpuABM|CpuLM|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
110 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
111 { "CPU_CLFLUSH_FLAGS",
115 { "CPU_SYSCALL_FLAGS",
122 "CpuMMX|CpuSSE|CpuSSE2" },
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
127 { "CPU_SSE4_1_FLAGS",
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
129 { "CPU_SSE4_2_FLAGS",
130 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
131 { "CPU_ANY_SSE_FLAGS",
132 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
139 { "CPU_XSAVEOPT_FLAGS",
142 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
143 { "CPU_PCLMUL_FLAGS",
144 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
146 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
148 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
150 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
161 { "CPU_RDTSCP_FLAGS",
165 { "CPU_FSGSBASE_FLAGS",
179 { "CPU_INVPCID_FLAGS",
181 { "CPU_VMFUNC_FLAGS",
185 { "CPU_3DNOWA_FLAGS",
186 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
187 { "CPU_PADLOCK_FLAGS",
192 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
196 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
198 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
199 { "CPU_AVX512F_FLAGS",
200 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F" },
201 { "CPU_AVX512CD_FLAGS",
202 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD" },
203 { "CPU_AVX512ER_FLAGS",
204 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512ER" },
205 { "CPU_AVX512PF_FLAGS",
206 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512PF" },
207 { "CPU_ANY_AVX_FLAGS",
208 "CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
215 { "CPU_RDSEED_FLAGS",
217 { "CPU_PRFCHW_FLAGS",
225 { "CPU_CLFLUSHOPT_FLAGS",
227 { "CPU_XSAVES_FLAGS",
229 { "CPU_XSAVEC_FLAGS",
233 static initializer operand_type_init[] =
235 { "OPERAND_TYPE_NONE",
237 { "OPERAND_TYPE_REG8",
239 { "OPERAND_TYPE_REG16",
241 { "OPERAND_TYPE_REG32",
243 { "OPERAND_TYPE_REG64",
245 { "OPERAND_TYPE_IMM1",
247 { "OPERAND_TYPE_IMM8",
249 { "OPERAND_TYPE_IMM8S",
251 { "OPERAND_TYPE_IMM16",
253 { "OPERAND_TYPE_IMM32",
255 { "OPERAND_TYPE_IMM32S",
257 { "OPERAND_TYPE_IMM64",
259 { "OPERAND_TYPE_BASEINDEX",
261 { "OPERAND_TYPE_DISP8",
263 { "OPERAND_TYPE_DISP16",
265 { "OPERAND_TYPE_DISP32",
267 { "OPERAND_TYPE_DISP32S",
269 { "OPERAND_TYPE_DISP64",
271 { "OPERAND_TYPE_INOUTPORTREG",
273 { "OPERAND_TYPE_SHIFTCOUNT",
275 { "OPERAND_TYPE_CONTROL",
277 { "OPERAND_TYPE_TEST",
279 { "OPERAND_TYPE_DEBUG",
281 { "OPERAND_TYPE_FLOATREG",
283 { "OPERAND_TYPE_FLOATACC",
285 { "OPERAND_TYPE_SREG2",
287 { "OPERAND_TYPE_SREG3",
289 { "OPERAND_TYPE_ACC",
291 { "OPERAND_TYPE_JUMPABSOLUTE",
293 { "OPERAND_TYPE_REGMMX",
295 { "OPERAND_TYPE_REGXMM",
297 { "OPERAND_TYPE_REGYMM",
299 { "OPERAND_TYPE_REGZMM",
301 { "OPERAND_TYPE_REGMASK",
303 { "OPERAND_TYPE_ESSEG",
305 { "OPERAND_TYPE_ACC32",
307 { "OPERAND_TYPE_ACC64",
309 { "OPERAND_TYPE_INOUTPORTREG",
311 { "OPERAND_TYPE_REG16_INOUTPORTREG",
312 "Reg16|InOutPortReg" },
313 { "OPERAND_TYPE_DISP16_32",
315 { "OPERAND_TYPE_ANYDISP",
316 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
317 { "OPERAND_TYPE_IMM16_32",
319 { "OPERAND_TYPE_IMM16_32S",
321 { "OPERAND_TYPE_IMM16_32_32S",
322 "Imm16|Imm32|Imm32S" },
323 { "OPERAND_TYPE_IMM32_64",
325 { "OPERAND_TYPE_IMM32_32S_DISP32",
326 "Imm32|Imm32S|Disp32" },
327 { "OPERAND_TYPE_IMM64_DISP64",
329 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
330 "Imm32|Imm32S|Imm64|Disp32" },
331 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
332 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
333 { "OPERAND_TYPE_VEC_IMM4",
335 { "OPERAND_TYPE_REGBND",
337 { "OPERAND_TYPE_VEC_DISP8",
341 typedef struct bitfield
348 #define BITFIELD(n) { n, 0, #n }
350 static bitfield cpu_flags[] =
358 BITFIELD (CpuClflush),
360 BITFIELD (CpuSYSCALL),
365 BITFIELD (CpuFISTTP),
371 BITFIELD (CpuSSE4_1),
372 BITFIELD (CpuSSE4_2),
375 BITFIELD (CpuAVX512F),
376 BITFIELD (CpuAVX512CD),
377 BITFIELD (CpuAVX512ER),
378 BITFIELD (CpuAVX512PF),
383 BITFIELD (Cpu3dnowA),
384 BITFIELD (CpuPadLock),
390 BITFIELD (CpuXsaveopt),
392 BITFIELD (CpuPCLMUL),
403 BITFIELD (CpuRdtscp),
404 BITFIELD (CpuFSGSBase),
411 BITFIELD (CpuINVPCID),
412 BITFIELD (CpuVMFUNC),
413 BITFIELD (CpuRDSEED),
415 BITFIELD (CpuPRFCHW),
419 BITFIELD (CpuClflushOpt),
420 BITFIELD (CpuXSAVES),
421 BITFIELD (CpuXSAVEC),
426 BITFIELD (CpuUnused),
430 static bitfield opcode_modifiers[] =
436 BITFIELD (ShortForm),
438 BITFIELD (JumpDword),
440 BITFIELD (JumpInterSegment),
447 BITFIELD (CheckRegSize),
448 BITFIELD (IgnoreSize),
449 BITFIELD (DefaultSize),
458 BITFIELD (BNDPrefixOk),
459 BITFIELD (IsLockable),
460 BITFIELD (RegKludge),
461 BITFIELD (FirstXmm0),
462 BITFIELD (Implicit1stXmm0),
463 BITFIELD (RepPrefixOk),
464 BITFIELD (HLEPrefixOk),
467 BITFIELD (AddrPrefixOp0),
476 BITFIELD (VexOpcode),
477 BITFIELD (VexSources),
478 BITFIELD (VexImmExt),
485 BITFIELD (Broadcast),
486 BITFIELD (StaticRounding),
488 BITFIELD (Disp8MemShift),
489 BITFIELD (NoDefMask),
491 BITFIELD (ATTMnemonic),
492 BITFIELD (ATTSyntax),
493 BITFIELD (IntelSyntax),
496 static bitfield operand_types[] =
515 BITFIELD (BaseIndex),
521 BITFIELD (InOutPortReg),
522 BITFIELD (ShiftCount),
530 BITFIELD (JumpAbsolute),
543 BITFIELD (Unspecified),
547 BITFIELD (Vec_Disp8),
553 static const char *filename;
556 compare (const void *x, const void *y)
558 const bitfield *xp = (const bitfield *) x;
559 const bitfield *yp = (const bitfield *) y;
560 return xp->position - yp->position;
564 fail (const char *message, ...)
568 va_start (args, message);
569 fprintf (stderr, _("%s: Error: "), program_name);
570 vfprintf (stderr, message, args);
576 process_copyright (FILE *fp)
578 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
579 /* Copyright 2007-2014\n\
580 Free Software Foundation, Inc.\n\
582 This file is part of the GNU opcodes library.\n\
584 This library is free software; you can redistribute it and/or modify\n\
585 it under the terms of the GNU General Public License as published by\n\
586 the Free Software Foundation; either version 3, or (at your option)\n\
587 any later version.\n\
589 It is distributed in the hope that it will be useful, but WITHOUT\n\
590 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
591 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
592 License for more details.\n\
594 You should have received a copy of the GNU General Public License\n\
595 along with this program; if not, write to the Free Software\n\
596 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
597 MA 02110-1301, USA. */\n");
600 /* Remove leading white spaces. */
603 remove_leading_whitespaces (char *str)
605 while (ISSPACE (*str))
610 /* Remove trailing white spaces. */
613 remove_trailing_whitespaces (char *str)
615 size_t last = strlen (str);
623 if (ISSPACE (str [last]))
631 /* Find next field separated by SEP and terminate it. Return a
632 pointer to the one after it. */
635 next_field (char *str, char sep, char **next, char *last)
639 p = remove_leading_whitespaces (str);
640 for (str = p; *str != sep && *str != '\0'; str++);
643 remove_trailing_whitespaces (p);
654 set_bitfield (const char *f, bitfield *array, int value,
655 unsigned int size, int lineno)
659 if (strcmp (f, "CpuFP") == 0)
661 set_bitfield("Cpu387", array, value, size, lineno);
662 set_bitfield("Cpu287", array, value, size, lineno);
665 else if (strcmp (f, "Mmword") == 0)
667 else if (strcmp (f, "Oword") == 0)
670 for (i = 0; i < size; i++)
671 if (strcasecmp (array[i].name, f) == 0)
673 array[i].value = value;
679 const char *v = strchr (f, '=');
686 for (i = 0; i < size; i++)
687 if (strncasecmp (array[i].name, f, n) == 0)
689 value = strtol (v + 1, &end, 0);
692 array[i].value = value;
701 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
703 fail (_("Unknown bitfield: %s\n"), f);
707 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
708 int macro, const char *comma, const char *indent)
712 fprintf (table, "%s{ { ", indent);
714 for (i = 0; i < size - 1; i++)
716 if (((i + 1) % 20) != 0)
717 fprintf (table, "%d, ", flags[i].value);
719 fprintf (table, "%d,", flags[i].value);
720 if (((i + 1) % 20) == 0)
722 /* We need \\ for macro. */
724 fprintf (table, " \\\n %s", indent);
726 fprintf (table, "\n %s", indent);
730 fprintf (table, "%d } }%s\n", flags[i].value, comma);
734 process_i386_cpu_flag (FILE *table, char *flag, int macro,
735 const char *comma, const char *indent,
738 char *str, *next, *last;
740 bitfield flags [ARRAY_SIZE (cpu_flags)];
742 /* Copy the default cpu flags. */
743 memcpy (flags, cpu_flags, sizeof (cpu_flags));
745 if (strcasecmp (flag, "unknown") == 0)
747 /* We turn on everything except for cpu64 in case of
748 CPU_UNKNOWN_FLAGS. */
749 for (i = 0; i < ARRAY_SIZE (flags); i++)
750 if (flags[i].position != Cpu64)
753 else if (flag[0] == '~')
755 last = flag + strlen (flag);
762 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
769 /* First we turn on everything except for cpu64. */
770 for (i = 0; i < ARRAY_SIZE (flags); i++)
771 if (flags[i].position != Cpu64)
774 /* Turn off selective bits. */
775 for (; next && next < last; )
777 str = next_field (next, '|', &next, last);
779 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
782 else if (strcmp (flag, "0"))
784 /* Turn on selective bits. */
785 last = flag + strlen (flag);
786 for (next = flag; next && next < last; )
788 str = next_field (next, '|', &next, last);
790 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
794 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
799 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
803 fprintf (table, " { ");
805 for (i = 0; i < size - 1; i++)
807 if (((i + 1) % 20) != 0)
808 fprintf (table, "%d, ", modifier[i].value);
810 fprintf (table, "%d,", modifier[i].value);
811 if (((i + 1) % 20) == 0)
812 fprintf (table, "\n ");
815 fprintf (table, "%d },\n", modifier[i].value);
819 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
821 char *str, *next, *last;
822 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
824 /* Copy the default opcode modifier. */
825 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
827 if (strcmp (mod, "0"))
829 last = mod + strlen (mod);
830 for (next = mod; next && next < last; )
832 str = next_field (next, '|', &next, last);
834 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
838 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
842 output_operand_type (FILE *table, bitfield *types, unsigned int size,
843 int macro, const char *indent)
847 fprintf (table, "{ { ");
849 for (i = 0; i < size - 1; i++)
851 if (((i + 1) % 20) != 0)
852 fprintf (table, "%d, ", types[i].value);
854 fprintf (table, "%d,", types[i].value);
855 if (((i + 1) % 20) == 0)
857 /* We need \\ for macro. */
859 fprintf (table, " \\\n%s", indent);
861 fprintf (table, "\n%s", indent);
865 fprintf (table, "%d } }", types[i].value);
869 process_i386_operand_type (FILE *table, char *op, int macro,
870 const char *indent, int lineno)
872 char *str, *next, *last;
873 bitfield types [ARRAY_SIZE (operand_types)];
875 /* Copy the default operand type. */
876 memcpy (types, operand_types, sizeof (types));
878 if (strcmp (op, "0"))
880 last = op + strlen (op);
881 for (next = op; next && next < last; )
883 str = next_field (next, '|', &next, last);
885 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
888 output_operand_type (table, types, ARRAY_SIZE (types), macro,
893 output_i386_opcode (FILE *table, const char *name, char *str,
894 char *last, int lineno)
897 char *operands, *base_opcode, *extension_opcode, *opcode_length;
898 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
900 /* Find number of operands. */
901 operands = next_field (str, ',', &str, last);
903 /* Find base_opcode. */
904 base_opcode = next_field (str, ',', &str, last);
906 /* Find extension_opcode. */
907 extension_opcode = next_field (str, ',', &str, last);
909 /* Find opcode_length. */
910 opcode_length = next_field (str, ',', &str, last);
912 /* Find cpu_flags. */
913 cpu_flags = next_field (str, ',', &str, last);
915 /* Find opcode_modifier. */
916 opcode_modifier = next_field (str, ',', &str, last);
918 /* Remove the first {. */
919 str = remove_leading_whitespaces (str);
922 str = remove_leading_whitespaces (str + 1);
926 /* There are at least "X}". */
930 /* Remove trailing white spaces and }. */
934 if (ISSPACE (str[i]) || str[i] == '}')
943 /* Find operand_types. */
944 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
948 operand_types [i] = NULL;
952 operand_types [i] = next_field (str, ',', &str, last);
953 if (*operand_types[i] == '0')
956 operand_types[i] = NULL;
961 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
962 name, operands, base_opcode, extension_opcode,
965 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
967 process_i386_opcode_modifier (table, opcode_modifier, lineno);
969 fprintf (table, " { ");
971 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
973 if (operand_types[i] == NULL || *operand_types[i] == '0')
976 process_i386_operand_type (table, "0", 0, "\t ", lineno);
981 fprintf (table, ",\n ");
983 process_i386_operand_type (table, operand_types[i], 0,
986 fprintf (table, " } },\n");
989 struct opcode_hash_entry
991 struct opcode_hash_entry *next;
997 /* Calculate the hash value of an opcode hash entry P. */
1000 opcode_hash_hash (const void *p)
1002 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1003 return htab_hash_string (entry->name);
1006 /* Compare a string Q against an opcode hash entry P. */
1009 opcode_hash_eq (const void *p, const void *q)
1011 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1012 const char *name = (const char *) q;
1013 return strcmp (name, entry->name) == 0;
1017 process_i386_opcodes (FILE *table)
1022 char *str, *p, *last, *name;
1023 struct opcode_hash_entry **hash_slot, **entry, *next;
1024 htab_t opcode_hash_table;
1025 struct opcode_hash_entry **opcode_array;
1026 unsigned int opcode_array_size = 1024;
1029 filename = "i386-opc.tbl";
1030 fp = fopen (filename, "r");
1033 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1037 opcode_array = (struct opcode_hash_entry **)
1038 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1040 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1041 opcode_hash_eq, NULL,
1044 fprintf (table, "\n/* i386 opcode table. */\n\n");
1045 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1047 /* Put everything on opcode array. */
1050 if (fgets (buf, sizeof (buf), fp) == NULL)
1055 p = remove_leading_whitespaces (buf);
1057 /* Skip comments. */
1058 str = strstr (p, "//");
1062 /* Remove trailing white spaces. */
1063 remove_trailing_whitespaces (p);
1068 /* Ignore comments. */
1076 last = p + strlen (p);
1079 name = next_field (p, ',', &str, last);
1081 /* Get the slot in hash table. */
1082 hash_slot = (struct opcode_hash_entry **)
1083 htab_find_slot_with_hash (opcode_hash_table, name,
1084 htab_hash_string (name),
1087 if (*hash_slot == NULL)
1089 /* It is the new one. Put it on opcode array. */
1090 if (i >= opcode_array_size)
1092 /* Grow the opcode array when needed. */
1093 opcode_array_size += 1024;
1094 opcode_array = (struct opcode_hash_entry **)
1095 xrealloc (opcode_array,
1096 sizeof (*opcode_array) * opcode_array_size);
1099 opcode_array[i] = (struct opcode_hash_entry *)
1100 xmalloc (sizeof (struct opcode_hash_entry));
1101 opcode_array[i]->next = NULL;
1102 opcode_array[i]->name = xstrdup (name);
1103 opcode_array[i]->opcode = xstrdup (str);
1104 opcode_array[i]->lineno = lineno;
1105 *hash_slot = opcode_array[i];
1110 /* Append it to the existing one. */
1112 while ((*entry) != NULL)
1113 entry = &(*entry)->next;
1114 *entry = (struct opcode_hash_entry *)
1115 xmalloc (sizeof (struct opcode_hash_entry));
1116 (*entry)->next = NULL;
1117 (*entry)->name = (*hash_slot)->name;
1118 (*entry)->opcode = xstrdup (str);
1119 (*entry)->lineno = lineno;
1123 /* Process opcode array. */
1124 for (j = 0; j < i; j++)
1126 for (next = opcode_array[j]; next; next = next->next)
1130 lineno = next->lineno;
1131 last = str + strlen (str);
1132 output_i386_opcode (table, name, str, last, lineno);
1138 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1140 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1142 process_i386_opcode_modifier (table, "0", -1);
1144 fprintf (table, " { ");
1145 process_i386_operand_type (table, "0", 0, "\t ", -1);
1146 fprintf (table, " } }\n");
1148 fprintf (table, "};\n");
1152 process_i386_registers (FILE *table)
1156 char *str, *p, *last;
1157 char *reg_name, *reg_type, *reg_flags, *reg_num;
1158 char *dw2_32_num, *dw2_64_num;
1161 filename = "i386-reg.tbl";
1162 fp = fopen (filename, "r");
1164 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1167 fprintf (table, "\n/* i386 register table. */\n\n");
1168 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1172 if (fgets (buf, sizeof (buf), fp) == NULL)
1177 p = remove_leading_whitespaces (buf);
1179 /* Skip comments. */
1180 str = strstr (p, "//");
1184 /* Remove trailing white spaces. */
1185 remove_trailing_whitespaces (p);
1190 fprintf (table, "%s\n", p);
1198 last = p + strlen (p);
1200 /* Find reg_name. */
1201 reg_name = next_field (p, ',', &str, last);
1203 /* Find reg_type. */
1204 reg_type = next_field (str, ',', &str, last);
1206 /* Find reg_flags. */
1207 reg_flags = next_field (str, ',', &str, last);
1210 reg_num = next_field (str, ',', &str, last);
1212 fprintf (table, " { \"%s\",\n ", reg_name);
1214 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1216 /* Find 32-bit Dwarf2 register number. */
1217 dw2_32_num = next_field (str, ',', &str, last);
1219 /* Find 64-bit Dwarf2 register number. */
1220 dw2_64_num = next_field (str, ',', &str, last);
1222 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1223 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1228 fprintf (table, "};\n");
1230 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1234 process_i386_initializers (void)
1237 FILE *fp = fopen ("i386-init.h", "w");
1241 fail (_("can't create i386-init.h, errno = %s\n"),
1244 process_copyright (fp);
1246 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1248 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1249 init = xstrdup (cpu_flag_init[i].init);
1250 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1254 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1256 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1257 init = xstrdup (operand_type_init[i].init);
1258 process_i386_operand_type (fp, init, 1, " ", -1);
1266 /* Program options. */
1267 #define OPTION_SRCDIR 200
1269 struct option long_options[] =
1271 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1272 {"debug", no_argument, NULL, 'd'},
1273 {"version", no_argument, NULL, 'V'},
1274 {"help", no_argument, NULL, 'h'},
1275 {0, no_argument, NULL, 0}
1279 print_version (void)
1281 printf ("%s: version 1.0\n", program_name);
1286 usage (FILE * stream, int status)
1288 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1294 main (int argc, char **argv)
1296 extern int chdir (char *);
1297 char *srcdir = NULL;
1301 program_name = *argv;
1302 xmalloc_set_program_name (program_name);
1304 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1329 if (chdir (srcdir) != 0)
1330 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1331 srcdir, xstrerror (errno));
1333 /* Check the unused bitfield in i386_cpu_flags. */
1335 c = CpuNumOfBits - CpuMax - 1;
1337 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1340 /* Check the unused bitfield in i386_operand_type. */
1342 c = OTNumOfBits - OTMax - 1;
1344 fail (_("%d unused bits in i386_operand_type.\n"), c);
1347 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1350 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1351 sizeof (opcode_modifiers [0]), compare);
1353 qsort (operand_types, ARRAY_SIZE (operand_types),
1354 sizeof (operand_types [0]), compare);
1356 table = fopen ("i386-tbl.h", "w");
1358 fail (_("can't create i386-tbl.h, errno = %s\n"),
1361 process_copyright (table);
1363 process_i386_opcodes (table);
1364 process_i386_registers (table);
1365 process_i386_initializers ();