1 /* Copyright 2007, 2008 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"
25 #include "safe-ctype.h"
30 #define _(String) gettext (String)
32 static const char *program_name = NULL;
35 typedef struct initializer
41 static initializer cpu_flag_init [] =
43 { "CPU_UNKNOWN_FLAGS",
45 { "CPU_GENERIC32_FLAGS",
46 "Cpu186|Cpu286|Cpu386" },
47 { "CPU_GENERIC64_FLAGS",
48 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
56 "Cpu186|Cpu286|Cpu386" },
58 "Cpu186|Cpu286|Cpu386|Cpu486" },
60 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
62 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686" },
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX" },
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE" },
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2" },
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX|Cpu3dnow" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuMMX|Cpu3dnow|Cpu3dnowA" },
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
83 { "CPU_AMDFAM10_FLAGS",
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
90 "CpuMMX|CpuSSE|CpuSSE2" },
92 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
94 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
96 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
98 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
107 { "CPU_3DNOWA_FLAGS",
108 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
109 { "CPU_PADLOCK_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
118 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
121 static initializer operand_type_init [] =
123 { "OPERAND_TYPE_NONE",
125 { "OPERAND_TYPE_REG8",
127 { "OPERAND_TYPE_REG16",
129 { "OPERAND_TYPE_REG32",
131 { "OPERAND_TYPE_REG64",
133 { "OPERAND_TYPE_IMM1",
135 { "OPERAND_TYPE_IMM8",
137 { "OPERAND_TYPE_IMM8S",
139 { "OPERAND_TYPE_IMM16",
141 { "OPERAND_TYPE_IMM32",
143 { "OPERAND_TYPE_IMM32S",
145 { "OPERAND_TYPE_IMM64",
147 { "OPERAND_TYPE_BASEINDEX",
149 { "OPERAND_TYPE_DISP8",
151 { "OPERAND_TYPE_DISP16",
153 { "OPERAND_TYPE_DISP32",
155 { "OPERAND_TYPE_DISP32S",
157 { "OPERAND_TYPE_DISP64",
159 { "OPERAND_TYPE_INOUTPORTREG",
161 { "OPERAND_TYPE_SHIFTCOUNT",
163 { "OPERAND_TYPE_CONTROL",
165 { "OPERAND_TYPE_TEST",
167 { "OPERAND_TYPE_DEBUG",
169 { "OPERAND_TYPE_FLOATREG",
171 { "OPERAND_TYPE_FLOATACC",
173 { "OPERAND_TYPE_SREG2",
175 { "OPERAND_TYPE_SREG3",
177 { "OPERAND_TYPE_ACC",
179 { "OPERAND_TYPE_JUMPABSOLUTE",
181 { "OPERAND_TYPE_REGMMX",
183 { "OPERAND_TYPE_REGXMM",
185 { "OPERAND_TYPE_ESSEG",
187 { "OPERAND_TYPE_ACC32",
189 { "OPERAND_TYPE_ACC64",
191 { "OPERAND_TYPE_REG16_INOUTPORTREG",
192 "Reg16|InOutPortReg" },
193 { "OPERAND_TYPE_DISP16_32",
195 { "OPERAND_TYPE_ANYDISP",
196 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
197 { "OPERAND_TYPE_IMM16_32",
199 { "OPERAND_TYPE_IMM16_32S",
201 { "OPERAND_TYPE_IMM16_32_32S",
202 "Imm16|Imm32|Imm32S" },
203 { "OPERAND_TYPE_IMM32_32S_DISP32",
204 "Imm32|Imm32S|Disp32" },
205 { "OPERAND_TYPE_IMM64_DISP64",
207 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
208 "Imm32|Imm32S|Imm64|Disp32" },
209 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
210 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
213 typedef struct bitfield
220 #define BITFIELD(n) { n, 0, #n }
222 static bitfield cpu_flags[] =
238 BITFIELD (CpuSSE4_1),
239 BITFIELD (CpuSSE4_2),
243 BITFIELD (Cpu3dnowA),
244 BITFIELD (CpuPadLock),
254 BITFIELD (CpuUnused),
258 static bitfield opcode_modifiers[] =
263 BITFIELD (ShortForm),
265 BITFIELD (JumpDword),
267 BITFIELD (JumpInterSegment),
274 BITFIELD (IgnoreSize),
275 BITFIELD (DefaultSize),
284 BITFIELD (RegKludge),
285 BITFIELD (FirstXmm0),
286 BITFIELD (ByteOkIntel),
289 BITFIELD (AddrPrefixOp0),
299 BITFIELD (ATTMnemonic),
300 BITFIELD (ATTSyntax),
301 BITFIELD (IntelSyntax),
304 static bitfield operand_types[] =
320 BITFIELD (BaseIndex),
326 BITFIELD (InOutPortReg),
327 BITFIELD (ShiftCount),
335 BITFIELD (JumpAbsolute),
346 BITFIELD (Unspecified),
354 static const char *filename;
357 compare (const void *x, const void *y)
359 const bitfield *xp = (const bitfield *) x;
360 const bitfield *yp = (const bitfield *) y;
361 return xp->position - yp->position;
365 fail (const char *message, ...)
369 va_start (args, message);
370 fprintf (stderr, _("%s: Error: "), program_name);
371 vfprintf (stderr, message, args);
377 process_copyright (FILE *fp)
379 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
380 /* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
382 This file is part of the GNU opcodes library.\n\
384 This library is free software; you can redistribute it and/or modify\n\
385 it under the terms of the GNU General Public License as published by\n\
386 the Free Software Foundation; either version 3, or (at your option)\n\
387 any later version.\n\
389 It is distributed in the hope that it will be useful, but WITHOUT\n\
390 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
391 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
392 License for more details.\n\
394 You should have received a copy of the GNU General Public License\n\
395 along with this program; if not, write to the Free Software\n\
396 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
397 MA 02110-1301, USA. */\n");
400 /* Remove leading white spaces. */
403 remove_leading_whitespaces (char *str)
405 while (ISSPACE (*str))
410 /* Remove trailing white spaces. */
413 remove_trailing_whitespaces (char *str)
415 size_t last = strlen (str);
423 if (ISSPACE (str [last]))
431 /* Find next field separated by SEP and terminate it. Return a
432 pointer to the one after it. */
435 next_field (char *str, char sep, char **next)
439 p = remove_leading_whitespaces (str);
440 for (str = p; *str != sep && *str != '\0'; str++);
443 remove_trailing_whitespaces (p);
451 set_bitfield (const char *f, bitfield *array, unsigned int size)
455 if (strcmp (f, "CpuSledgehammer") == 0)
457 else if (strcmp (f, "Mmword") == 0)
459 else if (strcmp (f, "Oword") == 0)
462 for (i = 0; i < size; i++)
463 if (strcasecmp (array[i].name, f) == 0)
469 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
473 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
474 int macro, const char *comma, const char *indent)
478 fprintf (table, "%s{ { ", indent);
480 for (i = 0; i < size - 1; i++)
482 fprintf (table, "%d, ", flags[i].value);
483 if (((i + 1) % 20) == 0)
485 /* We need \\ for macro. */
487 fprintf (table, " \\\n %s", indent);
489 fprintf (table, "\n %s", indent);
493 fprintf (table, "%d } }%s\n", flags[i].value, comma);
497 process_i386_cpu_flag (FILE *table, char *flag, int macro,
498 const char *comma, const char *indent)
500 char *str, *next, *last;
501 bitfield flags [ARRAY_SIZE (cpu_flags)];
503 /* Copy the default cpu flags. */
504 memcpy (flags, cpu_flags, sizeof (cpu_flags));
506 if (strcasecmp (flag, "unknown") == 0)
510 /* We turn on everything except for cpu64 in case of
511 CPU_UNKNOWN_FLAGS. */
512 for (i = 0; i < ARRAY_SIZE (flags); i++)
513 if (flags[i].position != Cpu64)
516 else if (strcmp (flag, "0"))
518 last = flag + strlen (flag);
519 for (next = flag; next && next < last; )
521 str = next_field (next, '|', &next);
523 set_bitfield (str, flags, ARRAY_SIZE (flags));
527 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
532 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
536 fprintf (table, " { ");
538 for (i = 0; i < size - 1; i++)
540 fprintf (table, "%d, ", modifier[i].value);
541 if (((i + 1) % 20) == 0)
542 fprintf (table, "\n ");
545 fprintf (table, "%d },\n", modifier[i].value);
549 process_i386_opcode_modifier (FILE *table, char *mod)
551 char *str, *next, *last;
552 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
554 /* Copy the default opcode modifier. */
555 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
557 if (strcmp (mod, "0"))
559 last = mod + strlen (mod);
560 for (next = mod; next && next < last; )
562 str = next_field (next, '|', &next);
564 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
567 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
571 output_operand_type (FILE *table, bitfield *types, unsigned int size,
572 int macro, const char *indent)
576 fprintf (table, "{ { ");
578 for (i = 0; i < size - 1; i++)
580 fprintf (table, "%d, ", types[i].value);
581 if (((i + 1) % 20) == 0)
583 /* We need \\ for macro. */
585 fprintf (table, "\\\n%s", indent);
587 fprintf (table, "\n%s", indent);
591 fprintf (table, "%d } }", types[i].value);
595 process_i386_operand_type (FILE *table, char *op, int macro,
598 char *str, *next, *last;
599 bitfield types [ARRAY_SIZE (operand_types)];
601 /* Copy the default operand type. */
602 memcpy (types, operand_types, sizeof (types));
604 if (strcmp (op, "0"))
606 last = op + strlen (op);
607 for (next = op; next && next < last; )
609 str = next_field (next, '|', &next);
611 set_bitfield (str, types, ARRAY_SIZE (types));
614 output_operand_type (table, types, ARRAY_SIZE (types), macro,
619 process_i386_opcodes (FILE *table)
624 char *str, *p, *last;
625 char *name, *operands, *base_opcode, *extension_opcode;
627 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
629 filename = "i386-opc.tbl";
630 fp = fopen (filename, "r");
633 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
636 fprintf (table, "\n/* i386 opcode table. */\n\n");
637 fprintf (table, "const template i386_optab[] =\n{\n");
641 if (fgets (buf, sizeof (buf), fp) == NULL)
646 p = remove_leading_whitespaces (buf);
649 str = strstr (p, "//");
653 /* Remove trailing white spaces. */
654 remove_trailing_whitespaces (p);
659 fprintf (table, "%s\n", p);
667 last = p + strlen (p);
670 name = next_field (p, ',', &str);
675 /* Find number of operands. */
676 operands = next_field (str, ',', &str);
681 /* Find base_opcode. */
682 base_opcode = next_field (str, ',', &str);
687 /* Find extension_opcode. */
688 extension_opcode = next_field (str, ',', &str);
693 /* Find opcode_length. */
694 opcode_length = next_field (str, ',', &str);
699 /* Find cpu_flags. */
700 cpu_flags = next_field (str, ',', &str);
705 /* Find opcode_modifier. */
706 opcode_modifier = next_field (str, ',', &str);
711 /* Remove the first {. */
712 str = remove_leading_whitespaces (str);
715 str = remove_leading_whitespaces (str + 1);
719 /* There are at least "X}". */
723 /* Remove trailing white spaces and }. */
727 if (ISSPACE (str[i]) || str[i] == '}')
736 /* Find operand_types. */
737 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
741 operand_types [i] = NULL;
745 operand_types [i] = next_field (str, ',', &str);
746 if (*operand_types[i] == '0')
749 operand_types[i] = NULL;
754 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
755 name, operands, base_opcode, extension_opcode,
758 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
760 process_i386_opcode_modifier (table, opcode_modifier);
762 fprintf (table, " { ");
764 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
766 if (operand_types[i] == NULL
767 || *operand_types[i] == '0')
770 process_i386_operand_type (table, "0", 0, "\t ");
775 fprintf (table, ",\n ");
777 process_i386_operand_type (table, operand_types[i], 0,
780 fprintf (table, " } },\n");
785 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
787 process_i386_cpu_flag (table, "0", 0, ",", " ");
789 process_i386_opcode_modifier (table, "0");
791 fprintf (table, " { ");
792 process_i386_operand_type (table, "0", 0, "\t ");
793 fprintf (table, " } }\n");
795 fprintf (table, "};\n");
799 process_i386_registers (FILE *table)
803 char *str, *p, *last;
804 char *reg_name, *reg_type, *reg_flags, *reg_num;
805 char *dw2_32_num, *dw2_64_num;
807 filename = "i386-reg.tbl";
808 fp = fopen (filename, "r");
810 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
813 fprintf (table, "\n/* i386 register table. */\n\n");
814 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
818 if (fgets (buf, sizeof (buf), fp) == NULL)
823 p = remove_leading_whitespaces (buf);
826 str = strstr (p, "//");
830 /* Remove trailing white spaces. */
831 remove_trailing_whitespaces (p);
836 fprintf (table, "%s\n", p);
844 last = p + strlen (p);
847 reg_name = next_field (p, ',', &str);
853 reg_type = next_field (str, ',', &str);
858 /* Find reg_flags. */
859 reg_flags = next_field (str, ',', &str);
865 reg_num = next_field (str, ',', &str);
870 fprintf (table, " { \"%s\",\n ", reg_name);
872 process_i386_operand_type (table, reg_type, 0, "\t");
874 /* Find 32-bit Dwarf2 register number. */
875 dw2_32_num = next_field (str, ',', &str);
880 /* Find 64-bit Dwarf2 register number. */
881 dw2_64_num = next_field (str, ',', &str);
883 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
884 reg_flags, reg_num, dw2_32_num, dw2_64_num);
889 fprintf (table, "};\n");
891 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
895 process_i386_initializers (void)
898 FILE *fp = fopen ("i386-init.h", "w");
902 fail (_("can't create i386-init.h, errno = %s\n"),
905 process_copyright (fp);
907 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
909 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
910 init = xstrdup (cpu_flag_init[i].init);
911 process_i386_cpu_flag (fp, init, 1, "", " ");
915 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
917 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
918 init = xstrdup (operand_type_init[i].init);
919 process_i386_operand_type (fp, init, 1, " ");
927 /* Program options. */
928 #define OPTION_SRCDIR 200
930 struct option long_options[] =
932 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
933 {"debug", no_argument, NULL, 'd'},
934 {"version", no_argument, NULL, 'V'},
935 {"help", no_argument, NULL, 'h'},
936 {0, no_argument, NULL, 0}
942 printf ("%s: version 1.0\n", program_name);
947 usage (FILE * stream, int status)
949 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
955 main (int argc, char **argv)
957 extern int chdir (char *);
962 program_name = *argv;
963 xmalloc_set_program_name (program_name);
965 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
990 if (chdir (srcdir) != 0)
991 fail (_("unable to change directory to \"%s\", errno = %s\n"),
992 srcdir, xstrerror (errno));
994 /* Check the unused bitfield in i386_cpu_flags. */
996 c = CpuNumOfBits - CpuMax - 1;
998 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1001 /* Check the unused bitfield in i386_operand_type. */
1003 c = OTNumOfBits - OTMax - 1;
1005 fail (_("%d unused bits in i386_operand_type.\n"), c);
1008 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1011 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1012 sizeof (opcode_modifiers [0]), compare);
1014 qsort (operand_types, ARRAY_SIZE (operand_types),
1015 sizeof (operand_types [0]), compare);
1017 table = fopen ("i386-tbl.h", "w");
1019 fail (_("can't create i386-tbl.h, errno = %s\n"),
1022 process_copyright (table);
1024 process_i386_opcodes (table);
1025 process_i386_registers (table);
1026 process_i386_initializers ();