1 /* Copyright 2007, 2008, 2009, 2010, 2011
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|CpuNop|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" },
147 { "CPU_RDTSCP_FLAGS",
151 { "CPU_FSGSBASE_FLAGS",
159 { "CPU_3DNOWA_FLAGS",
160 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
161 { "CPU_PADLOCK_FLAGS",
166 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
170 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
171 { "CPU_ANY_AVX_FLAGS",
177 static initializer operand_type_init
[] =
179 { "OPERAND_TYPE_NONE",
181 { "OPERAND_TYPE_REG8",
183 { "OPERAND_TYPE_REG16",
185 { "OPERAND_TYPE_REG32",
187 { "OPERAND_TYPE_REG64",
189 { "OPERAND_TYPE_IMM1",
191 { "OPERAND_TYPE_IMM8",
193 { "OPERAND_TYPE_IMM8S",
195 { "OPERAND_TYPE_IMM16",
197 { "OPERAND_TYPE_IMM32",
199 { "OPERAND_TYPE_IMM32S",
201 { "OPERAND_TYPE_IMM64",
203 { "OPERAND_TYPE_BASEINDEX",
205 { "OPERAND_TYPE_DISP8",
207 { "OPERAND_TYPE_DISP16",
209 { "OPERAND_TYPE_DISP32",
211 { "OPERAND_TYPE_DISP32S",
213 { "OPERAND_TYPE_DISP64",
215 { "OPERAND_TYPE_INOUTPORTREG",
217 { "OPERAND_TYPE_SHIFTCOUNT",
219 { "OPERAND_TYPE_CONTROL",
221 { "OPERAND_TYPE_TEST",
223 { "OPERAND_TYPE_DEBUG",
225 { "OPERAND_TYPE_FLOATREG",
227 { "OPERAND_TYPE_FLOATACC",
229 { "OPERAND_TYPE_SREG2",
231 { "OPERAND_TYPE_SREG3",
233 { "OPERAND_TYPE_ACC",
235 { "OPERAND_TYPE_JUMPABSOLUTE",
237 { "OPERAND_TYPE_REGMMX",
239 { "OPERAND_TYPE_REGXMM",
241 { "OPERAND_TYPE_REGYMM",
243 { "OPERAND_TYPE_ESSEG",
245 { "OPERAND_TYPE_ACC32",
247 { "OPERAND_TYPE_ACC64",
249 { "OPERAND_TYPE_INOUTPORTREG",
251 { "OPERAND_TYPE_REG16_INOUTPORTREG",
252 "Reg16|InOutPortReg" },
253 { "OPERAND_TYPE_DISP16_32",
255 { "OPERAND_TYPE_ANYDISP",
256 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
257 { "OPERAND_TYPE_IMM16_32",
259 { "OPERAND_TYPE_IMM16_32S",
261 { "OPERAND_TYPE_IMM16_32_32S",
262 "Imm16|Imm32|Imm32S" },
263 { "OPERAND_TYPE_IMM32_32S_DISP32",
264 "Imm32|Imm32S|Disp32" },
265 { "OPERAND_TYPE_IMM64_DISP64",
267 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
268 "Imm32|Imm32S|Imm64|Disp32" },
269 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
270 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
271 { "OPERAND_TYPE_VEC_IMM4",
275 typedef struct bitfield
282 #define BITFIELD(n) { n, 0, #n }
284 static bitfield cpu_flags
[] =
292 BITFIELD (CpuClflush
),
294 BITFIELD (CpuSYSCALL
),
299 BITFIELD (CpuFISTTP
),
305 BITFIELD (CpuSSE4_1
),
306 BITFIELD (CpuSSE4_2
),
311 BITFIELD (Cpu3dnowA
),
312 BITFIELD (CpuPadLock
),
318 BITFIELD (CpuXsaveopt
),
320 BITFIELD (CpuPCLMUL
),
329 BITFIELD (CpuRdtscp
),
330 BITFIELD (CpuFSGSBase
),
336 BITFIELD (CpuUnused
),
340 static bitfield opcode_modifiers
[] =
346 BITFIELD (ShortForm
),
348 BITFIELD (JumpDword
),
350 BITFIELD (JumpInterSegment
),
357 BITFIELD (CheckRegSize
),
358 BITFIELD (IgnoreSize
),
359 BITFIELD (DefaultSize
),
368 BITFIELD (IsLockable
),
369 BITFIELD (RegKludge
),
370 BITFIELD (FirstXmm0
),
371 BITFIELD (Implicit1stXmm0
),
374 BITFIELD (AddrPrefixOp0
),
383 BITFIELD (VexOpcode
),
384 BITFIELD (VexSources
),
385 BITFIELD (VexImmExt
),
389 BITFIELD (ATTMnemonic
),
390 BITFIELD (ATTSyntax
),
391 BITFIELD (IntelSyntax
),
394 static bitfield operand_types
[] =
411 BITFIELD (BaseIndex
),
417 BITFIELD (InOutPortReg
),
418 BITFIELD (ShiftCount
),
426 BITFIELD (JumpAbsolute
),
438 BITFIELD (Unspecified
),
446 static const char *filename
;
449 compare (const void *x
, const void *y
)
451 const bitfield
*xp
= (const bitfield
*) x
;
452 const bitfield
*yp
= (const bitfield
*) y
;
453 return xp
->position
- yp
->position
;
457 fail (const char *message
, ...)
461 va_start (args
, message
);
462 fprintf (stderr
, _("%s: Error: "), program_name
);
463 vfprintf (stderr
, message
, args
);
469 process_copyright (FILE *fp
)
471 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
472 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
473 Free Software Foundation, Inc.\n\
475 This file is part of the GNU opcodes library.\n\
477 This library is free software; you can redistribute it and/or modify\n\
478 it under the terms of the GNU General Public License as published by\n\
479 the Free Software Foundation; either version 3, or (at your option)\n\
480 any later version.\n\
482 It is distributed in the hope that it will be useful, but WITHOUT\n\
483 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
484 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
485 License for more details.\n\
487 You should have received a copy of the GNU General Public License\n\
488 along with this program; if not, write to the Free Software\n\
489 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
490 MA 02110-1301, USA. */\n");
493 /* Remove leading white spaces. */
496 remove_leading_whitespaces (char *str
)
498 while (ISSPACE (*str
))
503 /* Remove trailing white spaces. */
506 remove_trailing_whitespaces (char *str
)
508 size_t last
= strlen (str
);
516 if (ISSPACE (str
[last
]))
524 /* Find next field separated by SEP and terminate it. Return a
525 pointer to the one after it. */
528 next_field (char *str
, char sep
, char **next
, char *last
)
532 p
= remove_leading_whitespaces (str
);
533 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
536 remove_trailing_whitespaces (p
);
547 set_bitfield (const char *f
, bitfield
*array
, int value
,
548 unsigned int size
, int lineno
)
552 if (strcmp (f
, "CpuFP") == 0)
554 set_bitfield("Cpu387", array
, value
, size
, lineno
);
555 set_bitfield("Cpu287", array
, value
, size
, lineno
);
558 else if (strcmp (f
, "Mmword") == 0)
560 else if (strcmp (f
, "Oword") == 0)
563 for (i
= 0; i
< size
; i
++)
564 if (strcasecmp (array
[i
].name
, f
) == 0)
566 array
[i
].value
= value
;
572 const char *v
= strchr (f
, '=');
579 for (i
= 0; i
< size
; i
++)
580 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
582 value
= strtol (v
+ 1, &end
, 0);
585 array
[i
].value
= value
;
594 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
596 fail (_("Unknown bitfield: %s\n"), f
);
600 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
601 int macro
, const char *comma
, const char *indent
)
605 fprintf (table
, "%s{ { ", indent
);
607 for (i
= 0; i
< size
- 1; i
++)
609 fprintf (table
, "%d, ", flags
[i
].value
);
610 if (((i
+ 1) % 20) == 0)
612 /* We need \\ for macro. */
614 fprintf (table
, " \\\n %s", indent
);
616 fprintf (table
, "\n %s", indent
);
620 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
624 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
625 const char *comma
, const char *indent
,
628 char *str
, *next
, *last
;
630 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
632 /* Copy the default cpu flags. */
633 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
635 if (strcasecmp (flag
, "unknown") == 0)
637 /* We turn on everything except for cpu64 in case of
638 CPU_UNKNOWN_FLAGS. */
639 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
640 if (flags
[i
].position
!= Cpu64
)
643 else if (flag
[0] == '~')
645 last
= flag
+ strlen (flag
);
652 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
659 /* First we turn on everything except for cpu64. */
660 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
661 if (flags
[i
].position
!= Cpu64
)
664 /* Turn off selective bits. */
665 for (; next
&& next
< last
; )
667 str
= next_field (next
, '|', &next
, last
);
669 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
672 else if (strcmp (flag
, "0"))
674 /* Turn on selective bits. */
675 last
= flag
+ strlen (flag
);
676 for (next
= flag
; next
&& next
< last
; )
678 str
= next_field (next
, '|', &next
, last
);
680 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
684 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
689 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
693 fprintf (table
, " { ");
695 for (i
= 0; i
< size
- 1; i
++)
697 fprintf (table
, "%d, ", modifier
[i
].value
);
698 if (((i
+ 1) % 20) == 0)
699 fprintf (table
, "\n ");
702 fprintf (table
, "%d },\n", modifier
[i
].value
);
706 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
708 char *str
, *next
, *last
;
709 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
711 /* Copy the default opcode modifier. */
712 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
714 if (strcmp (mod
, "0"))
716 last
= mod
+ strlen (mod
);
717 for (next
= mod
; next
&& next
< last
; )
719 str
= next_field (next
, '|', &next
, last
);
721 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
725 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
729 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
730 int macro
, const char *indent
)
734 fprintf (table
, "{ { ");
736 for (i
= 0; i
< size
- 1; i
++)
738 fprintf (table
, "%d, ", types
[i
].value
);
739 if (((i
+ 1) % 20) == 0)
741 /* We need \\ for macro. */
743 fprintf (table
, "\\\n%s", indent
);
745 fprintf (table
, "\n%s", indent
);
749 fprintf (table
, "%d } }", types
[i
].value
);
753 process_i386_operand_type (FILE *table
, char *op
, int macro
,
754 const char *indent
, int lineno
)
756 char *str
, *next
, *last
;
757 bitfield types
[ARRAY_SIZE (operand_types
)];
759 /* Copy the default operand type. */
760 memcpy (types
, operand_types
, sizeof (types
));
762 if (strcmp (op
, "0"))
764 last
= op
+ strlen (op
);
765 for (next
= op
; next
&& next
< last
; )
767 str
= next_field (next
, '|', &next
, last
);
769 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
772 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
777 output_i386_opcode (FILE *table
, const char *name
, char *str
,
778 char *last
, int lineno
)
781 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
782 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
784 /* Find number of operands. */
785 operands
= next_field (str
, ',', &str
, last
);
787 /* Find base_opcode. */
788 base_opcode
= next_field (str
, ',', &str
, last
);
790 /* Find extension_opcode. */
791 extension_opcode
= next_field (str
, ',', &str
, last
);
793 /* Find opcode_length. */
794 opcode_length
= next_field (str
, ',', &str
, last
);
796 /* Find cpu_flags. */
797 cpu_flags
= next_field (str
, ',', &str
, last
);
799 /* Find opcode_modifier. */
800 opcode_modifier
= next_field (str
, ',', &str
, last
);
802 /* Remove the first {. */
803 str
= remove_leading_whitespaces (str
);
806 str
= remove_leading_whitespaces (str
+ 1);
810 /* There are at least "X}". */
814 /* Remove trailing white spaces and }. */
818 if (ISSPACE (str
[i
]) || str
[i
] == '}')
827 /* Find operand_types. */
828 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
832 operand_types
[i
] = NULL
;
836 operand_types
[i
] = next_field (str
, ',', &str
, last
);
837 if (*operand_types
[i
] == '0')
840 operand_types
[i
] = NULL
;
845 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
846 name
, operands
, base_opcode
, extension_opcode
,
849 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
851 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
853 fprintf (table
, " { ");
855 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
857 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
860 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
865 fprintf (table
, ",\n ");
867 process_i386_operand_type (table
, operand_types
[i
], 0,
870 fprintf (table
, " } },\n");
873 struct opcode_hash_entry
875 struct opcode_hash_entry
*next
;
881 /* Calculate the hash value of an opcode hash entry P. */
884 opcode_hash_hash (const void *p
)
886 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
887 return htab_hash_string (entry
->name
);
890 /* Compare a string Q against an opcode hash entry P. */
893 opcode_hash_eq (const void *p
, const void *q
)
895 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
896 const char *name
= (const char *) q
;
897 return strcmp (name
, entry
->name
) == 0;
901 process_i386_opcodes (FILE *table
)
906 char *str
, *p
, *last
, *name
;
907 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
908 htab_t opcode_hash_table
;
909 struct opcode_hash_entry
**opcode_array
;
910 unsigned int opcode_array_size
= 1024;
913 filename
= "i386-opc.tbl";
914 fp
= fopen (filename
, "r");
917 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
921 opcode_array
= (struct opcode_hash_entry
**)
922 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
924 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
925 opcode_hash_eq
, NULL
,
928 fprintf (table
, "\n/* i386 opcode table. */\n\n");
929 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
931 /* Put everything on opcode array. */
934 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
939 p
= remove_leading_whitespaces (buf
);
942 str
= strstr (p
, "//");
946 /* Remove trailing white spaces. */
947 remove_trailing_whitespaces (p
);
952 /* Ignore comments. */
960 last
= p
+ strlen (p
);
963 name
= next_field (p
, ',', &str
, last
);
965 /* Get the slot in hash table. */
966 hash_slot
= (struct opcode_hash_entry
**)
967 htab_find_slot_with_hash (opcode_hash_table
, name
,
968 htab_hash_string (name
),
971 if (*hash_slot
== NULL
)
973 /* It is the new one. Put it on opcode array. */
974 if (i
>= opcode_array_size
)
976 /* Grow the opcode array when needed. */
977 opcode_array_size
+= 1024;
978 opcode_array
= (struct opcode_hash_entry
**)
979 xrealloc (opcode_array
,
980 sizeof (*opcode_array
) * opcode_array_size
);
983 opcode_array
[i
] = (struct opcode_hash_entry
*)
984 xmalloc (sizeof (struct opcode_hash_entry
));
985 opcode_array
[i
]->next
= NULL
;
986 opcode_array
[i
]->name
= xstrdup (name
);
987 opcode_array
[i
]->opcode
= xstrdup (str
);
988 opcode_array
[i
]->lineno
= lineno
;
989 *hash_slot
= opcode_array
[i
];
994 /* Append it to the existing one. */
996 while ((*entry
) != NULL
)
997 entry
= &(*entry
)->next
;
998 *entry
= (struct opcode_hash_entry
*)
999 xmalloc (sizeof (struct opcode_hash_entry
));
1000 (*entry
)->next
= NULL
;
1001 (*entry
)->name
= (*hash_slot
)->name
;
1002 (*entry
)->opcode
= xstrdup (str
);
1003 (*entry
)->lineno
= lineno
;
1007 /* Process opcode array. */
1008 for (j
= 0; j
< i
; j
++)
1010 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1014 lineno
= next
->lineno
;
1015 last
= str
+ strlen (str
);
1016 output_i386_opcode (table
, name
, str
, last
, lineno
);
1022 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1024 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1026 process_i386_opcode_modifier (table
, "0", -1);
1028 fprintf (table
, " { ");
1029 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1030 fprintf (table
, " } }\n");
1032 fprintf (table
, "};\n");
1036 process_i386_registers (FILE *table
)
1040 char *str
, *p
, *last
;
1041 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1042 char *dw2_32_num
, *dw2_64_num
;
1045 filename
= "i386-reg.tbl";
1046 fp
= fopen (filename
, "r");
1048 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1051 fprintf (table
, "\n/* i386 register table. */\n\n");
1052 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1056 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1061 p
= remove_leading_whitespaces (buf
);
1063 /* Skip comments. */
1064 str
= strstr (p
, "//");
1068 /* Remove trailing white spaces. */
1069 remove_trailing_whitespaces (p
);
1074 fprintf (table
, "%s\n", p
);
1082 last
= p
+ strlen (p
);
1084 /* Find reg_name. */
1085 reg_name
= next_field (p
, ',', &str
, last
);
1087 /* Find reg_type. */
1088 reg_type
= next_field (str
, ',', &str
, last
);
1090 /* Find reg_flags. */
1091 reg_flags
= next_field (str
, ',', &str
, last
);
1094 reg_num
= next_field (str
, ',', &str
, last
);
1096 fprintf (table
, " { \"%s\",\n ", reg_name
);
1098 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1100 /* Find 32-bit Dwarf2 register number. */
1101 dw2_32_num
= next_field (str
, ',', &str
, last
);
1103 /* Find 64-bit Dwarf2 register number. */
1104 dw2_64_num
= next_field (str
, ',', &str
, last
);
1106 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1107 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1112 fprintf (table
, "};\n");
1114 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1118 process_i386_initializers (void)
1121 FILE *fp
= fopen ("i386-init.h", "w");
1125 fail (_("can't create i386-init.h, errno = %s\n"),
1128 process_copyright (fp
);
1130 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1132 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1133 init
= xstrdup (cpu_flag_init
[i
].init
);
1134 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1138 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1140 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1141 init
= xstrdup (operand_type_init
[i
].init
);
1142 process_i386_operand_type (fp
, init
, 1, " ", -1);
1150 /* Program options. */
1151 #define OPTION_SRCDIR 200
1153 struct option long_options
[] =
1155 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1156 {"debug", no_argument
, NULL
, 'd'},
1157 {"version", no_argument
, NULL
, 'V'},
1158 {"help", no_argument
, NULL
, 'h'},
1159 {0, no_argument
, NULL
, 0}
1163 print_version (void)
1165 printf ("%s: version 1.0\n", program_name
);
1170 usage (FILE * stream
, int status
)
1172 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1178 main (int argc
, char **argv
)
1180 extern int chdir (char *);
1181 char *srcdir
= NULL
;
1185 program_name
= *argv
;
1186 xmalloc_set_program_name (program_name
);
1188 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1213 if (chdir (srcdir
) != 0)
1214 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1215 srcdir
, xstrerror (errno
));
1217 /* Check the unused bitfield in i386_cpu_flags. */
1219 c
= CpuNumOfBits
- CpuMax
- 1;
1221 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1224 /* Check the unused bitfield in i386_operand_type. */
1226 c
= OTNumOfBits
- OTMax
- 1;
1228 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1231 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1234 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1235 sizeof (opcode_modifiers
[0]), compare
);
1237 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1238 sizeof (operand_types
[0]), compare
);
1240 table
= fopen ("i386-tbl.h", "w");
1242 fail (_("can't create i386-tbl.h, errno = %s\n"),
1245 process_copyright (table
);
1247 process_i386_opcodes (table
);
1248 process_i386_registers (table
);
1249 process_i386_initializers ();