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" },
133 { "CPU_RDTSCP_FLAGS",
139 { "CPU_3DNOWA_FLAGS",
140 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
141 { "CPU_PADLOCK_FLAGS",
146 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
150 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
151 { "CPU_ANY_AVX_FLAGS",
155 static initializer operand_type_init
[] =
157 { "OPERAND_TYPE_NONE",
159 { "OPERAND_TYPE_REG8",
161 { "OPERAND_TYPE_REG16",
163 { "OPERAND_TYPE_REG32",
165 { "OPERAND_TYPE_REG64",
167 { "OPERAND_TYPE_IMM1",
169 { "OPERAND_TYPE_IMM8",
171 { "OPERAND_TYPE_IMM8S",
173 { "OPERAND_TYPE_IMM16",
175 { "OPERAND_TYPE_IMM32",
177 { "OPERAND_TYPE_IMM32S",
179 { "OPERAND_TYPE_IMM64",
181 { "OPERAND_TYPE_BASEINDEX",
183 { "OPERAND_TYPE_DISP8",
185 { "OPERAND_TYPE_DISP16",
187 { "OPERAND_TYPE_DISP32",
189 { "OPERAND_TYPE_DISP32S",
191 { "OPERAND_TYPE_DISP64",
193 { "OPERAND_TYPE_INOUTPORTREG",
195 { "OPERAND_TYPE_SHIFTCOUNT",
197 { "OPERAND_TYPE_CONTROL",
199 { "OPERAND_TYPE_TEST",
201 { "OPERAND_TYPE_DEBUG",
203 { "OPERAND_TYPE_FLOATREG",
205 { "OPERAND_TYPE_FLOATACC",
207 { "OPERAND_TYPE_SREG2",
209 { "OPERAND_TYPE_SREG3",
211 { "OPERAND_TYPE_ACC",
213 { "OPERAND_TYPE_JUMPABSOLUTE",
215 { "OPERAND_TYPE_REGMMX",
217 { "OPERAND_TYPE_REGXMM",
219 { "OPERAND_TYPE_REGYMM",
221 { "OPERAND_TYPE_ESSEG",
223 { "OPERAND_TYPE_ACC32",
225 { "OPERAND_TYPE_ACC64",
227 { "OPERAND_TYPE_INOUTPORTREG",
229 { "OPERAND_TYPE_REG16_INOUTPORTREG",
230 "Reg16|InOutPortReg" },
231 { "OPERAND_TYPE_DISP16_32",
233 { "OPERAND_TYPE_ANYDISP",
234 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
235 { "OPERAND_TYPE_IMM16_32",
237 { "OPERAND_TYPE_IMM16_32S",
239 { "OPERAND_TYPE_IMM16_32_32S",
240 "Imm16|Imm32|Imm32S" },
241 { "OPERAND_TYPE_IMM32_32S_DISP32",
242 "Imm32|Imm32S|Disp32" },
243 { "OPERAND_TYPE_IMM64_DISP64",
245 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
246 "Imm32|Imm32S|Imm64|Disp32" },
247 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
248 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
251 typedef struct bitfield
258 #define BITFIELD(n) { n, 0, #n }
260 static bitfield cpu_flags
[] =
268 BITFIELD (CpuClflush
),
269 BITFIELD (CpuSYSCALL
),
274 BITFIELD (CpuFISTTP
),
280 BITFIELD (CpuSSE4_1
),
281 BITFIELD (CpuSSE4_2
),
285 BITFIELD (Cpu3dnowA
),
286 BITFIELD (CpuPadLock
),
293 BITFIELD (CpuPCLMUL
),
299 BITFIELD (CpuRdtscp
),
303 BITFIELD (CpuUnused
),
307 static bitfield opcode_modifiers
[] =
313 BITFIELD (ShortForm
),
315 BITFIELD (JumpDword
),
317 BITFIELD (JumpInterSegment
),
324 BITFIELD (IgnoreSize
),
325 BITFIELD (DefaultSize
),
334 BITFIELD (RegKludge
),
335 BITFIELD (FirstXmm0
),
336 BITFIELD (Implicit1stXmm0
),
337 BITFIELD (ByteOkIntel
),
340 BITFIELD (AddrPrefixOp0
),
355 BITFIELD (Vex3Sources
),
356 BITFIELD (VexImmExt
),
360 BITFIELD (ATTMnemonic
),
361 BITFIELD (ATTSyntax
),
362 BITFIELD (IntelSyntax
),
365 static bitfield operand_types
[] =
382 BITFIELD (BaseIndex
),
388 BITFIELD (InOutPortReg
),
389 BITFIELD (ShiftCount
),
397 BITFIELD (JumpAbsolute
),
409 BITFIELD (Unspecified
),
416 static const char *filename
;
419 compare (const void *x
, const void *y
)
421 const bitfield
*xp
= (const bitfield
*) x
;
422 const bitfield
*yp
= (const bitfield
*) y
;
423 return xp
->position
- yp
->position
;
427 fail (const char *message
, ...)
431 va_start (args
, message
);
432 fprintf (stderr
, _("%s: Error: "), program_name
);
433 vfprintf (stderr
, message
, args
);
439 process_copyright (FILE *fp
)
441 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
442 /* Copyright 2007, 2008, 2009\n\
443 Free Software Foundation, Inc.\n\
445 This file is part of the GNU opcodes library.\n\
447 This library is free software; you can redistribute it and/or modify\n\
448 it under the terms of the GNU General Public License as published by\n\
449 the Free Software Foundation; either version 3, or (at your option)\n\
450 any later version.\n\
452 It is distributed in the hope that it will be useful, but WITHOUT\n\
453 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
454 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
455 License for more details.\n\
457 You should have received a copy of the GNU General Public License\n\
458 along with this program; if not, write to the Free Software\n\
459 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
460 MA 02110-1301, USA. */\n");
463 /* Remove leading white spaces. */
466 remove_leading_whitespaces (char *str
)
468 while (ISSPACE (*str
))
473 /* Remove trailing white spaces. */
476 remove_trailing_whitespaces (char *str
)
478 size_t last
= strlen (str
);
486 if (ISSPACE (str
[last
]))
494 /* Find next field separated by SEP and terminate it. Return a
495 pointer to the one after it. */
498 next_field (char *str
, char sep
, char **next
, char *last
)
502 p
= remove_leading_whitespaces (str
);
503 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
506 remove_trailing_whitespaces (p
);
517 set_bitfield (const char *f
, bitfield
*array
, unsigned int size
, int lineno
)
521 if (strcmp (f
, "CpuFP") == 0)
523 set_bitfield("Cpu387", array
, size
, lineno
);
524 set_bitfield("Cpu287", array
, size
, lineno
);
527 else if (strcmp (f
, "Mmword") == 0)
529 else if (strcmp (f
, "Oword") == 0)
532 for (i
= 0; i
< size
; i
++)
533 if (strcasecmp (array
[i
].name
, f
) == 0)
540 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
542 fail (_("Unknown bitfield: %s\n"), f
);
546 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
547 int macro
, const char *comma
, const char *indent
)
551 fprintf (table
, "%s{ { ", indent
);
553 for (i
= 0; i
< size
- 1; i
++)
555 fprintf (table
, "%d, ", flags
[i
].value
);
556 if (((i
+ 1) % 20) == 0)
558 /* We need \\ for macro. */
560 fprintf (table
, " \\\n %s", indent
);
562 fprintf (table
, "\n %s", indent
);
566 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
570 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
571 const char *comma
, const char *indent
,
574 char *str
, *next
, *last
;
575 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
577 /* Copy the default cpu flags. */
578 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
580 if (strcasecmp (flag
, "unknown") == 0)
584 /* We turn on everything except for cpu64 in case of
585 CPU_UNKNOWN_FLAGS. */
586 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
587 if (flags
[i
].position
!= Cpu64
)
590 else if (strcmp (flag
, "0"))
592 last
= flag
+ strlen (flag
);
593 for (next
= flag
; next
&& next
< last
; )
595 str
= next_field (next
, '|', &next
, last
);
597 set_bitfield (str
, flags
, ARRAY_SIZE (flags
), lineno
);
601 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
606 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
610 fprintf (table
, " { ");
612 for (i
= 0; i
< size
- 1; i
++)
614 fprintf (table
, "%d, ", modifier
[i
].value
);
615 if (((i
+ 1) % 20) == 0)
616 fprintf (table
, "\n ");
619 fprintf (table
, "%d },\n", modifier
[i
].value
);
623 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
625 char *str
, *next
, *last
;
626 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
628 /* Copy the default opcode modifier. */
629 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
631 if (strcmp (mod
, "0"))
633 last
= mod
+ strlen (mod
);
634 for (next
= mod
; next
&& next
< last
; )
636 str
= next_field (next
, '|', &next
, last
);
638 set_bitfield (str
, modifiers
, ARRAY_SIZE (modifiers
), lineno
);
641 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
645 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
646 int macro
, const char *indent
)
650 fprintf (table
, "{ { ");
652 for (i
= 0; i
< size
- 1; i
++)
654 fprintf (table
, "%d, ", types
[i
].value
);
655 if (((i
+ 1) % 20) == 0)
657 /* We need \\ for macro. */
659 fprintf (table
, "\\\n%s", indent
);
661 fprintf (table
, "\n%s", indent
);
665 fprintf (table
, "%d } }", types
[i
].value
);
669 process_i386_operand_type (FILE *table
, char *op
, int macro
,
670 const char *indent
, int lineno
)
672 char *str
, *next
, *last
;
673 bitfield types
[ARRAY_SIZE (operand_types
)];
675 /* Copy the default operand type. */
676 memcpy (types
, operand_types
, sizeof (types
));
678 if (strcmp (op
, "0"))
680 last
= op
+ strlen (op
);
681 for (next
= op
; next
&& next
< last
; )
683 str
= next_field (next
, '|', &next
, last
);
685 set_bitfield (str
, types
, ARRAY_SIZE (types
), lineno
);
688 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
693 output_i386_opcode (FILE *table
, const char *name
, char *str
,
694 char *last
, int lineno
)
697 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
698 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
700 /* Find number of operands. */
701 operands
= next_field (str
, ',', &str
, last
);
703 /* Find base_opcode. */
704 base_opcode
= next_field (str
, ',', &str
, last
);
706 /* Find extension_opcode. */
707 extension_opcode
= next_field (str
, ',', &str
, last
);
709 /* Find opcode_length. */
710 opcode_length
= next_field (str
, ',', &str
, last
);
712 /* Find cpu_flags. */
713 cpu_flags
= next_field (str
, ',', &str
, last
);
715 /* Find opcode_modifier. */
716 opcode_modifier
= next_field (str
, ',', &str
, last
);
718 /* Remove the first {. */
719 str
= remove_leading_whitespaces (str
);
722 str
= remove_leading_whitespaces (str
+ 1);
726 /* There are at least "X}". */
730 /* Remove trailing white spaces and }. */
734 if (ISSPACE (str
[i
]) || str
[i
] == '}')
743 /* Find operand_types. */
744 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
748 operand_types
[i
] = NULL
;
752 operand_types
[i
] = next_field (str
, ',', &str
, last
);
753 if (*operand_types
[i
] == '0')
756 operand_types
[i
] = NULL
;
761 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
762 name
, operands
, base_opcode
, extension_opcode
,
765 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
767 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
769 fprintf (table
, " { ");
771 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
773 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
776 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
781 fprintf (table
, ",\n ");
783 process_i386_operand_type (table
, operand_types
[i
], 0,
786 fprintf (table
, " } },\n");
789 struct opcode_hash_entry
791 struct opcode_hash_entry
*next
;
797 /* Calculate the hash value of an opcode hash entry P. */
800 opcode_hash_hash (const void *p
)
802 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
803 return htab_hash_string (entry
->name
);
806 /* Compare a string Q against an opcode hash entry P. */
809 opcode_hash_eq (const void *p
, const void *q
)
811 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
812 const char *name
= (const char *) q
;
813 return strcmp (name
, entry
->name
) == 0;
817 process_i386_opcodes (FILE *table
)
822 char *str
, *p
, *last
, *name
;
823 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
824 htab_t opcode_hash_table
;
825 struct opcode_hash_entry
**opcode_array
;
826 unsigned int opcode_array_size
= 1024;
829 filename
= "i386-opc.tbl";
830 fp
= fopen (filename
, "r");
833 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
837 opcode_array
= (struct opcode_hash_entry
**)
838 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
840 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
841 opcode_hash_eq
, NULL
,
844 fprintf (table
, "\n/* i386 opcode table. */\n\n");
845 fprintf (table
, "const template i386_optab[] =\n{\n");
847 /* Put everything on opcode array. */
850 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
855 p
= remove_leading_whitespaces (buf
);
858 str
= strstr (p
, "//");
862 /* Remove trailing white spaces. */
863 remove_trailing_whitespaces (p
);
868 /* Ignore comments. */
876 last
= p
+ strlen (p
);
879 name
= next_field (p
, ',', &str
, last
);
881 /* Get the slot in hash table. */
882 hash_slot
= (struct opcode_hash_entry
**)
883 htab_find_slot_with_hash (opcode_hash_table
, name
,
884 htab_hash_string (name
),
887 if (*hash_slot
== NULL
)
889 /* It is the new one. Put it on opcode array. */
890 if (i
>= opcode_array_size
)
892 /* Grow the opcode array when needed. */
893 opcode_array_size
+= 1024;
894 opcode_array
= (struct opcode_hash_entry
**)
895 xrealloc (opcode_array
,
896 sizeof (*opcode_array
) * opcode_array_size
);
899 opcode_array
[i
] = (struct opcode_hash_entry
*)
900 xmalloc (sizeof (struct opcode_hash_entry
));
901 opcode_array
[i
]->next
= NULL
;
902 opcode_array
[i
]->name
= xstrdup (name
);
903 opcode_array
[i
]->opcode
= xstrdup (str
);
904 opcode_array
[i
]->lineno
= lineno
;
905 *hash_slot
= opcode_array
[i
];
910 /* Append it to the existing one. */
912 while ((*entry
) != NULL
)
913 entry
= &(*entry
)->next
;
914 *entry
= (struct opcode_hash_entry
*)
915 xmalloc (sizeof (struct opcode_hash_entry
));
916 (*entry
)->next
= NULL
;
917 (*entry
)->name
= (*hash_slot
)->name
;
918 (*entry
)->opcode
= xstrdup (str
);
919 (*entry
)->lineno
= lineno
;
923 /* Process opcode array. */
924 for (j
= 0; j
< i
; j
++)
926 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
930 lineno
= next
->lineno
;
931 last
= str
+ strlen (str
);
932 output_i386_opcode (table
, name
, str
, last
, lineno
);
938 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
940 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
942 process_i386_opcode_modifier (table
, "0", -1);
944 fprintf (table
, " { ");
945 process_i386_operand_type (table
, "0", 0, "\t ", -1);
946 fprintf (table
, " } }\n");
948 fprintf (table
, "};\n");
952 process_i386_registers (FILE *table
)
956 char *str
, *p
, *last
;
957 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
958 char *dw2_32_num
, *dw2_64_num
;
961 filename
= "i386-reg.tbl";
962 fp
= fopen (filename
, "r");
964 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
967 fprintf (table
, "\n/* i386 register table. */\n\n");
968 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
972 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
977 p
= remove_leading_whitespaces (buf
);
980 str
= strstr (p
, "//");
984 /* Remove trailing white spaces. */
985 remove_trailing_whitespaces (p
);
990 fprintf (table
, "%s\n", p
);
998 last
= p
+ strlen (p
);
1000 /* Find reg_name. */
1001 reg_name
= next_field (p
, ',', &str
, last
);
1003 /* Find reg_type. */
1004 reg_type
= next_field (str
, ',', &str
, last
);
1006 /* Find reg_flags. */
1007 reg_flags
= next_field (str
, ',', &str
, last
);
1010 reg_num
= next_field (str
, ',', &str
, last
);
1012 fprintf (table
, " { \"%s\",\n ", reg_name
);
1014 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1016 /* Find 32-bit Dwarf2 register number. */
1017 dw2_32_num
= next_field (str
, ',', &str
, last
);
1019 /* Find 64-bit Dwarf2 register number. */
1020 dw2_64_num
= next_field (str
, ',', &str
, last
);
1022 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1023 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1028 fprintf (table
, "};\n");
1030 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1034 process_i386_initializers (void)
1037 FILE *fp
= fopen ("i386-init.h", "w");
1041 fail (_("can't create i386-init.h, errno = %s\n"),
1044 process_copyright (fp
);
1046 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1048 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1049 init
= xstrdup (cpu_flag_init
[i
].init
);
1050 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1054 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1056 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1057 init
= xstrdup (operand_type_init
[i
].init
);
1058 process_i386_operand_type (fp
, init
, 1, " ", -1);
1066 /* Program options. */
1067 #define OPTION_SRCDIR 200
1069 struct option long_options
[] =
1071 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1072 {"debug", no_argument
, NULL
, 'd'},
1073 {"version", no_argument
, NULL
, 'V'},
1074 {"help", no_argument
, NULL
, 'h'},
1075 {0, no_argument
, NULL
, 0}
1079 print_version (void)
1081 printf ("%s: version 1.0\n", program_name
);
1086 usage (FILE * stream
, int status
)
1088 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1094 main (int argc
, char **argv
)
1096 extern int chdir (char *);
1097 char *srcdir
= NULL
;
1101 program_name
= *argv
;
1102 xmalloc_set_program_name (program_name
);
1104 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1129 if (chdir (srcdir
) != 0)
1130 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1131 srcdir
, xstrerror (errno
));
1133 /* Check the unused bitfield in i386_cpu_flags. */
1135 c
= CpuNumOfBits
- CpuMax
- 1;
1137 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1140 /* Check the unused bitfield in i386_operand_type. */
1142 c
= OTNumOfBits
- OTMax
- 1;
1144 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1147 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1150 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1151 sizeof (opcode_modifiers
[0]), compare
);
1153 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1154 sizeof (operand_types
[0]), compare
);
1156 table
= fopen ("i386-tbl.h", "w");
1158 fail (_("can't create i386-tbl.h, errno = %s\n"),
1161 process_copyright (table
);
1163 process_i386_opcodes (table
);
1164 process_i386_registers (table
);
1165 process_i386_initializers ();