1 /* Copyright 2007, 2008, 2009, 2010
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" },
65 { "CPU_PENTIUMPRO_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuNop|CpuMMX|Cpu3dnow" },
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
89 { "CPU_AMDFAM10_FLAGS",
90 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
92 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP" },
100 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
101 { "CPU_CLFLUSH_FLAGS",
105 { "CPU_SYSCALL_FLAGS",
112 "CpuMMX|CpuSSE|CpuSSE2" },
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
116 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
117 { "CPU_SSE4_1_FLAGS",
118 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
119 { "CPU_SSE4_2_FLAGS",
120 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
121 { "CPU_ANY_SSE_FLAGS",
122 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX" },
129 { "CPU_XSAVEOPT_FLAGS",
132 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
133 { "CPU_PCLMUL_FLAGS",
134 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
136 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
138 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
140 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
145 { "CPU_RDTSCP_FLAGS",
149 { "CPU_FSGSBASE_FLAGS",
157 { "CPU_3DNOWA_FLAGS",
158 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
159 { "CPU_PADLOCK_FLAGS",
164 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
168 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
169 { "CPU_ANY_AVX_FLAGS",
175 static initializer operand_type_init
[] =
177 { "OPERAND_TYPE_NONE",
179 { "OPERAND_TYPE_REG8",
181 { "OPERAND_TYPE_REG16",
183 { "OPERAND_TYPE_REG32",
185 { "OPERAND_TYPE_REG64",
187 { "OPERAND_TYPE_IMM1",
189 { "OPERAND_TYPE_IMM8",
191 { "OPERAND_TYPE_IMM8S",
193 { "OPERAND_TYPE_IMM16",
195 { "OPERAND_TYPE_IMM32",
197 { "OPERAND_TYPE_IMM32S",
199 { "OPERAND_TYPE_IMM64",
201 { "OPERAND_TYPE_BASEINDEX",
203 { "OPERAND_TYPE_DISP8",
205 { "OPERAND_TYPE_DISP16",
207 { "OPERAND_TYPE_DISP32",
209 { "OPERAND_TYPE_DISP32S",
211 { "OPERAND_TYPE_DISP64",
213 { "OPERAND_TYPE_INOUTPORTREG",
215 { "OPERAND_TYPE_SHIFTCOUNT",
217 { "OPERAND_TYPE_CONTROL",
219 { "OPERAND_TYPE_TEST",
221 { "OPERAND_TYPE_DEBUG",
223 { "OPERAND_TYPE_FLOATREG",
225 { "OPERAND_TYPE_FLOATACC",
227 { "OPERAND_TYPE_SREG2",
229 { "OPERAND_TYPE_SREG3",
231 { "OPERAND_TYPE_ACC",
233 { "OPERAND_TYPE_JUMPABSOLUTE",
235 { "OPERAND_TYPE_REGMMX",
237 { "OPERAND_TYPE_REGXMM",
239 { "OPERAND_TYPE_REGYMM",
241 { "OPERAND_TYPE_ESSEG",
243 { "OPERAND_TYPE_ACC32",
245 { "OPERAND_TYPE_ACC64",
247 { "OPERAND_TYPE_INOUTPORTREG",
249 { "OPERAND_TYPE_REG16_INOUTPORTREG",
250 "Reg16|InOutPortReg" },
251 { "OPERAND_TYPE_DISP16_32",
253 { "OPERAND_TYPE_ANYDISP",
254 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
255 { "OPERAND_TYPE_IMM16_32",
257 { "OPERAND_TYPE_IMM16_32S",
259 { "OPERAND_TYPE_IMM16_32_32S",
260 "Imm16|Imm32|Imm32S" },
261 { "OPERAND_TYPE_IMM32_32S_DISP32",
262 "Imm32|Imm32S|Disp32" },
263 { "OPERAND_TYPE_IMM64_DISP64",
265 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
266 "Imm32|Imm32S|Imm64|Disp32" },
267 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
268 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
269 { "OPERAND_TYPE_VEC_IMM4",
273 typedef struct bitfield
280 #define BITFIELD(n) { n, 0, #n }
282 static bitfield cpu_flags
[] =
290 BITFIELD (CpuClflush
),
292 BITFIELD (CpuSYSCALL
),
297 BITFIELD (CpuFISTTP
),
303 BITFIELD (CpuSSE4_1
),
304 BITFIELD (CpuSSE4_2
),
309 BITFIELD (Cpu3dnowA
),
310 BITFIELD (CpuPadLock
),
316 BITFIELD (CpuXsaveopt
),
318 BITFIELD (CpuPCLMUL
),
326 BITFIELD (CpuRdtscp
),
327 BITFIELD (CpuFSGSBase
),
333 BITFIELD (CpuUnused
),
337 static bitfield opcode_modifiers
[] =
343 BITFIELD (ShortForm
),
345 BITFIELD (JumpDword
),
347 BITFIELD (JumpInterSegment
),
354 BITFIELD (IgnoreSize
),
355 BITFIELD (DefaultSize
),
364 BITFIELD (IsLockable
),
365 BITFIELD (RegKludge
),
366 BITFIELD (FirstXmm0
),
367 BITFIELD (Implicit1stXmm0
),
370 BITFIELD (AddrPrefixOp0
),
379 BITFIELD (VexOpcode
),
380 BITFIELD (VexSources
),
381 BITFIELD (VexImmExt
),
385 BITFIELD (ATTMnemonic
),
386 BITFIELD (ATTSyntax
),
387 BITFIELD (IntelSyntax
),
390 static bitfield operand_types
[] =
407 BITFIELD (BaseIndex
),
413 BITFIELD (InOutPortReg
),
414 BITFIELD (ShiftCount
),
422 BITFIELD (JumpAbsolute
),
434 BITFIELD (Unspecified
),
442 static const char *filename
;
445 compare (const void *x
, const void *y
)
447 const bitfield
*xp
= (const bitfield
*) x
;
448 const bitfield
*yp
= (const bitfield
*) y
;
449 return xp
->position
- yp
->position
;
453 fail (const char *message
, ...)
457 va_start (args
, message
);
458 fprintf (stderr
, _("%s: Error: "), program_name
);
459 vfprintf (stderr
, message
, args
);
465 process_copyright (FILE *fp
)
467 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
468 /* Copyright 2007, 2008, 2009, 2010\n\
469 Free Software Foundation, Inc.\n\
471 This file is part of the GNU opcodes library.\n\
473 This library is free software; you can redistribute it and/or modify\n\
474 it under the terms of the GNU General Public License as published by\n\
475 the Free Software Foundation; either version 3, or (at your option)\n\
476 any later version.\n\
478 It is distributed in the hope that it will be useful, but WITHOUT\n\
479 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
480 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
481 License for more details.\n\
483 You should have received a copy of the GNU General Public License\n\
484 along with this program; if not, write to the Free Software\n\
485 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
486 MA 02110-1301, USA. */\n");
489 /* Remove leading white spaces. */
492 remove_leading_whitespaces (char *str
)
494 while (ISSPACE (*str
))
499 /* Remove trailing white spaces. */
502 remove_trailing_whitespaces (char *str
)
504 size_t last
= strlen (str
);
512 if (ISSPACE (str
[last
]))
520 /* Find next field separated by SEP and terminate it. Return a
521 pointer to the one after it. */
524 next_field (char *str
, char sep
, char **next
, char *last
)
528 p
= remove_leading_whitespaces (str
);
529 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
532 remove_trailing_whitespaces (p
);
543 set_bitfield (const char *f
, bitfield
*array
, int value
,
544 unsigned int size
, int lineno
)
548 if (strcmp (f
, "CpuFP") == 0)
550 set_bitfield("Cpu387", array
, value
, size
, lineno
);
551 set_bitfield("Cpu287", array
, value
, size
, lineno
);
554 else if (strcmp (f
, "Mmword") == 0)
556 else if (strcmp (f
, "Oword") == 0)
559 for (i
= 0; i
< size
; i
++)
560 if (strcasecmp (array
[i
].name
, f
) == 0)
562 array
[i
].value
= value
;
568 const char *v
= strchr (f
, '=');
575 for (i
= 0; i
< size
; i
++)
576 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
578 value
= strtol (v
+ 1, &end
, 0);
581 array
[i
].value
= value
;
590 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
592 fail (_("Unknown bitfield: %s\n"), f
);
596 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
597 int macro
, const char *comma
, const char *indent
)
601 fprintf (table
, "%s{ { ", indent
);
603 for (i
= 0; i
< size
- 1; i
++)
605 fprintf (table
, "%d, ", flags
[i
].value
);
606 if (((i
+ 1) % 20) == 0)
608 /* We need \\ for macro. */
610 fprintf (table
, " \\\n %s", indent
);
612 fprintf (table
, "\n %s", indent
);
616 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
620 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
621 const char *comma
, const char *indent
,
624 char *str
, *next
, *last
;
626 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
628 /* Copy the default cpu flags. */
629 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
631 if (strcasecmp (flag
, "unknown") == 0)
633 /* We turn on everything except for cpu64 in case of
634 CPU_UNKNOWN_FLAGS. */
635 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
636 if (flags
[i
].position
!= Cpu64
)
639 else if (flag
[0] == '~')
641 last
= flag
+ strlen (flag
);
648 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
655 /* First we turn on everything except for cpu64. */
656 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
657 if (flags
[i
].position
!= Cpu64
)
660 /* Turn off selective bits. */
661 for (; next
&& next
< last
; )
663 str
= next_field (next
, '|', &next
, last
);
665 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
668 else if (strcmp (flag
, "0"))
670 /* Turn on selective bits. */
671 last
= flag
+ strlen (flag
);
672 for (next
= flag
; next
&& next
< last
; )
674 str
= next_field (next
, '|', &next
, last
);
676 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
680 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
685 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
689 fprintf (table
, " { ");
691 for (i
= 0; i
< size
- 1; i
++)
693 fprintf (table
, "%d, ", modifier
[i
].value
);
694 if (((i
+ 1) % 20) == 0)
695 fprintf (table
, "\n ");
698 fprintf (table
, "%d },\n", modifier
[i
].value
);
702 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
704 char *str
, *next
, *last
;
705 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
707 /* Copy the default opcode modifier. */
708 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
710 if (strcmp (mod
, "0"))
712 last
= mod
+ strlen (mod
);
713 for (next
= mod
; next
&& next
< last
; )
715 str
= next_field (next
, '|', &next
, last
);
717 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
721 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
725 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
726 int macro
, const char *indent
)
730 fprintf (table
, "{ { ");
732 for (i
= 0; i
< size
- 1; i
++)
734 fprintf (table
, "%d, ", types
[i
].value
);
735 if (((i
+ 1) % 20) == 0)
737 /* We need \\ for macro. */
739 fprintf (table
, "\\\n%s", indent
);
741 fprintf (table
, "\n%s", indent
);
745 fprintf (table
, "%d } }", types
[i
].value
);
749 process_i386_operand_type (FILE *table
, char *op
, int macro
,
750 const char *indent
, int lineno
)
752 char *str
, *next
, *last
;
753 bitfield types
[ARRAY_SIZE (operand_types
)];
755 /* Copy the default operand type. */
756 memcpy (types
, operand_types
, sizeof (types
));
758 if (strcmp (op
, "0"))
760 last
= op
+ strlen (op
);
761 for (next
= op
; next
&& next
< last
; )
763 str
= next_field (next
, '|', &next
, last
);
765 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
768 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
773 output_i386_opcode (FILE *table
, const char *name
, char *str
,
774 char *last
, int lineno
)
777 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
778 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
780 /* Find number of operands. */
781 operands
= next_field (str
, ',', &str
, last
);
783 /* Find base_opcode. */
784 base_opcode
= next_field (str
, ',', &str
, last
);
786 /* Find extension_opcode. */
787 extension_opcode
= next_field (str
, ',', &str
, last
);
789 /* Find opcode_length. */
790 opcode_length
= next_field (str
, ',', &str
, last
);
792 /* Find cpu_flags. */
793 cpu_flags
= next_field (str
, ',', &str
, last
);
795 /* Find opcode_modifier. */
796 opcode_modifier
= next_field (str
, ',', &str
, last
);
798 /* Remove the first {. */
799 str
= remove_leading_whitespaces (str
);
802 str
= remove_leading_whitespaces (str
+ 1);
806 /* There are at least "X}". */
810 /* Remove trailing white spaces and }. */
814 if (ISSPACE (str
[i
]) || str
[i
] == '}')
823 /* Find operand_types. */
824 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
828 operand_types
[i
] = NULL
;
832 operand_types
[i
] = next_field (str
, ',', &str
, last
);
833 if (*operand_types
[i
] == '0')
836 operand_types
[i
] = NULL
;
841 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
842 name
, operands
, base_opcode
, extension_opcode
,
845 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
847 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
849 fprintf (table
, " { ");
851 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
853 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
856 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
861 fprintf (table
, ",\n ");
863 process_i386_operand_type (table
, operand_types
[i
], 0,
866 fprintf (table
, " } },\n");
869 struct opcode_hash_entry
871 struct opcode_hash_entry
*next
;
877 /* Calculate the hash value of an opcode hash entry P. */
880 opcode_hash_hash (const void *p
)
882 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
883 return htab_hash_string (entry
->name
);
886 /* Compare a string Q against an opcode hash entry P. */
889 opcode_hash_eq (const void *p
, const void *q
)
891 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
892 const char *name
= (const char *) q
;
893 return strcmp (name
, entry
->name
) == 0;
897 process_i386_opcodes (FILE *table
)
902 char *str
, *p
, *last
, *name
;
903 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
904 htab_t opcode_hash_table
;
905 struct opcode_hash_entry
**opcode_array
;
906 unsigned int opcode_array_size
= 1024;
909 filename
= "i386-opc.tbl";
910 fp
= fopen (filename
, "r");
913 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
917 opcode_array
= (struct opcode_hash_entry
**)
918 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
920 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
921 opcode_hash_eq
, NULL
,
924 fprintf (table
, "\n/* i386 opcode table. */\n\n");
925 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
927 /* Put everything on opcode array. */
930 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
935 p
= remove_leading_whitespaces (buf
);
938 str
= strstr (p
, "//");
942 /* Remove trailing white spaces. */
943 remove_trailing_whitespaces (p
);
948 /* Ignore comments. */
956 last
= p
+ strlen (p
);
959 name
= next_field (p
, ',', &str
, last
);
961 /* Get the slot in hash table. */
962 hash_slot
= (struct opcode_hash_entry
**)
963 htab_find_slot_with_hash (opcode_hash_table
, name
,
964 htab_hash_string (name
),
967 if (*hash_slot
== NULL
)
969 /* It is the new one. Put it on opcode array. */
970 if (i
>= opcode_array_size
)
972 /* Grow the opcode array when needed. */
973 opcode_array_size
+= 1024;
974 opcode_array
= (struct opcode_hash_entry
**)
975 xrealloc (opcode_array
,
976 sizeof (*opcode_array
) * opcode_array_size
);
979 opcode_array
[i
] = (struct opcode_hash_entry
*)
980 xmalloc (sizeof (struct opcode_hash_entry
));
981 opcode_array
[i
]->next
= NULL
;
982 opcode_array
[i
]->name
= xstrdup (name
);
983 opcode_array
[i
]->opcode
= xstrdup (str
);
984 opcode_array
[i
]->lineno
= lineno
;
985 *hash_slot
= opcode_array
[i
];
990 /* Append it to the existing one. */
992 while ((*entry
) != NULL
)
993 entry
= &(*entry
)->next
;
994 *entry
= (struct opcode_hash_entry
*)
995 xmalloc (sizeof (struct opcode_hash_entry
));
996 (*entry
)->next
= NULL
;
997 (*entry
)->name
= (*hash_slot
)->name
;
998 (*entry
)->opcode
= xstrdup (str
);
999 (*entry
)->lineno
= lineno
;
1003 /* Process opcode array. */
1004 for (j
= 0; j
< i
; j
++)
1006 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1010 lineno
= next
->lineno
;
1011 last
= str
+ strlen (str
);
1012 output_i386_opcode (table
, name
, str
, last
, lineno
);
1018 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1020 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1022 process_i386_opcode_modifier (table
, "0", -1);
1024 fprintf (table
, " { ");
1025 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1026 fprintf (table
, " } }\n");
1028 fprintf (table
, "};\n");
1032 process_i386_registers (FILE *table
)
1036 char *str
, *p
, *last
;
1037 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1038 char *dw2_32_num
, *dw2_64_num
;
1041 filename
= "i386-reg.tbl";
1042 fp
= fopen (filename
, "r");
1044 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1047 fprintf (table
, "\n/* i386 register table. */\n\n");
1048 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1052 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1057 p
= remove_leading_whitespaces (buf
);
1059 /* Skip comments. */
1060 str
= strstr (p
, "//");
1064 /* Remove trailing white spaces. */
1065 remove_trailing_whitespaces (p
);
1070 fprintf (table
, "%s\n", p
);
1078 last
= p
+ strlen (p
);
1080 /* Find reg_name. */
1081 reg_name
= next_field (p
, ',', &str
, last
);
1083 /* Find reg_type. */
1084 reg_type
= next_field (str
, ',', &str
, last
);
1086 /* Find reg_flags. */
1087 reg_flags
= next_field (str
, ',', &str
, last
);
1090 reg_num
= next_field (str
, ',', &str
, last
);
1092 fprintf (table
, " { \"%s\",\n ", reg_name
);
1094 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1096 /* Find 32-bit Dwarf2 register number. */
1097 dw2_32_num
= next_field (str
, ',', &str
, last
);
1099 /* Find 64-bit Dwarf2 register number. */
1100 dw2_64_num
= next_field (str
, ',', &str
, last
);
1102 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1103 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1108 fprintf (table
, "};\n");
1110 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1114 process_i386_initializers (void)
1117 FILE *fp
= fopen ("i386-init.h", "w");
1121 fail (_("can't create i386-init.h, errno = %s\n"),
1124 process_copyright (fp
);
1126 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1128 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1129 init
= xstrdup (cpu_flag_init
[i
].init
);
1130 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1134 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1136 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1137 init
= xstrdup (operand_type_init
[i
].init
);
1138 process_i386_operand_type (fp
, init
, 1, " ", -1);
1146 /* Program options. */
1147 #define OPTION_SRCDIR 200
1149 struct option long_options
[] =
1151 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1152 {"debug", no_argument
, NULL
, 'd'},
1153 {"version", no_argument
, NULL
, 'V'},
1154 {"help", no_argument
, NULL
, 'h'},
1155 {0, no_argument
, NULL
, 0}
1159 print_version (void)
1161 printf ("%s: version 1.0\n", program_name
);
1166 usage (FILE * stream
, int status
)
1168 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1174 main (int argc
, char **argv
)
1176 extern int chdir (char *);
1177 char *srcdir
= NULL
;
1181 program_name
= *argv
;
1182 xmalloc_set_program_name (program_name
);
1184 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1209 if (chdir (srcdir
) != 0)
1210 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1211 srcdir
, xstrerror (errno
));
1213 /* Check the unused bitfield in i386_cpu_flags. */
1215 c
= CpuNumOfBits
- CpuMax
- 1;
1217 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1220 /* Check the unused bitfield in i386_operand_type. */
1222 c
= OTNumOfBits
- OTMax
- 1;
1224 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1227 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1230 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1231 sizeof (opcode_modifiers
[0]), compare
);
1233 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1234 sizeof (operand_types
[0]), compare
);
1236 table
= fopen ("i386-tbl.h", "w");
1238 fail (_("can't create i386-tbl.h, errno = %s\n"),
1241 process_copyright (table
);
1243 process_i386_opcodes (table
);
1244 process_i386_registers (table
);
1245 process_i386_initializers ();