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" },
135 { "CPU_RDTSCP_FLAGS",
141 { "CPU_3DNOWA_FLAGS",
142 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
143 { "CPU_PADLOCK_FLAGS",
148 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
152 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
153 { "CPU_ANY_AVX_FLAGS",
159 static initializer operand_type_init
[] =
161 { "OPERAND_TYPE_NONE",
163 { "OPERAND_TYPE_REG8",
165 { "OPERAND_TYPE_REG16",
167 { "OPERAND_TYPE_REG32",
169 { "OPERAND_TYPE_REG64",
171 { "OPERAND_TYPE_IMM1",
173 { "OPERAND_TYPE_IMM8",
175 { "OPERAND_TYPE_IMM8S",
177 { "OPERAND_TYPE_IMM16",
179 { "OPERAND_TYPE_IMM32",
181 { "OPERAND_TYPE_IMM32S",
183 { "OPERAND_TYPE_IMM64",
185 { "OPERAND_TYPE_BASEINDEX",
187 { "OPERAND_TYPE_DISP8",
189 { "OPERAND_TYPE_DISP16",
191 { "OPERAND_TYPE_DISP32",
193 { "OPERAND_TYPE_DISP32S",
195 { "OPERAND_TYPE_DISP64",
197 { "OPERAND_TYPE_INOUTPORTREG",
199 { "OPERAND_TYPE_SHIFTCOUNT",
201 { "OPERAND_TYPE_CONTROL",
203 { "OPERAND_TYPE_TEST",
205 { "OPERAND_TYPE_DEBUG",
207 { "OPERAND_TYPE_FLOATREG",
209 { "OPERAND_TYPE_FLOATACC",
211 { "OPERAND_TYPE_SREG2",
213 { "OPERAND_TYPE_SREG3",
215 { "OPERAND_TYPE_ACC",
217 { "OPERAND_TYPE_JUMPABSOLUTE",
219 { "OPERAND_TYPE_REGMMX",
221 { "OPERAND_TYPE_REGXMM",
223 { "OPERAND_TYPE_REGYMM",
225 { "OPERAND_TYPE_ESSEG",
227 { "OPERAND_TYPE_ACC32",
229 { "OPERAND_TYPE_ACC64",
231 { "OPERAND_TYPE_INOUTPORTREG",
233 { "OPERAND_TYPE_REG16_INOUTPORTREG",
234 "Reg16|InOutPortReg" },
235 { "OPERAND_TYPE_DISP16_32",
237 { "OPERAND_TYPE_ANYDISP",
238 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
239 { "OPERAND_TYPE_IMM16_32",
241 { "OPERAND_TYPE_IMM16_32S",
243 { "OPERAND_TYPE_IMM16_32_32S",
244 "Imm16|Imm32|Imm32S" },
245 { "OPERAND_TYPE_IMM32_32S_DISP32",
246 "Imm32|Imm32S|Disp32" },
247 { "OPERAND_TYPE_IMM64_DISP64",
249 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
250 "Imm32|Imm32S|Imm64|Disp32" },
251 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
252 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
255 typedef struct bitfield
262 #define BITFIELD(n) { n, 0, #n }
264 static bitfield cpu_flags
[] =
272 BITFIELD (CpuClflush
),
273 BITFIELD (CpuSYSCALL
),
278 BITFIELD (CpuFISTTP
),
284 BITFIELD (CpuSSE4_1
),
285 BITFIELD (CpuSSE4_2
),
290 BITFIELD (Cpu3dnowA
),
291 BITFIELD (CpuPadLock
),
298 BITFIELD (CpuPCLMUL
),
305 BITFIELD (CpuRdtscp
),
309 BITFIELD (CpuUnused
),
313 static bitfield opcode_modifiers
[] =
319 BITFIELD (ShortForm
),
321 BITFIELD (JumpDword
),
323 BITFIELD (JumpInterSegment
),
330 BITFIELD (IgnoreSize
),
331 BITFIELD (DefaultSize
),
340 BITFIELD (RegKludge
),
341 BITFIELD (FirstXmm0
),
342 BITFIELD (Implicit1stXmm0
),
343 BITFIELD (ByteOkIntel
),
346 BITFIELD (AddrPrefixOp0
),
363 BITFIELD (Vex3Sources
),
364 BITFIELD (VexImmExt
),
368 BITFIELD (ATTMnemonic
),
369 BITFIELD (ATTSyntax
),
370 BITFIELD (IntelSyntax
),
373 static bitfield operand_types
[] =
390 BITFIELD (BaseIndex
),
396 BITFIELD (InOutPortReg
),
397 BITFIELD (ShiftCount
),
405 BITFIELD (JumpAbsolute
),
417 BITFIELD (Unspecified
),
424 static const char *filename
;
427 compare (const void *x
, const void *y
)
429 const bitfield
*xp
= (const bitfield
*) x
;
430 const bitfield
*yp
= (const bitfield
*) y
;
431 return xp
->position
- yp
->position
;
435 fail (const char *message
, ...)
439 va_start (args
, message
);
440 fprintf (stderr
, _("%s: Error: "), program_name
);
441 vfprintf (stderr
, message
, args
);
447 process_copyright (FILE *fp
)
449 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
450 /* Copyright 2007, 2008, 2009\n\
451 Free Software Foundation, Inc.\n\
453 This file is part of the GNU opcodes library.\n\
455 This library is free software; you can redistribute it and/or modify\n\
456 it under the terms of the GNU General Public License as published by\n\
457 the Free Software Foundation; either version 3, or (at your option)\n\
458 any later version.\n\
460 It is distributed in the hope that it will be useful, but WITHOUT\n\
461 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
462 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
463 License for more details.\n\
465 You should have received a copy of the GNU General Public License\n\
466 along with this program; if not, write to the Free Software\n\
467 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
468 MA 02110-1301, USA. */\n");
471 /* Remove leading white spaces. */
474 remove_leading_whitespaces (char *str
)
476 while (ISSPACE (*str
))
481 /* Remove trailing white spaces. */
484 remove_trailing_whitespaces (char *str
)
486 size_t last
= strlen (str
);
494 if (ISSPACE (str
[last
]))
502 /* Find next field separated by SEP and terminate it. Return a
503 pointer to the one after it. */
506 next_field (char *str
, char sep
, char **next
, char *last
)
510 p
= remove_leading_whitespaces (str
);
511 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
514 remove_trailing_whitespaces (p
);
525 set_bitfield (const char *f
, bitfield
*array
, int value
,
526 unsigned int size
, int lineno
)
530 if (strcmp (f
, "CpuFP") == 0)
532 set_bitfield("Cpu387", array
, value
, size
, lineno
);
533 set_bitfield("Cpu287", array
, value
, size
, lineno
);
536 else if (strcmp (f
, "Mmword") == 0)
538 else if (strcmp (f
, "Oword") == 0)
541 for (i
= 0; i
< size
; i
++)
542 if (strcasecmp (array
[i
].name
, f
) == 0)
544 array
[i
].value
= value
;
550 const char *v
= strchr (f
, '=');
557 for (i
= 0; i
< size
; i
++)
558 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
560 value
= strtol (v
+ 1, &end
, 0);
563 array
[i
].value
= value
;
572 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
574 fail (_("Unknown bitfield: %s\n"), f
);
578 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
579 int macro
, const char *comma
, const char *indent
)
583 fprintf (table
, "%s{ { ", indent
);
585 for (i
= 0; i
< size
- 1; i
++)
587 fprintf (table
, "%d, ", flags
[i
].value
);
588 if (((i
+ 1) % 20) == 0)
590 /* We need \\ for macro. */
592 fprintf (table
, " \\\n %s", indent
);
594 fprintf (table
, "\n %s", indent
);
598 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
602 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
603 const char *comma
, const char *indent
,
606 char *str
, *next
, *last
;
608 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
610 /* Copy the default cpu flags. */
611 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
613 if (strcasecmp (flag
, "unknown") == 0)
615 /* We turn on everything except for cpu64 in case of
616 CPU_UNKNOWN_FLAGS. */
617 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
618 if (flags
[i
].position
!= Cpu64
)
621 else if (flag
[0] == '~')
623 last
= flag
+ strlen (flag
);
630 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
637 /* First we turn on everything except for cpu64. */
638 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
639 if (flags
[i
].position
!= Cpu64
)
642 /* Turn off selective bits. */
643 for (; next
&& next
< last
; )
645 str
= next_field (next
, '|', &next
, last
);
647 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
650 else if (strcmp (flag
, "0"))
652 /* Turn on selective bits. */
653 last
= flag
+ strlen (flag
);
654 for (next
= flag
; next
&& next
< last
; )
656 str
= next_field (next
, '|', &next
, last
);
658 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
662 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
667 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
671 fprintf (table
, " { ");
673 for (i
= 0; i
< size
- 1; i
++)
675 fprintf (table
, "%d, ", modifier
[i
].value
);
676 if (((i
+ 1) % 20) == 0)
677 fprintf (table
, "\n ");
680 fprintf (table
, "%d },\n", modifier
[i
].value
);
684 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
686 char *str
, *next
, *last
;
687 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
689 /* Copy the default opcode modifier. */
690 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
692 if (strcmp (mod
, "0"))
694 last
= mod
+ strlen (mod
);
695 for (next
= mod
; next
&& next
< last
; )
697 str
= next_field (next
, '|', &next
, last
);
699 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
703 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
707 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
708 int macro
, const char *indent
)
712 fprintf (table
, "{ { ");
714 for (i
= 0; i
< size
- 1; i
++)
716 fprintf (table
, "%d, ", types
[i
].value
);
717 if (((i
+ 1) % 20) == 0)
719 /* We need \\ for macro. */
721 fprintf (table
, "\\\n%s", indent
);
723 fprintf (table
, "\n%s", indent
);
727 fprintf (table
, "%d } }", types
[i
].value
);
731 process_i386_operand_type (FILE *table
, char *op
, int macro
,
732 const char *indent
, int lineno
)
734 char *str
, *next
, *last
;
735 bitfield types
[ARRAY_SIZE (operand_types
)];
737 /* Copy the default operand type. */
738 memcpy (types
, operand_types
, sizeof (types
));
740 if (strcmp (op
, "0"))
742 last
= op
+ strlen (op
);
743 for (next
= op
; next
&& next
< last
; )
745 str
= next_field (next
, '|', &next
, last
);
747 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
750 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
755 output_i386_opcode (FILE *table
, const char *name
, char *str
,
756 char *last
, int lineno
)
759 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
760 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
762 /* Find number of operands. */
763 operands
= next_field (str
, ',', &str
, last
);
765 /* Find base_opcode. */
766 base_opcode
= next_field (str
, ',', &str
, last
);
768 /* Find extension_opcode. */
769 extension_opcode
= next_field (str
, ',', &str
, last
);
771 /* Find opcode_length. */
772 opcode_length
= next_field (str
, ',', &str
, last
);
774 /* Find cpu_flags. */
775 cpu_flags
= next_field (str
, ',', &str
, last
);
777 /* Find opcode_modifier. */
778 opcode_modifier
= next_field (str
, ',', &str
, last
);
780 /* Remove the first {. */
781 str
= remove_leading_whitespaces (str
);
784 str
= remove_leading_whitespaces (str
+ 1);
788 /* There are at least "X}". */
792 /* Remove trailing white spaces and }. */
796 if (ISSPACE (str
[i
]) || str
[i
] == '}')
805 /* Find operand_types. */
806 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
810 operand_types
[i
] = NULL
;
814 operand_types
[i
] = next_field (str
, ',', &str
, last
);
815 if (*operand_types
[i
] == '0')
818 operand_types
[i
] = NULL
;
823 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
824 name
, operands
, base_opcode
, extension_opcode
,
827 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
829 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
831 fprintf (table
, " { ");
833 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
835 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
838 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
843 fprintf (table
, ",\n ");
845 process_i386_operand_type (table
, operand_types
[i
], 0,
848 fprintf (table
, " } },\n");
851 struct opcode_hash_entry
853 struct opcode_hash_entry
*next
;
859 /* Calculate the hash value of an opcode hash entry P. */
862 opcode_hash_hash (const void *p
)
864 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
865 return htab_hash_string (entry
->name
);
868 /* Compare a string Q against an opcode hash entry P. */
871 opcode_hash_eq (const void *p
, const void *q
)
873 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
874 const char *name
= (const char *) q
;
875 return strcmp (name
, entry
->name
) == 0;
879 process_i386_opcodes (FILE *table
)
884 char *str
, *p
, *last
, *name
;
885 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
886 htab_t opcode_hash_table
;
887 struct opcode_hash_entry
**opcode_array
;
888 unsigned int opcode_array_size
= 1024;
891 filename
= "i386-opc.tbl";
892 fp
= fopen (filename
, "r");
895 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
899 opcode_array
= (struct opcode_hash_entry
**)
900 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
902 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
903 opcode_hash_eq
, NULL
,
906 fprintf (table
, "\n/* i386 opcode table. */\n\n");
907 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
909 /* Put everything on opcode array. */
912 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
917 p
= remove_leading_whitespaces (buf
);
920 str
= strstr (p
, "//");
924 /* Remove trailing white spaces. */
925 remove_trailing_whitespaces (p
);
930 /* Ignore comments. */
938 last
= p
+ strlen (p
);
941 name
= next_field (p
, ',', &str
, last
);
943 /* Get the slot in hash table. */
944 hash_slot
= (struct opcode_hash_entry
**)
945 htab_find_slot_with_hash (opcode_hash_table
, name
,
946 htab_hash_string (name
),
949 if (*hash_slot
== NULL
)
951 /* It is the new one. Put it on opcode array. */
952 if (i
>= opcode_array_size
)
954 /* Grow the opcode array when needed. */
955 opcode_array_size
+= 1024;
956 opcode_array
= (struct opcode_hash_entry
**)
957 xrealloc (opcode_array
,
958 sizeof (*opcode_array
) * opcode_array_size
);
961 opcode_array
[i
] = (struct opcode_hash_entry
*)
962 xmalloc (sizeof (struct opcode_hash_entry
));
963 opcode_array
[i
]->next
= NULL
;
964 opcode_array
[i
]->name
= xstrdup (name
);
965 opcode_array
[i
]->opcode
= xstrdup (str
);
966 opcode_array
[i
]->lineno
= lineno
;
967 *hash_slot
= opcode_array
[i
];
972 /* Append it to the existing one. */
974 while ((*entry
) != NULL
)
975 entry
= &(*entry
)->next
;
976 *entry
= (struct opcode_hash_entry
*)
977 xmalloc (sizeof (struct opcode_hash_entry
));
978 (*entry
)->next
= NULL
;
979 (*entry
)->name
= (*hash_slot
)->name
;
980 (*entry
)->opcode
= xstrdup (str
);
981 (*entry
)->lineno
= lineno
;
985 /* Process opcode array. */
986 for (j
= 0; j
< i
; j
++)
988 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
992 lineno
= next
->lineno
;
993 last
= str
+ strlen (str
);
994 output_i386_opcode (table
, name
, str
, last
, lineno
);
1000 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1002 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1004 process_i386_opcode_modifier (table
, "0", -1);
1006 fprintf (table
, " { ");
1007 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1008 fprintf (table
, " } }\n");
1010 fprintf (table
, "};\n");
1014 process_i386_registers (FILE *table
)
1018 char *str
, *p
, *last
;
1019 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1020 char *dw2_32_num
, *dw2_64_num
;
1023 filename
= "i386-reg.tbl";
1024 fp
= fopen (filename
, "r");
1026 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1029 fprintf (table
, "\n/* i386 register table. */\n\n");
1030 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1034 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1039 p
= remove_leading_whitespaces (buf
);
1041 /* Skip comments. */
1042 str
= strstr (p
, "//");
1046 /* Remove trailing white spaces. */
1047 remove_trailing_whitespaces (p
);
1052 fprintf (table
, "%s\n", p
);
1060 last
= p
+ strlen (p
);
1062 /* Find reg_name. */
1063 reg_name
= next_field (p
, ',', &str
, last
);
1065 /* Find reg_type. */
1066 reg_type
= next_field (str
, ',', &str
, last
);
1068 /* Find reg_flags. */
1069 reg_flags
= next_field (str
, ',', &str
, last
);
1072 reg_num
= next_field (str
, ',', &str
, last
);
1074 fprintf (table
, " { \"%s\",\n ", reg_name
);
1076 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1078 /* Find 32-bit Dwarf2 register number. */
1079 dw2_32_num
= next_field (str
, ',', &str
, last
);
1081 /* Find 64-bit Dwarf2 register number. */
1082 dw2_64_num
= next_field (str
, ',', &str
, last
);
1084 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1085 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1090 fprintf (table
, "};\n");
1092 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1096 process_i386_initializers (void)
1099 FILE *fp
= fopen ("i386-init.h", "w");
1103 fail (_("can't create i386-init.h, errno = %s\n"),
1106 process_copyright (fp
);
1108 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1110 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1111 init
= xstrdup (cpu_flag_init
[i
].init
);
1112 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1116 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1118 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1119 init
= xstrdup (operand_type_init
[i
].init
);
1120 process_i386_operand_type (fp
, init
, 1, " ", -1);
1128 /* Program options. */
1129 #define OPTION_SRCDIR 200
1131 struct option long_options
[] =
1133 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1134 {"debug", no_argument
, NULL
, 'd'},
1135 {"version", no_argument
, NULL
, 'V'},
1136 {"help", no_argument
, NULL
, 'h'},
1137 {0, no_argument
, NULL
, 0}
1141 print_version (void)
1143 printf ("%s: version 1.0\n", program_name
);
1148 usage (FILE * stream
, int status
)
1150 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1156 main (int argc
, char **argv
)
1158 extern int chdir (char *);
1159 char *srcdir
= NULL
;
1163 program_name
= *argv
;
1164 xmalloc_set_program_name (program_name
);
1166 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1191 if (chdir (srcdir
) != 0)
1192 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1193 srcdir
, xstrerror (errno
));
1195 /* Check the unused bitfield in i386_cpu_flags. */
1197 c
= CpuNumOfBits
- CpuMax
- 1;
1199 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1202 /* Check the unused bitfield in i386_operand_type. */
1204 c
= OTNumOfBits
- OTMax
- 1;
1206 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1209 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1212 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1213 sizeof (opcode_modifiers
[0]), compare
);
1215 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1216 sizeof (operand_types
[0]), compare
);
1218 table
= fopen ("i386-tbl.h", "w");
1220 fail (_("can't create i386-tbl.h, errno = %s\n"),
1223 process_copyright (table
);
1225 process_i386_opcodes (table
);
1226 process_i386_registers (table
);
1227 process_i386_initializers ();