merge from gcc
[binutils.git] / opcodes / i386-gen.c
blob12c8bb90ec3efb79dff9525dbacfee80e723292b
1 /* Copyright 2007, 2008 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
20 #include "sysdep.h"
21 #include <stdio.h>
22 #include <errno.h>
23 #include "getopt.h"
24 #include "libiberty.h"
25 #include "safe-ctype.h"
27 #include "i386-opc.h"
29 #include <libintl.h>
30 #define _(String) gettext (String)
32 static const char *program_name = NULL;
33 static int debug = 0;
35 typedef struct initializer
37 const char *name;
38 const char *init;
39 } initializer;
41 static initializer cpu_flag_init [] =
43 { "CPU_UNKNOWN_FLAGS",
44 "unknown" },
45 { "CPU_GENERIC32_FLAGS",
46 "Cpu186|Cpu286|Cpu386" },
47 { "CPU_GENERIC64_FLAGS",
48 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
49 { "CPU_NONE_FLAGS",
50 "0" },
51 { "CPU_I186_FLAGS",
52 "Cpu186" },
53 { "CPU_I286_FLAGS",
54 "Cpu186|Cpu286" },
55 { "CPU_I386_FLAGS",
56 "Cpu186|Cpu286|Cpu386" },
57 { "CPU_I486_FLAGS",
58 "Cpu186|Cpu286|Cpu386|Cpu486" },
59 { "CPU_I586_FLAGS",
60 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
61 { "CPU_I686_FLAGS",
62 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686" },
63 { "CPU_P2_FLAGS",
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX" },
65 { "CPU_P3_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE" },
67 { "CPU_P4_FLAGS",
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2" },
69 { "CPU_NOCONA_FLAGS",
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
71 { "CPU_CORE_FLAGS",
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
73 { "CPU_CORE2_FLAGS",
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
75 { "CPU_K6_FLAGS",
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX" },
77 { "CPU_K6_2_FLAGS",
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX|Cpu3dnow" },
79 { "CPU_ATHLON_FLAGS",
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuMMX|Cpu3dnow|Cpu3dnowA" },
81 { "CPU_K8_FLAGS",
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
83 { "CPU_AMDFAM10_FLAGS",
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
85 { "CPU_MMX_FLAGS",
86 "CpuMMX" },
87 { "CPU_SSE_FLAGS",
88 "CpuMMX|CpuSSE" },
89 { "CPU_SSE2_FLAGS",
90 "CpuMMX|CpuSSE|CpuSSE2" },
91 { "CPU_SSE3_FLAGS",
92 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
93 { "CPU_SSSE3_FLAGS",
94 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
95 { "CPU_SSE4_1_FLAGS",
96 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
97 { "CPU_SSE4_2_FLAGS",
98 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
99 { "CPU_VMX_FLAGS",
100 "CpuVMX" },
101 { "CPU_SMX_FLAGS",
102 "CpuSMX" },
103 { "CPU_XSAVE_FLAGS",
104 "CpuXsave" },
105 { "CPU_AES_FLAGS",
106 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
107 { "CPU_PCLMUL_FLAGS",
108 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
109 { "CPU_FMA_FLAGS",
110 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
111 { "CPU_3DNOW_FLAGS",
112 "CpuMMX|Cpu3dnow" },
113 { "CPU_3DNOWA_FLAGS",
114 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
115 { "CPU_PADLOCK_FLAGS",
116 "CpuPadLock" },
117 { "CPU_SVME_FLAGS",
118 "CpuSVME" },
119 { "CPU_SSE4A_FLAGS",
120 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
121 { "CPU_ABM_FLAGS",
122 "CpuABM" },
123 { "CPU_SSE5_FLAGS",
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
125 { "CPU_AVX_FLAGS",
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
129 static initializer operand_type_init [] =
131 { "OPERAND_TYPE_NONE",
132 "0" },
133 { "OPERAND_TYPE_REG8",
134 "Reg8" },
135 { "OPERAND_TYPE_REG16",
136 "Reg16" },
137 { "OPERAND_TYPE_REG32",
138 "Reg32" },
139 { "OPERAND_TYPE_REG64",
140 "Reg64" },
141 { "OPERAND_TYPE_IMM1",
142 "Imm1" },
143 { "OPERAND_TYPE_IMM8",
144 "Imm8" },
145 { "OPERAND_TYPE_IMM8S",
146 "Imm8S" },
147 { "OPERAND_TYPE_IMM16",
148 "Imm16" },
149 { "OPERAND_TYPE_IMM32",
150 "Imm32" },
151 { "OPERAND_TYPE_IMM32S",
152 "Imm32S" },
153 { "OPERAND_TYPE_IMM64",
154 "Imm64" },
155 { "OPERAND_TYPE_BASEINDEX",
156 "BaseIndex" },
157 { "OPERAND_TYPE_DISP8",
158 "Disp8" },
159 { "OPERAND_TYPE_DISP16",
160 "Disp16" },
161 { "OPERAND_TYPE_DISP32",
162 "Disp32" },
163 { "OPERAND_TYPE_DISP32S",
164 "Disp32S" },
165 { "OPERAND_TYPE_DISP64",
166 "Disp64" },
167 { "OPERAND_TYPE_INOUTPORTREG",
168 "InOutPortReg" },
169 { "OPERAND_TYPE_SHIFTCOUNT",
170 "ShiftCount" },
171 { "OPERAND_TYPE_CONTROL",
172 "Control" },
173 { "OPERAND_TYPE_TEST",
174 "Test" },
175 { "OPERAND_TYPE_DEBUG",
176 "FloatReg" },
177 { "OPERAND_TYPE_FLOATREG",
178 "FloatReg" },
179 { "OPERAND_TYPE_FLOATACC",
180 "FloatAcc" },
181 { "OPERAND_TYPE_SREG2",
182 "SReg2" },
183 { "OPERAND_TYPE_SREG3",
184 "SReg3" },
185 { "OPERAND_TYPE_ACC",
186 "Acc" },
187 { "OPERAND_TYPE_JUMPABSOLUTE",
188 "JumpAbsolute" },
189 { "OPERAND_TYPE_REGMMX",
190 "RegMMX" },
191 { "OPERAND_TYPE_REGXMM",
192 "RegXMM" },
193 { "OPERAND_TYPE_REGYMM",
194 "RegYMM" },
195 { "OPERAND_TYPE_ESSEG",
196 "EsSeg" },
197 { "OPERAND_TYPE_ACC32",
198 "Reg32|Acc|Dword" },
199 { "OPERAND_TYPE_ACC64",
200 "Reg64|Acc|Qword" },
201 { "OPERAND_TYPE_INOUTPORTREG",
202 "InOutPortReg" },
203 { "OPERAND_TYPE_REG16_INOUTPORTREG",
204 "Reg16|InOutPortReg" },
205 { "OPERAND_TYPE_DISP16_32",
206 "Disp16|Disp32" },
207 { "OPERAND_TYPE_ANYDISP",
208 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
209 { "OPERAND_TYPE_IMM16_32",
210 "Imm16|Imm32" },
211 { "OPERAND_TYPE_IMM16_32S",
212 "Imm16|Imm32S" },
213 { "OPERAND_TYPE_IMM16_32_32S",
214 "Imm16|Imm32|Imm32S" },
215 { "OPERAND_TYPE_IMM32_32S_DISP32",
216 "Imm32|Imm32S|Disp32" },
217 { "OPERAND_TYPE_IMM64_DISP64",
218 "Imm64|Disp64" },
219 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
220 "Imm32|Imm32S|Imm64|Disp32" },
221 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
222 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
223 { "OPERAND_TYPE_VEX_IMM4",
224 "VEX_Imm4" },
227 typedef struct bitfield
229 int position;
230 int value;
231 const char *name;
232 } bitfield;
234 #define BITFIELD(n) { n, 0, #n }
236 static bitfield cpu_flags[] =
238 BITFIELD (Cpu186),
239 BITFIELD (Cpu286),
240 BITFIELD (Cpu386),
241 BITFIELD (Cpu486),
242 BITFIELD (Cpu586),
243 BITFIELD (Cpu686),
244 BITFIELD (CpuP4),
245 BITFIELD (CpuK6),
246 BITFIELD (CpuK8),
247 BITFIELD (CpuMMX),
248 BITFIELD (CpuSSE),
249 BITFIELD (CpuSSE2),
250 BITFIELD (CpuSSE3),
251 BITFIELD (CpuSSSE3),
252 BITFIELD (CpuSSE4_1),
253 BITFIELD (CpuSSE4_2),
254 BITFIELD (CpuAVX),
255 BITFIELD (CpuSSE4a),
256 BITFIELD (CpuSSE5),
257 BITFIELD (Cpu3dnow),
258 BITFIELD (Cpu3dnowA),
259 BITFIELD (CpuPadLock),
260 BITFIELD (CpuSVME),
261 BITFIELD (CpuVMX),
262 BITFIELD (CpuSMX),
263 BITFIELD (CpuABM),
264 BITFIELD (CpuXsave),
265 BITFIELD (CpuAES),
266 BITFIELD (CpuPCLMUL),
267 BITFIELD (CpuFMA),
268 BITFIELD (CpuLM),
269 BITFIELD (Cpu64),
270 BITFIELD (CpuNo64),
271 #ifdef CpuUnused
272 BITFIELD (CpuUnused),
273 #endif
276 static bitfield opcode_modifiers[] =
278 BITFIELD (D),
279 BITFIELD (W),
280 BITFIELD (Modrm),
281 BITFIELD (ShortForm),
282 BITFIELD (Jump),
283 BITFIELD (JumpDword),
284 BITFIELD (JumpByte),
285 BITFIELD (JumpInterSegment),
286 BITFIELD (FloatMF),
287 BITFIELD (FloatR),
288 BITFIELD (FloatD),
289 BITFIELD (Size16),
290 BITFIELD (Size32),
291 BITFIELD (Size64),
292 BITFIELD (IgnoreSize),
293 BITFIELD (DefaultSize),
294 BITFIELD (No_bSuf),
295 BITFIELD (No_wSuf),
296 BITFIELD (No_lSuf),
297 BITFIELD (No_sSuf),
298 BITFIELD (No_qSuf),
299 BITFIELD (No_ldSuf),
300 BITFIELD (FWait),
301 BITFIELD (IsString),
302 BITFIELD (RegKludge),
303 BITFIELD (FirstXmm0),
304 BITFIELD (Implicit1stXmm0),
305 BITFIELD (ByteOkIntel),
306 BITFIELD (ToDword),
307 BITFIELD (ToQword),
308 BITFIELD (AddrPrefixOp0),
309 BITFIELD (IsPrefix),
310 BITFIELD (ImmExt),
311 BITFIELD (NoRex64),
312 BITFIELD (Rex64),
313 BITFIELD (Ugh),
314 BITFIELD (Drex),
315 BITFIELD (Drexv),
316 BITFIELD (Drexc),
317 BITFIELD (Vex),
318 BITFIELD (Vex256),
319 BITFIELD (VexNDD),
320 BITFIELD (VexNDS),
321 BITFIELD (VexW0),
322 BITFIELD (VexW1),
323 BITFIELD (Vex0F),
324 BITFIELD (Vex0F38),
325 BITFIELD (Vex0F3A),
326 BITFIELD (Vex3Sources),
327 BITFIELD (VexImmExt),
328 BITFIELD (SSE2AVX),
329 BITFIELD (OldGcc),
330 BITFIELD (ATTMnemonic),
331 BITFIELD (ATTSyntax),
332 BITFIELD (IntelSyntax),
335 static bitfield operand_types[] =
337 BITFIELD (Reg8),
338 BITFIELD (Reg16),
339 BITFIELD (Reg32),
340 BITFIELD (Reg64),
341 BITFIELD (FloatReg),
342 BITFIELD (RegMMX),
343 BITFIELD (RegXMM),
344 BITFIELD (RegYMM),
345 BITFIELD (Imm8),
346 BITFIELD (Imm8S),
347 BITFIELD (Imm16),
348 BITFIELD (Imm32),
349 BITFIELD (Imm32S),
350 BITFIELD (Imm64),
351 BITFIELD (Imm1),
352 BITFIELD (BaseIndex),
353 BITFIELD (Disp8),
354 BITFIELD (Disp16),
355 BITFIELD (Disp32),
356 BITFIELD (Disp32S),
357 BITFIELD (Disp64),
358 BITFIELD (InOutPortReg),
359 BITFIELD (ShiftCount),
360 BITFIELD (Control),
361 BITFIELD (Debug),
362 BITFIELD (Test),
363 BITFIELD (SReg2),
364 BITFIELD (SReg3),
365 BITFIELD (Acc),
366 BITFIELD (FloatAcc),
367 BITFIELD (JumpAbsolute),
368 BITFIELD (EsSeg),
369 BITFIELD (RegMem),
370 BITFIELD (Mem),
371 BITFIELD (Byte),
372 BITFIELD (Word),
373 BITFIELD (Dword),
374 BITFIELD (Fword),
375 BITFIELD (Qword),
376 BITFIELD (Tbyte),
377 BITFIELD (Xmmword),
378 BITFIELD (Ymmword),
379 BITFIELD (Unspecified),
380 BITFIELD (Anysize),
381 BITFIELD (Vex_Imm4),
382 #ifdef OTUnused
383 BITFIELD (OTUnused),
384 #endif
387 static int lineno;
388 static const char *filename;
390 static int
391 compare (const void *x, const void *y)
393 const bitfield *xp = (const bitfield *) x;
394 const bitfield *yp = (const bitfield *) y;
395 return xp->position - yp->position;
398 static void
399 fail (const char *message, ...)
401 va_list args;
403 va_start (args, message);
404 fprintf (stderr, _("%s: Error: "), program_name);
405 vfprintf (stderr, message, args);
406 va_end (args);
407 xexit (1);
410 static void
411 process_copyright (FILE *fp)
413 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
414 /* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
416 This file is part of the GNU opcodes library.\n\
418 This library is free software; you can redistribute it and/or modify\n\
419 it under the terms of the GNU General Public License as published by\n\
420 the Free Software Foundation; either version 3, or (at your option)\n\
421 any later version.\n\
423 It is distributed in the hope that it will be useful, but WITHOUT\n\
424 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
425 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
426 License for more details.\n\
428 You should have received a copy of the GNU General Public License\n\
429 along with this program; if not, write to the Free Software\n\
430 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
431 MA 02110-1301, USA. */\n");
434 /* Remove leading white spaces. */
436 static char *
437 remove_leading_whitespaces (char *str)
439 while (ISSPACE (*str))
440 str++;
441 return str;
444 /* Remove trailing white spaces. */
446 static void
447 remove_trailing_whitespaces (char *str)
449 size_t last = strlen (str);
451 if (last == 0)
452 return;
456 last--;
457 if (ISSPACE (str [last]))
458 str[last] = '\0';
459 else
460 break;
462 while (last != 0);
465 /* Find next field separated by SEP and terminate it. Return a
466 pointer to the one after it. */
468 static char *
469 next_field (char *str, char sep, char **next)
471 char *p;
473 p = remove_leading_whitespaces (str);
474 for (str = p; *str != sep && *str != '\0'; str++);
476 *str = '\0';
477 remove_trailing_whitespaces (p);
479 *next = str + 1;
481 return p;
484 static void
485 set_bitfield (const char *f, bitfield *array, unsigned int size)
487 unsigned int i;
489 if (strcmp (f, "CpuSledgehammer") == 0)
490 f= "CpuK8";
491 else if (strcmp (f, "Mmword") == 0)
492 f= "Qword";
493 else if (strcmp (f, "Oword") == 0)
494 f= "Xmmword";
496 for (i = 0; i < size; i++)
497 if (strcasecmp (array[i].name, f) == 0)
499 array[i].value = 1;
500 return;
503 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
506 static void
507 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
508 int macro, const char *comma, const char *indent)
510 unsigned int i;
512 fprintf (table, "%s{ { ", indent);
514 for (i = 0; i < size - 1; i++)
516 fprintf (table, "%d, ", flags[i].value);
517 if (((i + 1) % 20) == 0)
519 /* We need \\ for macro. */
520 if (macro)
521 fprintf (table, " \\\n %s", indent);
522 else
523 fprintf (table, "\n %s", indent);
527 fprintf (table, "%d } }%s\n", flags[i].value, comma);
530 static void
531 process_i386_cpu_flag (FILE *table, char *flag, int macro,
532 const char *comma, const char *indent)
534 char *str, *next, *last;
535 bitfield flags [ARRAY_SIZE (cpu_flags)];
537 /* Copy the default cpu flags. */
538 memcpy (flags, cpu_flags, sizeof (cpu_flags));
540 if (strcasecmp (flag, "unknown") == 0)
542 unsigned int i;
544 /* We turn on everything except for cpu64 in case of
545 CPU_UNKNOWN_FLAGS. */
546 for (i = 0; i < ARRAY_SIZE (flags); i++)
547 if (flags[i].position != Cpu64)
548 flags[i].value = 1;
550 else if (strcmp (flag, "0"))
552 last = flag + strlen (flag);
553 for (next = flag; next && next < last; )
555 str = next_field (next, '|', &next);
556 if (str)
557 set_bitfield (str, flags, ARRAY_SIZE (flags));
561 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
562 comma, indent);
565 static void
566 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
568 unsigned int i;
570 fprintf (table, " { ");
572 for (i = 0; i < size - 1; i++)
574 fprintf (table, "%d, ", modifier[i].value);
575 if (((i + 1) % 20) == 0)
576 fprintf (table, "\n ");
579 fprintf (table, "%d },\n", modifier[i].value);
582 static void
583 process_i386_opcode_modifier (FILE *table, char *mod)
585 char *str, *next, *last;
586 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
588 /* Copy the default opcode modifier. */
589 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
591 if (strcmp (mod, "0"))
593 last = mod + strlen (mod);
594 for (next = mod; next && next < last; )
596 str = next_field (next, '|', &next);
597 if (str)
598 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
601 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
604 static void
605 output_operand_type (FILE *table, bitfield *types, unsigned int size,
606 int macro, const char *indent)
608 unsigned int i;
610 fprintf (table, "{ { ");
612 for (i = 0; i < size - 1; i++)
614 fprintf (table, "%d, ", types[i].value);
615 if (((i + 1) % 20) == 0)
617 /* We need \\ for macro. */
618 if (macro)
619 fprintf (table, "\\\n%s", indent);
620 else
621 fprintf (table, "\n%s", indent);
625 fprintf (table, "%d } }", types[i].value);
628 static void
629 process_i386_operand_type (FILE *table, char *op, int macro,
630 const char *indent)
632 char *str, *next, *last;
633 bitfield types [ARRAY_SIZE (operand_types)];
635 /* Copy the default operand type. */
636 memcpy (types, operand_types, sizeof (types));
638 if (strcmp (op, "0"))
640 last = op + strlen (op);
641 for (next = op; next && next < last; )
643 str = next_field (next, '|', &next);
644 if (str)
645 set_bitfield (str, types, ARRAY_SIZE (types));
648 output_operand_type (table, types, ARRAY_SIZE (types), macro,
649 indent);
652 static void
653 process_i386_opcodes (FILE *table)
655 FILE *fp;
656 char buf[2048];
657 unsigned int i;
658 char *str, *p, *last;
659 char *name, *operands, *base_opcode, *extension_opcode;
660 char *opcode_length;
661 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
663 filename = "i386-opc.tbl";
664 fp = fopen (filename, "r");
666 if (fp == NULL)
667 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
668 xstrerror (errno));
670 fprintf (table, "\n/* i386 opcode table. */\n\n");
671 fprintf (table, "const template i386_optab[] =\n{\n");
673 while (!feof (fp))
675 if (fgets (buf, sizeof (buf), fp) == NULL)
676 break;
678 lineno++;
680 p = remove_leading_whitespaces (buf);
682 /* Skip comments. */
683 str = strstr (p, "//");
684 if (str != NULL)
685 str[0] = '\0';
687 /* Remove trailing white spaces. */
688 remove_trailing_whitespaces (p);
690 switch (p[0])
692 case '#':
693 fprintf (table, "%s\n", p);
694 case '\0':
695 continue;
696 break;
697 default:
698 break;
701 last = p + strlen (p);
703 /* Find name. */
704 name = next_field (p, ',', &str);
706 if (str >= last)
707 abort ();
709 /* Find number of operands. */
710 operands = next_field (str, ',', &str);
712 if (str >= last)
713 abort ();
715 /* Find base_opcode. */
716 base_opcode = next_field (str, ',', &str);
718 if (str >= last)
719 abort ();
721 /* Find extension_opcode. */
722 extension_opcode = next_field (str, ',', &str);
724 if (str >= last)
725 abort ();
727 /* Find opcode_length. */
728 opcode_length = next_field (str, ',', &str);
730 if (str >= last)
731 abort ();
733 /* Find cpu_flags. */
734 cpu_flags = next_field (str, ',', &str);
736 if (str >= last)
737 abort ();
739 /* Find opcode_modifier. */
740 opcode_modifier = next_field (str, ',', &str);
742 if (str >= last)
743 abort ();
745 /* Remove the first {. */
746 str = remove_leading_whitespaces (str);
747 if (*str != '{')
748 abort ();
749 str = remove_leading_whitespaces (str + 1);
751 i = strlen (str);
753 /* There are at least "X}". */
754 if (i < 2)
755 abort ();
757 /* Remove trailing white spaces and }. */
760 i--;
761 if (ISSPACE (str[i]) || str[i] == '}')
762 str[i] = '\0';
763 else
764 break;
766 while (i != 0);
768 last = str + i;
770 /* Find operand_types. */
771 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
773 if (str >= last)
775 operand_types [i] = NULL;
776 break;
779 operand_types [i] = next_field (str, ',', &str);
780 if (*operand_types[i] == '0')
782 if (i != 0)
783 operand_types[i] = NULL;
784 break;
788 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
789 name, operands, base_opcode, extension_opcode,
790 opcode_length);
792 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
794 process_i386_opcode_modifier (table, opcode_modifier);
796 fprintf (table, " { ");
798 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
800 if (operand_types[i] == NULL
801 || *operand_types[i] == '0')
803 if (i == 0)
804 process_i386_operand_type (table, "0", 0, "\t ");
805 break;
808 if (i != 0)
809 fprintf (table, ",\n ");
811 process_i386_operand_type (table, operand_types[i], 0,
812 "\t ");
814 fprintf (table, " } },\n");
817 fclose (fp);
819 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
821 process_i386_cpu_flag (table, "0", 0, ",", " ");
823 process_i386_opcode_modifier (table, "0");
825 fprintf (table, " { ");
826 process_i386_operand_type (table, "0", 0, "\t ");
827 fprintf (table, " } }\n");
829 fprintf (table, "};\n");
832 static void
833 process_i386_registers (FILE *table)
835 FILE *fp;
836 char buf[2048];
837 char *str, *p, *last;
838 char *reg_name, *reg_type, *reg_flags, *reg_num;
839 char *dw2_32_num, *dw2_64_num;
841 filename = "i386-reg.tbl";
842 fp = fopen (filename, "r");
843 if (fp == NULL)
844 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
845 xstrerror (errno));
847 fprintf (table, "\n/* i386 register table. */\n\n");
848 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
850 while (!feof (fp))
852 if (fgets (buf, sizeof (buf), fp) == NULL)
853 break;
855 lineno++;
857 p = remove_leading_whitespaces (buf);
859 /* Skip comments. */
860 str = strstr (p, "//");
861 if (str != NULL)
862 str[0] = '\0';
864 /* Remove trailing white spaces. */
865 remove_trailing_whitespaces (p);
867 switch (p[0])
869 case '#':
870 fprintf (table, "%s\n", p);
871 case '\0':
872 continue;
873 break;
874 default:
875 break;
878 last = p + strlen (p);
880 /* Find reg_name. */
881 reg_name = next_field (p, ',', &str);
883 if (str >= last)
884 abort ();
886 /* Find reg_type. */
887 reg_type = next_field (str, ',', &str);
889 if (str >= last)
890 abort ();
892 /* Find reg_flags. */
893 reg_flags = next_field (str, ',', &str);
895 if (str >= last)
896 abort ();
898 /* Find reg_num. */
899 reg_num = next_field (str, ',', &str);
901 if (str >= last)
902 abort ();
904 fprintf (table, " { \"%s\",\n ", reg_name);
906 process_i386_operand_type (table, reg_type, 0, "\t");
908 /* Find 32-bit Dwarf2 register number. */
909 dw2_32_num = next_field (str, ',', &str);
911 if (str >= last)
912 abort ();
914 /* Find 64-bit Dwarf2 register number. */
915 dw2_64_num = next_field (str, ',', &str);
917 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
918 reg_flags, reg_num, dw2_32_num, dw2_64_num);
921 fclose (fp);
923 fprintf (table, "};\n");
925 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
928 static void
929 process_i386_initializers (void)
931 unsigned int i;
932 FILE *fp = fopen ("i386-init.h", "w");
933 char *init;
935 if (fp == NULL)
936 fail (_("can't create i386-init.h, errno = %s\n"),
937 xstrerror (errno));
939 process_copyright (fp);
941 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
943 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
944 init = xstrdup (cpu_flag_init[i].init);
945 process_i386_cpu_flag (fp, init, 1, "", " ");
946 free (init);
949 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
951 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
952 init = xstrdup (operand_type_init[i].init);
953 process_i386_operand_type (fp, init, 1, " ");
954 free (init);
956 fprintf (fp, "\n");
958 fclose (fp);
961 /* Program options. */
962 #define OPTION_SRCDIR 200
964 struct option long_options[] =
966 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
967 {"debug", no_argument, NULL, 'd'},
968 {"version", no_argument, NULL, 'V'},
969 {"help", no_argument, NULL, 'h'},
970 {0, no_argument, NULL, 0}
973 static void
974 print_version (void)
976 printf ("%s: version 1.0\n", program_name);
977 xexit (0);
980 static void
981 usage (FILE * stream, int status)
983 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
984 program_name);
985 xexit (status);
989 main (int argc, char **argv)
991 extern int chdir (char *);
992 char *srcdir = NULL;
993 int c;
994 FILE *table;
996 program_name = *argv;
997 xmalloc_set_program_name (program_name);
999 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1000 switch (c)
1002 case OPTION_SRCDIR:
1003 srcdir = optarg;
1004 break;
1005 case 'V':
1006 case 'v':
1007 print_version ();
1008 break;
1009 case 'd':
1010 debug = 1;
1011 break;
1012 case 'h':
1013 case '?':
1014 usage (stderr, 0);
1015 default:
1016 case 0:
1017 break;
1020 if (optind != argc)
1021 usage (stdout, 1);
1023 if (srcdir != NULL)
1024 if (chdir (srcdir) != 0)
1025 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1026 srcdir, xstrerror (errno));
1028 /* Check the unused bitfield in i386_cpu_flags. */
1029 #ifndef CpuUnused
1030 c = CpuNumOfBits - CpuMax - 1;
1031 if (c)
1032 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1033 #endif
1035 /* Check the unused bitfield in i386_operand_type. */
1036 #ifndef OTUnused
1037 c = OTNumOfBits - OTMax - 1;
1038 if (c)
1039 fail (_("%d unused bits in i386_operand_type.\n"), c);
1040 #endif
1042 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1043 compare);
1045 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1046 sizeof (opcode_modifiers [0]), compare);
1048 qsort (operand_types, ARRAY_SIZE (operand_types),
1049 sizeof (operand_types [0]), compare);
1051 table = fopen ("i386-tbl.h", "w");
1052 if (table == NULL)
1053 fail (_("can't create i386-tbl.h, errno = %s\n"),
1054 xstrerror (errno));
1056 process_copyright (table);
1058 process_i386_opcodes (table);
1059 process_i386_registers (table);
1060 process_i386_initializers ();
1062 fclose (table);
1064 exit (0);