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" },
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",
163 { "CPU_3DNOWA_FLAGS",
164 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
165 { "CPU_PADLOCK_FLAGS",
170 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
174 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
175 { "CPU_ANY_AVX_FLAGS",
181 static initializer operand_type_init
[] =
183 { "OPERAND_TYPE_NONE",
185 { "OPERAND_TYPE_REG8",
187 { "OPERAND_TYPE_REG16",
189 { "OPERAND_TYPE_REG32",
191 { "OPERAND_TYPE_REG64",
193 { "OPERAND_TYPE_IMM1",
195 { "OPERAND_TYPE_IMM8",
197 { "OPERAND_TYPE_IMM8S",
199 { "OPERAND_TYPE_IMM16",
201 { "OPERAND_TYPE_IMM32",
203 { "OPERAND_TYPE_IMM32S",
205 { "OPERAND_TYPE_IMM64",
207 { "OPERAND_TYPE_BASEINDEX",
209 { "OPERAND_TYPE_DISP8",
211 { "OPERAND_TYPE_DISP16",
213 { "OPERAND_TYPE_DISP32",
215 { "OPERAND_TYPE_DISP32S",
217 { "OPERAND_TYPE_DISP64",
219 { "OPERAND_TYPE_INOUTPORTREG",
221 { "OPERAND_TYPE_SHIFTCOUNT",
223 { "OPERAND_TYPE_CONTROL",
225 { "OPERAND_TYPE_TEST",
227 { "OPERAND_TYPE_DEBUG",
229 { "OPERAND_TYPE_FLOATREG",
231 { "OPERAND_TYPE_FLOATACC",
233 { "OPERAND_TYPE_SREG2",
235 { "OPERAND_TYPE_SREG3",
237 { "OPERAND_TYPE_ACC",
239 { "OPERAND_TYPE_JUMPABSOLUTE",
241 { "OPERAND_TYPE_REGMMX",
243 { "OPERAND_TYPE_REGXMM",
245 { "OPERAND_TYPE_REGYMM",
247 { "OPERAND_TYPE_ESSEG",
249 { "OPERAND_TYPE_ACC32",
251 { "OPERAND_TYPE_ACC64",
253 { "OPERAND_TYPE_INOUTPORTREG",
255 { "OPERAND_TYPE_REG16_INOUTPORTREG",
256 "Reg16|InOutPortReg" },
257 { "OPERAND_TYPE_DISP16_32",
259 { "OPERAND_TYPE_ANYDISP",
260 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
261 { "OPERAND_TYPE_IMM16_32",
263 { "OPERAND_TYPE_IMM16_32S",
265 { "OPERAND_TYPE_IMM16_32_32S",
266 "Imm16|Imm32|Imm32S" },
267 { "OPERAND_TYPE_IMM32_32S_DISP32",
268 "Imm32|Imm32S|Disp32" },
269 { "OPERAND_TYPE_IMM64_DISP64",
271 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
272 "Imm32|Imm32S|Imm64|Disp32" },
273 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
274 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
275 { "OPERAND_TYPE_VEC_IMM4",
279 typedef struct bitfield
286 #define BITFIELD(n) { n, 0, #n }
288 static bitfield cpu_flags
[] =
296 BITFIELD (CpuClflush
),
298 BITFIELD (CpuSYSCALL
),
303 BITFIELD (CpuFISTTP
),
309 BITFIELD (CpuSSE4_1
),
310 BITFIELD (CpuSSE4_2
),
315 BITFIELD (Cpu3dnowA
),
316 BITFIELD (CpuPadLock
),
322 BITFIELD (CpuXsaveopt
),
324 BITFIELD (CpuPCLMUL
),
334 BITFIELD (CpuRdtscp
),
335 BITFIELD (CpuFSGSBase
),
341 BITFIELD (CpuUnused
),
345 static bitfield opcode_modifiers
[] =
351 BITFIELD (ShortForm
),
353 BITFIELD (JumpDword
),
355 BITFIELD (JumpInterSegment
),
362 BITFIELD (CheckRegSize
),
363 BITFIELD (IgnoreSize
),
364 BITFIELD (DefaultSize
),
373 BITFIELD (IsLockable
),
374 BITFIELD (RegKludge
),
375 BITFIELD (FirstXmm0
),
376 BITFIELD (Implicit1stXmm0
),
379 BITFIELD (AddrPrefixOp0
),
388 BITFIELD (VexOpcode
),
389 BITFIELD (VexSources
),
390 BITFIELD (VexImmExt
),
394 BITFIELD (ATTMnemonic
),
395 BITFIELD (ATTSyntax
),
396 BITFIELD (IntelSyntax
),
399 static bitfield operand_types
[] =
416 BITFIELD (BaseIndex
),
422 BITFIELD (InOutPortReg
),
423 BITFIELD (ShiftCount
),
431 BITFIELD (JumpAbsolute
),
443 BITFIELD (Unspecified
),
451 static const char *filename
;
454 compare (const void *x
, const void *y
)
456 const bitfield
*xp
= (const bitfield
*) x
;
457 const bitfield
*yp
= (const bitfield
*) y
;
458 return xp
->position
- yp
->position
;
462 fail (const char *message
, ...)
466 va_start (args
, message
);
467 fprintf (stderr
, _("%s: Error: "), program_name
);
468 vfprintf (stderr
, message
, args
);
474 process_copyright (FILE *fp
)
476 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
477 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
478 Free Software Foundation, Inc.\n\
480 This file is part of the GNU opcodes library.\n\
482 This library is free software; you can redistribute it and/or modify\n\
483 it under the terms of the GNU General Public License as published by\n\
484 the Free Software Foundation; either version 3, or (at your option)\n\
485 any later version.\n\
487 It is distributed in the hope that it will be useful, but WITHOUT\n\
488 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
489 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
490 License for more details.\n\
492 You should have received a copy of the GNU General Public License\n\
493 along with this program; if not, write to the Free Software\n\
494 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
495 MA 02110-1301, USA. */\n");
498 /* Remove leading white spaces. */
501 remove_leading_whitespaces (char *str
)
503 while (ISSPACE (*str
))
508 /* Remove trailing white spaces. */
511 remove_trailing_whitespaces (char *str
)
513 size_t last
= strlen (str
);
521 if (ISSPACE (str
[last
]))
529 /* Find next field separated by SEP and terminate it. Return a
530 pointer to the one after it. */
533 next_field (char *str
, char sep
, char **next
, char *last
)
537 p
= remove_leading_whitespaces (str
);
538 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
541 remove_trailing_whitespaces (p
);
552 set_bitfield (const char *f
, bitfield
*array
, int value
,
553 unsigned int size
, int lineno
)
557 if (strcmp (f
, "CpuFP") == 0)
559 set_bitfield("Cpu387", array
, value
, size
, lineno
);
560 set_bitfield("Cpu287", array
, value
, size
, lineno
);
563 else if (strcmp (f
, "Mmword") == 0)
565 else if (strcmp (f
, "Oword") == 0)
568 for (i
= 0; i
< size
; i
++)
569 if (strcasecmp (array
[i
].name
, f
) == 0)
571 array
[i
].value
= value
;
577 const char *v
= strchr (f
, '=');
584 for (i
= 0; i
< size
; i
++)
585 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
587 value
= strtol (v
+ 1, &end
, 0);
590 array
[i
].value
= value
;
599 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
601 fail (_("Unknown bitfield: %s\n"), f
);
605 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
606 int macro
, const char *comma
, const char *indent
)
610 fprintf (table
, "%s{ { ", indent
);
612 for (i
= 0; i
< size
- 1; i
++)
614 fprintf (table
, "%d, ", flags
[i
].value
);
615 if (((i
+ 1) % 20) == 0)
617 /* We need \\ for macro. */
619 fprintf (table
, " \\\n %s", indent
);
621 fprintf (table
, "\n %s", indent
);
625 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
629 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
630 const char *comma
, const char *indent
,
633 char *str
, *next
, *last
;
635 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
637 /* Copy the default cpu flags. */
638 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
640 if (strcasecmp (flag
, "unknown") == 0)
642 /* We turn on everything except for cpu64 in case of
643 CPU_UNKNOWN_FLAGS. */
644 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
645 if (flags
[i
].position
!= Cpu64
)
648 else if (flag
[0] == '~')
650 last
= flag
+ strlen (flag
);
657 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
664 /* First we turn on everything except for cpu64. */
665 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
666 if (flags
[i
].position
!= Cpu64
)
669 /* Turn off selective bits. */
670 for (; next
&& next
< last
; )
672 str
= next_field (next
, '|', &next
, last
);
674 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
677 else if (strcmp (flag
, "0"))
679 /* Turn on selective bits. */
680 last
= flag
+ strlen (flag
);
681 for (next
= flag
; next
&& next
< last
; )
683 str
= next_field (next
, '|', &next
, last
);
685 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
689 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
694 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
698 fprintf (table
, " { ");
700 for (i
= 0; i
< size
- 1; i
++)
702 fprintf (table
, "%d, ", modifier
[i
].value
);
703 if (((i
+ 1) % 20) == 0)
704 fprintf (table
, "\n ");
707 fprintf (table
, "%d },\n", modifier
[i
].value
);
711 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
713 char *str
, *next
, *last
;
714 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
716 /* Copy the default opcode modifier. */
717 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
719 if (strcmp (mod
, "0"))
721 last
= mod
+ strlen (mod
);
722 for (next
= mod
; next
&& next
< last
; )
724 str
= next_field (next
, '|', &next
, last
);
726 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
730 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
734 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
735 int macro
, const char *indent
)
739 fprintf (table
, "{ { ");
741 for (i
= 0; i
< size
- 1; i
++)
743 fprintf (table
, "%d, ", types
[i
].value
);
744 if (((i
+ 1) % 20) == 0)
746 /* We need \\ for macro. */
748 fprintf (table
, "\\\n%s", indent
);
750 fprintf (table
, "\n%s", indent
);
754 fprintf (table
, "%d } }", types
[i
].value
);
758 process_i386_operand_type (FILE *table
, char *op
, int macro
,
759 const char *indent
, int lineno
)
761 char *str
, *next
, *last
;
762 bitfield types
[ARRAY_SIZE (operand_types
)];
764 /* Copy the default operand type. */
765 memcpy (types
, operand_types
, sizeof (types
));
767 if (strcmp (op
, "0"))
769 last
= op
+ strlen (op
);
770 for (next
= op
; next
&& next
< last
; )
772 str
= next_field (next
, '|', &next
, last
);
774 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
777 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
782 output_i386_opcode (FILE *table
, const char *name
, char *str
,
783 char *last
, int lineno
)
786 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
787 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
789 /* Find number of operands. */
790 operands
= next_field (str
, ',', &str
, last
);
792 /* Find base_opcode. */
793 base_opcode
= next_field (str
, ',', &str
, last
);
795 /* Find extension_opcode. */
796 extension_opcode
= next_field (str
, ',', &str
, last
);
798 /* Find opcode_length. */
799 opcode_length
= next_field (str
, ',', &str
, last
);
801 /* Find cpu_flags. */
802 cpu_flags
= next_field (str
, ',', &str
, last
);
804 /* Find opcode_modifier. */
805 opcode_modifier
= next_field (str
, ',', &str
, last
);
807 /* Remove the first {. */
808 str
= remove_leading_whitespaces (str
);
811 str
= remove_leading_whitespaces (str
+ 1);
815 /* There are at least "X}". */
819 /* Remove trailing white spaces and }. */
823 if (ISSPACE (str
[i
]) || str
[i
] == '}')
832 /* Find operand_types. */
833 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
837 operand_types
[i
] = NULL
;
841 operand_types
[i
] = next_field (str
, ',', &str
, last
);
842 if (*operand_types
[i
] == '0')
845 operand_types
[i
] = NULL
;
850 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
851 name
, operands
, base_opcode
, extension_opcode
,
854 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
856 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
858 fprintf (table
, " { ");
860 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
862 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
865 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
870 fprintf (table
, ",\n ");
872 process_i386_operand_type (table
, operand_types
[i
], 0,
875 fprintf (table
, " } },\n");
878 struct opcode_hash_entry
880 struct opcode_hash_entry
*next
;
886 /* Calculate the hash value of an opcode hash entry P. */
889 opcode_hash_hash (const void *p
)
891 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
892 return htab_hash_string (entry
->name
);
895 /* Compare a string Q against an opcode hash entry P. */
898 opcode_hash_eq (const void *p
, const void *q
)
900 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
901 const char *name
= (const char *) q
;
902 return strcmp (name
, entry
->name
) == 0;
906 process_i386_opcodes (FILE *table
)
911 char *str
, *p
, *last
, *name
;
912 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
913 htab_t opcode_hash_table
;
914 struct opcode_hash_entry
**opcode_array
;
915 unsigned int opcode_array_size
= 1024;
918 filename
= "i386-opc.tbl";
919 fp
= fopen (filename
, "r");
922 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
926 opcode_array
= (struct opcode_hash_entry
**)
927 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
929 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
930 opcode_hash_eq
, NULL
,
933 fprintf (table
, "\n/* i386 opcode table. */\n\n");
934 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
936 /* Put everything on opcode array. */
939 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
944 p
= remove_leading_whitespaces (buf
);
947 str
= strstr (p
, "//");
951 /* Remove trailing white spaces. */
952 remove_trailing_whitespaces (p
);
957 /* Ignore comments. */
965 last
= p
+ strlen (p
);
968 name
= next_field (p
, ',', &str
, last
);
970 /* Get the slot in hash table. */
971 hash_slot
= (struct opcode_hash_entry
**)
972 htab_find_slot_with_hash (opcode_hash_table
, name
,
973 htab_hash_string (name
),
976 if (*hash_slot
== NULL
)
978 /* It is the new one. Put it on opcode array. */
979 if (i
>= opcode_array_size
)
981 /* Grow the opcode array when needed. */
982 opcode_array_size
+= 1024;
983 opcode_array
= (struct opcode_hash_entry
**)
984 xrealloc (opcode_array
,
985 sizeof (*opcode_array
) * opcode_array_size
);
988 opcode_array
[i
] = (struct opcode_hash_entry
*)
989 xmalloc (sizeof (struct opcode_hash_entry
));
990 opcode_array
[i
]->next
= NULL
;
991 opcode_array
[i
]->name
= xstrdup (name
);
992 opcode_array
[i
]->opcode
= xstrdup (str
);
993 opcode_array
[i
]->lineno
= lineno
;
994 *hash_slot
= opcode_array
[i
];
999 /* Append it to the existing one. */
1001 while ((*entry
) != NULL
)
1002 entry
= &(*entry
)->next
;
1003 *entry
= (struct opcode_hash_entry
*)
1004 xmalloc (sizeof (struct opcode_hash_entry
));
1005 (*entry
)->next
= NULL
;
1006 (*entry
)->name
= (*hash_slot
)->name
;
1007 (*entry
)->opcode
= xstrdup (str
);
1008 (*entry
)->lineno
= lineno
;
1012 /* Process opcode array. */
1013 for (j
= 0; j
< i
; j
++)
1015 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1019 lineno
= next
->lineno
;
1020 last
= str
+ strlen (str
);
1021 output_i386_opcode (table
, name
, str
, last
, lineno
);
1027 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1029 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1031 process_i386_opcode_modifier (table
, "0", -1);
1033 fprintf (table
, " { ");
1034 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1035 fprintf (table
, " } }\n");
1037 fprintf (table
, "};\n");
1041 process_i386_registers (FILE *table
)
1045 char *str
, *p
, *last
;
1046 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1047 char *dw2_32_num
, *dw2_64_num
;
1050 filename
= "i386-reg.tbl";
1051 fp
= fopen (filename
, "r");
1053 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1056 fprintf (table
, "\n/* i386 register table. */\n\n");
1057 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1061 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1066 p
= remove_leading_whitespaces (buf
);
1068 /* Skip comments. */
1069 str
= strstr (p
, "//");
1073 /* Remove trailing white spaces. */
1074 remove_trailing_whitespaces (p
);
1079 fprintf (table
, "%s\n", p
);
1087 last
= p
+ strlen (p
);
1089 /* Find reg_name. */
1090 reg_name
= next_field (p
, ',', &str
, last
);
1092 /* Find reg_type. */
1093 reg_type
= next_field (str
, ',', &str
, last
);
1095 /* Find reg_flags. */
1096 reg_flags
= next_field (str
, ',', &str
, last
);
1099 reg_num
= next_field (str
, ',', &str
, last
);
1101 fprintf (table
, " { \"%s\",\n ", reg_name
);
1103 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1105 /* Find 32-bit Dwarf2 register number. */
1106 dw2_32_num
= next_field (str
, ',', &str
, last
);
1108 /* Find 64-bit Dwarf2 register number. */
1109 dw2_64_num
= next_field (str
, ',', &str
, last
);
1111 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1112 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1117 fprintf (table
, "};\n");
1119 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1123 process_i386_initializers (void)
1126 FILE *fp
= fopen ("i386-init.h", "w");
1130 fail (_("can't create i386-init.h, errno = %s\n"),
1133 process_copyright (fp
);
1135 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1137 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1138 init
= xstrdup (cpu_flag_init
[i
].init
);
1139 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1143 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1145 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1146 init
= xstrdup (operand_type_init
[i
].init
);
1147 process_i386_operand_type (fp
, init
, 1, " ", -1);
1155 /* Program options. */
1156 #define OPTION_SRCDIR 200
1158 struct option long_options
[] =
1160 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1161 {"debug", no_argument
, NULL
, 'd'},
1162 {"version", no_argument
, NULL
, 'V'},
1163 {"help", no_argument
, NULL
, 'h'},
1164 {0, no_argument
, NULL
, 0}
1168 print_version (void)
1170 printf ("%s: version 1.0\n", program_name
);
1175 usage (FILE * stream
, int status
)
1177 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1183 main (int argc
, char **argv
)
1185 extern int chdir (char *);
1186 char *srcdir
= NULL
;
1190 program_name
= *argv
;
1191 xmalloc_set_program_name (program_name
);
1193 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1218 if (chdir (srcdir
) != 0)
1219 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1220 srcdir
, xstrerror (errno
));
1222 /* Check the unused bitfield in i386_cpu_flags. */
1224 c
= CpuNumOfBits
- CpuMax
- 1;
1226 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1229 /* Check the unused bitfield in i386_operand_type. */
1231 c
= OTNumOfBits
- OTMax
- 1;
1233 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1236 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1239 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1240 sizeof (opcode_modifiers
[0]), compare
);
1242 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1243 sizeof (operand_types
[0]), compare
);
1245 table
= fopen ("i386-tbl.h", "w");
1247 fail (_("can't create i386-tbl.h, errno = %s\n"),
1250 process_copyright (table
);
1252 process_i386_opcodes (table
);
1253 process_i386_registers (table
);
1254 process_i386_initializers ();