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",
46 "~(CpuL1OM|CpuK1OM)" },
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",
191 static initializer operand_type_init
[] =
193 { "OPERAND_TYPE_NONE",
195 { "OPERAND_TYPE_REG8",
197 { "OPERAND_TYPE_REG16",
199 { "OPERAND_TYPE_REG32",
201 { "OPERAND_TYPE_REG64",
203 { "OPERAND_TYPE_IMM1",
205 { "OPERAND_TYPE_IMM8",
207 { "OPERAND_TYPE_IMM8S",
209 { "OPERAND_TYPE_IMM16",
211 { "OPERAND_TYPE_IMM32",
213 { "OPERAND_TYPE_IMM32S",
215 { "OPERAND_TYPE_IMM64",
217 { "OPERAND_TYPE_BASEINDEX",
219 { "OPERAND_TYPE_DISP8",
221 { "OPERAND_TYPE_DISP16",
223 { "OPERAND_TYPE_DISP32",
225 { "OPERAND_TYPE_DISP32S",
227 { "OPERAND_TYPE_DISP64",
229 { "OPERAND_TYPE_INOUTPORTREG",
231 { "OPERAND_TYPE_SHIFTCOUNT",
233 { "OPERAND_TYPE_CONTROL",
235 { "OPERAND_TYPE_TEST",
237 { "OPERAND_TYPE_DEBUG",
239 { "OPERAND_TYPE_FLOATREG",
241 { "OPERAND_TYPE_FLOATACC",
243 { "OPERAND_TYPE_SREG2",
245 { "OPERAND_TYPE_SREG3",
247 { "OPERAND_TYPE_ACC",
249 { "OPERAND_TYPE_JUMPABSOLUTE",
251 { "OPERAND_TYPE_REGMMX",
253 { "OPERAND_TYPE_REGXMM",
255 { "OPERAND_TYPE_REGYMM",
257 { "OPERAND_TYPE_ESSEG",
259 { "OPERAND_TYPE_ACC32",
261 { "OPERAND_TYPE_ACC64",
263 { "OPERAND_TYPE_INOUTPORTREG",
265 { "OPERAND_TYPE_REG16_INOUTPORTREG",
266 "Reg16|InOutPortReg" },
267 { "OPERAND_TYPE_DISP16_32",
269 { "OPERAND_TYPE_ANYDISP",
270 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
271 { "OPERAND_TYPE_IMM16_32",
273 { "OPERAND_TYPE_IMM16_32S",
275 { "OPERAND_TYPE_IMM16_32_32S",
276 "Imm16|Imm32|Imm32S" },
277 { "OPERAND_TYPE_IMM32_32S_DISP32",
278 "Imm32|Imm32S|Disp32" },
279 { "OPERAND_TYPE_IMM64_DISP64",
281 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
282 "Imm32|Imm32S|Imm64|Disp32" },
283 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
284 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
285 { "OPERAND_TYPE_VEC_IMM4",
289 typedef struct bitfield
296 #define BITFIELD(n) { n, 0, #n }
298 static bitfield cpu_flags
[] =
306 BITFIELD (CpuClflush
),
308 BITFIELD (CpuSYSCALL
),
313 BITFIELD (CpuFISTTP
),
319 BITFIELD (CpuSSE4_1
),
320 BITFIELD (CpuSSE4_2
),
327 BITFIELD (Cpu3dnowA
),
328 BITFIELD (CpuPadLock
),
334 BITFIELD (CpuXsaveopt
),
336 BITFIELD (CpuPCLMUL
),
346 BITFIELD (CpuRdtscp
),
347 BITFIELD (CpuFSGSBase
),
352 BITFIELD (CpuINVPCID
),
356 BITFIELD (CpuUnused
),
360 static bitfield opcode_modifiers
[] =
366 BITFIELD (ShortForm
),
368 BITFIELD (JumpDword
),
370 BITFIELD (JumpInterSegment
),
377 BITFIELD (CheckRegSize
),
378 BITFIELD (IgnoreSize
),
379 BITFIELD (DefaultSize
),
388 BITFIELD (IsLockable
),
389 BITFIELD (RegKludge
),
390 BITFIELD (FirstXmm0
),
391 BITFIELD (Implicit1stXmm0
),
394 BITFIELD (AddrPrefixOp0
),
403 BITFIELD (VexOpcode
),
404 BITFIELD (VexSources
),
405 BITFIELD (VexImmExt
),
410 BITFIELD (ATTMnemonic
),
411 BITFIELD (ATTSyntax
),
412 BITFIELD (IntelSyntax
),
415 static bitfield operand_types
[] =
432 BITFIELD (BaseIndex
),
438 BITFIELD (InOutPortReg
),
439 BITFIELD (ShiftCount
),
447 BITFIELD (JumpAbsolute
),
459 BITFIELD (Unspecified
),
467 static const char *filename
;
470 compare (const void *x
, const void *y
)
472 const bitfield
*xp
= (const bitfield
*) x
;
473 const bitfield
*yp
= (const bitfield
*) y
;
474 return xp
->position
- yp
->position
;
478 fail (const char *message
, ...)
482 va_start (args
, message
);
483 fprintf (stderr
, _("%s: Error: "), program_name
);
484 vfprintf (stderr
, message
, args
);
490 process_copyright (FILE *fp
)
492 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
493 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
494 Free Software Foundation, Inc.\n\
496 This file is part of the GNU opcodes library.\n\
498 This library is free software; you can redistribute it and/or modify\n\
499 it under the terms of the GNU General Public License as published by\n\
500 the Free Software Foundation; either version 3, or (at your option)\n\
501 any later version.\n\
503 It is distributed in the hope that it will be useful, but WITHOUT\n\
504 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
505 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
506 License for more details.\n\
508 You should have received a copy of the GNU General Public License\n\
509 along with this program; if not, write to the Free Software\n\
510 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
511 MA 02110-1301, USA. */\n");
514 /* Remove leading white spaces. */
517 remove_leading_whitespaces (char *str
)
519 while (ISSPACE (*str
))
524 /* Remove trailing white spaces. */
527 remove_trailing_whitespaces (char *str
)
529 size_t last
= strlen (str
);
537 if (ISSPACE (str
[last
]))
545 /* Find next field separated by SEP and terminate it. Return a
546 pointer to the one after it. */
549 next_field (char *str
, char sep
, char **next
, char *last
)
553 p
= remove_leading_whitespaces (str
);
554 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
557 remove_trailing_whitespaces (p
);
568 set_bitfield (const char *f
, bitfield
*array
, int value
,
569 unsigned int size
, int lineno
)
573 if (strcmp (f
, "CpuFP") == 0)
575 set_bitfield("Cpu387", array
, value
, size
, lineno
);
576 set_bitfield("Cpu287", array
, value
, size
, lineno
);
579 else if (strcmp (f
, "Mmword") == 0)
581 else if (strcmp (f
, "Oword") == 0)
584 for (i
= 0; i
< size
; i
++)
585 if (strcasecmp (array
[i
].name
, f
) == 0)
587 array
[i
].value
= value
;
593 const char *v
= strchr (f
, '=');
600 for (i
= 0; i
< size
; i
++)
601 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
603 value
= strtol (v
+ 1, &end
, 0);
606 array
[i
].value
= value
;
615 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
617 fail (_("Unknown bitfield: %s\n"), f
);
621 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
622 int macro
, const char *comma
, const char *indent
)
626 fprintf (table
, "%s{ { ", indent
);
628 for (i
= 0; i
< size
- 1; i
++)
630 fprintf (table
, "%d, ", flags
[i
].value
);
631 if (((i
+ 1) % 20) == 0)
633 /* We need \\ for macro. */
635 fprintf (table
, " \\\n %s", indent
);
637 fprintf (table
, "\n %s", indent
);
641 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
645 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
646 const char *comma
, const char *indent
,
649 char *str
, *next
, *last
;
651 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
653 /* Copy the default cpu flags. */
654 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
656 if (strcasecmp (flag
, "unknown") == 0)
658 /* We turn on everything except for cpu64 in case of
659 CPU_UNKNOWN_FLAGS. */
660 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
661 if (flags
[i
].position
!= Cpu64
)
664 else if (flag
[0] == '~')
666 last
= flag
+ strlen (flag
);
673 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
680 /* First we turn on everything except for cpu64. */
681 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
682 if (flags
[i
].position
!= Cpu64
)
685 /* Turn off selective bits. */
686 for (; next
&& next
< last
; )
688 str
= next_field (next
, '|', &next
, last
);
690 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
693 else if (strcmp (flag
, "0"))
695 /* Turn on selective bits. */
696 last
= flag
+ strlen (flag
);
697 for (next
= flag
; next
&& next
< last
; )
699 str
= next_field (next
, '|', &next
, last
);
701 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
705 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
710 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
714 fprintf (table
, " { ");
716 for (i
= 0; i
< size
- 1; i
++)
718 fprintf (table
, "%d, ", modifier
[i
].value
);
719 if (((i
+ 1) % 20) == 0)
720 fprintf (table
, "\n ");
723 fprintf (table
, "%d },\n", modifier
[i
].value
);
727 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
729 char *str
, *next
, *last
;
730 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
732 /* Copy the default opcode modifier. */
733 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
735 if (strcmp (mod
, "0"))
737 last
= mod
+ strlen (mod
);
738 for (next
= mod
; next
&& next
< last
; )
740 str
= next_field (next
, '|', &next
, last
);
742 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
746 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
750 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
751 int macro
, const char *indent
)
755 fprintf (table
, "{ { ");
757 for (i
= 0; i
< size
- 1; i
++)
759 fprintf (table
, "%d, ", types
[i
].value
);
760 if (((i
+ 1) % 20) == 0)
762 /* We need \\ for macro. */
764 fprintf (table
, "\\\n%s", indent
);
766 fprintf (table
, "\n%s", indent
);
770 fprintf (table
, "%d } }", types
[i
].value
);
774 process_i386_operand_type (FILE *table
, char *op
, int macro
,
775 const char *indent
, int lineno
)
777 char *str
, *next
, *last
;
778 bitfield types
[ARRAY_SIZE (operand_types
)];
780 /* Copy the default operand type. */
781 memcpy (types
, operand_types
, sizeof (types
));
783 if (strcmp (op
, "0"))
785 last
= op
+ strlen (op
);
786 for (next
= op
; next
&& next
< last
; )
788 str
= next_field (next
, '|', &next
, last
);
790 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
793 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
798 output_i386_opcode (FILE *table
, const char *name
, char *str
,
799 char *last
, int lineno
)
802 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
803 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
805 /* Find number of operands. */
806 operands
= next_field (str
, ',', &str
, last
);
808 /* Find base_opcode. */
809 base_opcode
= next_field (str
, ',', &str
, last
);
811 /* Find extension_opcode. */
812 extension_opcode
= next_field (str
, ',', &str
, last
);
814 /* Find opcode_length. */
815 opcode_length
= next_field (str
, ',', &str
, last
);
817 /* Find cpu_flags. */
818 cpu_flags
= next_field (str
, ',', &str
, last
);
820 /* Find opcode_modifier. */
821 opcode_modifier
= next_field (str
, ',', &str
, last
);
823 /* Remove the first {. */
824 str
= remove_leading_whitespaces (str
);
827 str
= remove_leading_whitespaces (str
+ 1);
831 /* There are at least "X}". */
835 /* Remove trailing white spaces and }. */
839 if (ISSPACE (str
[i
]) || str
[i
] == '}')
848 /* Find operand_types. */
849 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
853 operand_types
[i
] = NULL
;
857 operand_types
[i
] = next_field (str
, ',', &str
, last
);
858 if (*operand_types
[i
] == '0')
861 operand_types
[i
] = NULL
;
866 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
867 name
, operands
, base_opcode
, extension_opcode
,
870 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
872 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
874 fprintf (table
, " { ");
876 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
878 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
881 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
886 fprintf (table
, ",\n ");
888 process_i386_operand_type (table
, operand_types
[i
], 0,
891 fprintf (table
, " } },\n");
894 struct opcode_hash_entry
896 struct opcode_hash_entry
*next
;
902 /* Calculate the hash value of an opcode hash entry P. */
905 opcode_hash_hash (const void *p
)
907 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
908 return htab_hash_string (entry
->name
);
911 /* Compare a string Q against an opcode hash entry P. */
914 opcode_hash_eq (const void *p
, const void *q
)
916 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
917 const char *name
= (const char *) q
;
918 return strcmp (name
, entry
->name
) == 0;
922 process_i386_opcodes (FILE *table
)
927 char *str
, *p
, *last
, *name
;
928 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
929 htab_t opcode_hash_table
;
930 struct opcode_hash_entry
**opcode_array
;
931 unsigned int opcode_array_size
= 1024;
934 filename
= "i386-opc.tbl";
935 fp
= fopen (filename
, "r");
938 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
942 opcode_array
= (struct opcode_hash_entry
**)
943 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
945 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
946 opcode_hash_eq
, NULL
,
949 fprintf (table
, "\n/* i386 opcode table. */\n\n");
950 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
952 /* Put everything on opcode array. */
955 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
960 p
= remove_leading_whitespaces (buf
);
963 str
= strstr (p
, "//");
967 /* Remove trailing white spaces. */
968 remove_trailing_whitespaces (p
);
973 /* Ignore comments. */
981 last
= p
+ strlen (p
);
984 name
= next_field (p
, ',', &str
, last
);
986 /* Get the slot in hash table. */
987 hash_slot
= (struct opcode_hash_entry
**)
988 htab_find_slot_with_hash (opcode_hash_table
, name
,
989 htab_hash_string (name
),
992 if (*hash_slot
== NULL
)
994 /* It is the new one. Put it on opcode array. */
995 if (i
>= opcode_array_size
)
997 /* Grow the opcode array when needed. */
998 opcode_array_size
+= 1024;
999 opcode_array
= (struct opcode_hash_entry
**)
1000 xrealloc (opcode_array
,
1001 sizeof (*opcode_array
) * opcode_array_size
);
1004 opcode_array
[i
] = (struct opcode_hash_entry
*)
1005 xmalloc (sizeof (struct opcode_hash_entry
));
1006 opcode_array
[i
]->next
= NULL
;
1007 opcode_array
[i
]->name
= xstrdup (name
);
1008 opcode_array
[i
]->opcode
= xstrdup (str
);
1009 opcode_array
[i
]->lineno
= lineno
;
1010 *hash_slot
= opcode_array
[i
];
1015 /* Append it to the existing one. */
1017 while ((*entry
) != NULL
)
1018 entry
= &(*entry
)->next
;
1019 *entry
= (struct opcode_hash_entry
*)
1020 xmalloc (sizeof (struct opcode_hash_entry
));
1021 (*entry
)->next
= NULL
;
1022 (*entry
)->name
= (*hash_slot
)->name
;
1023 (*entry
)->opcode
= xstrdup (str
);
1024 (*entry
)->lineno
= lineno
;
1028 /* Process opcode array. */
1029 for (j
= 0; j
< i
; j
++)
1031 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1035 lineno
= next
->lineno
;
1036 last
= str
+ strlen (str
);
1037 output_i386_opcode (table
, name
, str
, last
, lineno
);
1043 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1045 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1047 process_i386_opcode_modifier (table
, "0", -1);
1049 fprintf (table
, " { ");
1050 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1051 fprintf (table
, " } }\n");
1053 fprintf (table
, "};\n");
1057 process_i386_registers (FILE *table
)
1061 char *str
, *p
, *last
;
1062 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1063 char *dw2_32_num
, *dw2_64_num
;
1066 filename
= "i386-reg.tbl";
1067 fp
= fopen (filename
, "r");
1069 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1072 fprintf (table
, "\n/* i386 register table. */\n\n");
1073 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1077 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1082 p
= remove_leading_whitespaces (buf
);
1084 /* Skip comments. */
1085 str
= strstr (p
, "//");
1089 /* Remove trailing white spaces. */
1090 remove_trailing_whitespaces (p
);
1095 fprintf (table
, "%s\n", p
);
1103 last
= p
+ strlen (p
);
1105 /* Find reg_name. */
1106 reg_name
= next_field (p
, ',', &str
, last
);
1108 /* Find reg_type. */
1109 reg_type
= next_field (str
, ',', &str
, last
);
1111 /* Find reg_flags. */
1112 reg_flags
= next_field (str
, ',', &str
, last
);
1115 reg_num
= next_field (str
, ',', &str
, last
);
1117 fprintf (table
, " { \"%s\",\n ", reg_name
);
1119 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1121 /* Find 32-bit Dwarf2 register number. */
1122 dw2_32_num
= next_field (str
, ',', &str
, last
);
1124 /* Find 64-bit Dwarf2 register number. */
1125 dw2_64_num
= next_field (str
, ',', &str
, last
);
1127 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1128 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1133 fprintf (table
, "};\n");
1135 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1139 process_i386_initializers (void)
1142 FILE *fp
= fopen ("i386-init.h", "w");
1146 fail (_("can't create i386-init.h, errno = %s\n"),
1149 process_copyright (fp
);
1151 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1153 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1154 init
= xstrdup (cpu_flag_init
[i
].init
);
1155 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1159 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1161 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1162 init
= xstrdup (operand_type_init
[i
].init
);
1163 process_i386_operand_type (fp
, init
, 1, " ", -1);
1171 /* Program options. */
1172 #define OPTION_SRCDIR 200
1174 struct option long_options
[] =
1176 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1177 {"debug", no_argument
, NULL
, 'd'},
1178 {"version", no_argument
, NULL
, 'V'},
1179 {"help", no_argument
, NULL
, 'h'},
1180 {0, no_argument
, NULL
, 0}
1184 print_version (void)
1186 printf ("%s: version 1.0\n", program_name
);
1191 usage (FILE * stream
, int status
)
1193 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1199 main (int argc
, char **argv
)
1201 extern int chdir (char *);
1202 char *srcdir
= NULL
;
1206 program_name
= *argv
;
1207 xmalloc_set_program_name (program_name
);
1209 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1234 if (chdir (srcdir
) != 0)
1235 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1236 srcdir
, xstrerror (errno
));
1238 /* Check the unused bitfield in i386_cpu_flags. */
1240 c
= CpuNumOfBits
- CpuMax
- 1;
1242 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1245 /* Check the unused bitfield in i386_operand_type. */
1247 c
= OTNumOfBits
- OTMax
- 1;
1249 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1252 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1255 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1256 sizeof (opcode_modifiers
[0]), compare
);
1258 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1259 sizeof (operand_types
[0]), compare
);
1261 table
= fopen ("i386-tbl.h", "w");
1263 fail (_("can't create i386-tbl.h, errno = %s\n"),
1266 process_copyright (table
);
1268 process_i386_opcodes (table
);
1269 process_i386_registers (table
);
1270 process_i386_initializers ();