2008-07-07 Stan Shebs <stan@codesourcery.com>
[binutils.git] / opcodes / i386-gen.c
blobaa9a7ff61e98d6d69372da992157926536a366c2
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_MOVBE_FLAGS",
112 "CpuMovbe" },
113 { "CPU_EPT_FLAGS",
114 "CpuEPT" },
115 { "CPU_3DNOW_FLAGS",
116 "CpuMMX|Cpu3dnow" },
117 { "CPU_3DNOWA_FLAGS",
118 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
119 { "CPU_PADLOCK_FLAGS",
120 "CpuPadLock" },
121 { "CPU_SVME_FLAGS",
122 "CpuSVME" },
123 { "CPU_SSE4A_FLAGS",
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
125 { "CPU_ABM_FLAGS",
126 "CpuABM" },
127 { "CPU_SSE5_FLAGS",
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
129 { "CPU_AVX_FLAGS",
130 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
133 static initializer operand_type_init [] =
135 { "OPERAND_TYPE_NONE",
136 "0" },
137 { "OPERAND_TYPE_REG8",
138 "Reg8" },
139 { "OPERAND_TYPE_REG16",
140 "Reg16" },
141 { "OPERAND_TYPE_REG32",
142 "Reg32" },
143 { "OPERAND_TYPE_REG64",
144 "Reg64" },
145 { "OPERAND_TYPE_IMM1",
146 "Imm1" },
147 { "OPERAND_TYPE_IMM8",
148 "Imm8" },
149 { "OPERAND_TYPE_IMM8S",
150 "Imm8S" },
151 { "OPERAND_TYPE_IMM16",
152 "Imm16" },
153 { "OPERAND_TYPE_IMM32",
154 "Imm32" },
155 { "OPERAND_TYPE_IMM32S",
156 "Imm32S" },
157 { "OPERAND_TYPE_IMM64",
158 "Imm64" },
159 { "OPERAND_TYPE_BASEINDEX",
160 "BaseIndex" },
161 { "OPERAND_TYPE_DISP8",
162 "Disp8" },
163 { "OPERAND_TYPE_DISP16",
164 "Disp16" },
165 { "OPERAND_TYPE_DISP32",
166 "Disp32" },
167 { "OPERAND_TYPE_DISP32S",
168 "Disp32S" },
169 { "OPERAND_TYPE_DISP64",
170 "Disp64" },
171 { "OPERAND_TYPE_INOUTPORTREG",
172 "InOutPortReg" },
173 { "OPERAND_TYPE_SHIFTCOUNT",
174 "ShiftCount" },
175 { "OPERAND_TYPE_CONTROL",
176 "Control" },
177 { "OPERAND_TYPE_TEST",
178 "Test" },
179 { "OPERAND_TYPE_DEBUG",
180 "FloatReg" },
181 { "OPERAND_TYPE_FLOATREG",
182 "FloatReg" },
183 { "OPERAND_TYPE_FLOATACC",
184 "FloatAcc" },
185 { "OPERAND_TYPE_SREG2",
186 "SReg2" },
187 { "OPERAND_TYPE_SREG3",
188 "SReg3" },
189 { "OPERAND_TYPE_ACC",
190 "Acc" },
191 { "OPERAND_TYPE_JUMPABSOLUTE",
192 "JumpAbsolute" },
193 { "OPERAND_TYPE_REGMMX",
194 "RegMMX" },
195 { "OPERAND_TYPE_REGXMM",
196 "RegXMM" },
197 { "OPERAND_TYPE_REGYMM",
198 "RegYMM" },
199 { "OPERAND_TYPE_ESSEG",
200 "EsSeg" },
201 { "OPERAND_TYPE_ACC32",
202 "Reg32|Acc|Dword" },
203 { "OPERAND_TYPE_ACC64",
204 "Reg64|Acc|Qword" },
205 { "OPERAND_TYPE_INOUTPORTREG",
206 "InOutPortReg" },
207 { "OPERAND_TYPE_REG16_INOUTPORTREG",
208 "Reg16|InOutPortReg" },
209 { "OPERAND_TYPE_DISP16_32",
210 "Disp16|Disp32" },
211 { "OPERAND_TYPE_ANYDISP",
212 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
213 { "OPERAND_TYPE_IMM16_32",
214 "Imm16|Imm32" },
215 { "OPERAND_TYPE_IMM16_32S",
216 "Imm16|Imm32S" },
217 { "OPERAND_TYPE_IMM16_32_32S",
218 "Imm16|Imm32|Imm32S" },
219 { "OPERAND_TYPE_IMM32_32S_DISP32",
220 "Imm32|Imm32S|Disp32" },
221 { "OPERAND_TYPE_IMM64_DISP64",
222 "Imm64|Disp64" },
223 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
224 "Imm32|Imm32S|Imm64|Disp32" },
225 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
226 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
227 { "OPERAND_TYPE_VEX_IMM4",
228 "VEX_Imm4" },
231 typedef struct bitfield
233 int position;
234 int value;
235 const char *name;
236 } bitfield;
238 #define BITFIELD(n) { n, 0, #n }
240 static bitfield cpu_flags[] =
242 BITFIELD (Cpu186),
243 BITFIELD (Cpu286),
244 BITFIELD (Cpu386),
245 BITFIELD (Cpu486),
246 BITFIELD (Cpu586),
247 BITFIELD (Cpu686),
248 BITFIELD (CpuP4),
249 BITFIELD (CpuK6),
250 BITFIELD (CpuK8),
251 BITFIELD (CpuMMX),
252 BITFIELD (CpuSSE),
253 BITFIELD (CpuSSE2),
254 BITFIELD (CpuSSE3),
255 BITFIELD (CpuSSSE3),
256 BITFIELD (CpuSSE4_1),
257 BITFIELD (CpuSSE4_2),
258 BITFIELD (CpuAVX),
259 BITFIELD (CpuSSE4a),
260 BITFIELD (CpuSSE5),
261 BITFIELD (Cpu3dnow),
262 BITFIELD (Cpu3dnowA),
263 BITFIELD (CpuPadLock),
264 BITFIELD (CpuSVME),
265 BITFIELD (CpuVMX),
266 BITFIELD (CpuSMX),
267 BITFIELD (CpuABM),
268 BITFIELD (CpuXsave),
269 BITFIELD (CpuAES),
270 BITFIELD (CpuPCLMUL),
271 BITFIELD (CpuFMA),
272 BITFIELD (CpuLM),
273 BITFIELD (CpuMovbe),
274 BITFIELD (CpuEPT),
275 BITFIELD (Cpu64),
276 BITFIELD (CpuNo64),
277 #ifdef CpuUnused
278 BITFIELD (CpuUnused),
279 #endif
282 static bitfield opcode_modifiers[] =
284 BITFIELD (D),
285 BITFIELD (W),
286 BITFIELD (Modrm),
287 BITFIELD (ShortForm),
288 BITFIELD (Jump),
289 BITFIELD (JumpDword),
290 BITFIELD (JumpByte),
291 BITFIELD (JumpInterSegment),
292 BITFIELD (FloatMF),
293 BITFIELD (FloatR),
294 BITFIELD (FloatD),
295 BITFIELD (Size16),
296 BITFIELD (Size32),
297 BITFIELD (Size64),
298 BITFIELD (IgnoreSize),
299 BITFIELD (DefaultSize),
300 BITFIELD (No_bSuf),
301 BITFIELD (No_wSuf),
302 BITFIELD (No_lSuf),
303 BITFIELD (No_sSuf),
304 BITFIELD (No_qSuf),
305 BITFIELD (No_ldSuf),
306 BITFIELD (FWait),
307 BITFIELD (IsString),
308 BITFIELD (RegKludge),
309 BITFIELD (FirstXmm0),
310 BITFIELD (Implicit1stXmm0),
311 BITFIELD (ByteOkIntel),
312 BITFIELD (ToDword),
313 BITFIELD (ToQword),
314 BITFIELD (AddrPrefixOp0),
315 BITFIELD (IsPrefix),
316 BITFIELD (ImmExt),
317 BITFIELD (NoRex64),
318 BITFIELD (Rex64),
319 BITFIELD (Ugh),
320 BITFIELD (Drex),
321 BITFIELD (Drexv),
322 BITFIELD (Drexc),
323 BITFIELD (Vex),
324 BITFIELD (Vex256),
325 BITFIELD (VexNDD),
326 BITFIELD (VexNDS),
327 BITFIELD (VexW0),
328 BITFIELD (VexW1),
329 BITFIELD (Vex0F),
330 BITFIELD (Vex0F38),
331 BITFIELD (Vex0F3A),
332 BITFIELD (Vex3Sources),
333 BITFIELD (VexImmExt),
334 BITFIELD (SSE2AVX),
335 BITFIELD (NoAVX),
336 BITFIELD (OldGcc),
337 BITFIELD (ATTMnemonic),
338 BITFIELD (ATTSyntax),
339 BITFIELD (IntelSyntax),
342 static bitfield operand_types[] =
344 BITFIELD (Reg8),
345 BITFIELD (Reg16),
346 BITFIELD (Reg32),
347 BITFIELD (Reg64),
348 BITFIELD (FloatReg),
349 BITFIELD (RegMMX),
350 BITFIELD (RegXMM),
351 BITFIELD (RegYMM),
352 BITFIELD (Imm8),
353 BITFIELD (Imm8S),
354 BITFIELD (Imm16),
355 BITFIELD (Imm32),
356 BITFIELD (Imm32S),
357 BITFIELD (Imm64),
358 BITFIELD (Imm1),
359 BITFIELD (BaseIndex),
360 BITFIELD (Disp8),
361 BITFIELD (Disp16),
362 BITFIELD (Disp32),
363 BITFIELD (Disp32S),
364 BITFIELD (Disp64),
365 BITFIELD (InOutPortReg),
366 BITFIELD (ShiftCount),
367 BITFIELD (Control),
368 BITFIELD (Debug),
369 BITFIELD (Test),
370 BITFIELD (SReg2),
371 BITFIELD (SReg3),
372 BITFIELD (Acc),
373 BITFIELD (FloatAcc),
374 BITFIELD (JumpAbsolute),
375 BITFIELD (EsSeg),
376 BITFIELD (RegMem),
377 BITFIELD (Mem),
378 BITFIELD (Byte),
379 BITFIELD (Word),
380 BITFIELD (Dword),
381 BITFIELD (Fword),
382 BITFIELD (Qword),
383 BITFIELD (Tbyte),
384 BITFIELD (Xmmword),
385 BITFIELD (Ymmword),
386 BITFIELD (Unspecified),
387 BITFIELD (Anysize),
388 BITFIELD (Vex_Imm4),
389 #ifdef OTUnused
390 BITFIELD (OTUnused),
391 #endif
394 static int lineno;
395 static const char *filename;
397 static int
398 compare (const void *x, const void *y)
400 const bitfield *xp = (const bitfield *) x;
401 const bitfield *yp = (const bitfield *) y;
402 return xp->position - yp->position;
405 static void
406 fail (const char *message, ...)
408 va_list args;
410 va_start (args, message);
411 fprintf (stderr, _("%s: Error: "), program_name);
412 vfprintf (stderr, message, args);
413 va_end (args);
414 xexit (1);
417 static void
418 process_copyright (FILE *fp)
420 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
421 /* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
423 This file is part of the GNU opcodes library.\n\
425 This library is free software; you can redistribute it and/or modify\n\
426 it under the terms of the GNU General Public License as published by\n\
427 the Free Software Foundation; either version 3, or (at your option)\n\
428 any later version.\n\
430 It is distributed in the hope that it will be useful, but WITHOUT\n\
431 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
432 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
433 License for more details.\n\
435 You should have received a copy of the GNU General Public License\n\
436 along with this program; if not, write to the Free Software\n\
437 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
438 MA 02110-1301, USA. */\n");
441 /* Remove leading white spaces. */
443 static char *
444 remove_leading_whitespaces (char *str)
446 while (ISSPACE (*str))
447 str++;
448 return str;
451 /* Remove trailing white spaces. */
453 static void
454 remove_trailing_whitespaces (char *str)
456 size_t last = strlen (str);
458 if (last == 0)
459 return;
463 last--;
464 if (ISSPACE (str [last]))
465 str[last] = '\0';
466 else
467 break;
469 while (last != 0);
472 /* Find next field separated by SEP and terminate it. Return a
473 pointer to the one after it. */
475 static char *
476 next_field (char *str, char sep, char **next)
478 char *p;
480 p = remove_leading_whitespaces (str);
481 for (str = p; *str != sep && *str != '\0'; str++);
483 *str = '\0';
484 remove_trailing_whitespaces (p);
486 *next = str + 1;
488 return p;
491 static void
492 set_bitfield (const char *f, bitfield *array, unsigned int size)
494 unsigned int i;
496 if (strcmp (f, "CpuSledgehammer") == 0)
497 f= "CpuK8";
498 else if (strcmp (f, "Mmword") == 0)
499 f= "Qword";
500 else if (strcmp (f, "Oword") == 0)
501 f= "Xmmword";
503 for (i = 0; i < size; i++)
504 if (strcasecmp (array[i].name, f) == 0)
506 array[i].value = 1;
507 return;
510 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
513 static void
514 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
515 int macro, const char *comma, const char *indent)
517 unsigned int i;
519 fprintf (table, "%s{ { ", indent);
521 for (i = 0; i < size - 1; i++)
523 fprintf (table, "%d, ", flags[i].value);
524 if (((i + 1) % 20) == 0)
526 /* We need \\ for macro. */
527 if (macro)
528 fprintf (table, " \\\n %s", indent);
529 else
530 fprintf (table, "\n %s", indent);
534 fprintf (table, "%d } }%s\n", flags[i].value, comma);
537 static void
538 process_i386_cpu_flag (FILE *table, char *flag, int macro,
539 const char *comma, const char *indent)
541 char *str, *next, *last;
542 bitfield flags [ARRAY_SIZE (cpu_flags)];
544 /* Copy the default cpu flags. */
545 memcpy (flags, cpu_flags, sizeof (cpu_flags));
547 if (strcasecmp (flag, "unknown") == 0)
549 unsigned int i;
551 /* We turn on everything except for cpu64 in case of
552 CPU_UNKNOWN_FLAGS. */
553 for (i = 0; i < ARRAY_SIZE (flags); i++)
554 if (flags[i].position != Cpu64)
555 flags[i].value = 1;
557 else if (strcmp (flag, "0"))
559 last = flag + strlen (flag);
560 for (next = flag; next && next < last; )
562 str = next_field (next, '|', &next);
563 if (str)
564 set_bitfield (str, flags, ARRAY_SIZE (flags));
568 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
569 comma, indent);
572 static void
573 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
575 unsigned int i;
577 fprintf (table, " { ");
579 for (i = 0; i < size - 1; i++)
581 fprintf (table, "%d, ", modifier[i].value);
582 if (((i + 1) % 20) == 0)
583 fprintf (table, "\n ");
586 fprintf (table, "%d },\n", modifier[i].value);
589 static void
590 process_i386_opcode_modifier (FILE *table, char *mod)
592 char *str, *next, *last;
593 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
595 /* Copy the default opcode modifier. */
596 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
598 if (strcmp (mod, "0"))
600 last = mod + strlen (mod);
601 for (next = mod; next && next < last; )
603 str = next_field (next, '|', &next);
604 if (str)
605 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
608 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
611 static void
612 output_operand_type (FILE *table, bitfield *types, unsigned int size,
613 int macro, const char *indent)
615 unsigned int i;
617 fprintf (table, "{ { ");
619 for (i = 0; i < size - 1; i++)
621 fprintf (table, "%d, ", types[i].value);
622 if (((i + 1) % 20) == 0)
624 /* We need \\ for macro. */
625 if (macro)
626 fprintf (table, "\\\n%s", indent);
627 else
628 fprintf (table, "\n%s", indent);
632 fprintf (table, "%d } }", types[i].value);
635 static void
636 process_i386_operand_type (FILE *table, char *op, int macro,
637 const char *indent)
639 char *str, *next, *last;
640 bitfield types [ARRAY_SIZE (operand_types)];
642 /* Copy the default operand type. */
643 memcpy (types, operand_types, sizeof (types));
645 if (strcmp (op, "0"))
647 last = op + strlen (op);
648 for (next = op; next && next < last; )
650 str = next_field (next, '|', &next);
651 if (str)
652 set_bitfield (str, types, ARRAY_SIZE (types));
655 output_operand_type (table, types, ARRAY_SIZE (types), macro,
656 indent);
659 static void
660 process_i386_opcodes (FILE *table)
662 FILE *fp;
663 char buf[2048];
664 unsigned int i;
665 char *str, *p, *last;
666 char *name, *operands, *base_opcode, *extension_opcode;
667 char *opcode_length;
668 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
670 filename = "i386-opc.tbl";
671 fp = fopen (filename, "r");
673 if (fp == NULL)
674 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
675 xstrerror (errno));
677 fprintf (table, "\n/* i386 opcode table. */\n\n");
678 fprintf (table, "const template i386_optab[] =\n{\n");
680 while (!feof (fp))
682 if (fgets (buf, sizeof (buf), fp) == NULL)
683 break;
685 lineno++;
687 p = remove_leading_whitespaces (buf);
689 /* Skip comments. */
690 str = strstr (p, "//");
691 if (str != NULL)
692 str[0] = '\0';
694 /* Remove trailing white spaces. */
695 remove_trailing_whitespaces (p);
697 switch (p[0])
699 case '#':
700 fprintf (table, "%s\n", p);
701 case '\0':
702 continue;
703 break;
704 default:
705 break;
708 last = p + strlen (p);
710 /* Find name. */
711 name = next_field (p, ',', &str);
713 if (str >= last)
714 abort ();
716 /* Find number of operands. */
717 operands = next_field (str, ',', &str);
719 if (str >= last)
720 abort ();
722 /* Find base_opcode. */
723 base_opcode = next_field (str, ',', &str);
725 if (str >= last)
726 abort ();
728 /* Find extension_opcode. */
729 extension_opcode = next_field (str, ',', &str);
731 if (str >= last)
732 abort ();
734 /* Find opcode_length. */
735 opcode_length = next_field (str, ',', &str);
737 if (str >= last)
738 abort ();
740 /* Find cpu_flags. */
741 cpu_flags = next_field (str, ',', &str);
743 if (str >= last)
744 abort ();
746 /* Find opcode_modifier. */
747 opcode_modifier = next_field (str, ',', &str);
749 if (str >= last)
750 abort ();
752 /* Remove the first {. */
753 str = remove_leading_whitespaces (str);
754 if (*str != '{')
755 abort ();
756 str = remove_leading_whitespaces (str + 1);
758 i = strlen (str);
760 /* There are at least "X}". */
761 if (i < 2)
762 abort ();
764 /* Remove trailing white spaces and }. */
767 i--;
768 if (ISSPACE (str[i]) || str[i] == '}')
769 str[i] = '\0';
770 else
771 break;
773 while (i != 0);
775 last = str + i;
777 /* Find operand_types. */
778 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
780 if (str >= last)
782 operand_types [i] = NULL;
783 break;
786 operand_types [i] = next_field (str, ',', &str);
787 if (*operand_types[i] == '0')
789 if (i != 0)
790 operand_types[i] = NULL;
791 break;
795 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
796 name, operands, base_opcode, extension_opcode,
797 opcode_length);
799 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
801 process_i386_opcode_modifier (table, opcode_modifier);
803 fprintf (table, " { ");
805 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
807 if (operand_types[i] == NULL
808 || *operand_types[i] == '0')
810 if (i == 0)
811 process_i386_operand_type (table, "0", 0, "\t ");
812 break;
815 if (i != 0)
816 fprintf (table, ",\n ");
818 process_i386_operand_type (table, operand_types[i], 0,
819 "\t ");
821 fprintf (table, " } },\n");
824 fclose (fp);
826 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
828 process_i386_cpu_flag (table, "0", 0, ",", " ");
830 process_i386_opcode_modifier (table, "0");
832 fprintf (table, " { ");
833 process_i386_operand_type (table, "0", 0, "\t ");
834 fprintf (table, " } }\n");
836 fprintf (table, "};\n");
839 static void
840 process_i386_registers (FILE *table)
842 FILE *fp;
843 char buf[2048];
844 char *str, *p, *last;
845 char *reg_name, *reg_type, *reg_flags, *reg_num;
846 char *dw2_32_num, *dw2_64_num;
848 filename = "i386-reg.tbl";
849 fp = fopen (filename, "r");
850 if (fp == NULL)
851 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
852 xstrerror (errno));
854 fprintf (table, "\n/* i386 register table. */\n\n");
855 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
857 while (!feof (fp))
859 if (fgets (buf, sizeof (buf), fp) == NULL)
860 break;
862 lineno++;
864 p = remove_leading_whitespaces (buf);
866 /* Skip comments. */
867 str = strstr (p, "//");
868 if (str != NULL)
869 str[0] = '\0';
871 /* Remove trailing white spaces. */
872 remove_trailing_whitespaces (p);
874 switch (p[0])
876 case '#':
877 fprintf (table, "%s\n", p);
878 case '\0':
879 continue;
880 break;
881 default:
882 break;
885 last = p + strlen (p);
887 /* Find reg_name. */
888 reg_name = next_field (p, ',', &str);
890 if (str >= last)
891 abort ();
893 /* Find reg_type. */
894 reg_type = next_field (str, ',', &str);
896 if (str >= last)
897 abort ();
899 /* Find reg_flags. */
900 reg_flags = next_field (str, ',', &str);
902 if (str >= last)
903 abort ();
905 /* Find reg_num. */
906 reg_num = next_field (str, ',', &str);
908 if (str >= last)
909 abort ();
911 fprintf (table, " { \"%s\",\n ", reg_name);
913 process_i386_operand_type (table, reg_type, 0, "\t");
915 /* Find 32-bit Dwarf2 register number. */
916 dw2_32_num = next_field (str, ',', &str);
918 if (str >= last)
919 abort ();
921 /* Find 64-bit Dwarf2 register number. */
922 dw2_64_num = next_field (str, ',', &str);
924 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
925 reg_flags, reg_num, dw2_32_num, dw2_64_num);
928 fclose (fp);
930 fprintf (table, "};\n");
932 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
935 static void
936 process_i386_initializers (void)
938 unsigned int i;
939 FILE *fp = fopen ("i386-init.h", "w");
940 char *init;
942 if (fp == NULL)
943 fail (_("can't create i386-init.h, errno = %s\n"),
944 xstrerror (errno));
946 process_copyright (fp);
948 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
950 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
951 init = xstrdup (cpu_flag_init[i].init);
952 process_i386_cpu_flag (fp, init, 1, "", " ");
953 free (init);
956 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
958 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
959 init = xstrdup (operand_type_init[i].init);
960 process_i386_operand_type (fp, init, 1, " ");
961 free (init);
963 fprintf (fp, "\n");
965 fclose (fp);
968 /* Program options. */
969 #define OPTION_SRCDIR 200
971 struct option long_options[] =
973 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
974 {"debug", no_argument, NULL, 'd'},
975 {"version", no_argument, NULL, 'V'},
976 {"help", no_argument, NULL, 'h'},
977 {0, no_argument, NULL, 0}
980 static void
981 print_version (void)
983 printf ("%s: version 1.0\n", program_name);
984 xexit (0);
987 static void
988 usage (FILE * stream, int status)
990 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
991 program_name);
992 xexit (status);
996 main (int argc, char **argv)
998 extern int chdir (char *);
999 char *srcdir = NULL;
1000 int c;
1001 FILE *table;
1003 program_name = *argv;
1004 xmalloc_set_program_name (program_name);
1006 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1007 switch (c)
1009 case OPTION_SRCDIR:
1010 srcdir = optarg;
1011 break;
1012 case 'V':
1013 case 'v':
1014 print_version ();
1015 break;
1016 case 'd':
1017 debug = 1;
1018 break;
1019 case 'h':
1020 case '?':
1021 usage (stderr, 0);
1022 default:
1023 case 0:
1024 break;
1027 if (optind != argc)
1028 usage (stdout, 1);
1030 if (srcdir != NULL)
1031 if (chdir (srcdir) != 0)
1032 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1033 srcdir, xstrerror (errno));
1035 /* Check the unused bitfield in i386_cpu_flags. */
1036 #ifndef CpuUnused
1037 c = CpuNumOfBits - CpuMax - 1;
1038 if (c)
1039 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1040 #endif
1042 /* Check the unused bitfield in i386_operand_type. */
1043 #ifndef OTUnused
1044 c = OTNumOfBits - OTMax - 1;
1045 if (c)
1046 fail (_("%d unused bits in i386_operand_type.\n"), c);
1047 #endif
1049 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1050 compare);
1052 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1053 sizeof (opcode_modifiers [0]), compare);
1055 qsort (operand_types, ARRAY_SIZE (operand_types),
1056 sizeof (operand_types [0]), compare);
1058 table = fopen ("i386-tbl.h", "w");
1059 if (table == NULL)
1060 fail (_("can't create i386-tbl.h, errno = %s\n"),
1061 xstrerror (errno));
1063 process_copyright (table);
1065 process_i386_opcodes (table);
1066 process_i386_registers (table);
1067 process_i386_initializers ();
1069 fclose (table);
1071 exit (0);