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" },
237 { "OPERAND_TYPE_VEX_IMM4",
241 typedef struct bitfield
248 #define BITFIELD(n) { n, 0, #n }
250 static bitfield cpu_flags
[] =
258 BITFIELD (CpuClflush
),
259 BITFIELD (CpuSYSCALL
),
265 BITFIELD (CpuSSE4_1
),
266 BITFIELD (CpuSSE4_2
),
271 BITFIELD (Cpu3dnowA
),
272 BITFIELD (CpuPadLock
),
279 BITFIELD (CpuPCLMUL
),
284 BITFIELD (CpuRdtscp
),
288 BITFIELD (CpuUnused
),
292 static bitfield opcode_modifiers
[] =
298 BITFIELD (ShortForm
),
300 BITFIELD (JumpDword
),
302 BITFIELD (JumpInterSegment
),
309 BITFIELD (IgnoreSize
),
310 BITFIELD (DefaultSize
),
319 BITFIELD (RegKludge
),
320 BITFIELD (FirstXmm0
),
321 BITFIELD (Implicit1stXmm0
),
322 BITFIELD (ByteOkIntel
),
325 BITFIELD (AddrPrefixOp0
),
343 BITFIELD (Vex3Sources
),
344 BITFIELD (VexImmExt
),
348 BITFIELD (ATTMnemonic
),
349 BITFIELD (ATTSyntax
),
350 BITFIELD (IntelSyntax
),
353 static bitfield operand_types
[] =
370 BITFIELD (BaseIndex
),
376 BITFIELD (InOutPortReg
),
377 BITFIELD (ShiftCount
),
385 BITFIELD (JumpAbsolute
),
397 BITFIELD (Unspecified
),
405 static const char *filename
;
408 compare (const void *x
, const void *y
)
410 const bitfield
*xp
= (const bitfield
*) x
;
411 const bitfield
*yp
= (const bitfield
*) y
;
412 return xp
->position
- yp
->position
;
416 fail (const char *message
, ...)
420 va_start (args
, message
);
421 fprintf (stderr
, _("%s: Error: "), program_name
);
422 vfprintf (stderr
, message
, args
);
428 process_copyright (FILE *fp
)
430 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
431 /* Copyright 2007, 2008, 2009\n\
432 Free Software Foundation, Inc.\n\
434 This file is part of the GNU opcodes library.\n\
436 This library is free software; you can redistribute it and/or modify\n\
437 it under the terms of the GNU General Public License as published by\n\
438 the Free Software Foundation; either version 3, or (at your option)\n\
439 any later version.\n\
441 It is distributed in the hope that it will be useful, but WITHOUT\n\
442 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
443 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
444 License for more details.\n\
446 You should have received a copy of the GNU General Public License\n\
447 along with this program; if not, write to the Free Software\n\
448 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
449 MA 02110-1301, USA. */\n");
452 /* Remove leading white spaces. */
455 remove_leading_whitespaces (char *str
)
457 while (ISSPACE (*str
))
462 /* Remove trailing white spaces. */
465 remove_trailing_whitespaces (char *str
)
467 size_t last
= strlen (str
);
475 if (ISSPACE (str
[last
]))
483 /* Find next field separated by SEP and terminate it. Return a
484 pointer to the one after it. */
487 next_field (char *str
, char sep
, char **next
, char *last
)
491 p
= remove_leading_whitespaces (str
);
492 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
495 remove_trailing_whitespaces (p
);
506 set_bitfield (const char *f
, bitfield
*array
, unsigned int size
, int lineno
)
510 if (strcmp (f
, "Mmword") == 0)
512 else if (strcmp (f
, "Oword") == 0)
515 for (i
= 0; i
< size
; i
++)
516 if (strcasecmp (array
[i
].name
, f
) == 0)
523 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
525 fail (_("Unknown bitfield: %s\n"), f
);
529 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
530 int macro
, const char *comma
, const char *indent
)
534 fprintf (table
, "%s{ { ", indent
);
536 for (i
= 0; i
< size
- 1; i
++)
538 fprintf (table
, "%d, ", flags
[i
].value
);
539 if (((i
+ 1) % 20) == 0)
541 /* We need \\ for macro. */
543 fprintf (table
, " \\\n %s", indent
);
545 fprintf (table
, "\n %s", indent
);
549 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
553 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
554 const char *comma
, const char *indent
,
557 char *str
, *next
, *last
;
558 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
560 /* Copy the default cpu flags. */
561 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
563 if (strcasecmp (flag
, "unknown") == 0)
567 /* We turn on everything except for cpu64 in case of
568 CPU_UNKNOWN_FLAGS. */
569 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
570 if (flags
[i
].position
!= Cpu64
)
573 else if (strcmp (flag
, "0"))
575 last
= flag
+ strlen (flag
);
576 for (next
= flag
; next
&& next
< last
; )
578 str
= next_field (next
, '|', &next
, last
);
580 set_bitfield (str
, flags
, ARRAY_SIZE (flags
), lineno
);
584 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
589 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
593 fprintf (table
, " { ");
595 for (i
= 0; i
< size
- 1; i
++)
597 fprintf (table
, "%d, ", modifier
[i
].value
);
598 if (((i
+ 1) % 20) == 0)
599 fprintf (table
, "\n ");
602 fprintf (table
, "%d },\n", modifier
[i
].value
);
606 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
608 char *str
, *next
, *last
;
609 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
611 /* Copy the default opcode modifier. */
612 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
614 if (strcmp (mod
, "0"))
616 last
= mod
+ strlen (mod
);
617 for (next
= mod
; next
&& next
< last
; )
619 str
= next_field (next
, '|', &next
, last
);
621 set_bitfield (str
, modifiers
, ARRAY_SIZE (modifiers
), lineno
);
624 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
628 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
629 int macro
, const char *indent
)
633 fprintf (table
, "{ { ");
635 for (i
= 0; i
< size
- 1; i
++)
637 fprintf (table
, "%d, ", types
[i
].value
);
638 if (((i
+ 1) % 20) == 0)
640 /* We need \\ for macro. */
642 fprintf (table
, "\\\n%s", indent
);
644 fprintf (table
, "\n%s", indent
);
648 fprintf (table
, "%d } }", types
[i
].value
);
652 process_i386_operand_type (FILE *table
, char *op
, int macro
,
653 const char *indent
, int lineno
)
655 char *str
, *next
, *last
;
656 bitfield types
[ARRAY_SIZE (operand_types
)];
658 /* Copy the default operand type. */
659 memcpy (types
, operand_types
, sizeof (types
));
661 if (strcmp (op
, "0"))
663 last
= op
+ strlen (op
);
664 for (next
= op
; next
&& next
< last
; )
666 str
= next_field (next
, '|', &next
, last
);
668 set_bitfield (str
, types
, ARRAY_SIZE (types
), lineno
);
671 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
676 output_i386_opcode (FILE *table
, const char *name
, char *str
,
677 char *last
, int lineno
)
680 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
681 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
683 /* Find number of operands. */
684 operands
= next_field (str
, ',', &str
, last
);
686 /* Find base_opcode. */
687 base_opcode
= next_field (str
, ',', &str
, last
);
689 /* Find extension_opcode. */
690 extension_opcode
= next_field (str
, ',', &str
, last
);
692 /* Find opcode_length. */
693 opcode_length
= next_field (str
, ',', &str
, last
);
695 /* Find cpu_flags. */
696 cpu_flags
= next_field (str
, ',', &str
, last
);
698 /* Find opcode_modifier. */
699 opcode_modifier
= next_field (str
, ',', &str
, last
);
701 /* Remove the first {. */
702 str
= remove_leading_whitespaces (str
);
705 str
= remove_leading_whitespaces (str
+ 1);
709 /* There are at least "X}". */
713 /* Remove trailing white spaces and }. */
717 if (ISSPACE (str
[i
]) || str
[i
] == '}')
726 /* Find operand_types. */
727 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
731 operand_types
[i
] = NULL
;
735 operand_types
[i
] = next_field (str
, ',', &str
, last
);
736 if (*operand_types
[i
] == '0')
739 operand_types
[i
] = NULL
;
744 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
745 name
, operands
, base_opcode
, extension_opcode
,
748 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
750 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
752 fprintf (table
, " { ");
754 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
756 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
759 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
764 fprintf (table
, ",\n ");
766 process_i386_operand_type (table
, operand_types
[i
], 0,
769 fprintf (table
, " } },\n");
772 struct opcode_hash_entry
774 struct opcode_hash_entry
*next
;
780 /* Calculate the hash value of an opcode hash entry P. */
783 opcode_hash_hash (const void *p
)
785 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
786 return htab_hash_string (entry
->name
);
789 /* Compare a string Q against an opcode hash entry P. */
792 opcode_hash_eq (const void *p
, const void *q
)
794 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
795 const char *name
= (const char *) q
;
796 return strcmp (name
, entry
->name
) == 0;
800 process_i386_opcodes (FILE *table
)
805 char *str
, *p
, *last
, *name
;
806 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
807 htab_t opcode_hash_table
;
808 struct opcode_hash_entry
**opcode_array
;
809 unsigned int opcode_array_size
= 1024;
812 filename
= "i386-opc.tbl";
813 fp
= fopen (filename
, "r");
816 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
820 opcode_array
= (struct opcode_hash_entry
**)
821 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
823 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
824 opcode_hash_eq
, NULL
,
827 fprintf (table
, "\n/* i386 opcode table. */\n\n");
828 fprintf (table
, "const template i386_optab[] =\n{\n");
830 /* Put everything on opcode array. */
833 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
838 p
= remove_leading_whitespaces (buf
);
841 str
= strstr (p
, "//");
845 /* Remove trailing white spaces. */
846 remove_trailing_whitespaces (p
);
851 /* Ignore comments. */
859 last
= p
+ strlen (p
);
862 name
= next_field (p
, ',', &str
, last
);
864 /* Get the slot in hash table. */
865 hash_slot
= (struct opcode_hash_entry
**)
866 htab_find_slot_with_hash (opcode_hash_table
, name
,
867 htab_hash_string (name
),
870 if (*hash_slot
== NULL
)
872 /* It is the new one. Put it on opcode array. */
873 if (i
>= opcode_array_size
)
875 /* Grow the opcode array when needed. */
876 opcode_array_size
+= 1024;
877 opcode_array
= (struct opcode_hash_entry
**)
878 xrealloc (opcode_array
,
879 sizeof (*opcode_array
) * opcode_array_size
);
882 opcode_array
[i
] = (struct opcode_hash_entry
*)
883 xmalloc (sizeof (struct opcode_hash_entry
));
884 opcode_array
[i
]->next
= NULL
;
885 opcode_array
[i
]->name
= xstrdup (name
);
886 opcode_array
[i
]->opcode
= xstrdup (str
);
887 opcode_array
[i
]->lineno
= lineno
;
888 *hash_slot
= opcode_array
[i
];
893 /* Append it to the existing one. */
895 while ((*entry
) != NULL
)
896 entry
= &(*entry
)->next
;
897 *entry
= (struct opcode_hash_entry
*)
898 xmalloc (sizeof (struct opcode_hash_entry
));
899 (*entry
)->next
= NULL
;
900 (*entry
)->name
= (*hash_slot
)->name
;
901 (*entry
)->opcode
= xstrdup (str
);
902 (*entry
)->lineno
= lineno
;
906 /* Process opcode array. */
907 for (j
= 0; j
< i
; j
++)
909 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
913 lineno
= next
->lineno
;
914 last
= str
+ strlen (str
);
915 output_i386_opcode (table
, name
, str
, last
, lineno
);
921 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
923 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
925 process_i386_opcode_modifier (table
, "0", -1);
927 fprintf (table
, " { ");
928 process_i386_operand_type (table
, "0", 0, "\t ", -1);
929 fprintf (table
, " } }\n");
931 fprintf (table
, "};\n");
935 process_i386_registers (FILE *table
)
939 char *str
, *p
, *last
;
940 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
941 char *dw2_32_num
, *dw2_64_num
;
944 filename
= "i386-reg.tbl";
945 fp
= fopen (filename
, "r");
947 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
950 fprintf (table
, "\n/* i386 register table. */\n\n");
951 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
955 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
960 p
= remove_leading_whitespaces (buf
);
963 str
= strstr (p
, "//");
967 /* Remove trailing white spaces. */
968 remove_trailing_whitespaces (p
);
973 fprintf (table
, "%s\n", p
);
981 last
= p
+ strlen (p
);
984 reg_name
= next_field (p
, ',', &str
, last
);
987 reg_type
= next_field (str
, ',', &str
, last
);
989 /* Find reg_flags. */
990 reg_flags
= next_field (str
, ',', &str
, last
);
993 reg_num
= next_field (str
, ',', &str
, last
);
995 fprintf (table
, " { \"%s\",\n ", reg_name
);
997 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
999 /* Find 32-bit Dwarf2 register number. */
1000 dw2_32_num
= next_field (str
, ',', &str
, last
);
1002 /* Find 64-bit Dwarf2 register number. */
1003 dw2_64_num
= next_field (str
, ',', &str
, last
);
1005 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1006 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1011 fprintf (table
, "};\n");
1013 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1017 process_i386_initializers (void)
1020 FILE *fp
= fopen ("i386-init.h", "w");
1024 fail (_("can't create i386-init.h, errno = %s\n"),
1027 process_copyright (fp
);
1029 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1031 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1032 init
= xstrdup (cpu_flag_init
[i
].init
);
1033 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1037 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1039 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1040 init
= xstrdup (operand_type_init
[i
].init
);
1041 process_i386_operand_type (fp
, init
, 1, " ", -1);
1049 /* Program options. */
1050 #define OPTION_SRCDIR 200
1052 struct option long_options
[] =
1054 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1055 {"debug", no_argument
, NULL
, 'd'},
1056 {"version", no_argument
, NULL
, 'V'},
1057 {"help", no_argument
, NULL
, 'h'},
1058 {0, no_argument
, NULL
, 0}
1062 print_version (void)
1064 printf ("%s: version 1.0\n", program_name
);
1069 usage (FILE * stream
, int status
)
1071 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1077 main (int argc
, char **argv
)
1079 extern int chdir (char *);
1080 char *srcdir
= NULL
;
1084 program_name
= *argv
;
1085 xmalloc_set_program_name (program_name
);
1087 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1112 if (chdir (srcdir
) != 0)
1113 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1114 srcdir
, xstrerror (errno
));
1116 /* Check the unused bitfield in i386_cpu_flags. */
1118 c
= CpuNumOfBits
- CpuMax
- 1;
1120 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1123 /* Check the unused bitfield in i386_operand_type. */
1125 c
= OTNumOfBits
- OTMax
- 1;
1127 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1130 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1133 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1134 sizeof (opcode_modifiers
[0]), compare
);
1136 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1137 sizeof (operand_types
[0]), compare
);
1139 table
= fopen ("i386-tbl.h", "w");
1141 fail (_("can't create i386-tbl.h, errno = %s\n"),
1144 process_copyright (table
);
1146 process_i386_opcodes (table
);
1147 process_i386_registers (table
);
1148 process_i386_initializers ();