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),
361 BITFIELD (VexOpcode),
362 BITFIELD (VexSources),
363 BITFIELD (VexImmExt),
367 BITFIELD (ATTMnemonic),
368 BITFIELD (ATTSyntax),
369 BITFIELD (IntelSyntax),
372 static bitfield operand_types[] =
389 BITFIELD (BaseIndex),
395 BITFIELD (InOutPortReg),
396 BITFIELD (ShiftCount),
404 BITFIELD (JumpAbsolute),
416 BITFIELD (Unspecified),
423 static const char *filename;
426 compare (const void *x, const void *y)
428 const bitfield *xp = (const bitfield *) x;
429 const bitfield *yp = (const bitfield *) y;
430 return xp->position - yp->position;
434 fail (const char *message, ...)
438 va_start (args, message);
439 fprintf (stderr, _("%s: Error: "), program_name);
440 vfprintf (stderr, message, args);
446 process_copyright (FILE *fp)
448 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
449 /* Copyright 2007, 2008, 2009\n\
450 Free Software Foundation, Inc.\n\
452 This file is part of the GNU opcodes library.\n\
454 This library is free software; you can redistribute it and/or modify\n\
455 it under the terms of the GNU General Public License as published by\n\
456 the Free Software Foundation; either version 3, or (at your option)\n\
457 any later version.\n\
459 It is distributed in the hope that it will be useful, but WITHOUT\n\
460 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
461 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
462 License for more details.\n\
464 You should have received a copy of the GNU General Public License\n\
465 along with this program; if not, write to the Free Software\n\
466 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
467 MA 02110-1301, USA. */\n");
470 /* Remove leading white spaces. */
473 remove_leading_whitespaces (char *str)
475 while (ISSPACE (*str))
480 /* Remove trailing white spaces. */
483 remove_trailing_whitespaces (char *str)
485 size_t last = strlen (str);
493 if (ISSPACE (str [last]))
501 /* Find next field separated by SEP and terminate it. Return a
502 pointer to the one after it. */
505 next_field (char *str, char sep, char **next, char *last)
509 p = remove_leading_whitespaces (str);
510 for (str = p; *str != sep && *str != '\0'; str++);
513 remove_trailing_whitespaces (p);
524 set_bitfield (const char *f, bitfield *array, int value,
525 unsigned int size, int lineno)
529 if (strcmp (f, "CpuFP") == 0)
531 set_bitfield("Cpu387", array, value, size, lineno);
532 set_bitfield("Cpu287", array, value, size, lineno);
535 else if (strcmp (f, "Mmword") == 0)
537 else if (strcmp (f, "Oword") == 0)
540 for (i = 0; i < size; i++)
541 if (strcasecmp (array[i].name, f) == 0)
543 array[i].value = value;
549 const char *v = strchr (f, '=');
556 for (i = 0; i < size; i++)
557 if (strncasecmp (array[i].name, f, n) == 0)
559 value = strtol (v + 1, &end, 0);
562 array[i].value = value;
571 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
573 fail (_("Unknown bitfield: %s\n"), f);
577 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
578 int macro, const char *comma, const char *indent)
582 fprintf (table, "%s{ { ", indent);
584 for (i = 0; i < size - 1; i++)
586 fprintf (table, "%d, ", flags[i].value);
587 if (((i + 1) % 20) == 0)
589 /* We need \\ for macro. */
591 fprintf (table, " \\\n %s", indent);
593 fprintf (table, "\n %s", indent);
597 fprintf (table, "%d } }%s\n", flags[i].value, comma);
601 process_i386_cpu_flag (FILE *table, char *flag, int macro,
602 const char *comma, const char *indent,
605 char *str, *next, *last;
607 bitfield flags [ARRAY_SIZE (cpu_flags)];
609 /* Copy the default cpu flags. */
610 memcpy (flags, cpu_flags, sizeof (cpu_flags));
612 if (strcasecmp (flag, "unknown") == 0)
614 /* We turn on everything except for cpu64 in case of
615 CPU_UNKNOWN_FLAGS. */
616 for (i = 0; i < ARRAY_SIZE (flags); i++)
617 if (flags[i].position != Cpu64)
620 else if (flag[0] == '~')
622 last = flag + strlen (flag);
629 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
636 /* First we turn on everything except for cpu64. */
637 for (i = 0; i < ARRAY_SIZE (flags); i++)
638 if (flags[i].position != Cpu64)
641 /* Turn off selective bits. */
642 for (; next && next < last; )
644 str = next_field (next, '|', &next, last);
646 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
649 else if (strcmp (flag, "0"))
651 /* Turn on selective bits. */
652 last = flag + strlen (flag);
653 for (next = flag; next && next < last; )
655 str = next_field (next, '|', &next, last);
657 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
661 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
666 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
670 fprintf (table, " { ");
672 for (i = 0; i < size - 1; i++)
674 fprintf (table, "%d, ", modifier[i].value);
675 if (((i + 1) % 20) == 0)
676 fprintf (table, "\n ");
679 fprintf (table, "%d },\n", modifier[i].value);
683 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
685 char *str, *next, *last;
686 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
688 /* Copy the default opcode modifier. */
689 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
691 if (strcmp (mod, "0"))
693 last = mod + strlen (mod);
694 for (next = mod; next && next < last; )
696 str = next_field (next, '|', &next, last);
698 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
702 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
706 output_operand_type (FILE *table, bitfield *types, unsigned int size,
707 int macro, const char *indent)
711 fprintf (table, "{ { ");
713 for (i = 0; i < size - 1; i++)
715 fprintf (table, "%d, ", types[i].value);
716 if (((i + 1) % 20) == 0)
718 /* We need \\ for macro. */
720 fprintf (table, "\\\n%s", indent);
722 fprintf (table, "\n%s", indent);
726 fprintf (table, "%d } }", types[i].value);
730 process_i386_operand_type (FILE *table, char *op, int macro,
731 const char *indent, int lineno)
733 char *str, *next, *last;
734 bitfield types [ARRAY_SIZE (operand_types)];
736 /* Copy the default operand type. */
737 memcpy (types, operand_types, sizeof (types));
739 if (strcmp (op, "0"))
741 last = op + strlen (op);
742 for (next = op; next && next < last; )
744 str = next_field (next, '|', &next, last);
746 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
749 output_operand_type (table, types, ARRAY_SIZE (types), macro,
754 output_i386_opcode (FILE *table, const char *name, char *str,
755 char *last, int lineno)
758 char *operands, *base_opcode, *extension_opcode, *opcode_length;
759 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
761 /* Find number of operands. */
762 operands = next_field (str, ',', &str, last);
764 /* Find base_opcode. */
765 base_opcode = next_field (str, ',', &str, last);
767 /* Find extension_opcode. */
768 extension_opcode = next_field (str, ',', &str, last);
770 /* Find opcode_length. */
771 opcode_length = next_field (str, ',', &str, last);
773 /* Find cpu_flags. */
774 cpu_flags = next_field (str, ',', &str, last);
776 /* Find opcode_modifier. */
777 opcode_modifier = next_field (str, ',', &str, last);
779 /* Remove the first {. */
780 str = remove_leading_whitespaces (str);
783 str = remove_leading_whitespaces (str + 1);
787 /* There are at least "X}". */
791 /* Remove trailing white spaces and }. */
795 if (ISSPACE (str[i]) || str[i] == '}')
804 /* Find operand_types. */
805 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
809 operand_types [i] = NULL;
813 operand_types [i] = next_field (str, ',', &str, last);
814 if (*operand_types[i] == '0')
817 operand_types[i] = NULL;
822 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
823 name, operands, base_opcode, extension_opcode,
826 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
828 process_i386_opcode_modifier (table, opcode_modifier, lineno);
830 fprintf (table, " { ");
832 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
834 if (operand_types[i] == NULL || *operand_types[i] == '0')
837 process_i386_operand_type (table, "0", 0, "\t ", lineno);
842 fprintf (table, ",\n ");
844 process_i386_operand_type (table, operand_types[i], 0,
847 fprintf (table, " } },\n");
850 struct opcode_hash_entry
852 struct opcode_hash_entry *next;
858 /* Calculate the hash value of an opcode hash entry P. */
861 opcode_hash_hash (const void *p)
863 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
864 return htab_hash_string (entry->name);
867 /* Compare a string Q against an opcode hash entry P. */
870 opcode_hash_eq (const void *p, const void *q)
872 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
873 const char *name = (const char *) q;
874 return strcmp (name, entry->name) == 0;
878 process_i386_opcodes (FILE *table)
883 char *str, *p, *last, *name;
884 struct opcode_hash_entry **hash_slot, **entry, *next;
885 htab_t opcode_hash_table;
886 struct opcode_hash_entry **opcode_array;
887 unsigned int opcode_array_size = 1024;
890 filename = "i386-opc.tbl";
891 fp = fopen (filename, "r");
894 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
898 opcode_array = (struct opcode_hash_entry **)
899 xmalloc (sizeof (*opcode_array) * opcode_array_size);
901 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
902 opcode_hash_eq, NULL,
905 fprintf (table, "\n/* i386 opcode table. */\n\n");
906 fprintf (table, "const insn_template i386_optab[] =\n{\n");
908 /* Put everything on opcode array. */
911 if (fgets (buf, sizeof (buf), fp) == NULL)
916 p = remove_leading_whitespaces (buf);
919 str = strstr (p, "//");
923 /* Remove trailing white spaces. */
924 remove_trailing_whitespaces (p);
929 /* Ignore comments. */
937 last = p + strlen (p);
940 name = next_field (p, ',', &str, last);
942 /* Get the slot in hash table. */
943 hash_slot = (struct opcode_hash_entry **)
944 htab_find_slot_with_hash (opcode_hash_table, name,
945 htab_hash_string (name),
948 if (*hash_slot == NULL)
950 /* It is the new one. Put it on opcode array. */
951 if (i >= opcode_array_size)
953 /* Grow the opcode array when needed. */
954 opcode_array_size += 1024;
955 opcode_array = (struct opcode_hash_entry **)
956 xrealloc (opcode_array,
957 sizeof (*opcode_array) * opcode_array_size);
960 opcode_array[i] = (struct opcode_hash_entry *)
961 xmalloc (sizeof (struct opcode_hash_entry));
962 opcode_array[i]->next = NULL;
963 opcode_array[i]->name = xstrdup (name);
964 opcode_array[i]->opcode = xstrdup (str);
965 opcode_array[i]->lineno = lineno;
966 *hash_slot = opcode_array[i];
971 /* Append it to the existing one. */
973 while ((*entry) != NULL)
974 entry = &(*entry)->next;
975 *entry = (struct opcode_hash_entry *)
976 xmalloc (sizeof (struct opcode_hash_entry));
977 (*entry)->next = NULL;
978 (*entry)->name = (*hash_slot)->name;
979 (*entry)->opcode = xstrdup (str);
980 (*entry)->lineno = lineno;
984 /* Process opcode array. */
985 for (j = 0; j < i; j++)
987 for (next = opcode_array[j]; next; next = next->next)
991 lineno = next->lineno;
992 last = str + strlen (str);
993 output_i386_opcode (table, name, str, last, lineno);
999 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1001 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1003 process_i386_opcode_modifier (table, "0", -1);
1005 fprintf (table, " { ");
1006 process_i386_operand_type (table, "0", 0, "\t ", -1);
1007 fprintf (table, " } }\n");
1009 fprintf (table, "};\n");
1013 process_i386_registers (FILE *table)
1017 char *str, *p, *last;
1018 char *reg_name, *reg_type, *reg_flags, *reg_num;
1019 char *dw2_32_num, *dw2_64_num;
1022 filename = "i386-reg.tbl";
1023 fp = fopen (filename, "r");
1025 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1028 fprintf (table, "\n/* i386 register table. */\n\n");
1029 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1033 if (fgets (buf, sizeof (buf), fp) == NULL)
1038 p = remove_leading_whitespaces (buf);
1040 /* Skip comments. */
1041 str = strstr (p, "//");
1045 /* Remove trailing white spaces. */
1046 remove_trailing_whitespaces (p);
1051 fprintf (table, "%s\n", p);
1059 last = p + strlen (p);
1061 /* Find reg_name. */
1062 reg_name = next_field (p, ',', &str, last);
1064 /* Find reg_type. */
1065 reg_type = next_field (str, ',', &str, last);
1067 /* Find reg_flags. */
1068 reg_flags = next_field (str, ',', &str, last);
1071 reg_num = next_field (str, ',', &str, last);
1073 fprintf (table, " { \"%s\",\n ", reg_name);
1075 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1077 /* Find 32-bit Dwarf2 register number. */
1078 dw2_32_num = next_field (str, ',', &str, last);
1080 /* Find 64-bit Dwarf2 register number. */
1081 dw2_64_num = next_field (str, ',', &str, last);
1083 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1084 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1089 fprintf (table, "};\n");
1091 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1095 process_i386_initializers (void)
1098 FILE *fp = fopen ("i386-init.h", "w");
1102 fail (_("can't create i386-init.h, errno = %s\n"),
1105 process_copyright (fp);
1107 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1109 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1110 init = xstrdup (cpu_flag_init[i].init);
1111 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1115 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1117 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1118 init = xstrdup (operand_type_init[i].init);
1119 process_i386_operand_type (fp, init, 1, " ", -1);
1127 /* Program options. */
1128 #define OPTION_SRCDIR 200
1130 struct option long_options[] =
1132 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1133 {"debug", no_argument, NULL, 'd'},
1134 {"version", no_argument, NULL, 'V'},
1135 {"help", no_argument, NULL, 'h'},
1136 {0, no_argument, NULL, 0}
1140 print_version (void)
1142 printf ("%s: version 1.0\n", program_name);
1147 usage (FILE * stream, int status)
1149 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1155 main (int argc, char **argv)
1157 extern int chdir (char *);
1158 char *srcdir = NULL;
1162 program_name = *argv;
1163 xmalloc_set_program_name (program_name);
1165 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1190 if (chdir (srcdir) != 0)
1191 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1192 srcdir, xstrerror (errno));
1194 /* Check the unused bitfield in i386_cpu_flags. */
1196 c = CpuNumOfBits - CpuMax - 1;
1198 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1201 /* Check the unused bitfield in i386_operand_type. */
1203 c = OTNumOfBits - OTMax - 1;
1205 fail (_("%d unused bits in i386_operand_type.\n"), c);
1208 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1211 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1212 sizeof (opcode_modifiers [0]), compare);
1214 qsort (operand_types, ARRAY_SIZE (operand_types),
1215 sizeof (operand_types [0]), compare);
1217 table = fopen ("i386-tbl.h", "w");
1219 fail (_("can't create i386-tbl.h, errno = %s\n"),
1222 process_copyright (table);
1224 process_i386_opcodes (table);
1225 process_i386_registers (table);
1226 process_i386_initializers ();