* target-reloc.h (relocate_section): Fix dead-pointer bug.
[binutils.git] / opcodes / i386-gen.c
blob8eaa089ef3b1eef35442bdad022b4aef8641597a
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 (NoAVX),
330 BITFIELD (OldGcc),
331 BITFIELD (ATTMnemonic),
332 BITFIELD (ATTSyntax),
333 BITFIELD (IntelSyntax),
336 static bitfield operand_types[] =
338 BITFIELD (Reg8),
339 BITFIELD (Reg16),
340 BITFIELD (Reg32),
341 BITFIELD (Reg64),
342 BITFIELD (FloatReg),
343 BITFIELD (RegMMX),
344 BITFIELD (RegXMM),
345 BITFIELD (RegYMM),
346 BITFIELD (Imm8),
347 BITFIELD (Imm8S),
348 BITFIELD (Imm16),
349 BITFIELD (Imm32),
350 BITFIELD (Imm32S),
351 BITFIELD (Imm64),
352 BITFIELD (Imm1),
353 BITFIELD (BaseIndex),
354 BITFIELD (Disp8),
355 BITFIELD (Disp16),
356 BITFIELD (Disp32),
357 BITFIELD (Disp32S),
358 BITFIELD (Disp64),
359 BITFIELD (InOutPortReg),
360 BITFIELD (ShiftCount),
361 BITFIELD (Control),
362 BITFIELD (Debug),
363 BITFIELD (Test),
364 BITFIELD (SReg2),
365 BITFIELD (SReg3),
366 BITFIELD (Acc),
367 BITFIELD (FloatAcc),
368 BITFIELD (JumpAbsolute),
369 BITFIELD (EsSeg),
370 BITFIELD (RegMem),
371 BITFIELD (Mem),
372 BITFIELD (Byte),
373 BITFIELD (Word),
374 BITFIELD (Dword),
375 BITFIELD (Fword),
376 BITFIELD (Qword),
377 BITFIELD (Tbyte),
378 BITFIELD (Xmmword),
379 BITFIELD (Ymmword),
380 BITFIELD (Unspecified),
381 BITFIELD (Anysize),
382 BITFIELD (Vex_Imm4),
383 #ifdef OTUnused
384 BITFIELD (OTUnused),
385 #endif
388 static int lineno;
389 static const char *filename;
391 static int
392 compare (const void *x, const void *y)
394 const bitfield *xp = (const bitfield *) x;
395 const bitfield *yp = (const bitfield *) y;
396 return xp->position - yp->position;
399 static void
400 fail (const char *message, ...)
402 va_list args;
404 va_start (args, message);
405 fprintf (stderr, _("%s: Error: "), program_name);
406 vfprintf (stderr, message, args);
407 va_end (args);
408 xexit (1);
411 static void
412 process_copyright (FILE *fp)
414 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
415 /* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
417 This file is part of the GNU opcodes library.\n\
419 This library is free software; you can redistribute it and/or modify\n\
420 it under the terms of the GNU General Public License as published by\n\
421 the Free Software Foundation; either version 3, or (at your option)\n\
422 any later version.\n\
424 It is distributed in the hope that it will be useful, but WITHOUT\n\
425 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
426 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
427 License for more details.\n\
429 You should have received a copy of the GNU General Public License\n\
430 along with this program; if not, write to the Free Software\n\
431 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
432 MA 02110-1301, USA. */\n");
435 /* Remove leading white spaces. */
437 static char *
438 remove_leading_whitespaces (char *str)
440 while (ISSPACE (*str))
441 str++;
442 return str;
445 /* Remove trailing white spaces. */
447 static void
448 remove_trailing_whitespaces (char *str)
450 size_t last = strlen (str);
452 if (last == 0)
453 return;
457 last--;
458 if (ISSPACE (str [last]))
459 str[last] = '\0';
460 else
461 break;
463 while (last != 0);
466 /* Find next field separated by SEP and terminate it. Return a
467 pointer to the one after it. */
469 static char *
470 next_field (char *str, char sep, char **next)
472 char *p;
474 p = remove_leading_whitespaces (str);
475 for (str = p; *str != sep && *str != '\0'; str++);
477 *str = '\0';
478 remove_trailing_whitespaces (p);
480 *next = str + 1;
482 return p;
485 static void
486 set_bitfield (const char *f, bitfield *array, unsigned int size)
488 unsigned int i;
490 if (strcmp (f, "CpuSledgehammer") == 0)
491 f= "CpuK8";
492 else if (strcmp (f, "Mmword") == 0)
493 f= "Qword";
494 else if (strcmp (f, "Oword") == 0)
495 f= "Xmmword";
497 for (i = 0; i < size; i++)
498 if (strcasecmp (array[i].name, f) == 0)
500 array[i].value = 1;
501 return;
504 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
507 static void
508 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
509 int macro, const char *comma, const char *indent)
511 unsigned int i;
513 fprintf (table, "%s{ { ", indent);
515 for (i = 0; i < size - 1; i++)
517 fprintf (table, "%d, ", flags[i].value);
518 if (((i + 1) % 20) == 0)
520 /* We need \\ for macro. */
521 if (macro)
522 fprintf (table, " \\\n %s", indent);
523 else
524 fprintf (table, "\n %s", indent);
528 fprintf (table, "%d } }%s\n", flags[i].value, comma);
531 static void
532 process_i386_cpu_flag (FILE *table, char *flag, int macro,
533 const char *comma, const char *indent)
535 char *str, *next, *last;
536 bitfield flags [ARRAY_SIZE (cpu_flags)];
538 /* Copy the default cpu flags. */
539 memcpy (flags, cpu_flags, sizeof (cpu_flags));
541 if (strcasecmp (flag, "unknown") == 0)
543 unsigned int i;
545 /* We turn on everything except for cpu64 in case of
546 CPU_UNKNOWN_FLAGS. */
547 for (i = 0; i < ARRAY_SIZE (flags); i++)
548 if (flags[i].position != Cpu64)
549 flags[i].value = 1;
551 else if (strcmp (flag, "0"))
553 last = flag + strlen (flag);
554 for (next = flag; next && next < last; )
556 str = next_field (next, '|', &next);
557 if (str)
558 set_bitfield (str, flags, ARRAY_SIZE (flags));
562 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
563 comma, indent);
566 static void
567 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
569 unsigned int i;
571 fprintf (table, " { ");
573 for (i = 0; i < size - 1; i++)
575 fprintf (table, "%d, ", modifier[i].value);
576 if (((i + 1) % 20) == 0)
577 fprintf (table, "\n ");
580 fprintf (table, "%d },\n", modifier[i].value);
583 static void
584 process_i386_opcode_modifier (FILE *table, char *mod)
586 char *str, *next, *last;
587 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
589 /* Copy the default opcode modifier. */
590 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
592 if (strcmp (mod, "0"))
594 last = mod + strlen (mod);
595 for (next = mod; next && next < last; )
597 str = next_field (next, '|', &next);
598 if (str)
599 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
602 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
605 static void
606 output_operand_type (FILE *table, bitfield *types, unsigned int size,
607 int macro, const char *indent)
609 unsigned int i;
611 fprintf (table, "{ { ");
613 for (i = 0; i < size - 1; i++)
615 fprintf (table, "%d, ", types[i].value);
616 if (((i + 1) % 20) == 0)
618 /* We need \\ for macro. */
619 if (macro)
620 fprintf (table, "\\\n%s", indent);
621 else
622 fprintf (table, "\n%s", indent);
626 fprintf (table, "%d } }", types[i].value);
629 static void
630 process_i386_operand_type (FILE *table, char *op, int macro,
631 const char *indent)
633 char *str, *next, *last;
634 bitfield types [ARRAY_SIZE (operand_types)];
636 /* Copy the default operand type. */
637 memcpy (types, operand_types, sizeof (types));
639 if (strcmp (op, "0"))
641 last = op + strlen (op);
642 for (next = op; next && next < last; )
644 str = next_field (next, '|', &next);
645 if (str)
646 set_bitfield (str, types, ARRAY_SIZE (types));
649 output_operand_type (table, types, ARRAY_SIZE (types), macro,
650 indent);
653 static void
654 process_i386_opcodes (FILE *table)
656 FILE *fp;
657 char buf[2048];
658 unsigned int i;
659 char *str, *p, *last;
660 char *name, *operands, *base_opcode, *extension_opcode;
661 char *opcode_length;
662 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
664 filename = "i386-opc.tbl";
665 fp = fopen (filename, "r");
667 if (fp == NULL)
668 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
669 xstrerror (errno));
671 fprintf (table, "\n/* i386 opcode table. */\n\n");
672 fprintf (table, "const template i386_optab[] =\n{\n");
674 while (!feof (fp))
676 if (fgets (buf, sizeof (buf), fp) == NULL)
677 break;
679 lineno++;
681 p = remove_leading_whitespaces (buf);
683 /* Skip comments. */
684 str = strstr (p, "//");
685 if (str != NULL)
686 str[0] = '\0';
688 /* Remove trailing white spaces. */
689 remove_trailing_whitespaces (p);
691 switch (p[0])
693 case '#':
694 fprintf (table, "%s\n", p);
695 case '\0':
696 continue;
697 break;
698 default:
699 break;
702 last = p + strlen (p);
704 /* Find name. */
705 name = next_field (p, ',', &str);
707 if (str >= last)
708 abort ();
710 /* Find number of operands. */
711 operands = next_field (str, ',', &str);
713 if (str >= last)
714 abort ();
716 /* Find base_opcode. */
717 base_opcode = next_field (str, ',', &str);
719 if (str >= last)
720 abort ();
722 /* Find extension_opcode. */
723 extension_opcode = next_field (str, ',', &str);
725 if (str >= last)
726 abort ();
728 /* Find opcode_length. */
729 opcode_length = next_field (str, ',', &str);
731 if (str >= last)
732 abort ();
734 /* Find cpu_flags. */
735 cpu_flags = next_field (str, ',', &str);
737 if (str >= last)
738 abort ();
740 /* Find opcode_modifier. */
741 opcode_modifier = next_field (str, ',', &str);
743 if (str >= last)
744 abort ();
746 /* Remove the first {. */
747 str = remove_leading_whitespaces (str);
748 if (*str != '{')
749 abort ();
750 str = remove_leading_whitespaces (str + 1);
752 i = strlen (str);
754 /* There are at least "X}". */
755 if (i < 2)
756 abort ();
758 /* Remove trailing white spaces and }. */
761 i--;
762 if (ISSPACE (str[i]) || str[i] == '}')
763 str[i] = '\0';
764 else
765 break;
767 while (i != 0);
769 last = str + i;
771 /* Find operand_types. */
772 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
774 if (str >= last)
776 operand_types [i] = NULL;
777 break;
780 operand_types [i] = next_field (str, ',', &str);
781 if (*operand_types[i] == '0')
783 if (i != 0)
784 operand_types[i] = NULL;
785 break;
789 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
790 name, operands, base_opcode, extension_opcode,
791 opcode_length);
793 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
795 process_i386_opcode_modifier (table, opcode_modifier);
797 fprintf (table, " { ");
799 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
801 if (operand_types[i] == NULL
802 || *operand_types[i] == '0')
804 if (i == 0)
805 process_i386_operand_type (table, "0", 0, "\t ");
806 break;
809 if (i != 0)
810 fprintf (table, ",\n ");
812 process_i386_operand_type (table, operand_types[i], 0,
813 "\t ");
815 fprintf (table, " } },\n");
818 fclose (fp);
820 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
822 process_i386_cpu_flag (table, "0", 0, ",", " ");
824 process_i386_opcode_modifier (table, "0");
826 fprintf (table, " { ");
827 process_i386_operand_type (table, "0", 0, "\t ");
828 fprintf (table, " } }\n");
830 fprintf (table, "};\n");
833 static void
834 process_i386_registers (FILE *table)
836 FILE *fp;
837 char buf[2048];
838 char *str, *p, *last;
839 char *reg_name, *reg_type, *reg_flags, *reg_num;
840 char *dw2_32_num, *dw2_64_num;
842 filename = "i386-reg.tbl";
843 fp = fopen (filename, "r");
844 if (fp == NULL)
845 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
846 xstrerror (errno));
848 fprintf (table, "\n/* i386 register table. */\n\n");
849 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
851 while (!feof (fp))
853 if (fgets (buf, sizeof (buf), fp) == NULL)
854 break;
856 lineno++;
858 p = remove_leading_whitespaces (buf);
860 /* Skip comments. */
861 str = strstr (p, "//");
862 if (str != NULL)
863 str[0] = '\0';
865 /* Remove trailing white spaces. */
866 remove_trailing_whitespaces (p);
868 switch (p[0])
870 case '#':
871 fprintf (table, "%s\n", p);
872 case '\0':
873 continue;
874 break;
875 default:
876 break;
879 last = p + strlen (p);
881 /* Find reg_name. */
882 reg_name = next_field (p, ',', &str);
884 if (str >= last)
885 abort ();
887 /* Find reg_type. */
888 reg_type = next_field (str, ',', &str);
890 if (str >= last)
891 abort ();
893 /* Find reg_flags. */
894 reg_flags = next_field (str, ',', &str);
896 if (str >= last)
897 abort ();
899 /* Find reg_num. */
900 reg_num = next_field (str, ',', &str);
902 if (str >= last)
903 abort ();
905 fprintf (table, " { \"%s\",\n ", reg_name);
907 process_i386_operand_type (table, reg_type, 0, "\t");
909 /* Find 32-bit Dwarf2 register number. */
910 dw2_32_num = next_field (str, ',', &str);
912 if (str >= last)
913 abort ();
915 /* Find 64-bit Dwarf2 register number. */
916 dw2_64_num = next_field (str, ',', &str);
918 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
919 reg_flags, reg_num, dw2_32_num, dw2_64_num);
922 fclose (fp);
924 fprintf (table, "};\n");
926 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
929 static void
930 process_i386_initializers (void)
932 unsigned int i;
933 FILE *fp = fopen ("i386-init.h", "w");
934 char *init;
936 if (fp == NULL)
937 fail (_("can't create i386-init.h, errno = %s\n"),
938 xstrerror (errno));
940 process_copyright (fp);
942 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
944 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
945 init = xstrdup (cpu_flag_init[i].init);
946 process_i386_cpu_flag (fp, init, 1, "", " ");
947 free (init);
950 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
952 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
953 init = xstrdup (operand_type_init[i].init);
954 process_i386_operand_type (fp, init, 1, " ");
955 free (init);
957 fprintf (fp, "\n");
959 fclose (fp);
962 /* Program options. */
963 #define OPTION_SRCDIR 200
965 struct option long_options[] =
967 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
968 {"debug", no_argument, NULL, 'd'},
969 {"version", no_argument, NULL, 'V'},
970 {"help", no_argument, NULL, 'h'},
971 {0, no_argument, NULL, 0}
974 static void
975 print_version (void)
977 printf ("%s: version 1.0\n", program_name);
978 xexit (0);
981 static void
982 usage (FILE * stream, int status)
984 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
985 program_name);
986 xexit (status);
990 main (int argc, char **argv)
992 extern int chdir (char *);
993 char *srcdir = NULL;
994 int c;
995 FILE *table;
997 program_name = *argv;
998 xmalloc_set_program_name (program_name);
1000 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1001 switch (c)
1003 case OPTION_SRCDIR:
1004 srcdir = optarg;
1005 break;
1006 case 'V':
1007 case 'v':
1008 print_version ();
1009 break;
1010 case 'd':
1011 debug = 1;
1012 break;
1013 case 'h':
1014 case '?':
1015 usage (stderr, 0);
1016 default:
1017 case 0:
1018 break;
1021 if (optind != argc)
1022 usage (stdout, 1);
1024 if (srcdir != NULL)
1025 if (chdir (srcdir) != 0)
1026 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1027 srcdir, xstrerror (errno));
1029 /* Check the unused bitfield in i386_cpu_flags. */
1030 #ifndef CpuUnused
1031 c = CpuNumOfBits - CpuMax - 1;
1032 if (c)
1033 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1034 #endif
1036 /* Check the unused bitfield in i386_operand_type. */
1037 #ifndef OTUnused
1038 c = OTNumOfBits - OTMax - 1;
1039 if (c)
1040 fail (_("%d unused bits in i386_operand_type.\n"), c);
1041 #endif
1043 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1044 compare);
1046 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1047 sizeof (opcode_modifiers [0]), compare);
1049 qsort (operand_types, ARRAY_SIZE (operand_types),
1050 sizeof (operand_types [0]), compare);
1052 table = fopen ("i386-tbl.h", "w");
1053 if (table == NULL)
1054 fail (_("can't create i386-tbl.h, errno = %s\n"),
1055 xstrerror (errno));
1057 process_copyright (table);
1059 process_i386_opcodes (table);
1060 process_i386_registers (table);
1061 process_i386_initializers ();
1063 fclose (table);
1065 exit (0);