1 /* Copyright 2007, 2008, 2009
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" },
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX" },
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX|CpuSSE" },
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuMMX|CpuSSE|CpuSSE2" },
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA" },
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
87 { "CPU_AMDFAM10_FLAGS",
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
96 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
97 { "CPU_CLFLUSH_FLAGS",
99 { "CPU_SYSCALL_FLAGS",
106 "CpuMMX|CpuSSE|CpuSSE2" },
108 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
110 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
111 { "CPU_SSE4_1_FLAGS",
112 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
113 { "CPU_SSE4_2_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
115 { "CPU_ANY_SSE_FLAGS",
116 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX" },
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
125 { "CPU_PCLMUL_FLAGS",
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
130 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
132 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP|CpuCVT16" },
134 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP|CpuCVT16" },
139 { "CPU_RDTSCP_FLAGS",
145 { "CPU_3DNOWA_FLAGS",
146 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
147 { "CPU_PADLOCK_FLAGS",
152 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
156 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
157 { "CPU_ANY_AVX_FLAGS",
163 static initializer operand_type_init
[] =
165 { "OPERAND_TYPE_NONE",
167 { "OPERAND_TYPE_REG8",
169 { "OPERAND_TYPE_REG16",
171 { "OPERAND_TYPE_REG32",
173 { "OPERAND_TYPE_REG64",
175 { "OPERAND_TYPE_IMM1",
177 { "OPERAND_TYPE_IMM8",
179 { "OPERAND_TYPE_IMM8S",
181 { "OPERAND_TYPE_IMM16",
183 { "OPERAND_TYPE_IMM32",
185 { "OPERAND_TYPE_IMM32S",
187 { "OPERAND_TYPE_IMM64",
189 { "OPERAND_TYPE_BASEINDEX",
191 { "OPERAND_TYPE_DISP8",
193 { "OPERAND_TYPE_DISP16",
195 { "OPERAND_TYPE_DISP32",
197 { "OPERAND_TYPE_DISP32S",
199 { "OPERAND_TYPE_DISP64",
201 { "OPERAND_TYPE_INOUTPORTREG",
203 { "OPERAND_TYPE_SHIFTCOUNT",
205 { "OPERAND_TYPE_CONTROL",
207 { "OPERAND_TYPE_TEST",
209 { "OPERAND_TYPE_DEBUG",
211 { "OPERAND_TYPE_FLOATREG",
213 { "OPERAND_TYPE_FLOATACC",
215 { "OPERAND_TYPE_SREG2",
217 { "OPERAND_TYPE_SREG3",
219 { "OPERAND_TYPE_ACC",
221 { "OPERAND_TYPE_JUMPABSOLUTE",
223 { "OPERAND_TYPE_REGMMX",
225 { "OPERAND_TYPE_REGXMM",
227 { "OPERAND_TYPE_REGYMM",
229 { "OPERAND_TYPE_ESSEG",
231 { "OPERAND_TYPE_ACC32",
233 { "OPERAND_TYPE_ACC64",
235 { "OPERAND_TYPE_INOUTPORTREG",
237 { "OPERAND_TYPE_REG16_INOUTPORTREG",
238 "Reg16|InOutPortReg" },
239 { "OPERAND_TYPE_DISP16_32",
241 { "OPERAND_TYPE_ANYDISP",
242 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
243 { "OPERAND_TYPE_IMM16_32",
245 { "OPERAND_TYPE_IMM16_32S",
247 { "OPERAND_TYPE_IMM16_32_32S",
248 "Imm16|Imm32|Imm32S" },
249 { "OPERAND_TYPE_IMM32_32S_DISP32",
250 "Imm32|Imm32S|Disp32" },
251 { "OPERAND_TYPE_IMM64_DISP64",
253 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
254 "Imm32|Imm32S|Imm64|Disp32" },
255 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
256 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
259 typedef struct bitfield
266 #define BITFIELD(n) { n, 0, #n }
268 static bitfield cpu_flags
[] =
276 BITFIELD (CpuClflush
),
277 BITFIELD (CpuSYSCALL
),
282 BITFIELD (CpuFISTTP
),
288 BITFIELD (CpuSSE4_1
),
289 BITFIELD (CpuSSE4_2
),
294 BITFIELD (Cpu3dnowA
),
295 BITFIELD (CpuPadLock
),
302 BITFIELD (CpuPCLMUL
),
311 BITFIELD (CpuRdtscp
),
315 BITFIELD (CpuUnused
),
319 static bitfield opcode_modifiers
[] =
325 BITFIELD (ShortForm
),
327 BITFIELD (JumpDword
),
329 BITFIELD (JumpInterSegment
),
336 BITFIELD (IgnoreSize
),
337 BITFIELD (DefaultSize
),
346 BITFIELD (IsLockable
),
347 BITFIELD (RegKludge
),
348 BITFIELD (FirstXmm0
),
349 BITFIELD (Implicit1stXmm0
),
350 BITFIELD (ByteOkIntel
),
353 BITFIELD (AddrPrefixOp0
),
371 BITFIELD (Vex3Sources
),
372 BITFIELD (Vex2Sources
),
373 BITFIELD (VexImmExt
),
377 BITFIELD (ATTMnemonic
),
378 BITFIELD (ATTSyntax
),
379 BITFIELD (IntelSyntax
),
382 static bitfield operand_types
[] =
399 BITFIELD (BaseIndex
),
405 BITFIELD (InOutPortReg
),
406 BITFIELD (ShiftCount
),
414 BITFIELD (JumpAbsolute
),
426 BITFIELD (Unspecified
),
433 static const char *filename
;
436 compare (const void *x
, const void *y
)
438 const bitfield
*xp
= (const bitfield
*) x
;
439 const bitfield
*yp
= (const bitfield
*) y
;
440 return xp
->position
- yp
->position
;
444 fail (const char *message
, ...)
448 va_start (args
, message
);
449 fprintf (stderr
, _("%s: Error: "), program_name
);
450 vfprintf (stderr
, message
, args
);
456 process_copyright (FILE *fp
)
458 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
459 /* Copyright 2007, 2008, 2009\n\
460 Free Software Foundation, Inc.\n\
462 This file is part of the GNU opcodes library.\n\
464 This library is free software; you can redistribute it and/or modify\n\
465 it under the terms of the GNU General Public License as published by\n\
466 the Free Software Foundation; either version 3, or (at your option)\n\
467 any later version.\n\
469 It is distributed in the hope that it will be useful, but WITHOUT\n\
470 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
471 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
472 License for more details.\n\
474 You should have received a copy of the GNU General Public License\n\
475 along with this program; if not, write to the Free Software\n\
476 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
477 MA 02110-1301, USA. */\n");
480 /* Remove leading white spaces. */
483 remove_leading_whitespaces (char *str
)
485 while (ISSPACE (*str
))
490 /* Remove trailing white spaces. */
493 remove_trailing_whitespaces (char *str
)
495 size_t last
= strlen (str
);
503 if (ISSPACE (str
[last
]))
511 /* Find next field separated by SEP and terminate it. Return a
512 pointer to the one after it. */
515 next_field (char *str
, char sep
, char **next
, char *last
)
519 p
= remove_leading_whitespaces (str
);
520 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
523 remove_trailing_whitespaces (p
);
534 set_bitfield (const char *f
, bitfield
*array
, int value
,
535 unsigned int size
, int lineno
)
539 if (strcmp (f
, "CpuFP") == 0)
541 set_bitfield("Cpu387", array
, value
, size
, lineno
);
542 set_bitfield("Cpu287", array
, value
, size
, lineno
);
545 else if (strcmp (f
, "Mmword") == 0)
547 else if (strcmp (f
, "Oword") == 0)
550 for (i
= 0; i
< size
; i
++)
551 if (strcasecmp (array
[i
].name
, f
) == 0)
553 array
[i
].value
= value
;
559 const char *v
= strchr (f
, '=');
566 for (i
= 0; i
< size
; i
++)
567 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
569 value
= strtol (v
+ 1, &end
, 0);
572 array
[i
].value
= value
;
581 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
583 fail (_("Unknown bitfield: %s\n"), f
);
587 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
588 int macro
, const char *comma
, const char *indent
)
592 fprintf (table
, "%s{ { ", indent
);
594 for (i
= 0; i
< size
- 1; i
++)
596 fprintf (table
, "%d, ", flags
[i
].value
);
597 if (((i
+ 1) % 20) == 0)
599 /* We need \\ for macro. */
601 fprintf (table
, " \\\n %s", indent
);
603 fprintf (table
, "\n %s", indent
);
607 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
611 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
612 const char *comma
, const char *indent
,
615 char *str
, *next
, *last
;
617 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
619 /* Copy the default cpu flags. */
620 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
622 if (strcasecmp (flag
, "unknown") == 0)
624 /* We turn on everything except for cpu64 in case of
625 CPU_UNKNOWN_FLAGS. */
626 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
627 if (flags
[i
].position
!= Cpu64
)
630 else if (flag
[0] == '~')
632 last
= flag
+ strlen (flag
);
639 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
646 /* First we turn on everything except for cpu64. */
647 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
648 if (flags
[i
].position
!= Cpu64
)
651 /* Turn off selective bits. */
652 for (; next
&& next
< last
; )
654 str
= next_field (next
, '|', &next
, last
);
656 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
659 else if (strcmp (flag
, "0"))
661 /* Turn on selective bits. */
662 last
= flag
+ strlen (flag
);
663 for (next
= flag
; next
&& next
< last
; )
665 str
= next_field (next
, '|', &next
, last
);
667 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
671 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
676 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
680 fprintf (table
, " { ");
682 for (i
= 0; i
< size
- 1; i
++)
684 fprintf (table
, "%d, ", modifier
[i
].value
);
685 if (((i
+ 1) % 20) == 0)
686 fprintf (table
, "\n ");
689 fprintf (table
, "%d },\n", modifier
[i
].value
);
693 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
695 char *str
, *next
, *last
;
696 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
698 /* Copy the default opcode modifier. */
699 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
701 if (strcmp (mod
, "0"))
703 last
= mod
+ strlen (mod
);
704 for (next
= mod
; next
&& next
< last
; )
706 str
= next_field (next
, '|', &next
, last
);
708 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
712 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
716 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
717 int macro
, const char *indent
)
721 fprintf (table
, "{ { ");
723 for (i
= 0; i
< size
- 1; i
++)
725 fprintf (table
, "%d, ", types
[i
].value
);
726 if (((i
+ 1) % 20) == 0)
728 /* We need \\ for macro. */
730 fprintf (table
, "\\\n%s", indent
);
732 fprintf (table
, "\n%s", indent
);
736 fprintf (table
, "%d } }", types
[i
].value
);
740 process_i386_operand_type (FILE *table
, char *op
, int macro
,
741 const char *indent
, int lineno
)
743 char *str
, *next
, *last
;
744 bitfield types
[ARRAY_SIZE (operand_types
)];
746 /* Copy the default operand type. */
747 memcpy (types
, operand_types
, sizeof (types
));
749 if (strcmp (op
, "0"))
751 last
= op
+ strlen (op
);
752 for (next
= op
; next
&& next
< last
; )
754 str
= next_field (next
, '|', &next
, last
);
756 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
759 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
764 output_i386_opcode (FILE *table
, const char *name
, char *str
,
765 char *last
, int lineno
)
768 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
769 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
771 /* Find number of operands. */
772 operands
= next_field (str
, ',', &str
, last
);
774 /* Find base_opcode. */
775 base_opcode
= next_field (str
, ',', &str
, last
);
777 /* Find extension_opcode. */
778 extension_opcode
= next_field (str
, ',', &str
, last
);
780 /* Find opcode_length. */
781 opcode_length
= next_field (str
, ',', &str
, last
);
783 /* Find cpu_flags. */
784 cpu_flags
= next_field (str
, ',', &str
, last
);
786 /* Find opcode_modifier. */
787 opcode_modifier
= next_field (str
, ',', &str
, last
);
789 /* Remove the first {. */
790 str
= remove_leading_whitespaces (str
);
793 str
= remove_leading_whitespaces (str
+ 1);
797 /* There are at least "X}". */
801 /* Remove trailing white spaces and }. */
805 if (ISSPACE (str
[i
]) || str
[i
] == '}')
814 /* Find operand_types. */
815 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
819 operand_types
[i
] = NULL
;
823 operand_types
[i
] = next_field (str
, ',', &str
, last
);
824 if (*operand_types
[i
] == '0')
827 operand_types
[i
] = NULL
;
832 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
833 name
, operands
, base_opcode
, extension_opcode
,
836 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
838 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
840 fprintf (table
, " { ");
842 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
844 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
847 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
852 fprintf (table
, ",\n ");
854 process_i386_operand_type (table
, operand_types
[i
], 0,
857 fprintf (table
, " } },\n");
860 struct opcode_hash_entry
862 struct opcode_hash_entry
*next
;
868 /* Calculate the hash value of an opcode hash entry P. */
871 opcode_hash_hash (const void *p
)
873 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
874 return htab_hash_string (entry
->name
);
877 /* Compare a string Q against an opcode hash entry P. */
880 opcode_hash_eq (const void *p
, const void *q
)
882 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
883 const char *name
= (const char *) q
;
884 return strcmp (name
, entry
->name
) == 0;
888 process_i386_opcodes (FILE *table
)
893 char *str
, *p
, *last
, *name
;
894 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
895 htab_t opcode_hash_table
;
896 struct opcode_hash_entry
**opcode_array
;
897 unsigned int opcode_array_size
= 1024;
900 filename
= "i386-opc.tbl";
901 fp
= fopen (filename
, "r");
904 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
908 opcode_array
= (struct opcode_hash_entry
**)
909 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
911 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
912 opcode_hash_eq
, NULL
,
915 fprintf (table
, "\n/* i386 opcode table. */\n\n");
916 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
918 /* Put everything on opcode array. */
921 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
926 p
= remove_leading_whitespaces (buf
);
929 str
= strstr (p
, "//");
933 /* Remove trailing white spaces. */
934 remove_trailing_whitespaces (p
);
939 /* Ignore comments. */
947 last
= p
+ strlen (p
);
950 name
= next_field (p
, ',', &str
, last
);
952 /* Get the slot in hash table. */
953 hash_slot
= (struct opcode_hash_entry
**)
954 htab_find_slot_with_hash (opcode_hash_table
, name
,
955 htab_hash_string (name
),
958 if (*hash_slot
== NULL
)
960 /* It is the new one. Put it on opcode array. */
961 if (i
>= opcode_array_size
)
963 /* Grow the opcode array when needed. */
964 opcode_array_size
+= 1024;
965 opcode_array
= (struct opcode_hash_entry
**)
966 xrealloc (opcode_array
,
967 sizeof (*opcode_array
) * opcode_array_size
);
970 opcode_array
[i
] = (struct opcode_hash_entry
*)
971 xmalloc (sizeof (struct opcode_hash_entry
));
972 opcode_array
[i
]->next
= NULL
;
973 opcode_array
[i
]->name
= xstrdup (name
);
974 opcode_array
[i
]->opcode
= xstrdup (str
);
975 opcode_array
[i
]->lineno
= lineno
;
976 *hash_slot
= opcode_array
[i
];
981 /* Append it to the existing one. */
983 while ((*entry
) != NULL
)
984 entry
= &(*entry
)->next
;
985 *entry
= (struct opcode_hash_entry
*)
986 xmalloc (sizeof (struct opcode_hash_entry
));
987 (*entry
)->next
= NULL
;
988 (*entry
)->name
= (*hash_slot
)->name
;
989 (*entry
)->opcode
= xstrdup (str
);
990 (*entry
)->lineno
= lineno
;
994 /* Process opcode array. */
995 for (j
= 0; j
< i
; j
++)
997 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1001 lineno
= next
->lineno
;
1002 last
= str
+ strlen (str
);
1003 output_i386_opcode (table
, name
, str
, last
, lineno
);
1009 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1011 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1013 process_i386_opcode_modifier (table
, "0", -1);
1015 fprintf (table
, " { ");
1016 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1017 fprintf (table
, " } }\n");
1019 fprintf (table
, "};\n");
1023 process_i386_registers (FILE *table
)
1027 char *str
, *p
, *last
;
1028 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1029 char *dw2_32_num
, *dw2_64_num
;
1032 filename
= "i386-reg.tbl";
1033 fp
= fopen (filename
, "r");
1035 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1038 fprintf (table
, "\n/* i386 register table. */\n\n");
1039 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1043 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1048 p
= remove_leading_whitespaces (buf
);
1050 /* Skip comments. */
1051 str
= strstr (p
, "//");
1055 /* Remove trailing white spaces. */
1056 remove_trailing_whitespaces (p
);
1061 fprintf (table
, "%s\n", p
);
1069 last
= p
+ strlen (p
);
1071 /* Find reg_name. */
1072 reg_name
= next_field (p
, ',', &str
, last
);
1074 /* Find reg_type. */
1075 reg_type
= next_field (str
, ',', &str
, last
);
1077 /* Find reg_flags. */
1078 reg_flags
= next_field (str
, ',', &str
, last
);
1081 reg_num
= next_field (str
, ',', &str
, last
);
1083 fprintf (table
, " { \"%s\",\n ", reg_name
);
1085 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1087 /* Find 32-bit Dwarf2 register number. */
1088 dw2_32_num
= next_field (str
, ',', &str
, last
);
1090 /* Find 64-bit Dwarf2 register number. */
1091 dw2_64_num
= next_field (str
, ',', &str
, last
);
1093 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1094 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1099 fprintf (table
, "};\n");
1101 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1105 process_i386_initializers (void)
1108 FILE *fp
= fopen ("i386-init.h", "w");
1112 fail (_("can't create i386-init.h, errno = %s\n"),
1115 process_copyright (fp
);
1117 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1119 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1120 init
= xstrdup (cpu_flag_init
[i
].init
);
1121 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1125 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1127 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1128 init
= xstrdup (operand_type_init
[i
].init
);
1129 process_i386_operand_type (fp
, init
, 1, " ", -1);
1137 /* Program options. */
1138 #define OPTION_SRCDIR 200
1140 struct option long_options
[] =
1142 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1143 {"debug", no_argument
, NULL
, 'd'},
1144 {"version", no_argument
, NULL
, 'V'},
1145 {"help", no_argument
, NULL
, 'h'},
1146 {0, no_argument
, NULL
, 0}
1150 print_version (void)
1152 printf ("%s: version 1.0\n", program_name
);
1157 usage (FILE * stream
, int status
)
1159 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1165 main (int argc
, char **argv
)
1167 extern int chdir (char *);
1168 char *srcdir
= NULL
;
1172 program_name
= *argv
;
1173 xmalloc_set_program_name (program_name
);
1175 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1200 if (chdir (srcdir
) != 0)
1201 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1202 srcdir
, xstrerror (errno
));
1204 /* Check the unused bitfield in i386_cpu_flags. */
1206 c
= CpuNumOfBits
- CpuMax
- 1;
1208 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1211 /* Check the unused bitfield in i386_operand_type. */
1213 c
= OTNumOfBits
- OTMax
- 1;
1215 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1218 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1221 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1222 sizeof (opcode_modifiers
[0]), compare
);
1224 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1225 sizeof (operand_types
[0]), compare
);
1227 table
= fopen ("i386-tbl.h", "w");
1229 fail (_("can't create i386-tbl.h, errno = %s\n"),
1232 process_copyright (table
);
1234 process_i386_opcodes (table
);
1235 process_i386_registers (table
);
1236 process_i386_initializers ();