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" },
120 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
123 { "CPU_RDTSCP_FLAGS",
129 { "CPU_3DNOWA_FLAGS",
130 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
131 { "CPU_PADLOCK_FLAGS",
136 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
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
),
268 BITFIELD (Cpu3dnowA
),
269 BITFIELD (CpuPadLock
),
276 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
),
338 BITFIELD (Vex3Sources
),
339 BITFIELD (VexImmExt
),
343 BITFIELD (ATTMnemonic
),
344 BITFIELD (ATTSyntax
),
345 BITFIELD (IntelSyntax
),
348 static bitfield operand_types
[] =
365 BITFIELD (BaseIndex
),
371 BITFIELD (InOutPortReg
),
372 BITFIELD (ShiftCount
),
380 BITFIELD (JumpAbsolute
),
392 BITFIELD (Unspecified
),
399 static const char *filename
;
402 compare (const void *x
, const void *y
)
404 const bitfield
*xp
= (const bitfield
*) x
;
405 const bitfield
*yp
= (const bitfield
*) y
;
406 return xp
->position
- yp
->position
;
410 fail (const char *message
, ...)
414 va_start (args
, message
);
415 fprintf (stderr
, _("%s: Error: "), program_name
);
416 vfprintf (stderr
, message
, args
);
422 process_copyright (FILE *fp
)
424 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
425 /* Copyright 2007, 2008, 2009\n\
426 Free Software Foundation, Inc.\n\
428 This file is part of the GNU opcodes library.\n\
430 This library is free software; you can redistribute it and/or modify\n\
431 it under the terms of the GNU General Public License as published by\n\
432 the Free Software Foundation; either version 3, or (at your option)\n\
433 any later version.\n\
435 It is distributed in the hope that it will be useful, but WITHOUT\n\
436 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
437 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
438 License for more details.\n\
440 You should have received a copy of the GNU General Public License\n\
441 along with this program; if not, write to the Free Software\n\
442 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
443 MA 02110-1301, USA. */\n");
446 /* Remove leading white spaces. */
449 remove_leading_whitespaces (char *str
)
451 while (ISSPACE (*str
))
456 /* Remove trailing white spaces. */
459 remove_trailing_whitespaces (char *str
)
461 size_t last
= strlen (str
);
469 if (ISSPACE (str
[last
]))
477 /* Find next field separated by SEP and terminate it. Return a
478 pointer to the one after it. */
481 next_field (char *str
, char sep
, char **next
, char *last
)
485 p
= remove_leading_whitespaces (str
);
486 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
489 remove_trailing_whitespaces (p
);
500 set_bitfield (const char *f
, bitfield
*array
, unsigned int size
, int lineno
)
504 if (strcmp (f
, "Mmword") == 0)
506 else if (strcmp (f
, "Oword") == 0)
509 for (i
= 0; i
< size
; i
++)
510 if (strcasecmp (array
[i
].name
, f
) == 0)
517 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
519 fail (_("Unknown bitfield: %s\n"), f
);
523 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
524 int macro
, const char *comma
, const char *indent
)
528 fprintf (table
, "%s{ { ", indent
);
530 for (i
= 0; i
< size
- 1; i
++)
532 fprintf (table
, "%d, ", flags
[i
].value
);
533 if (((i
+ 1) % 20) == 0)
535 /* We need \\ for macro. */
537 fprintf (table
, " \\\n %s", indent
);
539 fprintf (table
, "\n %s", indent
);
543 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
547 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
548 const char *comma
, const char *indent
,
551 char *str
, *next
, *last
;
552 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
554 /* Copy the default cpu flags. */
555 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
557 if (strcasecmp (flag
, "unknown") == 0)
561 /* We turn on everything except for cpu64 in case of
562 CPU_UNKNOWN_FLAGS. */
563 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
564 if (flags
[i
].position
!= Cpu64
)
567 else if (strcmp (flag
, "0"))
569 last
= flag
+ strlen (flag
);
570 for (next
= flag
; next
&& next
< last
; )
572 str
= next_field (next
, '|', &next
, last
);
574 set_bitfield (str
, flags
, ARRAY_SIZE (flags
), lineno
);
578 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
583 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
587 fprintf (table
, " { ");
589 for (i
= 0; i
< size
- 1; i
++)
591 fprintf (table
, "%d, ", modifier
[i
].value
);
592 if (((i
+ 1) % 20) == 0)
593 fprintf (table
, "\n ");
596 fprintf (table
, "%d },\n", modifier
[i
].value
);
600 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
602 char *str
, *next
, *last
;
603 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
605 /* Copy the default opcode modifier. */
606 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
608 if (strcmp (mod
, "0"))
610 last
= mod
+ strlen (mod
);
611 for (next
= mod
; next
&& next
< last
; )
613 str
= next_field (next
, '|', &next
, last
);
615 set_bitfield (str
, modifiers
, ARRAY_SIZE (modifiers
), lineno
);
618 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
622 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
623 int macro
, const char *indent
)
627 fprintf (table
, "{ { ");
629 for (i
= 0; i
< size
- 1; i
++)
631 fprintf (table
, "%d, ", types
[i
].value
);
632 if (((i
+ 1) % 20) == 0)
634 /* We need \\ for macro. */
636 fprintf (table
, "\\\n%s", indent
);
638 fprintf (table
, "\n%s", indent
);
642 fprintf (table
, "%d } }", types
[i
].value
);
646 process_i386_operand_type (FILE *table
, char *op
, int macro
,
647 const char *indent
, int lineno
)
649 char *str
, *next
, *last
;
650 bitfield types
[ARRAY_SIZE (operand_types
)];
652 /* Copy the default operand type. */
653 memcpy (types
, operand_types
, sizeof (types
));
655 if (strcmp (op
, "0"))
657 last
= op
+ strlen (op
);
658 for (next
= op
; next
&& next
< last
; )
660 str
= next_field (next
, '|', &next
, last
);
662 set_bitfield (str
, types
, ARRAY_SIZE (types
), lineno
);
665 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
670 output_i386_opcode (FILE *table
, const char *name
, char *str
,
671 char *last
, int lineno
)
674 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
675 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
677 /* Find number of operands. */
678 operands
= next_field (str
, ',', &str
, last
);
680 /* Find base_opcode. */
681 base_opcode
= next_field (str
, ',', &str
, last
);
683 /* Find extension_opcode. */
684 extension_opcode
= next_field (str
, ',', &str
, last
);
686 /* Find opcode_length. */
687 opcode_length
= next_field (str
, ',', &str
, last
);
689 /* Find cpu_flags. */
690 cpu_flags
= next_field (str
, ',', &str
, last
);
692 /* Find opcode_modifier. */
693 opcode_modifier
= next_field (str
, ',', &str
, last
);
695 /* Remove the first {. */
696 str
= remove_leading_whitespaces (str
);
699 str
= remove_leading_whitespaces (str
+ 1);
703 /* There are at least "X}". */
707 /* Remove trailing white spaces and }. */
711 if (ISSPACE (str
[i
]) || str
[i
] == '}')
720 /* Find operand_types. */
721 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
725 operand_types
[i
] = NULL
;
729 operand_types
[i
] = next_field (str
, ',', &str
, last
);
730 if (*operand_types
[i
] == '0')
733 operand_types
[i
] = NULL
;
738 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
739 name
, operands
, base_opcode
, extension_opcode
,
742 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
744 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
746 fprintf (table
, " { ");
748 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
750 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
753 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
758 fprintf (table
, ",\n ");
760 process_i386_operand_type (table
, operand_types
[i
], 0,
763 fprintf (table
, " } },\n");
766 struct opcode_hash_entry
768 struct opcode_hash_entry
*next
;
774 /* Calculate the hash value of an opcode hash entry P. */
777 opcode_hash_hash (const void *p
)
779 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
780 return htab_hash_string (entry
->name
);
783 /* Compare a string Q against an opcode hash entry P. */
786 opcode_hash_eq (const void *p
, const void *q
)
788 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
789 const char *name
= (const char *) q
;
790 return strcmp (name
, entry
->name
) == 0;
794 process_i386_opcodes (FILE *table
)
799 char *str
, *p
, *last
, *name
;
800 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
801 htab_t opcode_hash_table
;
802 struct opcode_hash_entry
**opcode_array
;
803 unsigned int opcode_array_size
= 1024;
806 filename
= "i386-opc.tbl";
807 fp
= fopen (filename
, "r");
810 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
814 opcode_array
= (struct opcode_hash_entry
**)
815 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
817 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
818 opcode_hash_eq
, NULL
,
821 fprintf (table
, "\n/* i386 opcode table. */\n\n");
822 fprintf (table
, "const template i386_optab[] =\n{\n");
824 /* Put everything on opcode array. */
827 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
832 p
= remove_leading_whitespaces (buf
);
835 str
= strstr (p
, "//");
839 /* Remove trailing white spaces. */
840 remove_trailing_whitespaces (p
);
845 /* Ignore comments. */
853 last
= p
+ strlen (p
);
856 name
= next_field (p
, ',', &str
, last
);
858 /* Get the slot in hash table. */
859 hash_slot
= (struct opcode_hash_entry
**)
860 htab_find_slot_with_hash (opcode_hash_table
, name
,
861 htab_hash_string (name
),
864 if (*hash_slot
== NULL
)
866 /* It is the new one. Put it on opcode array. */
867 if (i
>= opcode_array_size
)
869 /* Grow the opcode array when needed. */
870 opcode_array_size
+= 1024;
871 opcode_array
= (struct opcode_hash_entry
**)
872 xrealloc (opcode_array
,
873 sizeof (*opcode_array
) * opcode_array_size
);
876 opcode_array
[i
] = (struct opcode_hash_entry
*)
877 xmalloc (sizeof (struct opcode_hash_entry
));
878 opcode_array
[i
]->next
= NULL
;
879 opcode_array
[i
]->name
= xstrdup (name
);
880 opcode_array
[i
]->opcode
= xstrdup (str
);
881 opcode_array
[i
]->lineno
= lineno
;
882 *hash_slot
= opcode_array
[i
];
887 /* Append it to the existing one. */
889 while ((*entry
) != NULL
)
890 entry
= &(*entry
)->next
;
891 *entry
= (struct opcode_hash_entry
*)
892 xmalloc (sizeof (struct opcode_hash_entry
));
893 (*entry
)->next
= NULL
;
894 (*entry
)->name
= (*hash_slot
)->name
;
895 (*entry
)->opcode
= xstrdup (str
);
896 (*entry
)->lineno
= lineno
;
900 /* Process opcode array. */
901 for (j
= 0; j
< i
; j
++)
903 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
907 lineno
= next
->lineno
;
908 last
= str
+ strlen (str
);
909 output_i386_opcode (table
, name
, str
, last
, lineno
);
915 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
917 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
919 process_i386_opcode_modifier (table
, "0", -1);
921 fprintf (table
, " { ");
922 process_i386_operand_type (table
, "0", 0, "\t ", -1);
923 fprintf (table
, " } }\n");
925 fprintf (table
, "};\n");
929 process_i386_registers (FILE *table
)
933 char *str
, *p
, *last
;
934 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
935 char *dw2_32_num
, *dw2_64_num
;
938 filename
= "i386-reg.tbl";
939 fp
= fopen (filename
, "r");
941 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
944 fprintf (table
, "\n/* i386 register table. */\n\n");
945 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
949 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
954 p
= remove_leading_whitespaces (buf
);
957 str
= strstr (p
, "//");
961 /* Remove trailing white spaces. */
962 remove_trailing_whitespaces (p
);
967 fprintf (table
, "%s\n", p
);
975 last
= p
+ strlen (p
);
978 reg_name
= next_field (p
, ',', &str
, last
);
981 reg_type
= next_field (str
, ',', &str
, last
);
983 /* Find reg_flags. */
984 reg_flags
= next_field (str
, ',', &str
, last
);
987 reg_num
= next_field (str
, ',', &str
, last
);
989 fprintf (table
, " { \"%s\",\n ", reg_name
);
991 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
993 /* Find 32-bit Dwarf2 register number. */
994 dw2_32_num
= next_field (str
, ',', &str
, last
);
996 /* Find 64-bit Dwarf2 register number. */
997 dw2_64_num
= next_field (str
, ',', &str
, last
);
999 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1000 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1005 fprintf (table
, "};\n");
1007 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1011 process_i386_initializers (void)
1014 FILE *fp
= fopen ("i386-init.h", "w");
1018 fail (_("can't create i386-init.h, errno = %s\n"),
1021 process_copyright (fp
);
1023 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1025 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1026 init
= xstrdup (cpu_flag_init
[i
].init
);
1027 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1031 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1033 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1034 init
= xstrdup (operand_type_init
[i
].init
);
1035 process_i386_operand_type (fp
, init
, 1, " ", -1);
1043 /* Program options. */
1044 #define OPTION_SRCDIR 200
1046 struct option long_options
[] =
1048 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1049 {"debug", no_argument
, NULL
, 'd'},
1050 {"version", no_argument
, NULL
, 'V'},
1051 {"help", no_argument
, NULL
, 'h'},
1052 {0, no_argument
, NULL
, 0}
1056 print_version (void)
1058 printf ("%s: version 1.0\n", program_name
);
1063 usage (FILE * stream
, int status
)
1065 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1071 main (int argc
, char **argv
)
1073 extern int chdir (char *);
1074 char *srcdir
= NULL
;
1078 program_name
= *argv
;
1079 xmalloc_set_program_name (program_name
);
1081 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1106 if (chdir (srcdir
) != 0)
1107 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1108 srcdir
, xstrerror (errno
));
1110 /* Check the unused bitfield in i386_cpu_flags. */
1112 c
= CpuNumOfBits
- CpuMax
- 1;
1114 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1117 /* Check the unused bitfield in i386_operand_type. */
1119 c
= OTNumOfBits
- OTMax
- 1;
1121 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1124 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1127 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1128 sizeof (opcode_modifiers
[0]), compare
);
1130 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1131 sizeof (operand_types
[0]), compare
);
1133 table
= fopen ("i386-tbl.h", "w");
1135 fail (_("can't create i386-tbl.h, errno = %s\n"),
1138 process_copyright (table
);
1140 process_i386_opcodes (table
);
1141 process_i386_registers (table
);
1142 process_i386_initializers ();