1 /* Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013
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|CpuNop|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|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
100 "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" },
108 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
109 { "CPU_CLFLUSH_FLAGS",
113 { "CPU_SYSCALL_FLAGS",
120 "CpuMMX|CpuSSE|CpuSSE2" },
122 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
125 { "CPU_SSE4_1_FLAGS",
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
127 { "CPU_SSE4_2_FLAGS",
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
129 { "CPU_ANY_SSE_FLAGS",
130 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
137 { "CPU_XSAVEOPT_FLAGS",
140 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
141 { "CPU_PCLMUL_FLAGS",
142 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
144 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
146 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
148 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
159 { "CPU_RDTSCP_FLAGS",
163 { "CPU_FSGSBASE_FLAGS",
177 { "CPU_INVPCID_FLAGS",
179 { "CPU_VMFUNC_FLAGS",
183 { "CPU_3DNOWA_FLAGS",
184 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
185 { "CPU_PADLOCK_FLAGS",
190 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
194 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
196 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
197 { "CPU_AVX512F_FLAGS",
198 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F" },
199 { "CPU_AVX512CD_FLAGS",
200 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD" },
201 { "CPU_AVX512ER_FLAGS",
202 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512ER" },
203 { "CPU_AVX512PF_FLAGS",
204 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512PF" },
205 { "CPU_ANY_AVX_FLAGS",
206 "CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
213 { "CPU_RDSEED_FLAGS",
215 { "CPU_PRFCHW_FLAGS",
225 static initializer operand_type_init[] =
227 { "OPERAND_TYPE_NONE",
229 { "OPERAND_TYPE_REG8",
231 { "OPERAND_TYPE_REG16",
233 { "OPERAND_TYPE_REG32",
235 { "OPERAND_TYPE_REG64",
237 { "OPERAND_TYPE_IMM1",
239 { "OPERAND_TYPE_IMM8",
241 { "OPERAND_TYPE_IMM8S",
243 { "OPERAND_TYPE_IMM16",
245 { "OPERAND_TYPE_IMM32",
247 { "OPERAND_TYPE_IMM32S",
249 { "OPERAND_TYPE_IMM64",
251 { "OPERAND_TYPE_BASEINDEX",
253 { "OPERAND_TYPE_DISP8",
255 { "OPERAND_TYPE_DISP16",
257 { "OPERAND_TYPE_DISP32",
259 { "OPERAND_TYPE_DISP32S",
261 { "OPERAND_TYPE_DISP64",
263 { "OPERAND_TYPE_INOUTPORTREG",
265 { "OPERAND_TYPE_SHIFTCOUNT",
267 { "OPERAND_TYPE_CONTROL",
269 { "OPERAND_TYPE_TEST",
271 { "OPERAND_TYPE_DEBUG",
273 { "OPERAND_TYPE_FLOATREG",
275 { "OPERAND_TYPE_FLOATACC",
277 { "OPERAND_TYPE_SREG2",
279 { "OPERAND_TYPE_SREG3",
281 { "OPERAND_TYPE_ACC",
283 { "OPERAND_TYPE_JUMPABSOLUTE",
285 { "OPERAND_TYPE_REGMMX",
287 { "OPERAND_TYPE_REGXMM",
289 { "OPERAND_TYPE_REGYMM",
291 { "OPERAND_TYPE_REGZMM",
293 { "OPERAND_TYPE_REGMASK",
295 { "OPERAND_TYPE_ESSEG",
297 { "OPERAND_TYPE_ACC32",
299 { "OPERAND_TYPE_ACC64",
301 { "OPERAND_TYPE_INOUTPORTREG",
303 { "OPERAND_TYPE_REG16_INOUTPORTREG",
304 "Reg16|InOutPortReg" },
305 { "OPERAND_TYPE_DISP16_32",
307 { "OPERAND_TYPE_ANYDISP",
308 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
309 { "OPERAND_TYPE_IMM16_32",
311 { "OPERAND_TYPE_IMM16_32S",
313 { "OPERAND_TYPE_IMM16_32_32S",
314 "Imm16|Imm32|Imm32S" },
315 { "OPERAND_TYPE_IMM32_64",
317 { "OPERAND_TYPE_IMM32_32S_DISP32",
318 "Imm32|Imm32S|Disp32" },
319 { "OPERAND_TYPE_IMM64_DISP64",
321 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
322 "Imm32|Imm32S|Imm64|Disp32" },
323 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
324 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
325 { "OPERAND_TYPE_VEC_IMM4",
327 { "OPERAND_TYPE_REGBND",
329 { "OPERAND_TYPE_VEC_DISP8",
333 typedef struct bitfield
340 #define BITFIELD(n) { n, 0, #n }
342 static bitfield cpu_flags[] =
350 BITFIELD (CpuClflush),
352 BITFIELD (CpuSYSCALL),
357 BITFIELD (CpuFISTTP),
363 BITFIELD (CpuSSE4_1),
364 BITFIELD (CpuSSE4_2),
367 BITFIELD (CpuAVX512F),
368 BITFIELD (CpuAVX512CD),
369 BITFIELD (CpuAVX512ER),
370 BITFIELD (CpuAVX512PF),
375 BITFIELD (Cpu3dnowA),
376 BITFIELD (CpuPadLock),
382 BITFIELD (CpuXsaveopt),
384 BITFIELD (CpuPCLMUL),
395 BITFIELD (CpuRdtscp),
396 BITFIELD (CpuFSGSBase),
403 BITFIELD (CpuINVPCID),
404 BITFIELD (CpuVMFUNC),
405 BITFIELD (CpuRDSEED),
407 BITFIELD (CpuPRFCHW),
415 BITFIELD (CpuUnused),
419 static bitfield opcode_modifiers[] =
425 BITFIELD (ShortForm),
427 BITFIELD (JumpDword),
429 BITFIELD (JumpInterSegment),
436 BITFIELD (CheckRegSize),
437 BITFIELD (IgnoreSize),
438 BITFIELD (DefaultSize),
447 BITFIELD (BNDPrefixOk),
448 BITFIELD (IsLockable),
449 BITFIELD (RegKludge),
450 BITFIELD (FirstXmm0),
451 BITFIELD (Implicit1stXmm0),
452 BITFIELD (RepPrefixOk),
453 BITFIELD (HLEPrefixOk),
456 BITFIELD (AddrPrefixOp0),
465 BITFIELD (VexOpcode),
466 BITFIELD (VexSources),
467 BITFIELD (VexImmExt),
474 BITFIELD (Broadcast),
475 BITFIELD (StaticRounding),
477 BITFIELD (Disp8MemShift),
478 BITFIELD (NoDefMask),
480 BITFIELD (ATTMnemonic),
481 BITFIELD (ATTSyntax),
482 BITFIELD (IntelSyntax),
485 static bitfield operand_types[] =
504 BITFIELD (BaseIndex),
510 BITFIELD (InOutPortReg),
511 BITFIELD (ShiftCount),
519 BITFIELD (JumpAbsolute),
532 BITFIELD (Unspecified),
536 BITFIELD (Vec_Disp8),
542 static const char *filename;
545 compare (const void *x, const void *y)
547 const bitfield *xp = (const bitfield *) x;
548 const bitfield *yp = (const bitfield *) y;
549 return xp->position - yp->position;
553 fail (const char *message, ...)
557 va_start (args, message);
558 fprintf (stderr, _("%s: Error: "), program_name);
559 vfprintf (stderr, message, args);
565 process_copyright (FILE *fp)
567 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
568 /* Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013\n\
569 Free Software Foundation, Inc.\n\
571 This file is part of the GNU opcodes library.\n\
573 This library is free software; you can redistribute it and/or modify\n\
574 it under the terms of the GNU General Public License as published by\n\
575 the Free Software Foundation; either version 3, or (at your option)\n\
576 any later version.\n\
578 It is distributed in the hope that it will be useful, but WITHOUT\n\
579 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
580 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
581 License for more details.\n\
583 You should have received a copy of the GNU General Public License\n\
584 along with this program; if not, write to the Free Software\n\
585 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
586 MA 02110-1301, USA. */\n");
589 /* Remove leading white spaces. */
592 remove_leading_whitespaces (char *str)
594 while (ISSPACE (*str))
599 /* Remove trailing white spaces. */
602 remove_trailing_whitespaces (char *str)
604 size_t last = strlen (str);
612 if (ISSPACE (str [last]))
620 /* Find next field separated by SEP and terminate it. Return a
621 pointer to the one after it. */
624 next_field (char *str, char sep, char **next, char *last)
628 p = remove_leading_whitespaces (str);
629 for (str = p; *str != sep && *str != '\0'; str++);
632 remove_trailing_whitespaces (p);
643 set_bitfield (const char *f, bitfield *array, int value,
644 unsigned int size, int lineno)
648 if (strcmp (f, "CpuFP") == 0)
650 set_bitfield("Cpu387", array, value, size, lineno);
651 set_bitfield("Cpu287", array, value, size, lineno);
654 else if (strcmp (f, "Mmword") == 0)
656 else if (strcmp (f, "Oword") == 0)
659 for (i = 0; i < size; i++)
660 if (strcasecmp (array[i].name, f) == 0)
662 array[i].value = value;
668 const char *v = strchr (f, '=');
675 for (i = 0; i < size; i++)
676 if (strncasecmp (array[i].name, f, n) == 0)
678 value = strtol (v + 1, &end, 0);
681 array[i].value = value;
690 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
692 fail (_("Unknown bitfield: %s\n"), f);
696 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
697 int macro, const char *comma, const char *indent)
701 fprintf (table, "%s{ { ", indent);
703 for (i = 0; i < size - 1; i++)
705 fprintf (table, "%d, ", flags[i].value);
706 if (((i + 1) % 20) == 0)
708 /* We need \\ for macro. */
710 fprintf (table, " \\\n %s", indent);
712 fprintf (table, "\n %s", indent);
716 fprintf (table, "%d } }%s\n", flags[i].value, comma);
720 process_i386_cpu_flag (FILE *table, char *flag, int macro,
721 const char *comma, const char *indent,
724 char *str, *next, *last;
726 bitfield flags [ARRAY_SIZE (cpu_flags)];
728 /* Copy the default cpu flags. */
729 memcpy (flags, cpu_flags, sizeof (cpu_flags));
731 if (strcasecmp (flag, "unknown") == 0)
733 /* We turn on everything except for cpu64 in case of
734 CPU_UNKNOWN_FLAGS. */
735 for (i = 0; i < ARRAY_SIZE (flags); i++)
736 if (flags[i].position != Cpu64)
739 else if (flag[0] == '~')
741 last = flag + strlen (flag);
748 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
755 /* First we turn on everything except for cpu64. */
756 for (i = 0; i < ARRAY_SIZE (flags); i++)
757 if (flags[i].position != Cpu64)
760 /* Turn off selective bits. */
761 for (; next && next < last; )
763 str = next_field (next, '|', &next, last);
765 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
768 else if (strcmp (flag, "0"))
770 /* Turn on selective bits. */
771 last = flag + strlen (flag);
772 for (next = flag; next && next < last; )
774 str = next_field (next, '|', &next, last);
776 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
780 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
785 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
789 fprintf (table, " { ");
791 for (i = 0; i < size - 1; i++)
793 fprintf (table, "%d, ", modifier[i].value);
794 if (((i + 1) % 20) == 0)
795 fprintf (table, "\n ");
798 fprintf (table, "%d },\n", modifier[i].value);
802 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
804 char *str, *next, *last;
805 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
807 /* Copy the default opcode modifier. */
808 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
810 if (strcmp (mod, "0"))
812 last = mod + strlen (mod);
813 for (next = mod; next && next < last; )
815 str = next_field (next, '|', &next, last);
817 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
821 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
825 output_operand_type (FILE *table, bitfield *types, unsigned int size,
826 int macro, const char *indent)
830 fprintf (table, "{ { ");
832 for (i = 0; i < size - 1; i++)
834 fprintf (table, "%d, ", types[i].value);
835 if (((i + 1) % 20) == 0)
837 /* We need \\ for macro. */
839 fprintf (table, "\\\n%s", indent);
841 fprintf (table, "\n%s", indent);
845 fprintf (table, "%d } }", types[i].value);
849 process_i386_operand_type (FILE *table, char *op, int macro,
850 const char *indent, int lineno)
852 char *str, *next, *last;
853 bitfield types [ARRAY_SIZE (operand_types)];
855 /* Copy the default operand type. */
856 memcpy (types, operand_types, sizeof (types));
858 if (strcmp (op, "0"))
860 last = op + strlen (op);
861 for (next = op; next && next < last; )
863 str = next_field (next, '|', &next, last);
865 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
868 output_operand_type (table, types, ARRAY_SIZE (types), macro,
873 output_i386_opcode (FILE *table, const char *name, char *str,
874 char *last, int lineno)
877 char *operands, *base_opcode, *extension_opcode, *opcode_length;
878 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
880 /* Find number of operands. */
881 operands = next_field (str, ',', &str, last);
883 /* Find base_opcode. */
884 base_opcode = next_field (str, ',', &str, last);
886 /* Find extension_opcode. */
887 extension_opcode = next_field (str, ',', &str, last);
889 /* Find opcode_length. */
890 opcode_length = next_field (str, ',', &str, last);
892 /* Find cpu_flags. */
893 cpu_flags = next_field (str, ',', &str, last);
895 /* Find opcode_modifier. */
896 opcode_modifier = next_field (str, ',', &str, last);
898 /* Remove the first {. */
899 str = remove_leading_whitespaces (str);
902 str = remove_leading_whitespaces (str + 1);
906 /* There are at least "X}". */
910 /* Remove trailing white spaces and }. */
914 if (ISSPACE (str[i]) || str[i] == '}')
923 /* Find operand_types. */
924 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
928 operand_types [i] = NULL;
932 operand_types [i] = next_field (str, ',', &str, last);
933 if (*operand_types[i] == '0')
936 operand_types[i] = NULL;
941 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
942 name, operands, base_opcode, extension_opcode,
945 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
947 process_i386_opcode_modifier (table, opcode_modifier, lineno);
949 fprintf (table, " { ");
951 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
953 if (operand_types[i] == NULL || *operand_types[i] == '0')
956 process_i386_operand_type (table, "0", 0, "\t ", lineno);
961 fprintf (table, ",\n ");
963 process_i386_operand_type (table, operand_types[i], 0,
966 fprintf (table, " } },\n");
969 struct opcode_hash_entry
971 struct opcode_hash_entry *next;
977 /* Calculate the hash value of an opcode hash entry P. */
980 opcode_hash_hash (const void *p)
982 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
983 return htab_hash_string (entry->name);
986 /* Compare a string Q against an opcode hash entry P. */
989 opcode_hash_eq (const void *p, const void *q)
991 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
992 const char *name = (const char *) q;
993 return strcmp (name, entry->name) == 0;
997 process_i386_opcodes (FILE *table)
1002 char *str, *p, *last, *name;
1003 struct opcode_hash_entry **hash_slot, **entry, *next;
1004 htab_t opcode_hash_table;
1005 struct opcode_hash_entry **opcode_array;
1006 unsigned int opcode_array_size = 1024;
1009 filename = "i386-opc.tbl";
1010 fp = fopen (filename, "r");
1013 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1017 opcode_array = (struct opcode_hash_entry **)
1018 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1020 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1021 opcode_hash_eq, NULL,
1024 fprintf (table, "\n/* i386 opcode table. */\n\n");
1025 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1027 /* Put everything on opcode array. */
1030 if (fgets (buf, sizeof (buf), fp) == NULL)
1035 p = remove_leading_whitespaces (buf);
1037 /* Skip comments. */
1038 str = strstr (p, "//");
1042 /* Remove trailing white spaces. */
1043 remove_trailing_whitespaces (p);
1048 /* Ignore comments. */
1056 last = p + strlen (p);
1059 name = next_field (p, ',', &str, last);
1061 /* Get the slot in hash table. */
1062 hash_slot = (struct opcode_hash_entry **)
1063 htab_find_slot_with_hash (opcode_hash_table, name,
1064 htab_hash_string (name),
1067 if (*hash_slot == NULL)
1069 /* It is the new one. Put it on opcode array. */
1070 if (i >= opcode_array_size)
1072 /* Grow the opcode array when needed. */
1073 opcode_array_size += 1024;
1074 opcode_array = (struct opcode_hash_entry **)
1075 xrealloc (opcode_array,
1076 sizeof (*opcode_array) * opcode_array_size);
1079 opcode_array[i] = (struct opcode_hash_entry *)
1080 xmalloc (sizeof (struct opcode_hash_entry));
1081 opcode_array[i]->next = NULL;
1082 opcode_array[i]->name = xstrdup (name);
1083 opcode_array[i]->opcode = xstrdup (str);
1084 opcode_array[i]->lineno = lineno;
1085 *hash_slot = opcode_array[i];
1090 /* Append it to the existing one. */
1092 while ((*entry) != NULL)
1093 entry = &(*entry)->next;
1094 *entry = (struct opcode_hash_entry *)
1095 xmalloc (sizeof (struct opcode_hash_entry));
1096 (*entry)->next = NULL;
1097 (*entry)->name = (*hash_slot)->name;
1098 (*entry)->opcode = xstrdup (str);
1099 (*entry)->lineno = lineno;
1103 /* Process opcode array. */
1104 for (j = 0; j < i; j++)
1106 for (next = opcode_array[j]; next; next = next->next)
1110 lineno = next->lineno;
1111 last = str + strlen (str);
1112 output_i386_opcode (table, name, str, last, lineno);
1118 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1120 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1122 process_i386_opcode_modifier (table, "0", -1);
1124 fprintf (table, " { ");
1125 process_i386_operand_type (table, "0", 0, "\t ", -1);
1126 fprintf (table, " } }\n");
1128 fprintf (table, "};\n");
1132 process_i386_registers (FILE *table)
1136 char *str, *p, *last;
1137 char *reg_name, *reg_type, *reg_flags, *reg_num;
1138 char *dw2_32_num, *dw2_64_num;
1141 filename = "i386-reg.tbl";
1142 fp = fopen (filename, "r");
1144 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1147 fprintf (table, "\n/* i386 register table. */\n\n");
1148 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1152 if (fgets (buf, sizeof (buf), fp) == NULL)
1157 p = remove_leading_whitespaces (buf);
1159 /* Skip comments. */
1160 str = strstr (p, "//");
1164 /* Remove trailing white spaces. */
1165 remove_trailing_whitespaces (p);
1170 fprintf (table, "%s\n", p);
1178 last = p + strlen (p);
1180 /* Find reg_name. */
1181 reg_name = next_field (p, ',', &str, last);
1183 /* Find reg_type. */
1184 reg_type = next_field (str, ',', &str, last);
1186 /* Find reg_flags. */
1187 reg_flags = next_field (str, ',', &str, last);
1190 reg_num = next_field (str, ',', &str, last);
1192 fprintf (table, " { \"%s\",\n ", reg_name);
1194 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1196 /* Find 32-bit Dwarf2 register number. */
1197 dw2_32_num = next_field (str, ',', &str, last);
1199 /* Find 64-bit Dwarf2 register number. */
1200 dw2_64_num = next_field (str, ',', &str, last);
1202 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1203 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1208 fprintf (table, "};\n");
1210 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1214 process_i386_initializers (void)
1217 FILE *fp = fopen ("i386-init.h", "w");
1221 fail (_("can't create i386-init.h, errno = %s\n"),
1224 process_copyright (fp);
1226 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1228 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1229 init = xstrdup (cpu_flag_init[i].init);
1230 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1234 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1236 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1237 init = xstrdup (operand_type_init[i].init);
1238 process_i386_operand_type (fp, init, 1, " ", -1);
1246 /* Program options. */
1247 #define OPTION_SRCDIR 200
1249 struct option long_options[] =
1251 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1252 {"debug", no_argument, NULL, 'd'},
1253 {"version", no_argument, NULL, 'V'},
1254 {"help", no_argument, NULL, 'h'},
1255 {0, no_argument, NULL, 0}
1259 print_version (void)
1261 printf ("%s: version 1.0\n", program_name);
1266 usage (FILE * stream, int status)
1268 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1274 main (int argc, char **argv)
1276 extern int chdir (char *);
1277 char *srcdir = NULL;
1281 program_name = *argv;
1282 xmalloc_set_program_name (program_name);
1284 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1309 if (chdir (srcdir) != 0)
1310 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1311 srcdir, xstrerror (errno));
1313 /* Check the unused bitfield in i386_cpu_flags. */
1315 c = CpuNumOfBits - CpuMax - 1;
1317 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1320 /* Check the unused bitfield in i386_operand_type. */
1322 c = OTNumOfBits - OTMax - 1;
1324 fail (_("%d unused bits in i386_operand_type.\n"), c);
1327 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1330 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1331 sizeof (opcode_modifiers [0]), compare);
1333 qsort (operand_types, ARRAY_SIZE (operand_types),
1334 sizeof (operand_types [0]), compare);
1336 table = fopen ("i386-tbl.h", "w");
1338 fail (_("can't create i386-tbl.h, errno = %s\n"),
1341 process_copyright (table);
1343 process_i386_opcodes (table);
1344 process_i386_registers (table);
1345 process_i386_initializers ();