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" },
133 { "CPU_RDTSCP_FLAGS",
139 { "CPU_3DNOWA_FLAGS",
140 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
141 { "CPU_PADLOCK_FLAGS",
146 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
150 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
151 { "CPU_ANY_AVX_FLAGS",
157 static initializer operand_type_init
[] =
159 { "OPERAND_TYPE_NONE",
161 { "OPERAND_TYPE_REG8",
163 { "OPERAND_TYPE_REG16",
165 { "OPERAND_TYPE_REG32",
167 { "OPERAND_TYPE_REG64",
169 { "OPERAND_TYPE_IMM1",
171 { "OPERAND_TYPE_IMM8",
173 { "OPERAND_TYPE_IMM8S",
175 { "OPERAND_TYPE_IMM16",
177 { "OPERAND_TYPE_IMM32",
179 { "OPERAND_TYPE_IMM32S",
181 { "OPERAND_TYPE_IMM64",
183 { "OPERAND_TYPE_BASEINDEX",
185 { "OPERAND_TYPE_DISP8",
187 { "OPERAND_TYPE_DISP16",
189 { "OPERAND_TYPE_DISP32",
191 { "OPERAND_TYPE_DISP32S",
193 { "OPERAND_TYPE_DISP64",
195 { "OPERAND_TYPE_INOUTPORTREG",
197 { "OPERAND_TYPE_SHIFTCOUNT",
199 { "OPERAND_TYPE_CONTROL",
201 { "OPERAND_TYPE_TEST",
203 { "OPERAND_TYPE_DEBUG",
205 { "OPERAND_TYPE_FLOATREG",
207 { "OPERAND_TYPE_FLOATACC",
209 { "OPERAND_TYPE_SREG2",
211 { "OPERAND_TYPE_SREG3",
213 { "OPERAND_TYPE_ACC",
215 { "OPERAND_TYPE_JUMPABSOLUTE",
217 { "OPERAND_TYPE_REGMMX",
219 { "OPERAND_TYPE_REGXMM",
221 { "OPERAND_TYPE_REGYMM",
223 { "OPERAND_TYPE_ESSEG",
225 { "OPERAND_TYPE_ACC32",
227 { "OPERAND_TYPE_ACC64",
229 { "OPERAND_TYPE_INOUTPORTREG",
231 { "OPERAND_TYPE_REG16_INOUTPORTREG",
232 "Reg16|InOutPortReg" },
233 { "OPERAND_TYPE_DISP16_32",
235 { "OPERAND_TYPE_ANYDISP",
236 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
237 { "OPERAND_TYPE_IMM16_32",
239 { "OPERAND_TYPE_IMM16_32S",
241 { "OPERAND_TYPE_IMM16_32_32S",
242 "Imm16|Imm32|Imm32S" },
243 { "OPERAND_TYPE_IMM32_32S_DISP32",
244 "Imm32|Imm32S|Disp32" },
245 { "OPERAND_TYPE_IMM64_DISP64",
247 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
248 "Imm32|Imm32S|Imm64|Disp32" },
249 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
250 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
253 typedef struct bitfield
260 #define BITFIELD(n) { n, 0, #n }
262 static bitfield cpu_flags
[] =
270 BITFIELD (CpuClflush
),
271 BITFIELD (CpuSYSCALL
),
276 BITFIELD (CpuFISTTP
),
282 BITFIELD (CpuSSE4_1
),
283 BITFIELD (CpuSSE4_2
),
288 BITFIELD (Cpu3dnowA
),
289 BITFIELD (CpuPadLock
),
296 BITFIELD (CpuPCLMUL
),
302 BITFIELD (CpuRdtscp
),
306 BITFIELD (CpuUnused
),
310 static bitfield opcode_modifiers
[] =
316 BITFIELD (ShortForm
),
318 BITFIELD (JumpDword
),
320 BITFIELD (JumpInterSegment
),
327 BITFIELD (IgnoreSize
),
328 BITFIELD (DefaultSize
),
337 BITFIELD (RegKludge
),
338 BITFIELD (FirstXmm0
),
339 BITFIELD (Implicit1stXmm0
),
340 BITFIELD (ByteOkIntel
),
343 BITFIELD (AddrPrefixOp0
),
357 BITFIELD (Vex3Sources
),
358 BITFIELD (VexImmExt
),
362 BITFIELD (ATTMnemonic
),
363 BITFIELD (ATTSyntax
),
364 BITFIELD (IntelSyntax
),
367 static bitfield operand_types
[] =
384 BITFIELD (BaseIndex
),
390 BITFIELD (InOutPortReg
),
391 BITFIELD (ShiftCount
),
399 BITFIELD (JumpAbsolute
),
411 BITFIELD (Unspecified
),
418 static const char *filename
;
421 compare (const void *x
, const void *y
)
423 const bitfield
*xp
= (const bitfield
*) x
;
424 const bitfield
*yp
= (const bitfield
*) y
;
425 return xp
->position
- yp
->position
;
429 fail (const char *message
, ...)
433 va_start (args
, message
);
434 fprintf (stderr
, _("%s: Error: "), program_name
);
435 vfprintf (stderr
, message
, args
);
441 process_copyright (FILE *fp
)
443 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
444 /* Copyright 2007, 2008, 2009\n\
445 Free Software Foundation, Inc.\n\
447 This file is part of the GNU opcodes library.\n\
449 This library is free software; you can redistribute it and/or modify\n\
450 it under the terms of the GNU General Public License as published by\n\
451 the Free Software Foundation; either version 3, or (at your option)\n\
452 any later version.\n\
454 It is distributed in the hope that it will be useful, but WITHOUT\n\
455 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
456 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
457 License for more details.\n\
459 You should have received a copy of the GNU General Public License\n\
460 along with this program; if not, write to the Free Software\n\
461 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
462 MA 02110-1301, USA. */\n");
465 /* Remove leading white spaces. */
468 remove_leading_whitespaces (char *str
)
470 while (ISSPACE (*str
))
475 /* Remove trailing white spaces. */
478 remove_trailing_whitespaces (char *str
)
480 size_t last
= strlen (str
);
488 if (ISSPACE (str
[last
]))
496 /* Find next field separated by SEP and terminate it. Return a
497 pointer to the one after it. */
500 next_field (char *str
, char sep
, char **next
, char *last
)
504 p
= remove_leading_whitespaces (str
);
505 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
508 remove_trailing_whitespaces (p
);
519 set_bitfield (const char *f
, bitfield
*array
, int value
,
520 unsigned int size
, int lineno
)
524 if (strcmp (f
, "CpuFP") == 0)
526 set_bitfield("Cpu387", array
, value
, size
, lineno
);
527 set_bitfield("Cpu287", array
, value
, size
, lineno
);
530 else if (strcmp (f
, "Mmword") == 0)
532 else if (strcmp (f
, "Oword") == 0)
535 for (i
= 0; i
< size
; i
++)
536 if (strcasecmp (array
[i
].name
, f
) == 0)
538 array
[i
].value
= value
;
544 const char *v
= strchr (f
, '=');
551 for (i
= 0; i
< size
; i
++)
552 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
554 value
= strtol (v
+ 1, &end
, 0);
557 array
[i
].value
= value
;
566 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
568 fail (_("Unknown bitfield: %s\n"), f
);
572 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
573 int macro
, const char *comma
, const char *indent
)
577 fprintf (table
, "%s{ { ", indent
);
579 for (i
= 0; i
< size
- 1; i
++)
581 fprintf (table
, "%d, ", flags
[i
].value
);
582 if (((i
+ 1) % 20) == 0)
584 /* We need \\ for macro. */
586 fprintf (table
, " \\\n %s", indent
);
588 fprintf (table
, "\n %s", indent
);
592 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
596 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
597 const char *comma
, const char *indent
,
600 char *str
, *next
, *last
;
602 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
604 /* Copy the default cpu flags. */
605 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
607 if (strcasecmp (flag
, "unknown") == 0)
609 /* We turn on everything except for cpu64 in case of
610 CPU_UNKNOWN_FLAGS. */
611 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
612 if (flags
[i
].position
!= Cpu64
)
615 else if (flag
[0] == '~')
617 last
= flag
+ strlen (flag
);
624 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
631 /* First we turn on everything except for cpu64. */
632 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
633 if (flags
[i
].position
!= Cpu64
)
636 /* Turn off selective bits. */
637 for (; next
&& next
< last
; )
639 str
= next_field (next
, '|', &next
, last
);
641 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
644 else if (strcmp (flag
, "0"))
646 /* Turn on selective bits. */
647 last
= flag
+ strlen (flag
);
648 for (next
= flag
; next
&& next
< last
; )
650 str
= next_field (next
, '|', &next
, last
);
652 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
656 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
661 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
665 fprintf (table
, " { ");
667 for (i
= 0; i
< size
- 1; i
++)
669 fprintf (table
, "%d, ", modifier
[i
].value
);
670 if (((i
+ 1) % 20) == 0)
671 fprintf (table
, "\n ");
674 fprintf (table
, "%d },\n", modifier
[i
].value
);
678 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
680 char *str
, *next
, *last
;
681 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
683 /* Copy the default opcode modifier. */
684 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
686 if (strcmp (mod
, "0"))
688 last
= mod
+ strlen (mod
);
689 for (next
= mod
; next
&& next
< last
; )
691 str
= next_field (next
, '|', &next
, last
);
693 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
697 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
701 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
702 int macro
, const char *indent
)
706 fprintf (table
, "{ { ");
708 for (i
= 0; i
< size
- 1; i
++)
710 fprintf (table
, "%d, ", types
[i
].value
);
711 if (((i
+ 1) % 20) == 0)
713 /* We need \\ for macro. */
715 fprintf (table
, "\\\n%s", indent
);
717 fprintf (table
, "\n%s", indent
);
721 fprintf (table
, "%d } }", types
[i
].value
);
725 process_i386_operand_type (FILE *table
, char *op
, int macro
,
726 const char *indent
, int lineno
)
728 char *str
, *next
, *last
;
729 bitfield types
[ARRAY_SIZE (operand_types
)];
731 /* Copy the default operand type. */
732 memcpy (types
, operand_types
, sizeof (types
));
734 if (strcmp (op
, "0"))
736 last
= op
+ strlen (op
);
737 for (next
= op
; next
&& next
< last
; )
739 str
= next_field (next
, '|', &next
, last
);
741 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
744 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
749 output_i386_opcode (FILE *table
, const char *name
, char *str
,
750 char *last
, int lineno
)
753 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
754 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
756 /* Find number of operands. */
757 operands
= next_field (str
, ',', &str
, last
);
759 /* Find base_opcode. */
760 base_opcode
= next_field (str
, ',', &str
, last
);
762 /* Find extension_opcode. */
763 extension_opcode
= next_field (str
, ',', &str
, last
);
765 /* Find opcode_length. */
766 opcode_length
= next_field (str
, ',', &str
, last
);
768 /* Find cpu_flags. */
769 cpu_flags
= next_field (str
, ',', &str
, last
);
771 /* Find opcode_modifier. */
772 opcode_modifier
= next_field (str
, ',', &str
, last
);
774 /* Remove the first {. */
775 str
= remove_leading_whitespaces (str
);
778 str
= remove_leading_whitespaces (str
+ 1);
782 /* There are at least "X}". */
786 /* Remove trailing white spaces and }. */
790 if (ISSPACE (str
[i
]) || str
[i
] == '}')
799 /* Find operand_types. */
800 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
804 operand_types
[i
] = NULL
;
808 operand_types
[i
] = next_field (str
, ',', &str
, last
);
809 if (*operand_types
[i
] == '0')
812 operand_types
[i
] = NULL
;
817 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
818 name
, operands
, base_opcode
, extension_opcode
,
821 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
823 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
825 fprintf (table
, " { ");
827 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
829 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
832 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
837 fprintf (table
, ",\n ");
839 process_i386_operand_type (table
, operand_types
[i
], 0,
842 fprintf (table
, " } },\n");
845 struct opcode_hash_entry
847 struct opcode_hash_entry
*next
;
853 /* Calculate the hash value of an opcode hash entry P. */
856 opcode_hash_hash (const void *p
)
858 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
859 return htab_hash_string (entry
->name
);
862 /* Compare a string Q against an opcode hash entry P. */
865 opcode_hash_eq (const void *p
, const void *q
)
867 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
868 const char *name
= (const char *) q
;
869 return strcmp (name
, entry
->name
) == 0;
873 process_i386_opcodes (FILE *table
)
878 char *str
, *p
, *last
, *name
;
879 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
880 htab_t opcode_hash_table
;
881 struct opcode_hash_entry
**opcode_array
;
882 unsigned int opcode_array_size
= 1024;
885 filename
= "i386-opc.tbl";
886 fp
= fopen (filename
, "r");
889 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
893 opcode_array
= (struct opcode_hash_entry
**)
894 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
896 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
897 opcode_hash_eq
, NULL
,
900 fprintf (table
, "\n/* i386 opcode table. */\n\n");
901 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
903 /* Put everything on opcode array. */
906 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
911 p
= remove_leading_whitespaces (buf
);
914 str
= strstr (p
, "//");
918 /* Remove trailing white spaces. */
919 remove_trailing_whitespaces (p
);
924 /* Ignore comments. */
932 last
= p
+ strlen (p
);
935 name
= next_field (p
, ',', &str
, last
);
937 /* Get the slot in hash table. */
938 hash_slot
= (struct opcode_hash_entry
**)
939 htab_find_slot_with_hash (opcode_hash_table
, name
,
940 htab_hash_string (name
),
943 if (*hash_slot
== NULL
)
945 /* It is the new one. Put it on opcode array. */
946 if (i
>= opcode_array_size
)
948 /* Grow the opcode array when needed. */
949 opcode_array_size
+= 1024;
950 opcode_array
= (struct opcode_hash_entry
**)
951 xrealloc (opcode_array
,
952 sizeof (*opcode_array
) * opcode_array_size
);
955 opcode_array
[i
] = (struct opcode_hash_entry
*)
956 xmalloc (sizeof (struct opcode_hash_entry
));
957 opcode_array
[i
]->next
= NULL
;
958 opcode_array
[i
]->name
= xstrdup (name
);
959 opcode_array
[i
]->opcode
= xstrdup (str
);
960 opcode_array
[i
]->lineno
= lineno
;
961 *hash_slot
= opcode_array
[i
];
966 /* Append it to the existing one. */
968 while ((*entry
) != NULL
)
969 entry
= &(*entry
)->next
;
970 *entry
= (struct opcode_hash_entry
*)
971 xmalloc (sizeof (struct opcode_hash_entry
));
972 (*entry
)->next
= NULL
;
973 (*entry
)->name
= (*hash_slot
)->name
;
974 (*entry
)->opcode
= xstrdup (str
);
975 (*entry
)->lineno
= lineno
;
979 /* Process opcode array. */
980 for (j
= 0; j
< i
; j
++)
982 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
986 lineno
= next
->lineno
;
987 last
= str
+ strlen (str
);
988 output_i386_opcode (table
, name
, str
, last
, lineno
);
994 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
996 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
998 process_i386_opcode_modifier (table
, "0", -1);
1000 fprintf (table
, " { ");
1001 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1002 fprintf (table
, " } }\n");
1004 fprintf (table
, "};\n");
1008 process_i386_registers (FILE *table
)
1012 char *str
, *p
, *last
;
1013 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1014 char *dw2_32_num
, *dw2_64_num
;
1017 filename
= "i386-reg.tbl";
1018 fp
= fopen (filename
, "r");
1020 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1023 fprintf (table
, "\n/* i386 register table. */\n\n");
1024 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1028 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1033 p
= remove_leading_whitespaces (buf
);
1035 /* Skip comments. */
1036 str
= strstr (p
, "//");
1040 /* Remove trailing white spaces. */
1041 remove_trailing_whitespaces (p
);
1046 fprintf (table
, "%s\n", p
);
1054 last
= p
+ strlen (p
);
1056 /* Find reg_name. */
1057 reg_name
= next_field (p
, ',', &str
, last
);
1059 /* Find reg_type. */
1060 reg_type
= next_field (str
, ',', &str
, last
);
1062 /* Find reg_flags. */
1063 reg_flags
= next_field (str
, ',', &str
, last
);
1066 reg_num
= next_field (str
, ',', &str
, last
);
1068 fprintf (table
, " { \"%s\",\n ", reg_name
);
1070 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1072 /* Find 32-bit Dwarf2 register number. */
1073 dw2_32_num
= next_field (str
, ',', &str
, last
);
1075 /* Find 64-bit Dwarf2 register number. */
1076 dw2_64_num
= next_field (str
, ',', &str
, last
);
1078 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1079 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1084 fprintf (table
, "};\n");
1086 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1090 process_i386_initializers (void)
1093 FILE *fp
= fopen ("i386-init.h", "w");
1097 fail (_("can't create i386-init.h, errno = %s\n"),
1100 process_copyright (fp
);
1102 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1104 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1105 init
= xstrdup (cpu_flag_init
[i
].init
);
1106 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1110 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1112 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1113 init
= xstrdup (operand_type_init
[i
].init
);
1114 process_i386_operand_type (fp
, init
, 1, " ", -1);
1122 /* Program options. */
1123 #define OPTION_SRCDIR 200
1125 struct option long_options
[] =
1127 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1128 {"debug", no_argument
, NULL
, 'd'},
1129 {"version", no_argument
, NULL
, 'V'},
1130 {"help", no_argument
, NULL
, 'h'},
1131 {0, no_argument
, NULL
, 0}
1135 print_version (void)
1137 printf ("%s: version 1.0\n", program_name
);
1142 usage (FILE * stream
, int status
)
1144 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1150 main (int argc
, char **argv
)
1152 extern int chdir (char *);
1153 char *srcdir
= NULL
;
1157 program_name
= *argv
;
1158 xmalloc_set_program_name (program_name
);
1160 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1185 if (chdir (srcdir
) != 0)
1186 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1187 srcdir
, xstrerror (errno
));
1189 /* Check the unused bitfield in i386_cpu_flags. */
1191 c
= CpuNumOfBits
- CpuMax
- 1;
1193 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1196 /* Check the unused bitfield in i386_operand_type. */
1198 c
= OTNumOfBits
- OTMax
- 1;
1200 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1203 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1206 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1207 sizeof (opcode_modifiers
[0]), compare
);
1209 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1210 sizeof (operand_types
[0]), compare
);
1212 table
= fopen ("i386-tbl.h", "w");
1214 fail (_("can't create i386-tbl.h, errno = %s\n"),
1217 process_copyright (table
);
1219 process_i386_opcodes (table
);
1220 process_i386_registers (table
);
1221 process_i386_initializers ();