1 /* Copyright 2007, 2008, 2009
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",
47 { "CPU_GENERIC32_FLAGS",
48 "Cpu186|Cpu286|Cpu386" },
49 { "CPU_GENERIC64_FLAGS",
50 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|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" },
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX" },
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX|CpuSSE" },
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuMMX|CpuSSE|CpuSSE2" },
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA" },
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
87 { "CPU_AMDFAM10_FLAGS",
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
96 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
97 { "CPU_CLFLUSH_FLAGS",
99 { "CPU_SYSCALL_FLAGS",
106 "CpuMMX|CpuSSE|CpuSSE2" },
108 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
110 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
111 { "CPU_SSE4_1_FLAGS",
112 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
113 { "CPU_SSE4_2_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
115 { "CPU_ANY_SSE_FLAGS",
116 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX" },
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
125 { "CPU_PCLMUL_FLAGS",
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
130 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
132 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
137 { "CPU_RDTSCP_FLAGS",
143 { "CPU_3DNOWA_FLAGS",
144 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
145 { "CPU_PADLOCK_FLAGS",
150 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
154 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
155 { "CPU_ANY_AVX_FLAGS",
161 static initializer operand_type_init[] =
163 { "OPERAND_TYPE_NONE",
165 { "OPERAND_TYPE_REG8",
167 { "OPERAND_TYPE_REG16",
169 { "OPERAND_TYPE_REG32",
171 { "OPERAND_TYPE_REG64",
173 { "OPERAND_TYPE_IMM1",
175 { "OPERAND_TYPE_IMM8",
177 { "OPERAND_TYPE_IMM8S",
179 { "OPERAND_TYPE_IMM16",
181 { "OPERAND_TYPE_IMM32",
183 { "OPERAND_TYPE_IMM32S",
185 { "OPERAND_TYPE_IMM64",
187 { "OPERAND_TYPE_BASEINDEX",
189 { "OPERAND_TYPE_DISP8",
191 { "OPERAND_TYPE_DISP16",
193 { "OPERAND_TYPE_DISP32",
195 { "OPERAND_TYPE_DISP32S",
197 { "OPERAND_TYPE_DISP64",
199 { "OPERAND_TYPE_INOUTPORTREG",
201 { "OPERAND_TYPE_SHIFTCOUNT",
203 { "OPERAND_TYPE_CONTROL",
205 { "OPERAND_TYPE_TEST",
207 { "OPERAND_TYPE_DEBUG",
209 { "OPERAND_TYPE_FLOATREG",
211 { "OPERAND_TYPE_FLOATACC",
213 { "OPERAND_TYPE_SREG2",
215 { "OPERAND_TYPE_SREG3",
217 { "OPERAND_TYPE_ACC",
219 { "OPERAND_TYPE_JUMPABSOLUTE",
221 { "OPERAND_TYPE_REGMMX",
223 { "OPERAND_TYPE_REGXMM",
225 { "OPERAND_TYPE_REGYMM",
227 { "OPERAND_TYPE_ESSEG",
229 { "OPERAND_TYPE_ACC32",
231 { "OPERAND_TYPE_ACC64",
233 { "OPERAND_TYPE_INOUTPORTREG",
235 { "OPERAND_TYPE_REG16_INOUTPORTREG",
236 "Reg16|InOutPortReg" },
237 { "OPERAND_TYPE_DISP16_32",
239 { "OPERAND_TYPE_ANYDISP",
240 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
241 { "OPERAND_TYPE_IMM16_32",
243 { "OPERAND_TYPE_IMM16_32S",
245 { "OPERAND_TYPE_IMM16_32_32S",
246 "Imm16|Imm32|Imm32S" },
247 { "OPERAND_TYPE_IMM32_32S_DISP32",
248 "Imm32|Imm32S|Disp32" },
249 { "OPERAND_TYPE_IMM64_DISP64",
251 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
252 "Imm32|Imm32S|Imm64|Disp32" },
253 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
254 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
257 typedef struct bitfield
264 #define BITFIELD(n) { n, 0, #n }
266 static bitfield cpu_flags[] =
274 BITFIELD (CpuClflush),
275 BITFIELD (CpuSYSCALL),
280 BITFIELD (CpuFISTTP),
286 BITFIELD (CpuSSE4_1),
287 BITFIELD (CpuSSE4_2),
292 BITFIELD (Cpu3dnowA),
293 BITFIELD (CpuPadLock),
300 BITFIELD (CpuPCLMUL),
308 BITFIELD (CpuRdtscp),
312 BITFIELD (CpuUnused),
316 static bitfield opcode_modifiers[] =
322 BITFIELD (ShortForm),
324 BITFIELD (JumpDword),
326 BITFIELD (JumpInterSegment),
333 BITFIELD (IgnoreSize),
334 BITFIELD (DefaultSize),
343 BITFIELD (IsLockable),
344 BITFIELD (RegKludge),
345 BITFIELD (FirstXmm0),
346 BITFIELD (Implicit1stXmm0),
347 BITFIELD (ByteOkIntel),
350 BITFIELD (AddrPrefixOp0),
367 BITFIELD (Vex3Sources),
368 BITFIELD (Vex2Sources),
369 BITFIELD (VexImmExt),
373 BITFIELD (ATTMnemonic),
374 BITFIELD (ATTSyntax),
375 BITFIELD (IntelSyntax),
378 static bitfield operand_types[] =
395 BITFIELD (BaseIndex),
401 BITFIELD (InOutPortReg),
402 BITFIELD (ShiftCount),
410 BITFIELD (JumpAbsolute),
422 BITFIELD (Unspecified),
429 static const char *filename;
432 compare (const void *x, const void *y)
434 const bitfield *xp = (const bitfield *) x;
435 const bitfield *yp = (const bitfield *) y;
436 return xp->position - yp->position;
440 fail (const char *message, ...)
444 va_start (args, message);
445 fprintf (stderr, _("%s: Error: "), program_name);
446 vfprintf (stderr, message, args);
452 process_copyright (FILE *fp)
454 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
455 /* Copyright 2007, 2008, 2009\n\
456 Free Software Foundation, Inc.\n\
458 This file is part of the GNU opcodes library.\n\
460 This library is free software; you can redistribute it and/or modify\n\
461 it under the terms of the GNU General Public License as published by\n\
462 the Free Software Foundation; either version 3, or (at your option)\n\
463 any later version.\n\
465 It is distributed in the hope that it will be useful, but WITHOUT\n\
466 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
467 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
468 License for more details.\n\
470 You should have received a copy of the GNU General Public License\n\
471 along with this program; if not, write to the Free Software\n\
472 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
473 MA 02110-1301, USA. */\n");
476 /* Remove leading white spaces. */
479 remove_leading_whitespaces (char *str)
481 while (ISSPACE (*str))
486 /* Remove trailing white spaces. */
489 remove_trailing_whitespaces (char *str)
491 size_t last = strlen (str);
499 if (ISSPACE (str [last]))
507 /* Find next field separated by SEP and terminate it. Return a
508 pointer to the one after it. */
511 next_field (char *str, char sep, char **next, char *last)
515 p = remove_leading_whitespaces (str);
516 for (str = p; *str != sep && *str != '\0'; str++);
519 remove_trailing_whitespaces (p);
530 set_bitfield (const char *f, bitfield *array, int value,
531 unsigned int size, int lineno)
535 if (strcmp (f, "CpuFP") == 0)
537 set_bitfield("Cpu387", array, value, size, lineno);
538 set_bitfield("Cpu287", array, value, size, lineno);
541 else if (strcmp (f, "Mmword") == 0)
543 else if (strcmp (f, "Oword") == 0)
546 for (i = 0; i < size; i++)
547 if (strcasecmp (array[i].name, f) == 0)
549 array[i].value = value;
555 const char *v = strchr (f, '=');
562 for (i = 0; i < size; i++)
563 if (strncasecmp (array[i].name, f, n) == 0)
565 value = strtol (v + 1, &end, 0);
568 array[i].value = value;
577 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
579 fail (_("Unknown bitfield: %s\n"), f);
583 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
584 int macro, const char *comma, const char *indent)
588 fprintf (table, "%s{ { ", indent);
590 for (i = 0; i < size - 1; i++)
592 fprintf (table, "%d, ", flags[i].value);
593 if (((i + 1) % 20) == 0)
595 /* We need \\ for macro. */
597 fprintf (table, " \\\n %s", indent);
599 fprintf (table, "\n %s", indent);
603 fprintf (table, "%d } }%s\n", flags[i].value, comma);
607 process_i386_cpu_flag (FILE *table, char *flag, int macro,
608 const char *comma, const char *indent,
611 char *str, *next, *last;
613 bitfield flags [ARRAY_SIZE (cpu_flags)];
615 /* Copy the default cpu flags. */
616 memcpy (flags, cpu_flags, sizeof (cpu_flags));
618 if (strcasecmp (flag, "unknown") == 0)
620 /* We turn on everything except for cpu64 in case of
621 CPU_UNKNOWN_FLAGS. */
622 for (i = 0; i < ARRAY_SIZE (flags); i++)
623 if (flags[i].position != Cpu64)
626 else if (flag[0] == '~')
628 last = flag + strlen (flag);
635 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
642 /* First we turn on everything except for cpu64. */
643 for (i = 0; i < ARRAY_SIZE (flags); i++)
644 if (flags[i].position != Cpu64)
647 /* Turn off selective bits. */
648 for (; next && next < last; )
650 str = next_field (next, '|', &next, last);
652 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
655 else if (strcmp (flag, "0"))
657 /* Turn on selective bits. */
658 last = flag + strlen (flag);
659 for (next = flag; next && next < last; )
661 str = next_field (next, '|', &next, last);
663 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
667 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
672 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
676 fprintf (table, " { ");
678 for (i = 0; i < size - 1; i++)
680 fprintf (table, "%d, ", modifier[i].value);
681 if (((i + 1) % 20) == 0)
682 fprintf (table, "\n ");
685 fprintf (table, "%d },\n", modifier[i].value);
689 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
691 char *str, *next, *last;
692 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
694 /* Copy the default opcode modifier. */
695 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
697 if (strcmp (mod, "0"))
699 last = mod + strlen (mod);
700 for (next = mod; next && next < last; )
702 str = next_field (next, '|', &next, last);
704 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
708 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
712 output_operand_type (FILE *table, bitfield *types, unsigned int size,
713 int macro, const char *indent)
717 fprintf (table, "{ { ");
719 for (i = 0; i < size - 1; i++)
721 fprintf (table, "%d, ", types[i].value);
722 if (((i + 1) % 20) == 0)
724 /* We need \\ for macro. */
726 fprintf (table, "\\\n%s", indent);
728 fprintf (table, "\n%s", indent);
732 fprintf (table, "%d } }", types[i].value);
736 process_i386_operand_type (FILE *table, char *op, int macro,
737 const char *indent, int lineno)
739 char *str, *next, *last;
740 bitfield types [ARRAY_SIZE (operand_types)];
742 /* Copy the default operand type. */
743 memcpy (types, operand_types, sizeof (types));
745 if (strcmp (op, "0"))
747 last = op + strlen (op);
748 for (next = op; next && next < last; )
750 str = next_field (next, '|', &next, last);
752 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
755 output_operand_type (table, types, ARRAY_SIZE (types), macro,
760 output_i386_opcode (FILE *table, const char *name, char *str,
761 char *last, int lineno)
764 char *operands, *base_opcode, *extension_opcode, *opcode_length;
765 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
767 /* Find number of operands. */
768 operands = next_field (str, ',', &str, last);
770 /* Find base_opcode. */
771 base_opcode = next_field (str, ',', &str, last);
773 /* Find extension_opcode. */
774 extension_opcode = next_field (str, ',', &str, last);
776 /* Find opcode_length. */
777 opcode_length = next_field (str, ',', &str, last);
779 /* Find cpu_flags. */
780 cpu_flags = next_field (str, ',', &str, last);
782 /* Find opcode_modifier. */
783 opcode_modifier = next_field (str, ',', &str, last);
785 /* Remove the first {. */
786 str = remove_leading_whitespaces (str);
789 str = remove_leading_whitespaces (str + 1);
793 /* There are at least "X}". */
797 /* Remove trailing white spaces and }. */
801 if (ISSPACE (str[i]) || str[i] == '}')
810 /* Find operand_types. */
811 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
815 operand_types [i] = NULL;
819 operand_types [i] = next_field (str, ',', &str, last);
820 if (*operand_types[i] == '0')
823 operand_types[i] = NULL;
828 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
829 name, operands, base_opcode, extension_opcode,
832 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
834 process_i386_opcode_modifier (table, opcode_modifier, lineno);
836 fprintf (table, " { ");
838 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
840 if (operand_types[i] == NULL || *operand_types[i] == '0')
843 process_i386_operand_type (table, "0", 0, "\t ", lineno);
848 fprintf (table, ",\n ");
850 process_i386_operand_type (table, operand_types[i], 0,
853 fprintf (table, " } },\n");
856 struct opcode_hash_entry
858 struct opcode_hash_entry *next;
864 /* Calculate the hash value of an opcode hash entry P. */
867 opcode_hash_hash (const void *p)
869 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
870 return htab_hash_string (entry->name);
873 /* Compare a string Q against an opcode hash entry P. */
876 opcode_hash_eq (const void *p, const void *q)
878 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
879 const char *name = (const char *) q;
880 return strcmp (name, entry->name) == 0;
884 process_i386_opcodes (FILE *table)
889 char *str, *p, *last, *name;
890 struct opcode_hash_entry **hash_slot, **entry, *next;
891 htab_t opcode_hash_table;
892 struct opcode_hash_entry **opcode_array;
893 unsigned int opcode_array_size = 1024;
896 filename = "i386-opc.tbl";
897 fp = fopen (filename, "r");
900 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
904 opcode_array = (struct opcode_hash_entry **)
905 xmalloc (sizeof (*opcode_array) * opcode_array_size);
907 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
908 opcode_hash_eq, NULL,
911 fprintf (table, "\n/* i386 opcode table. */\n\n");
912 fprintf (table, "const insn_template i386_optab[] =\n{\n");
914 /* Put everything on opcode array. */
917 if (fgets (buf, sizeof (buf), fp) == NULL)
922 p = remove_leading_whitespaces (buf);
925 str = strstr (p, "//");
929 /* Remove trailing white spaces. */
930 remove_trailing_whitespaces (p);
935 /* Ignore comments. */
943 last = p + strlen (p);
946 name = next_field (p, ',', &str, last);
948 /* Get the slot in hash table. */
949 hash_slot = (struct opcode_hash_entry **)
950 htab_find_slot_with_hash (opcode_hash_table, name,
951 htab_hash_string (name),
954 if (*hash_slot == NULL)
956 /* It is the new one. Put it on opcode array. */
957 if (i >= opcode_array_size)
959 /* Grow the opcode array when needed. */
960 opcode_array_size += 1024;
961 opcode_array = (struct opcode_hash_entry **)
962 xrealloc (opcode_array,
963 sizeof (*opcode_array) * opcode_array_size);
966 opcode_array[i] = (struct opcode_hash_entry *)
967 xmalloc (sizeof (struct opcode_hash_entry));
968 opcode_array[i]->next = NULL;
969 opcode_array[i]->name = xstrdup (name);
970 opcode_array[i]->opcode = xstrdup (str);
971 opcode_array[i]->lineno = lineno;
972 *hash_slot = opcode_array[i];
977 /* Append it to the existing one. */
979 while ((*entry) != NULL)
980 entry = &(*entry)->next;
981 *entry = (struct opcode_hash_entry *)
982 xmalloc (sizeof (struct opcode_hash_entry));
983 (*entry)->next = NULL;
984 (*entry)->name = (*hash_slot)->name;
985 (*entry)->opcode = xstrdup (str);
986 (*entry)->lineno = lineno;
990 /* Process opcode array. */
991 for (j = 0; j < i; j++)
993 for (next = opcode_array[j]; next; next = next->next)
997 lineno = next->lineno;
998 last = str + strlen (str);
999 output_i386_opcode (table, name, str, last, lineno);
1005 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1007 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1009 process_i386_opcode_modifier (table, "0", -1);
1011 fprintf (table, " { ");
1012 process_i386_operand_type (table, "0", 0, "\t ", -1);
1013 fprintf (table, " } }\n");
1015 fprintf (table, "};\n");
1019 process_i386_registers (FILE *table)
1023 char *str, *p, *last;
1024 char *reg_name, *reg_type, *reg_flags, *reg_num;
1025 char *dw2_32_num, *dw2_64_num;
1028 filename = "i386-reg.tbl";
1029 fp = fopen (filename, "r");
1031 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1034 fprintf (table, "\n/* i386 register table. */\n\n");
1035 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1039 if (fgets (buf, sizeof (buf), fp) == NULL)
1044 p = remove_leading_whitespaces (buf);
1046 /* Skip comments. */
1047 str = strstr (p, "//");
1051 /* Remove trailing white spaces. */
1052 remove_trailing_whitespaces (p);
1057 fprintf (table, "%s\n", p);
1065 last = p + strlen (p);
1067 /* Find reg_name. */
1068 reg_name = next_field (p, ',', &str, last);
1070 /* Find reg_type. */
1071 reg_type = next_field (str, ',', &str, last);
1073 /* Find reg_flags. */
1074 reg_flags = next_field (str, ',', &str, last);
1077 reg_num = next_field (str, ',', &str, last);
1079 fprintf (table, " { \"%s\",\n ", reg_name);
1081 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1083 /* Find 32-bit Dwarf2 register number. */
1084 dw2_32_num = next_field (str, ',', &str, last);
1086 /* Find 64-bit Dwarf2 register number. */
1087 dw2_64_num = next_field (str, ',', &str, last);
1089 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1090 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1095 fprintf (table, "};\n");
1097 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1101 process_i386_initializers (void)
1104 FILE *fp = fopen ("i386-init.h", "w");
1108 fail (_("can't create i386-init.h, errno = %s\n"),
1111 process_copyright (fp);
1113 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1115 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1116 init = xstrdup (cpu_flag_init[i].init);
1117 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1121 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1123 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1124 init = xstrdup (operand_type_init[i].init);
1125 process_i386_operand_type (fp, init, 1, " ", -1);
1133 /* Program options. */
1134 #define OPTION_SRCDIR 200
1136 struct option long_options[] =
1138 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1139 {"debug", no_argument, NULL, 'd'},
1140 {"version", no_argument, NULL, 'V'},
1141 {"help", no_argument, NULL, 'h'},
1142 {0, no_argument, NULL, 0}
1146 print_version (void)
1148 printf ("%s: version 1.0\n", program_name);
1153 usage (FILE * stream, int status)
1155 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1161 main (int argc, char **argv)
1163 extern int chdir (char *);
1164 char *srcdir = NULL;
1168 program_name = *argv;
1169 xmalloc_set_program_name (program_name);
1171 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1196 if (chdir (srcdir) != 0)
1197 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1198 srcdir, xstrerror (errno));
1200 /* Check the unused bitfield in i386_cpu_flags. */
1202 c = CpuNumOfBits - CpuMax - 1;
1204 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1207 /* Check the unused bitfield in i386_operand_type. */
1209 c = OTNumOfBits - OTMax - 1;
1211 fail (_("%d unused bits in i386_operand_type.\n"), c);
1214 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1217 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1218 sizeof (opcode_modifiers [0]), compare);
1220 qsort (operand_types, ARRAY_SIZE (operand_types),
1221 sizeof (operand_types [0]), compare);
1223 table = fopen ("i386-tbl.h", "w");
1225 fail (_("can't create i386-tbl.h, errno = %s\n"),
1228 process_copyright (table);
1230 process_i386_opcodes (table);
1231 process_i386_registers (table);
1232 process_i386_initializers ();