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|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP" },
94 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C" },
102 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
103 { "CPU_CLFLUSH_FLAGS",
107 { "CPU_SYSCALL_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2" },
116 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
118 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
119 { "CPU_SSE4_1_FLAGS",
120 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
121 { "CPU_SSE4_2_FLAGS",
122 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
123 { "CPU_ANY_SSE_FLAGS",
124 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2" },
131 { "CPU_XSAVEOPT_FLAGS",
134 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
135 { "CPU_PCLMUL_FLAGS",
136 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
138 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
140 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
142 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
151 { "CPU_RDTSCP_FLAGS",
155 { "CPU_FSGSBASE_FLAGS",
165 { "CPU_INVPCID_FLAGS",
169 { "CPU_3DNOWA_FLAGS",
170 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
171 { "CPU_PADLOCK_FLAGS",
176 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
180 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
182 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
183 { "CPU_ANY_AVX_FLAGS",
189 static initializer operand_type_init
[] =
191 { "OPERAND_TYPE_NONE",
193 { "OPERAND_TYPE_REG8",
195 { "OPERAND_TYPE_REG16",
197 { "OPERAND_TYPE_REG32",
199 { "OPERAND_TYPE_REG64",
201 { "OPERAND_TYPE_IMM1",
203 { "OPERAND_TYPE_IMM8",
205 { "OPERAND_TYPE_IMM8S",
207 { "OPERAND_TYPE_IMM16",
209 { "OPERAND_TYPE_IMM32",
211 { "OPERAND_TYPE_IMM32S",
213 { "OPERAND_TYPE_IMM64",
215 { "OPERAND_TYPE_BASEINDEX",
217 { "OPERAND_TYPE_DISP8",
219 { "OPERAND_TYPE_DISP16",
221 { "OPERAND_TYPE_DISP32",
223 { "OPERAND_TYPE_DISP32S",
225 { "OPERAND_TYPE_DISP64",
227 { "OPERAND_TYPE_INOUTPORTREG",
229 { "OPERAND_TYPE_SHIFTCOUNT",
231 { "OPERAND_TYPE_CONTROL",
233 { "OPERAND_TYPE_TEST",
235 { "OPERAND_TYPE_DEBUG",
237 { "OPERAND_TYPE_FLOATREG",
239 { "OPERAND_TYPE_FLOATACC",
241 { "OPERAND_TYPE_SREG2",
243 { "OPERAND_TYPE_SREG3",
245 { "OPERAND_TYPE_ACC",
247 { "OPERAND_TYPE_JUMPABSOLUTE",
249 { "OPERAND_TYPE_REGMMX",
251 { "OPERAND_TYPE_REGXMM",
253 { "OPERAND_TYPE_REGYMM",
255 { "OPERAND_TYPE_ESSEG",
257 { "OPERAND_TYPE_ACC32",
259 { "OPERAND_TYPE_ACC64",
261 { "OPERAND_TYPE_INOUTPORTREG",
263 { "OPERAND_TYPE_REG16_INOUTPORTREG",
264 "Reg16|InOutPortReg" },
265 { "OPERAND_TYPE_DISP16_32",
267 { "OPERAND_TYPE_ANYDISP",
268 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
269 { "OPERAND_TYPE_IMM16_32",
271 { "OPERAND_TYPE_IMM16_32S",
273 { "OPERAND_TYPE_IMM16_32_32S",
274 "Imm16|Imm32|Imm32S" },
275 { "OPERAND_TYPE_IMM32_32S_DISP32",
276 "Imm32|Imm32S|Disp32" },
277 { "OPERAND_TYPE_IMM64_DISP64",
279 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
280 "Imm32|Imm32S|Imm64|Disp32" },
281 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
282 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
283 { "OPERAND_TYPE_VEC_IMM4",
287 typedef struct bitfield
294 #define BITFIELD(n) { n, 0, #n }
296 static bitfield cpu_flags
[] =
304 BITFIELD (CpuClflush
),
306 BITFIELD (CpuSYSCALL
),
311 BITFIELD (CpuFISTTP
),
317 BITFIELD (CpuSSE4_1
),
318 BITFIELD (CpuSSE4_2
),
324 BITFIELD (Cpu3dnowA
),
325 BITFIELD (CpuPadLock
),
331 BITFIELD (CpuXsaveopt
),
333 BITFIELD (CpuPCLMUL
),
343 BITFIELD (CpuRdtscp
),
344 BITFIELD (CpuFSGSBase
),
349 BITFIELD (CpuINVPCID
),
353 BITFIELD (CpuUnused
),
357 static bitfield opcode_modifiers
[] =
363 BITFIELD (ShortForm
),
365 BITFIELD (JumpDword
),
367 BITFIELD (JumpInterSegment
),
374 BITFIELD (CheckRegSize
),
375 BITFIELD (IgnoreSize
),
376 BITFIELD (DefaultSize
),
385 BITFIELD (IsLockable
),
386 BITFIELD (RegKludge
),
387 BITFIELD (FirstXmm0
),
388 BITFIELD (Implicit1stXmm0
),
391 BITFIELD (AddrPrefixOp0
),
400 BITFIELD (VexOpcode
),
401 BITFIELD (VexSources
),
402 BITFIELD (VexImmExt
),
407 BITFIELD (ATTMnemonic
),
408 BITFIELD (ATTSyntax
),
409 BITFIELD (IntelSyntax
),
412 static bitfield operand_types
[] =
429 BITFIELD (BaseIndex
),
435 BITFIELD (InOutPortReg
),
436 BITFIELD (ShiftCount
),
444 BITFIELD (JumpAbsolute
),
456 BITFIELD (Unspecified
),
464 static const char *filename
;
467 compare (const void *x
, const void *y
)
469 const bitfield
*xp
= (const bitfield
*) x
;
470 const bitfield
*yp
= (const bitfield
*) y
;
471 return xp
->position
- yp
->position
;
475 fail (const char *message
, ...)
479 va_start (args
, message
);
480 fprintf (stderr
, _("%s: Error: "), program_name
);
481 vfprintf (stderr
, message
, args
);
487 process_copyright (FILE *fp
)
489 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
490 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
491 Free Software Foundation, Inc.\n\
493 This file is part of the GNU opcodes library.\n\
495 This library is free software; you can redistribute it and/or modify\n\
496 it under the terms of the GNU General Public License as published by\n\
497 the Free Software Foundation; either version 3, or (at your option)\n\
498 any later version.\n\
500 It is distributed in the hope that it will be useful, but WITHOUT\n\
501 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
502 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
503 License for more details.\n\
505 You should have received a copy of the GNU General Public License\n\
506 along with this program; if not, write to the Free Software\n\
507 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
508 MA 02110-1301, USA. */\n");
511 /* Remove leading white spaces. */
514 remove_leading_whitespaces (char *str
)
516 while (ISSPACE (*str
))
521 /* Remove trailing white spaces. */
524 remove_trailing_whitespaces (char *str
)
526 size_t last
= strlen (str
);
534 if (ISSPACE (str
[last
]))
542 /* Find next field separated by SEP and terminate it. Return a
543 pointer to the one after it. */
546 next_field (char *str
, char sep
, char **next
, char *last
)
550 p
= remove_leading_whitespaces (str
);
551 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
554 remove_trailing_whitespaces (p
);
565 set_bitfield (const char *f
, bitfield
*array
, int value
,
566 unsigned int size
, int lineno
)
570 if (strcmp (f
, "CpuFP") == 0)
572 set_bitfield("Cpu387", array
, value
, size
, lineno
);
573 set_bitfield("Cpu287", array
, value
, size
, lineno
);
576 else if (strcmp (f
, "Mmword") == 0)
578 else if (strcmp (f
, "Oword") == 0)
581 for (i
= 0; i
< size
; i
++)
582 if (strcasecmp (array
[i
].name
, f
) == 0)
584 array
[i
].value
= value
;
590 const char *v
= strchr (f
, '=');
597 for (i
= 0; i
< size
; i
++)
598 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
600 value
= strtol (v
+ 1, &end
, 0);
603 array
[i
].value
= value
;
612 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
614 fail (_("Unknown bitfield: %s\n"), f
);
618 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
619 int macro
, const char *comma
, const char *indent
)
623 fprintf (table
, "%s{ { ", indent
);
625 for (i
= 0; i
< size
- 1; i
++)
627 fprintf (table
, "%d, ", flags
[i
].value
);
628 if (((i
+ 1) % 20) == 0)
630 /* We need \\ for macro. */
632 fprintf (table
, " \\\n %s", indent
);
634 fprintf (table
, "\n %s", indent
);
638 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
642 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
643 const char *comma
, const char *indent
,
646 char *str
, *next
, *last
;
648 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
650 /* Copy the default cpu flags. */
651 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
653 if (strcasecmp (flag
, "unknown") == 0)
655 /* We turn on everything except for cpu64 in case of
656 CPU_UNKNOWN_FLAGS. */
657 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
658 if (flags
[i
].position
!= Cpu64
)
661 else if (flag
[0] == '~')
663 last
= flag
+ strlen (flag
);
670 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
677 /* First we turn on everything except for cpu64. */
678 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
679 if (flags
[i
].position
!= Cpu64
)
682 /* Turn off selective bits. */
683 for (; next
&& next
< last
; )
685 str
= next_field (next
, '|', &next
, last
);
687 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
690 else if (strcmp (flag
, "0"))
692 /* Turn on selective bits. */
693 last
= flag
+ strlen (flag
);
694 for (next
= flag
; next
&& next
< last
; )
696 str
= next_field (next
, '|', &next
, last
);
698 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
702 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
707 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
711 fprintf (table
, " { ");
713 for (i
= 0; i
< size
- 1; i
++)
715 fprintf (table
, "%d, ", modifier
[i
].value
);
716 if (((i
+ 1) % 20) == 0)
717 fprintf (table
, "\n ");
720 fprintf (table
, "%d },\n", modifier
[i
].value
);
724 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
726 char *str
, *next
, *last
;
727 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
729 /* Copy the default opcode modifier. */
730 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
732 if (strcmp (mod
, "0"))
734 last
= mod
+ strlen (mod
);
735 for (next
= mod
; next
&& next
< last
; )
737 str
= next_field (next
, '|', &next
, last
);
739 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
743 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
747 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
748 int macro
, const char *indent
)
752 fprintf (table
, "{ { ");
754 for (i
= 0; i
< size
- 1; i
++)
756 fprintf (table
, "%d, ", types
[i
].value
);
757 if (((i
+ 1) % 20) == 0)
759 /* We need \\ for macro. */
761 fprintf (table
, "\\\n%s", indent
);
763 fprintf (table
, "\n%s", indent
);
767 fprintf (table
, "%d } }", types
[i
].value
);
771 process_i386_operand_type (FILE *table
, char *op
, int macro
,
772 const char *indent
, int lineno
)
774 char *str
, *next
, *last
;
775 bitfield types
[ARRAY_SIZE (operand_types
)];
777 /* Copy the default operand type. */
778 memcpy (types
, operand_types
, sizeof (types
));
780 if (strcmp (op
, "0"))
782 last
= op
+ strlen (op
);
783 for (next
= op
; next
&& next
< last
; )
785 str
= next_field (next
, '|', &next
, last
);
787 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
790 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
795 output_i386_opcode (FILE *table
, const char *name
, char *str
,
796 char *last
, int lineno
)
799 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
800 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
802 /* Find number of operands. */
803 operands
= next_field (str
, ',', &str
, last
);
805 /* Find base_opcode. */
806 base_opcode
= next_field (str
, ',', &str
, last
);
808 /* Find extension_opcode. */
809 extension_opcode
= next_field (str
, ',', &str
, last
);
811 /* Find opcode_length. */
812 opcode_length
= next_field (str
, ',', &str
, last
);
814 /* Find cpu_flags. */
815 cpu_flags
= next_field (str
, ',', &str
, last
);
817 /* Find opcode_modifier. */
818 opcode_modifier
= next_field (str
, ',', &str
, last
);
820 /* Remove the first {. */
821 str
= remove_leading_whitespaces (str
);
824 str
= remove_leading_whitespaces (str
+ 1);
828 /* There are at least "X}". */
832 /* Remove trailing white spaces and }. */
836 if (ISSPACE (str
[i
]) || str
[i
] == '}')
845 /* Find operand_types. */
846 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
850 operand_types
[i
] = NULL
;
854 operand_types
[i
] = next_field (str
, ',', &str
, last
);
855 if (*operand_types
[i
] == '0')
858 operand_types
[i
] = NULL
;
863 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
864 name
, operands
, base_opcode
, extension_opcode
,
867 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
869 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
871 fprintf (table
, " { ");
873 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
875 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
878 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
883 fprintf (table
, ",\n ");
885 process_i386_operand_type (table
, operand_types
[i
], 0,
888 fprintf (table
, " } },\n");
891 struct opcode_hash_entry
893 struct opcode_hash_entry
*next
;
899 /* Calculate the hash value of an opcode hash entry P. */
902 opcode_hash_hash (const void *p
)
904 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
905 return htab_hash_string (entry
->name
);
908 /* Compare a string Q against an opcode hash entry P. */
911 opcode_hash_eq (const void *p
, const void *q
)
913 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
914 const char *name
= (const char *) q
;
915 return strcmp (name
, entry
->name
) == 0;
919 process_i386_opcodes (FILE *table
)
924 char *str
, *p
, *last
, *name
;
925 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
926 htab_t opcode_hash_table
;
927 struct opcode_hash_entry
**opcode_array
;
928 unsigned int opcode_array_size
= 1024;
931 filename
= "i386-opc.tbl";
932 fp
= fopen (filename
, "r");
935 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
939 opcode_array
= (struct opcode_hash_entry
**)
940 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
942 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
943 opcode_hash_eq
, NULL
,
946 fprintf (table
, "\n/* i386 opcode table. */\n\n");
947 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
949 /* Put everything on opcode array. */
952 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
957 p
= remove_leading_whitespaces (buf
);
960 str
= strstr (p
, "//");
964 /* Remove trailing white spaces. */
965 remove_trailing_whitespaces (p
);
970 /* Ignore comments. */
978 last
= p
+ strlen (p
);
981 name
= next_field (p
, ',', &str
, last
);
983 /* Get the slot in hash table. */
984 hash_slot
= (struct opcode_hash_entry
**)
985 htab_find_slot_with_hash (opcode_hash_table
, name
,
986 htab_hash_string (name
),
989 if (*hash_slot
== NULL
)
991 /* It is the new one. Put it on opcode array. */
992 if (i
>= opcode_array_size
)
994 /* Grow the opcode array when needed. */
995 opcode_array_size
+= 1024;
996 opcode_array
= (struct opcode_hash_entry
**)
997 xrealloc (opcode_array
,
998 sizeof (*opcode_array
) * opcode_array_size
);
1001 opcode_array
[i
] = (struct opcode_hash_entry
*)
1002 xmalloc (sizeof (struct opcode_hash_entry
));
1003 opcode_array
[i
]->next
= NULL
;
1004 opcode_array
[i
]->name
= xstrdup (name
);
1005 opcode_array
[i
]->opcode
= xstrdup (str
);
1006 opcode_array
[i
]->lineno
= lineno
;
1007 *hash_slot
= opcode_array
[i
];
1012 /* Append it to the existing one. */
1014 while ((*entry
) != NULL
)
1015 entry
= &(*entry
)->next
;
1016 *entry
= (struct opcode_hash_entry
*)
1017 xmalloc (sizeof (struct opcode_hash_entry
));
1018 (*entry
)->next
= NULL
;
1019 (*entry
)->name
= (*hash_slot
)->name
;
1020 (*entry
)->opcode
= xstrdup (str
);
1021 (*entry
)->lineno
= lineno
;
1025 /* Process opcode array. */
1026 for (j
= 0; j
< i
; j
++)
1028 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1032 lineno
= next
->lineno
;
1033 last
= str
+ strlen (str
);
1034 output_i386_opcode (table
, name
, str
, last
, lineno
);
1040 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1042 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1044 process_i386_opcode_modifier (table
, "0", -1);
1046 fprintf (table
, " { ");
1047 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1048 fprintf (table
, " } }\n");
1050 fprintf (table
, "};\n");
1054 process_i386_registers (FILE *table
)
1058 char *str
, *p
, *last
;
1059 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1060 char *dw2_32_num
, *dw2_64_num
;
1063 filename
= "i386-reg.tbl";
1064 fp
= fopen (filename
, "r");
1066 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1069 fprintf (table
, "\n/* i386 register table. */\n\n");
1070 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1074 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1079 p
= remove_leading_whitespaces (buf
);
1081 /* Skip comments. */
1082 str
= strstr (p
, "//");
1086 /* Remove trailing white spaces. */
1087 remove_trailing_whitespaces (p
);
1092 fprintf (table
, "%s\n", p
);
1100 last
= p
+ strlen (p
);
1102 /* Find reg_name. */
1103 reg_name
= next_field (p
, ',', &str
, last
);
1105 /* Find reg_type. */
1106 reg_type
= next_field (str
, ',', &str
, last
);
1108 /* Find reg_flags. */
1109 reg_flags
= next_field (str
, ',', &str
, last
);
1112 reg_num
= next_field (str
, ',', &str
, last
);
1114 fprintf (table
, " { \"%s\",\n ", reg_name
);
1116 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1118 /* Find 32-bit Dwarf2 register number. */
1119 dw2_32_num
= next_field (str
, ',', &str
, last
);
1121 /* Find 64-bit Dwarf2 register number. */
1122 dw2_64_num
= next_field (str
, ',', &str
, last
);
1124 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1125 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1130 fprintf (table
, "};\n");
1132 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1136 process_i386_initializers (void)
1139 FILE *fp
= fopen ("i386-init.h", "w");
1143 fail (_("can't create i386-init.h, errno = %s\n"),
1146 process_copyright (fp
);
1148 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1150 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1151 init
= xstrdup (cpu_flag_init
[i
].init
);
1152 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1156 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1158 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1159 init
= xstrdup (operand_type_init
[i
].init
);
1160 process_i386_operand_type (fp
, init
, 1, " ", -1);
1168 /* Program options. */
1169 #define OPTION_SRCDIR 200
1171 struct option long_options
[] =
1173 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1174 {"debug", no_argument
, NULL
, 'd'},
1175 {"version", no_argument
, NULL
, 'V'},
1176 {"help", no_argument
, NULL
, 'h'},
1177 {0, no_argument
, NULL
, 0}
1181 print_version (void)
1183 printf ("%s: version 1.0\n", program_name
);
1188 usage (FILE * stream
, int status
)
1190 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1196 main (int argc
, char **argv
)
1198 extern int chdir (char *);
1199 char *srcdir
= NULL
;
1203 program_name
= *argv
;
1204 xmalloc_set_program_name (program_name
);
1206 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1231 if (chdir (srcdir
) != 0)
1232 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1233 srcdir
, xstrerror (errno
));
1235 /* Check the unused bitfield in i386_cpu_flags. */
1237 c
= CpuNumOfBits
- CpuMax
- 1;
1239 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1242 /* Check the unused bitfield in i386_operand_type. */
1244 c
= OTNumOfBits
- OTMax
- 1;
1246 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1249 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1252 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1253 sizeof (opcode_modifiers
[0]), compare
);
1255 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1256 sizeof (operand_types
[0]), compare
);
1258 table
= fopen ("i386-tbl.h", "w");
1260 fail (_("can't create i386-tbl.h, errno = %s\n"),
1263 process_copyright (table
);
1265 process_i386_opcodes (table
);
1266 process_i386_registers (table
);
1267 process_i386_initializers ();