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|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
58 "Cpu186|Cpu286|Cpu386" },
60 "Cpu186|Cpu286|Cpu386|Cpu486" },
62 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686" },
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX" },
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE" },
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|CpuMMX|CpuSSE|CpuSSE2" },
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|CpuMMX" },
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|CpuMMX|Cpu3dnow" },
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuMMX|Cpu3dnow|Cpu3dnowA" },
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
87 { "CPU_AMDFAM10_FLAGS",
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
89 { "CPU_CLFLUSH_FLAGS",
91 { "CPU_SYSCALL_FLAGS",
98 "CpuMMX|CpuSSE|CpuSSE2" },
100 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
102 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
103 { "CPU_SSE4_1_FLAGS",
104 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
105 { "CPU_SSE4_2_FLAGS",
106 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
115 { "CPU_PCLMUL_FLAGS",
116 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
118 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
121 { "CPU_RDTSCP_FLAGS",
127 { "CPU_3DNOWA_FLAGS",
128 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
129 { "CPU_PADLOCK_FLAGS",
134 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
138 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
140 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
143 static initializer operand_type_init
[] =
145 { "OPERAND_TYPE_NONE",
147 { "OPERAND_TYPE_REG8",
149 { "OPERAND_TYPE_REG16",
151 { "OPERAND_TYPE_REG32",
153 { "OPERAND_TYPE_REG64",
155 { "OPERAND_TYPE_IMM1",
157 { "OPERAND_TYPE_IMM8",
159 { "OPERAND_TYPE_IMM8S",
161 { "OPERAND_TYPE_IMM16",
163 { "OPERAND_TYPE_IMM32",
165 { "OPERAND_TYPE_IMM32S",
167 { "OPERAND_TYPE_IMM64",
169 { "OPERAND_TYPE_BASEINDEX",
171 { "OPERAND_TYPE_DISP8",
173 { "OPERAND_TYPE_DISP16",
175 { "OPERAND_TYPE_DISP32",
177 { "OPERAND_TYPE_DISP32S",
179 { "OPERAND_TYPE_DISP64",
181 { "OPERAND_TYPE_INOUTPORTREG",
183 { "OPERAND_TYPE_SHIFTCOUNT",
185 { "OPERAND_TYPE_CONTROL",
187 { "OPERAND_TYPE_TEST",
189 { "OPERAND_TYPE_DEBUG",
191 { "OPERAND_TYPE_FLOATREG",
193 { "OPERAND_TYPE_FLOATACC",
195 { "OPERAND_TYPE_SREG2",
197 { "OPERAND_TYPE_SREG3",
199 { "OPERAND_TYPE_ACC",
201 { "OPERAND_TYPE_JUMPABSOLUTE",
203 { "OPERAND_TYPE_REGMMX",
205 { "OPERAND_TYPE_REGXMM",
207 { "OPERAND_TYPE_REGYMM",
209 { "OPERAND_TYPE_ESSEG",
211 { "OPERAND_TYPE_ACC32",
213 { "OPERAND_TYPE_ACC64",
215 { "OPERAND_TYPE_INOUTPORTREG",
217 { "OPERAND_TYPE_REG16_INOUTPORTREG",
218 "Reg16|InOutPortReg" },
219 { "OPERAND_TYPE_DISP16_32",
221 { "OPERAND_TYPE_ANYDISP",
222 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
223 { "OPERAND_TYPE_IMM16_32",
225 { "OPERAND_TYPE_IMM16_32S",
227 { "OPERAND_TYPE_IMM16_32_32S",
228 "Imm16|Imm32|Imm32S" },
229 { "OPERAND_TYPE_IMM32_32S_DISP32",
230 "Imm32|Imm32S|Disp32" },
231 { "OPERAND_TYPE_IMM64_DISP64",
233 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
234 "Imm32|Imm32S|Imm64|Disp32" },
235 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
236 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
239 typedef struct bitfield
246 #define BITFIELD(n) { n, 0, #n }
248 static bitfield cpu_flags
[] =
256 BITFIELD (CpuClflush
),
257 BITFIELD (CpuSYSCALL
),
263 BITFIELD (CpuSSE4_1
),
264 BITFIELD (CpuSSE4_2
),
269 BITFIELD (Cpu3dnowA
),
270 BITFIELD (CpuPadLock
),
277 BITFIELD (CpuPCLMUL
),
282 BITFIELD (CpuRdtscp
),
286 BITFIELD (CpuUnused
),
290 static bitfield opcode_modifiers
[] =
296 BITFIELD (ShortForm
),
298 BITFIELD (JumpDword
),
300 BITFIELD (JumpInterSegment
),
307 BITFIELD (IgnoreSize
),
308 BITFIELD (DefaultSize
),
317 BITFIELD (RegKludge
),
318 BITFIELD (FirstXmm0
),
319 BITFIELD (Implicit1stXmm0
),
320 BITFIELD (ByteOkIntel
),
323 BITFIELD (AddrPrefixOp0
),
341 BITFIELD (Vex3Sources
),
342 BITFIELD (VexImmExt
),
346 BITFIELD (ATTMnemonic
),
347 BITFIELD (ATTSyntax
),
348 BITFIELD (IntelSyntax
),
351 static bitfield operand_types
[] =
368 BITFIELD (BaseIndex
),
374 BITFIELD (InOutPortReg
),
375 BITFIELD (ShiftCount
),
383 BITFIELD (JumpAbsolute
),
395 BITFIELD (Unspecified
),
402 static const char *filename
;
405 compare (const void *x
, const void *y
)
407 const bitfield
*xp
= (const bitfield
*) x
;
408 const bitfield
*yp
= (const bitfield
*) y
;
409 return xp
->position
- yp
->position
;
413 fail (const char *message
, ...)
417 va_start (args
, message
);
418 fprintf (stderr
, _("%s: Error: "), program_name
);
419 vfprintf (stderr
, message
, args
);
425 process_copyright (FILE *fp
)
427 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
428 /* Copyright 2007, 2008, 2009\n\
429 Free Software Foundation, Inc.\n\
431 This file is part of the GNU opcodes library.\n\
433 This library is free software; you can redistribute it and/or modify\n\
434 it under the terms of the GNU General Public License as published by\n\
435 the Free Software Foundation; either version 3, or (at your option)\n\
436 any later version.\n\
438 It is distributed in the hope that it will be useful, but WITHOUT\n\
439 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
440 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
441 License for more details.\n\
443 You should have received a copy of the GNU General Public License\n\
444 along with this program; if not, write to the Free Software\n\
445 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
446 MA 02110-1301, USA. */\n");
449 /* Remove leading white spaces. */
452 remove_leading_whitespaces (char *str
)
454 while (ISSPACE (*str
))
459 /* Remove trailing white spaces. */
462 remove_trailing_whitespaces (char *str
)
464 size_t last
= strlen (str
);
472 if (ISSPACE (str
[last
]))
480 /* Find next field separated by SEP and terminate it. Return a
481 pointer to the one after it. */
484 next_field (char *str
, char sep
, char **next
, char *last
)
488 p
= remove_leading_whitespaces (str
);
489 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
492 remove_trailing_whitespaces (p
);
503 set_bitfield (const char *f
, bitfield
*array
, unsigned int size
, int lineno
)
507 if (strcmp (f
, "Mmword") == 0)
509 else if (strcmp (f
, "Oword") == 0)
512 for (i
= 0; i
< size
; i
++)
513 if (strcasecmp (array
[i
].name
, f
) == 0)
520 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
522 fail (_("Unknown bitfield: %s\n"), f
);
526 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
527 int macro
, const char *comma
, const char *indent
)
531 fprintf (table
, "%s{ { ", indent
);
533 for (i
= 0; i
< size
- 1; i
++)
535 fprintf (table
, "%d, ", flags
[i
].value
);
536 if (((i
+ 1) % 20) == 0)
538 /* We need \\ for macro. */
540 fprintf (table
, " \\\n %s", indent
);
542 fprintf (table
, "\n %s", indent
);
546 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
550 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
551 const char *comma
, const char *indent
,
554 char *str
, *next
, *last
;
555 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
557 /* Copy the default cpu flags. */
558 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
560 if (strcasecmp (flag
, "unknown") == 0)
564 /* We turn on everything except for cpu64 in case of
565 CPU_UNKNOWN_FLAGS. */
566 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
567 if (flags
[i
].position
!= Cpu64
)
570 else if (strcmp (flag
, "0"))
572 last
= flag
+ strlen (flag
);
573 for (next
= flag
; next
&& next
< last
; )
575 str
= next_field (next
, '|', &next
, last
);
577 set_bitfield (str
, flags
, ARRAY_SIZE (flags
), lineno
);
581 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
586 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
590 fprintf (table
, " { ");
592 for (i
= 0; i
< size
- 1; i
++)
594 fprintf (table
, "%d, ", modifier
[i
].value
);
595 if (((i
+ 1) % 20) == 0)
596 fprintf (table
, "\n ");
599 fprintf (table
, "%d },\n", modifier
[i
].value
);
603 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
605 char *str
, *next
, *last
;
606 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
608 /* Copy the default opcode modifier. */
609 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
611 if (strcmp (mod
, "0"))
613 last
= mod
+ strlen (mod
);
614 for (next
= mod
; next
&& next
< last
; )
616 str
= next_field (next
, '|', &next
, last
);
618 set_bitfield (str
, modifiers
, ARRAY_SIZE (modifiers
), lineno
);
621 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
625 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
626 int macro
, const char *indent
)
630 fprintf (table
, "{ { ");
632 for (i
= 0; i
< size
- 1; i
++)
634 fprintf (table
, "%d, ", types
[i
].value
);
635 if (((i
+ 1) % 20) == 0)
637 /* We need \\ for macro. */
639 fprintf (table
, "\\\n%s", indent
);
641 fprintf (table
, "\n%s", indent
);
645 fprintf (table
, "%d } }", types
[i
].value
);
649 process_i386_operand_type (FILE *table
, char *op
, int macro
,
650 const char *indent
, int lineno
)
652 char *str
, *next
, *last
;
653 bitfield types
[ARRAY_SIZE (operand_types
)];
655 /* Copy the default operand type. */
656 memcpy (types
, operand_types
, sizeof (types
));
658 if (strcmp (op
, "0"))
660 last
= op
+ strlen (op
);
661 for (next
= op
; next
&& next
< last
; )
663 str
= next_field (next
, '|', &next
, last
);
665 set_bitfield (str
, types
, ARRAY_SIZE (types
), lineno
);
668 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
673 output_i386_opcode (FILE *table
, const char *name
, char *str
,
674 char *last
, int lineno
)
677 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
678 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
680 /* Find number of operands. */
681 operands
= next_field (str
, ',', &str
, last
);
683 /* Find base_opcode. */
684 base_opcode
= next_field (str
, ',', &str
, last
);
686 /* Find extension_opcode. */
687 extension_opcode
= next_field (str
, ',', &str
, last
);
689 /* Find opcode_length. */
690 opcode_length
= next_field (str
, ',', &str
, last
);
692 /* Find cpu_flags. */
693 cpu_flags
= next_field (str
, ',', &str
, last
);
695 /* Find opcode_modifier. */
696 opcode_modifier
= next_field (str
, ',', &str
, last
);
698 /* Remove the first {. */
699 str
= remove_leading_whitespaces (str
);
702 str
= remove_leading_whitespaces (str
+ 1);
706 /* There are at least "X}". */
710 /* Remove trailing white spaces and }. */
714 if (ISSPACE (str
[i
]) || str
[i
] == '}')
723 /* Find operand_types. */
724 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
728 operand_types
[i
] = NULL
;
732 operand_types
[i
] = next_field (str
, ',', &str
, last
);
733 if (*operand_types
[i
] == '0')
736 operand_types
[i
] = NULL
;
741 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
742 name
, operands
, base_opcode
, extension_opcode
,
745 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
747 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
749 fprintf (table
, " { ");
751 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
753 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
756 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
761 fprintf (table
, ",\n ");
763 process_i386_operand_type (table
, operand_types
[i
], 0,
766 fprintf (table
, " } },\n");
769 struct opcode_hash_entry
771 struct opcode_hash_entry
*next
;
777 /* Calculate the hash value of an opcode hash entry P. */
780 opcode_hash_hash (const void *p
)
782 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
783 return htab_hash_string (entry
->name
);
786 /* Compare a string Q against an opcode hash entry P. */
789 opcode_hash_eq (const void *p
, const void *q
)
791 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
792 const char *name
= (const char *) q
;
793 return strcmp (name
, entry
->name
) == 0;
797 process_i386_opcodes (FILE *table
)
802 char *str
, *p
, *last
, *name
;
803 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
804 htab_t opcode_hash_table
;
805 struct opcode_hash_entry
**opcode_array
;
806 unsigned int opcode_array_size
= 1024;
809 filename
= "i386-opc.tbl";
810 fp
= fopen (filename
, "r");
813 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
817 opcode_array
= (struct opcode_hash_entry
**)
818 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
820 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
821 opcode_hash_eq
, NULL
,
824 fprintf (table
, "\n/* i386 opcode table. */\n\n");
825 fprintf (table
, "const template i386_optab[] =\n{\n");
827 /* Put everything on opcode array. */
830 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
835 p
= remove_leading_whitespaces (buf
);
838 str
= strstr (p
, "//");
842 /* Remove trailing white spaces. */
843 remove_trailing_whitespaces (p
);
848 /* Ignore comments. */
856 last
= p
+ strlen (p
);
859 name
= next_field (p
, ',', &str
, last
);
861 /* Get the slot in hash table. */
862 hash_slot
= (struct opcode_hash_entry
**)
863 htab_find_slot_with_hash (opcode_hash_table
, name
,
864 htab_hash_string (name
),
867 if (*hash_slot
== NULL
)
869 /* It is the new one. Put it on opcode array. */
870 if (i
>= opcode_array_size
)
872 /* Grow the opcode array when needed. */
873 opcode_array_size
+= 1024;
874 opcode_array
= (struct opcode_hash_entry
**)
875 xrealloc (opcode_array
,
876 sizeof (*opcode_array
) * opcode_array_size
);
879 opcode_array
[i
] = (struct opcode_hash_entry
*)
880 xmalloc (sizeof (struct opcode_hash_entry
));
881 opcode_array
[i
]->next
= NULL
;
882 opcode_array
[i
]->name
= xstrdup (name
);
883 opcode_array
[i
]->opcode
= xstrdup (str
);
884 opcode_array
[i
]->lineno
= lineno
;
885 *hash_slot
= opcode_array
[i
];
890 /* Append it to the existing one. */
892 while ((*entry
) != NULL
)
893 entry
= &(*entry
)->next
;
894 *entry
= (struct opcode_hash_entry
*)
895 xmalloc (sizeof (struct opcode_hash_entry
));
896 (*entry
)->next
= NULL
;
897 (*entry
)->name
= (*hash_slot
)->name
;
898 (*entry
)->opcode
= xstrdup (str
);
899 (*entry
)->lineno
= lineno
;
903 /* Process opcode array. */
904 for (j
= 0; j
< i
; j
++)
906 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
910 lineno
= next
->lineno
;
911 last
= str
+ strlen (str
);
912 output_i386_opcode (table
, name
, str
, last
, lineno
);
918 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
920 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
922 process_i386_opcode_modifier (table
, "0", -1);
924 fprintf (table
, " { ");
925 process_i386_operand_type (table
, "0", 0, "\t ", -1);
926 fprintf (table
, " } }\n");
928 fprintf (table
, "};\n");
932 process_i386_registers (FILE *table
)
936 char *str
, *p
, *last
;
937 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
938 char *dw2_32_num
, *dw2_64_num
;
941 filename
= "i386-reg.tbl";
942 fp
= fopen (filename
, "r");
944 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
947 fprintf (table
, "\n/* i386 register table. */\n\n");
948 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
952 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
957 p
= remove_leading_whitespaces (buf
);
960 str
= strstr (p
, "//");
964 /* Remove trailing white spaces. */
965 remove_trailing_whitespaces (p
);
970 fprintf (table
, "%s\n", p
);
978 last
= p
+ strlen (p
);
981 reg_name
= next_field (p
, ',', &str
, last
);
984 reg_type
= next_field (str
, ',', &str
, last
);
986 /* Find reg_flags. */
987 reg_flags
= next_field (str
, ',', &str
, last
);
990 reg_num
= next_field (str
, ',', &str
, last
);
992 fprintf (table
, " { \"%s\",\n ", reg_name
);
994 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
996 /* Find 32-bit Dwarf2 register number. */
997 dw2_32_num
= next_field (str
, ',', &str
, last
);
999 /* Find 64-bit Dwarf2 register number. */
1000 dw2_64_num
= next_field (str
, ',', &str
, last
);
1002 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1003 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1008 fprintf (table
, "};\n");
1010 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1014 process_i386_initializers (void)
1017 FILE *fp
= fopen ("i386-init.h", "w");
1021 fail (_("can't create i386-init.h, errno = %s\n"),
1024 process_copyright (fp
);
1026 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1028 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1029 init
= xstrdup (cpu_flag_init
[i
].init
);
1030 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1034 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1036 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1037 init
= xstrdup (operand_type_init
[i
].init
);
1038 process_i386_operand_type (fp
, init
, 1, " ", -1);
1046 /* Program options. */
1047 #define OPTION_SRCDIR 200
1049 struct option long_options
[] =
1051 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1052 {"debug", no_argument
, NULL
, 'd'},
1053 {"version", no_argument
, NULL
, 'V'},
1054 {"help", no_argument
, NULL
, 'h'},
1055 {0, no_argument
, NULL
, 0}
1059 print_version (void)
1061 printf ("%s: version 1.0\n", program_name
);
1066 usage (FILE * stream
, int status
)
1068 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1074 main (int argc
, char **argv
)
1076 extern int chdir (char *);
1077 char *srcdir
= NULL
;
1081 program_name
= *argv
;
1082 xmalloc_set_program_name (program_name
);
1084 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1109 if (chdir (srcdir
) != 0)
1110 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1111 srcdir
, xstrerror (errno
));
1113 /* Check the unused bitfield in i386_cpu_flags. */
1115 c
= CpuNumOfBits
- CpuMax
- 1;
1117 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1120 /* Check the unused bitfield in i386_operand_type. */
1122 c
= OTNumOfBits
- OTMax
- 1;
1124 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1127 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1130 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1131 sizeof (opcode_modifiers
[0]), compare
);
1133 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1134 sizeof (operand_types
[0]), compare
);
1136 table
= fopen ("i386-tbl.h", "w");
1138 fail (_("can't create i386-tbl.h, errno = %s\n"),
1141 process_copyright (table
);
1143 process_i386_opcodes (table
);
1144 process_i386_registers (table
);
1145 process_i386_initializers ();