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",
231 { "CPU_PREFETCHWT1_FLAGS",
235 static initializer operand_type_init[] =
237 { "OPERAND_TYPE_NONE",
239 { "OPERAND_TYPE_REG8",
241 { "OPERAND_TYPE_REG16",
243 { "OPERAND_TYPE_REG32",
245 { "OPERAND_TYPE_REG64",
247 { "OPERAND_TYPE_IMM1",
249 { "OPERAND_TYPE_IMM8",
251 { "OPERAND_TYPE_IMM8S",
253 { "OPERAND_TYPE_IMM16",
255 { "OPERAND_TYPE_IMM32",
257 { "OPERAND_TYPE_IMM32S",
259 { "OPERAND_TYPE_IMM64",
261 { "OPERAND_TYPE_BASEINDEX",
263 { "OPERAND_TYPE_DISP8",
265 { "OPERAND_TYPE_DISP16",
267 { "OPERAND_TYPE_DISP32",
269 { "OPERAND_TYPE_DISP32S",
271 { "OPERAND_TYPE_DISP64",
273 { "OPERAND_TYPE_INOUTPORTREG",
275 { "OPERAND_TYPE_SHIFTCOUNT",
277 { "OPERAND_TYPE_CONTROL",
279 { "OPERAND_TYPE_TEST",
281 { "OPERAND_TYPE_DEBUG",
283 { "OPERAND_TYPE_FLOATREG",
285 { "OPERAND_TYPE_FLOATACC",
287 { "OPERAND_TYPE_SREG2",
289 { "OPERAND_TYPE_SREG3",
291 { "OPERAND_TYPE_ACC",
293 { "OPERAND_TYPE_JUMPABSOLUTE",
295 { "OPERAND_TYPE_REGMMX",
297 { "OPERAND_TYPE_REGXMM",
299 { "OPERAND_TYPE_REGYMM",
301 { "OPERAND_TYPE_REGZMM",
303 { "OPERAND_TYPE_REGMASK",
305 { "OPERAND_TYPE_ESSEG",
307 { "OPERAND_TYPE_ACC32",
309 { "OPERAND_TYPE_ACC64",
311 { "OPERAND_TYPE_INOUTPORTREG",
313 { "OPERAND_TYPE_REG16_INOUTPORTREG",
314 "Reg16|InOutPortReg" },
315 { "OPERAND_TYPE_DISP16_32",
317 { "OPERAND_TYPE_ANYDISP",
318 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
319 { "OPERAND_TYPE_IMM16_32",
321 { "OPERAND_TYPE_IMM16_32S",
323 { "OPERAND_TYPE_IMM16_32_32S",
324 "Imm16|Imm32|Imm32S" },
325 { "OPERAND_TYPE_IMM32_64",
327 { "OPERAND_TYPE_IMM32_32S_DISP32",
328 "Imm32|Imm32S|Disp32" },
329 { "OPERAND_TYPE_IMM64_DISP64",
331 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
332 "Imm32|Imm32S|Imm64|Disp32" },
333 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
334 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
335 { "OPERAND_TYPE_VEC_IMM4",
337 { "OPERAND_TYPE_REGBND",
339 { "OPERAND_TYPE_VEC_DISP8",
343 typedef struct bitfield
350 #define BITFIELD(n) { n, 0, #n }
352 static bitfield cpu_flags[] =
360 BITFIELD (CpuClflush),
362 BITFIELD (CpuSYSCALL),
367 BITFIELD (CpuFISTTP),
373 BITFIELD (CpuSSE4_1),
374 BITFIELD (CpuSSE4_2),
377 BITFIELD (CpuAVX512F),
378 BITFIELD (CpuAVX512CD),
379 BITFIELD (CpuAVX512ER),
380 BITFIELD (CpuAVX512PF),
385 BITFIELD (Cpu3dnowA),
386 BITFIELD (CpuPadLock),
392 BITFIELD (CpuXsaveopt),
394 BITFIELD (CpuPCLMUL),
405 BITFIELD (CpuRdtscp),
406 BITFIELD (CpuFSGSBase),
413 BITFIELD (CpuINVPCID),
414 BITFIELD (CpuVMFUNC),
415 BITFIELD (CpuRDSEED),
417 BITFIELD (CpuPRFCHW),
421 BITFIELD (CpuClflushOpt),
422 BITFIELD (CpuXSAVES),
423 BITFIELD (CpuXSAVEC),
424 BITFIELD (CpuPREFETCHWT1),
429 BITFIELD (CpuUnused),
433 static bitfield opcode_modifiers[] =
439 BITFIELD (ShortForm),
441 BITFIELD (JumpDword),
443 BITFIELD (JumpInterSegment),
450 BITFIELD (CheckRegSize),
451 BITFIELD (IgnoreSize),
452 BITFIELD (DefaultSize),
461 BITFIELD (BNDPrefixOk),
462 BITFIELD (IsLockable),
463 BITFIELD (RegKludge),
464 BITFIELD (FirstXmm0),
465 BITFIELD (Implicit1stXmm0),
466 BITFIELD (RepPrefixOk),
467 BITFIELD (HLEPrefixOk),
470 BITFIELD (AddrPrefixOp0),
479 BITFIELD (VexOpcode),
480 BITFIELD (VexSources),
481 BITFIELD (VexImmExt),
488 BITFIELD (Broadcast),
489 BITFIELD (StaticRounding),
491 BITFIELD (Disp8MemShift),
492 BITFIELD (NoDefMask),
494 BITFIELD (ATTMnemonic),
495 BITFIELD (ATTSyntax),
496 BITFIELD (IntelSyntax),
499 static bitfield operand_types[] =
518 BITFIELD (BaseIndex),
524 BITFIELD (InOutPortReg),
525 BITFIELD (ShiftCount),
533 BITFIELD (JumpAbsolute),
546 BITFIELD (Unspecified),
550 BITFIELD (Vec_Disp8),
556 static const char *filename;
559 compare (const void *x, const void *y)
561 const bitfield *xp = (const bitfield *) x;
562 const bitfield *yp = (const bitfield *) y;
563 return xp->position - yp->position;
567 fail (const char *message, ...)
571 va_start (args, message);
572 fprintf (stderr, _("%s: Error: "), program_name);
573 vfprintf (stderr, message, args);
579 process_copyright (FILE *fp)
581 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
582 /* Copyright 2007-2014\n\
583 Free Software Foundation, Inc.\n\
585 This file is part of the GNU opcodes library.\n\
587 This library is free software; you can redistribute it and/or modify\n\
588 it under the terms of the GNU General Public License as published by\n\
589 the Free Software Foundation; either version 3, or (at your option)\n\
590 any later version.\n\
592 It is distributed in the hope that it will be useful, but WITHOUT\n\
593 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
594 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
595 License for more details.\n\
597 You should have received a copy of the GNU General Public License\n\
598 along with this program; if not, write to the Free Software\n\
599 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
600 MA 02110-1301, USA. */\n");
603 /* Remove leading white spaces. */
606 remove_leading_whitespaces (char *str)
608 while (ISSPACE (*str))
613 /* Remove trailing white spaces. */
616 remove_trailing_whitespaces (char *str)
618 size_t last = strlen (str);
626 if (ISSPACE (str [last]))
634 /* Find next field separated by SEP and terminate it. Return a
635 pointer to the one after it. */
638 next_field (char *str, char sep, char **next, char *last)
642 p = remove_leading_whitespaces (str);
643 for (str = p; *str != sep && *str != '\0'; str++);
646 remove_trailing_whitespaces (p);
657 set_bitfield (const char *f, bitfield *array, int value,
658 unsigned int size, int lineno)
662 if (strcmp (f, "CpuFP") == 0)
664 set_bitfield("Cpu387", array, value, size, lineno);
665 set_bitfield("Cpu287", array, value, size, lineno);
668 else if (strcmp (f, "Mmword") == 0)
670 else if (strcmp (f, "Oword") == 0)
673 for (i = 0; i < size; i++)
674 if (strcasecmp (array[i].name, f) == 0)
676 array[i].value = value;
682 const char *v = strchr (f, '=');
689 for (i = 0; i < size; i++)
690 if (strncasecmp (array[i].name, f, n) == 0)
692 value = strtol (v + 1, &end, 0);
695 array[i].value = value;
704 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
706 fail (_("Unknown bitfield: %s\n"), f);
710 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
711 int macro, const char *comma, const char *indent)
715 fprintf (table, "%s{ { ", indent);
717 for (i = 0; i < size - 1; i++)
719 if (((i + 1) % 20) != 0)
720 fprintf (table, "%d, ", flags[i].value);
722 fprintf (table, "%d,", flags[i].value);
723 if (((i + 1) % 20) == 0)
725 /* We need \\ for macro. */
727 fprintf (table, " \\\n %s", indent);
729 fprintf (table, "\n %s", indent);
733 fprintf (table, "%d } }%s\n", flags[i].value, comma);
737 process_i386_cpu_flag (FILE *table, char *flag, int macro,
738 const char *comma, const char *indent,
741 char *str, *next, *last;
743 bitfield flags [ARRAY_SIZE (cpu_flags)];
745 /* Copy the default cpu flags. */
746 memcpy (flags, cpu_flags, sizeof (cpu_flags));
748 if (strcasecmp (flag, "unknown") == 0)
750 /* We turn on everything except for cpu64 in case of
751 CPU_UNKNOWN_FLAGS. */
752 for (i = 0; i < ARRAY_SIZE (flags); i++)
753 if (flags[i].position != Cpu64)
756 else if (flag[0] == '~')
758 last = flag + strlen (flag);
765 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
772 /* First we turn on everything except for cpu64. */
773 for (i = 0; i < ARRAY_SIZE (flags); i++)
774 if (flags[i].position != Cpu64)
777 /* Turn off selective bits. */
778 for (; next && next < last; )
780 str = next_field (next, '|', &next, last);
782 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
785 else if (strcmp (flag, "0"))
787 /* Turn on selective bits. */
788 last = flag + strlen (flag);
789 for (next = flag; next && next < last; )
791 str = next_field (next, '|', &next, last);
793 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
797 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
802 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
806 fprintf (table, " { ");
808 for (i = 0; i < size - 1; i++)
810 if (((i + 1) % 20) != 0)
811 fprintf (table, "%d, ", modifier[i].value);
813 fprintf (table, "%d,", modifier[i].value);
814 if (((i + 1) % 20) == 0)
815 fprintf (table, "\n ");
818 fprintf (table, "%d },\n", modifier[i].value);
822 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
824 char *str, *next, *last;
825 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
827 /* Copy the default opcode modifier. */
828 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
830 if (strcmp (mod, "0"))
832 last = mod + strlen (mod);
833 for (next = mod; next && next < last; )
835 str = next_field (next, '|', &next, last);
837 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
841 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
845 output_operand_type (FILE *table, bitfield *types, unsigned int size,
846 int macro, const char *indent)
850 fprintf (table, "{ { ");
852 for (i = 0; i < size - 1; i++)
854 if (((i + 1) % 20) != 0)
855 fprintf (table, "%d, ", types[i].value);
857 fprintf (table, "%d,", types[i].value);
858 if (((i + 1) % 20) == 0)
860 /* We need \\ for macro. */
862 fprintf (table, " \\\n%s", indent);
864 fprintf (table, "\n%s", indent);
868 fprintf (table, "%d } }", types[i].value);
872 process_i386_operand_type (FILE *table, char *op, int macro,
873 const char *indent, int lineno)
875 char *str, *next, *last;
876 bitfield types [ARRAY_SIZE (operand_types)];
878 /* Copy the default operand type. */
879 memcpy (types, operand_types, sizeof (types));
881 if (strcmp (op, "0"))
883 last = op + strlen (op);
884 for (next = op; next && next < last; )
886 str = next_field (next, '|', &next, last);
888 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
891 output_operand_type (table, types, ARRAY_SIZE (types), macro,
896 output_i386_opcode (FILE *table, const char *name, char *str,
897 char *last, int lineno)
900 char *operands, *base_opcode, *extension_opcode, *opcode_length;
901 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
903 /* Find number of operands. */
904 operands = next_field (str, ',', &str, last);
906 /* Find base_opcode. */
907 base_opcode = next_field (str, ',', &str, last);
909 /* Find extension_opcode. */
910 extension_opcode = next_field (str, ',', &str, last);
912 /* Find opcode_length. */
913 opcode_length = next_field (str, ',', &str, last);
915 /* Find cpu_flags. */
916 cpu_flags = next_field (str, ',', &str, last);
918 /* Find opcode_modifier. */
919 opcode_modifier = next_field (str, ',', &str, last);
921 /* Remove the first {. */
922 str = remove_leading_whitespaces (str);
925 str = remove_leading_whitespaces (str + 1);
929 /* There are at least "X}". */
933 /* Remove trailing white spaces and }. */
937 if (ISSPACE (str[i]) || str[i] == '}')
946 /* Find operand_types. */
947 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
951 operand_types [i] = NULL;
955 operand_types [i] = next_field (str, ',', &str, last);
956 if (*operand_types[i] == '0')
959 operand_types[i] = NULL;
964 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
965 name, operands, base_opcode, extension_opcode,
968 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
970 process_i386_opcode_modifier (table, opcode_modifier, lineno);
972 fprintf (table, " { ");
974 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
976 if (operand_types[i] == NULL || *operand_types[i] == '0')
979 process_i386_operand_type (table, "0", 0, "\t ", lineno);
984 fprintf (table, ",\n ");
986 process_i386_operand_type (table, operand_types[i], 0,
989 fprintf (table, " } },\n");
992 struct opcode_hash_entry
994 struct opcode_hash_entry *next;
1000 /* Calculate the hash value of an opcode hash entry P. */
1003 opcode_hash_hash (const void *p)
1005 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1006 return htab_hash_string (entry->name);
1009 /* Compare a string Q against an opcode hash entry P. */
1012 opcode_hash_eq (const void *p, const void *q)
1014 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1015 const char *name = (const char *) q;
1016 return strcmp (name, entry->name) == 0;
1020 process_i386_opcodes (FILE *table)
1025 char *str, *p, *last, *name;
1026 struct opcode_hash_entry **hash_slot, **entry, *next;
1027 htab_t opcode_hash_table;
1028 struct opcode_hash_entry **opcode_array;
1029 unsigned int opcode_array_size = 1024;
1032 filename = "i386-opc.tbl";
1033 fp = fopen (filename, "r");
1036 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1040 opcode_array = (struct opcode_hash_entry **)
1041 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1043 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1044 opcode_hash_eq, NULL,
1047 fprintf (table, "\n/* i386 opcode table. */\n\n");
1048 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1050 /* Put everything on opcode array. */
1053 if (fgets (buf, sizeof (buf), fp) == NULL)
1058 p = remove_leading_whitespaces (buf);
1060 /* Skip comments. */
1061 str = strstr (p, "//");
1065 /* Remove trailing white spaces. */
1066 remove_trailing_whitespaces (p);
1071 /* Ignore comments. */
1079 last = p + strlen (p);
1082 name = next_field (p, ',', &str, last);
1084 /* Get the slot in hash table. */
1085 hash_slot = (struct opcode_hash_entry **)
1086 htab_find_slot_with_hash (opcode_hash_table, name,
1087 htab_hash_string (name),
1090 if (*hash_slot == NULL)
1092 /* It is the new one. Put it on opcode array. */
1093 if (i >= opcode_array_size)
1095 /* Grow the opcode array when needed. */
1096 opcode_array_size += 1024;
1097 opcode_array = (struct opcode_hash_entry **)
1098 xrealloc (opcode_array,
1099 sizeof (*opcode_array) * opcode_array_size);
1102 opcode_array[i] = (struct opcode_hash_entry *)
1103 xmalloc (sizeof (struct opcode_hash_entry));
1104 opcode_array[i]->next = NULL;
1105 opcode_array[i]->name = xstrdup (name);
1106 opcode_array[i]->opcode = xstrdup (str);
1107 opcode_array[i]->lineno = lineno;
1108 *hash_slot = opcode_array[i];
1113 /* Append it to the existing one. */
1115 while ((*entry) != NULL)
1116 entry = &(*entry)->next;
1117 *entry = (struct opcode_hash_entry *)
1118 xmalloc (sizeof (struct opcode_hash_entry));
1119 (*entry)->next = NULL;
1120 (*entry)->name = (*hash_slot)->name;
1121 (*entry)->opcode = xstrdup (str);
1122 (*entry)->lineno = lineno;
1126 /* Process opcode array. */
1127 for (j = 0; j < i; j++)
1129 for (next = opcode_array[j]; next; next = next->next)
1133 lineno = next->lineno;
1134 last = str + strlen (str);
1135 output_i386_opcode (table, name, str, last, lineno);
1141 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1143 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1145 process_i386_opcode_modifier (table, "0", -1);
1147 fprintf (table, " { ");
1148 process_i386_operand_type (table, "0", 0, "\t ", -1);
1149 fprintf (table, " } }\n");
1151 fprintf (table, "};\n");
1155 process_i386_registers (FILE *table)
1159 char *str, *p, *last;
1160 char *reg_name, *reg_type, *reg_flags, *reg_num;
1161 char *dw2_32_num, *dw2_64_num;
1164 filename = "i386-reg.tbl";
1165 fp = fopen (filename, "r");
1167 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1170 fprintf (table, "\n/* i386 register table. */\n\n");
1171 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1175 if (fgets (buf, sizeof (buf), fp) == NULL)
1180 p = remove_leading_whitespaces (buf);
1182 /* Skip comments. */
1183 str = strstr (p, "//");
1187 /* Remove trailing white spaces. */
1188 remove_trailing_whitespaces (p);
1193 fprintf (table, "%s\n", p);
1201 last = p + strlen (p);
1203 /* Find reg_name. */
1204 reg_name = next_field (p, ',', &str, last);
1206 /* Find reg_type. */
1207 reg_type = next_field (str, ',', &str, last);
1209 /* Find reg_flags. */
1210 reg_flags = next_field (str, ',', &str, last);
1213 reg_num = next_field (str, ',', &str, last);
1215 fprintf (table, " { \"%s\",\n ", reg_name);
1217 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1219 /* Find 32-bit Dwarf2 register number. */
1220 dw2_32_num = next_field (str, ',', &str, last);
1222 /* Find 64-bit Dwarf2 register number. */
1223 dw2_64_num = next_field (str, ',', &str, last);
1225 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1226 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1231 fprintf (table, "};\n");
1233 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1237 process_i386_initializers (void)
1240 FILE *fp = fopen ("i386-init.h", "w");
1244 fail (_("can't create i386-init.h, errno = %s\n"),
1247 process_copyright (fp);
1249 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1251 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1252 init = xstrdup (cpu_flag_init[i].init);
1253 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1257 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1259 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1260 init = xstrdup (operand_type_init[i].init);
1261 process_i386_operand_type (fp, init, 1, " ", -1);
1269 /* Program options. */
1270 #define OPTION_SRCDIR 200
1272 struct option long_options[] =
1274 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1275 {"debug", no_argument, NULL, 'd'},
1276 {"version", no_argument, NULL, 'V'},
1277 {"help", no_argument, NULL, 'h'},
1278 {0, no_argument, NULL, 0}
1282 print_version (void)
1284 printf ("%s: version 1.0\n", program_name);
1289 usage (FILE * stream, int status)
1291 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1297 main (int argc, char **argv)
1299 extern int chdir (char *);
1300 char *srcdir = NULL;
1304 program_name = *argv;
1305 xmalloc_set_program_name (program_name);
1307 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1332 if (chdir (srcdir) != 0)
1333 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1334 srcdir, xstrerror (errno));
1336 /* Check the unused bitfield in i386_cpu_flags. */
1338 c = CpuNumOfBits - CpuMax - 1;
1340 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1343 /* Check the unused bitfield in i386_operand_type. */
1345 c = OTNumOfBits - OTMax - 1;
1347 fail (_("%d unused bits in i386_operand_type.\n"), c);
1350 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1353 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1354 sizeof (opcode_modifiers [0]), compare);
1356 qsort (operand_types, ARRAY_SIZE (operand_types),
1357 sizeof (operand_types [0]), compare);
1359 table = fopen ("i386-tbl.h", "w");
1361 fail (_("can't create i386-tbl.h, errno = %s\n"),
1364 process_copyright (table);
1366 process_i386_opcodes (table);
1367 process_i386_registers (table);
1368 process_i386_initializers ();