gas/
[binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright 2007, 2008 Free Software Foundation, Inc.
2
3 This file is part of the GNU opcodes library.
4
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.
9
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.
14
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. */
19
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"
26
27 #include "i386-opc.h"
28
29 #include <libintl.h>
30 #define _(String) gettext (String)
31
32 static const char *program_name = NULL;
33 static int debug = 0;
34
35 typedef struct initializer
36 {
37 const char *name;
38 const char *init;
39 } initializer;
40
41 static initializer cpu_flag_init [] =
42 {
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" },
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_3DNOW_FLAGS",
104 "CpuMMX|Cpu3dnow" },
105 { "CPU_3DNOWA_FLAGS",
106 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
107 { "CPU_PADLOCK_FLAGS",
108 "CpuPadLock" },
109 { "CPU_SVME_FLAGS",
110 "CpuSVME" },
111 { "CPU_SSE4A_FLAGS",
112 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
113 { "CPU_ABM_FLAGS",
114 "CpuABM" },
115 { "CPU_SSE5_FLAGS",
116 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
117 };
118
119 static initializer operand_type_init [] =
120 {
121 { "OPERAND_TYPE_NONE",
122 "0" },
123 { "OPERAND_TYPE_REG8",
124 "Reg8" },
125 { "OPERAND_TYPE_REG16",
126 "Reg16" },
127 { "OPERAND_TYPE_REG32",
128 "Reg32" },
129 { "OPERAND_TYPE_REG64",
130 "Reg64" },
131 { "OPERAND_TYPE_IMM1",
132 "Imm1" },
133 { "OPERAND_TYPE_IMM8",
134 "Imm8" },
135 { "OPERAND_TYPE_IMM8S",
136 "Imm8S" },
137 { "OPERAND_TYPE_IMM16",
138 "Imm16" },
139 { "OPERAND_TYPE_IMM32",
140 "Imm32" },
141 { "OPERAND_TYPE_IMM32S",
142 "Imm32S" },
143 { "OPERAND_TYPE_IMM64",
144 "Imm64" },
145 { "OPERAND_TYPE_BASEINDEX",
146 "BaseIndex" },
147 { "OPERAND_TYPE_DISP8",
148 "Disp8" },
149 { "OPERAND_TYPE_DISP16",
150 "Disp16" },
151 { "OPERAND_TYPE_DISP32",
152 "Disp32" },
153 { "OPERAND_TYPE_DISP32S",
154 "Disp32S" },
155 { "OPERAND_TYPE_DISP64",
156 "Disp64" },
157 { "OPERAND_TYPE_INOUTPORTREG",
158 "InOutPortReg" },
159 { "OPERAND_TYPE_SHIFTCOUNT",
160 "ShiftCount" },
161 { "OPERAND_TYPE_CONTROL",
162 "Control" },
163 { "OPERAND_TYPE_TEST",
164 "Test" },
165 { "OPERAND_TYPE_DEBUG",
166 "FloatReg" },
167 { "OPERAND_TYPE_FLOATREG",
168 "FloatReg" },
169 { "OPERAND_TYPE_FLOATACC",
170 "FloatAcc" },
171 { "OPERAND_TYPE_SREG2",
172 "SReg2" },
173 { "OPERAND_TYPE_SREG3",
174 "SReg3" },
175 { "OPERAND_TYPE_ACC",
176 "Acc" },
177 { "OPERAND_TYPE_JUMPABSOLUTE",
178 "JumpAbsolute" },
179 { "OPERAND_TYPE_REGMMX",
180 "RegMMX" },
181 { "OPERAND_TYPE_REGXMM",
182 "RegXMM" },
183 { "OPERAND_TYPE_ESSEG",
184 "EsSeg" },
185 { "OPERAND_TYPE_ACC32",
186 "Reg32|Acc|Dword" },
187 { "OPERAND_TYPE_ACC64",
188 "Reg64|Acc|Qword" },
189 { "OPERAND_TYPE_REG16_INOUTPORTREG",
190 "Reg16|InOutPortReg" },
191 { "OPERAND_TYPE_DISP16_32",
192 "Disp16|Disp32" },
193 { "OPERAND_TYPE_ANYDISP",
194 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
195 { "OPERAND_TYPE_IMM16_32",
196 "Imm16|Imm32" },
197 { "OPERAND_TYPE_IMM16_32S",
198 "Imm16|Imm32S" },
199 { "OPERAND_TYPE_IMM16_32_32S",
200 "Imm16|Imm32|Imm32S" },
201 { "OPERAND_TYPE_IMM32_32S_DISP32",
202 "Imm32|Imm32S|Disp32" },
203 { "OPERAND_TYPE_IMM64_DISP64",
204 "Imm64|Disp64" },
205 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
206 "Imm32|Imm32S|Imm64|Disp32" },
207 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
208 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
209 };
210
211 typedef struct bitfield
212 {
213 int position;
214 int value;
215 const char *name;
216 } bitfield;
217
218 #define BITFIELD(n) { n, 0, #n }
219
220 static bitfield cpu_flags[] =
221 {
222 BITFIELD (Cpu186),
223 BITFIELD (Cpu286),
224 BITFIELD (Cpu386),
225 BITFIELD (Cpu486),
226 BITFIELD (Cpu586),
227 BITFIELD (Cpu686),
228 BITFIELD (CpuP4),
229 BITFIELD (CpuK6),
230 BITFIELD (CpuK8),
231 BITFIELD (CpuMMX),
232 BITFIELD (CpuSSE),
233 BITFIELD (CpuSSE2),
234 BITFIELD (CpuSSE3),
235 BITFIELD (CpuSSSE3),
236 BITFIELD (CpuSSE4_1),
237 BITFIELD (CpuSSE4_2),
238 BITFIELD (CpuSSE4a),
239 BITFIELD (CpuSSE5),
240 BITFIELD (Cpu3dnow),
241 BITFIELD (Cpu3dnowA),
242 BITFIELD (CpuPadLock),
243 BITFIELD (CpuSVME),
244 BITFIELD (CpuVMX),
245 BITFIELD (CpuSMX),
246 BITFIELD (CpuABM),
247 BITFIELD (CpuLM),
248 BITFIELD (Cpu64),
249 BITFIELD (CpuNo64),
250 #ifdef CpuUnused
251 BITFIELD (CpuUnused),
252 #endif
253 };
254
255 static bitfield opcode_modifiers[] =
256 {
257 BITFIELD (D),
258 BITFIELD (W),
259 BITFIELD (Modrm),
260 BITFIELD (ShortForm),
261 BITFIELD (Jump),
262 BITFIELD (JumpDword),
263 BITFIELD (JumpByte),
264 BITFIELD (JumpInterSegment),
265 BITFIELD (FloatMF),
266 BITFIELD (FloatR),
267 BITFIELD (FloatD),
268 BITFIELD (Size16),
269 BITFIELD (Size32),
270 BITFIELD (Size64),
271 BITFIELD (IgnoreSize),
272 BITFIELD (DefaultSize),
273 BITFIELD (No_bSuf),
274 BITFIELD (No_wSuf),
275 BITFIELD (No_lSuf),
276 BITFIELD (No_sSuf),
277 BITFIELD (No_qSuf),
278 BITFIELD (No_ldSuf),
279 BITFIELD (FWait),
280 BITFIELD (IsString),
281 BITFIELD (RegKludge),
282 BITFIELD (FirstXmm0),
283 BITFIELD (ByteOkIntel),
284 BITFIELD (ToDword),
285 BITFIELD (ToQword),
286 BITFIELD (AddrPrefixOp0),
287 BITFIELD (IsPrefix),
288 BITFIELD (ImmExt),
289 BITFIELD (NoRex64),
290 BITFIELD (Rex64),
291 BITFIELD (Ugh),
292 BITFIELD (Drex),
293 BITFIELD (Drexv),
294 BITFIELD (Drexc),
295 BITFIELD (OldGcc),
296 BITFIELD (ATTMnemonic),
297 BITFIELD (ATTSyntax),
298 BITFIELD (IntelSyntax),
299 };
300
301 static bitfield operand_types[] =
302 {
303 BITFIELD (Reg8),
304 BITFIELD (Reg16),
305 BITFIELD (Reg32),
306 BITFIELD (Reg64),
307 BITFIELD (FloatReg),
308 BITFIELD (RegMMX),
309 BITFIELD (RegXMM),
310 BITFIELD (Imm8),
311 BITFIELD (Imm8S),
312 BITFIELD (Imm16),
313 BITFIELD (Imm32),
314 BITFIELD (Imm32S),
315 BITFIELD (Imm64),
316 BITFIELD (Imm1),
317 BITFIELD (BaseIndex),
318 BITFIELD (Disp8),
319 BITFIELD (Disp16),
320 BITFIELD (Disp32),
321 BITFIELD (Disp32S),
322 BITFIELD (Disp64),
323 BITFIELD (InOutPortReg),
324 BITFIELD (ShiftCount),
325 BITFIELD (Control),
326 BITFIELD (Debug),
327 BITFIELD (Test),
328 BITFIELD (SReg2),
329 BITFIELD (SReg3),
330 BITFIELD (Acc),
331 BITFIELD (FloatAcc),
332 BITFIELD (JumpAbsolute),
333 BITFIELD (EsSeg),
334 BITFIELD (RegMem),
335 BITFIELD (Mem),
336 BITFIELD (Byte),
337 BITFIELD (Word),
338 BITFIELD (Dword),
339 BITFIELD (Fword),
340 BITFIELD (Qword),
341 BITFIELD (Tbyte),
342 BITFIELD (Xmmword),
343 BITFIELD (Unspecified),
344 BITFIELD (Anysize),
345 #ifdef OTUnused
346 BITFIELD (OTUnused),
347 #endif
348 };
349
350 static int lineno;
351 static const char *filename;
352
353 static int
354 compare (const void *x, const void *y)
355 {
356 const bitfield *xp = (const bitfield *) x;
357 const bitfield *yp = (const bitfield *) y;
358 return xp->position - yp->position;
359 }
360
361 static void
362 fail (const char *message, ...)
363 {
364 va_list args;
365
366 va_start (args, message);
367 fprintf (stderr, _("%s: Error: "), program_name);
368 vfprintf (stderr, message, args);
369 va_end (args);
370 xexit (1);
371 }
372
373 static void
374 process_copyright (FILE *fp)
375 {
376 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
377 /* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
378 \n\
379 This file is part of the GNU opcodes library.\n\
380 \n\
381 This library is free software; you can redistribute it and/or modify\n\
382 it under the terms of the GNU General Public License as published by\n\
383 the Free Software Foundation; either version 3, or (at your option)\n\
384 any later version.\n\
385 \n\
386 It is distributed in the hope that it will be useful, but WITHOUT\n\
387 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
388 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
389 License for more details.\n\
390 \n\
391 You should have received a copy of the GNU General Public License\n\
392 along with this program; if not, write to the Free Software\n\
393 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
394 MA 02110-1301, USA. */\n");
395 }
396
397 /* Remove leading white spaces. */
398
399 static char *
400 remove_leading_whitespaces (char *str)
401 {
402 while (ISSPACE (*str))
403 str++;
404 return str;
405 }
406
407 /* Remove trailing white spaces. */
408
409 static void
410 remove_trailing_whitespaces (char *str)
411 {
412 size_t last = strlen (str);
413
414 if (last == 0)
415 return;
416
417 do
418 {
419 last--;
420 if (ISSPACE (str [last]))
421 str[last] = '\0';
422 else
423 break;
424 }
425 while (last != 0);
426 }
427
428 /* Find next field separated by SEP and terminate it. Return a
429 pointer to the one after it. */
430
431 static char *
432 next_field (char *str, char sep, char **next)
433 {
434 char *p;
435
436 p = remove_leading_whitespaces (str);
437 for (str = p; *str != sep && *str != '\0'; str++);
438
439 *str = '\0';
440 remove_trailing_whitespaces (p);
441
442 *next = str + 1;
443
444 return p;
445 }
446
447 static void
448 set_bitfield (const char *f, bitfield *array, unsigned int size)
449 {
450 unsigned int i;
451
452 if (strcmp (f, "CpuSledgehammer") == 0)
453 f= "CpuK8";
454 else if (strcmp (f, "Mmword") == 0)
455 f= "Qword";
456 else if (strcmp (f, "Oword") == 0)
457 f= "Xmmword";
458
459 for (i = 0; i < size; i++)
460 if (strcasecmp (array[i].name, f) == 0)
461 {
462 array[i].value = 1;
463 return;
464 }
465
466 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
467 }
468
469 static void
470 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
471 int macro, const char *comma, const char *indent)
472 {
473 unsigned int i;
474
475 fprintf (table, "%s{ { ", indent);
476
477 for (i = 0; i < size - 1; i++)
478 {
479 fprintf (table, "%d, ", flags[i].value);
480 if (((i + 1) % 20) == 0)
481 {
482 /* We need \\ for macro. */
483 if (macro)
484 fprintf (table, " \\\n %s", indent);
485 else
486 fprintf (table, "\n %s", indent);
487 }
488 }
489
490 fprintf (table, "%d } }%s\n", flags[i].value, comma);
491 }
492
493 static void
494 process_i386_cpu_flag (FILE *table, char *flag, int macro,
495 const char *comma, const char *indent)
496 {
497 char *str, *next, *last;
498 bitfield flags [ARRAY_SIZE (cpu_flags)];
499
500 /* Copy the default cpu flags. */
501 memcpy (flags, cpu_flags, sizeof (cpu_flags));
502
503 if (strcasecmp (flag, "unknown") == 0)
504 {
505 unsigned int i;
506
507 /* We turn on everything except for cpu64 in case of
508 CPU_UNKNOWN_FLAGS. */
509 for (i = 0; i < ARRAY_SIZE (flags); i++)
510 if (flags[i].position != Cpu64)
511 flags[i].value = 1;
512 }
513 else if (strcmp (flag, "0"))
514 {
515 last = flag + strlen (flag);
516 for (next = flag; next && next < last; )
517 {
518 str = next_field (next, '|', &next);
519 if (str)
520 set_bitfield (str, flags, ARRAY_SIZE (flags));
521 }
522 }
523
524 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
525 comma, indent);
526 }
527
528 static void
529 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
530 {
531 unsigned int i;
532
533 fprintf (table, " { ");
534
535 for (i = 0; i < size - 1; i++)
536 {
537 fprintf (table, "%d, ", modifier[i].value);
538 if (((i + 1) % 20) == 0)
539 fprintf (table, "\n ");
540 }
541
542 fprintf (table, "%d },\n", modifier[i].value);
543 }
544
545 static void
546 process_i386_opcode_modifier (FILE *table, char *mod)
547 {
548 char *str, *next, *last;
549 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
550
551 /* Copy the default opcode modifier. */
552 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
553
554 if (strcmp (mod, "0"))
555 {
556 last = mod + strlen (mod);
557 for (next = mod; next && next < last; )
558 {
559 str = next_field (next, '|', &next);
560 if (str)
561 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
562 }
563 }
564 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
565 }
566
567 static void
568 output_operand_type (FILE *table, bitfield *types, unsigned int size,
569 int macro, const char *indent)
570 {
571 unsigned int i;
572
573 fprintf (table, "{ { ");
574
575 for (i = 0; i < size - 1; i++)
576 {
577 fprintf (table, "%d, ", types[i].value);
578 if (((i + 1) % 20) == 0)
579 {
580 /* We need \\ for macro. */
581 if (macro)
582 fprintf (table, "\\\n%s", indent);
583 else
584 fprintf (table, "\n%s", indent);
585 }
586 }
587
588 fprintf (table, "%d } }", types[i].value);
589 }
590
591 static void
592 process_i386_operand_type (FILE *table, char *op, int macro,
593 const char *indent)
594 {
595 char *str, *next, *last;
596 bitfield types [ARRAY_SIZE (operand_types)];
597
598 /* Copy the default operand type. */
599 memcpy (types, operand_types, sizeof (types));
600
601 if (strcmp (op, "0"))
602 {
603 last = op + strlen (op);
604 for (next = op; next && next < last; )
605 {
606 str = next_field (next, '|', &next);
607 if (str)
608 set_bitfield (str, types, ARRAY_SIZE (types));
609 }
610 }
611 output_operand_type (table, types, ARRAY_SIZE (types), macro,
612 indent);
613 }
614
615 static void
616 process_i386_opcodes (FILE *table)
617 {
618 FILE *fp;
619 char buf[2048];
620 unsigned int i;
621 char *str, *p, *last;
622 char *name, *operands, *base_opcode, *extension_opcode;
623 char *opcode_length;
624 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
625
626 filename = "i386-opc.tbl";
627 fp = fopen (filename, "r");
628
629 if (fp == NULL)
630 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
631 xstrerror (errno));
632
633 fprintf (table, "\n/* i386 opcode table. */\n\n");
634 fprintf (table, "const template i386_optab[] =\n{\n");
635
636 while (!feof (fp))
637 {
638 if (fgets (buf, sizeof (buf), fp) == NULL)
639 break;
640
641 lineno++;
642
643 p = remove_leading_whitespaces (buf);
644
645 /* Skip comments. */
646 str = strstr (p, "//");
647 if (str != NULL)
648 str[0] = '\0';
649
650 /* Remove trailing white spaces. */
651 remove_trailing_whitespaces (p);
652
653 switch (p[0])
654 {
655 case '#':
656 fprintf (table, "%s\n", p);
657 case '\0':
658 continue;
659 break;
660 default:
661 break;
662 }
663
664 last = p + strlen (p);
665
666 /* Find name. */
667 name = next_field (p, ',', &str);
668
669 if (str >= last)
670 abort ();
671
672 /* Find number of operands. */
673 operands = next_field (str, ',', &str);
674
675 if (str >= last)
676 abort ();
677
678 /* Find base_opcode. */
679 base_opcode = next_field (str, ',', &str);
680
681 if (str >= last)
682 abort ();
683
684 /* Find extension_opcode. */
685 extension_opcode = next_field (str, ',', &str);
686
687 if (str >= last)
688 abort ();
689
690 /* Find opcode_length. */
691 opcode_length = next_field (str, ',', &str);
692
693 if (str >= last)
694 abort ();
695
696 /* Find cpu_flags. */
697 cpu_flags = next_field (str, ',', &str);
698
699 if (str >= last)
700 abort ();
701
702 /* Find opcode_modifier. */
703 opcode_modifier = next_field (str, ',', &str);
704
705 if (str >= last)
706 abort ();
707
708 /* Remove the first {. */
709 str = remove_leading_whitespaces (str);
710 if (*str != '{')
711 abort ();
712 str = remove_leading_whitespaces (str + 1);
713
714 i = strlen (str);
715
716 /* There are at least "X}". */
717 if (i < 2)
718 abort ();
719
720 /* Remove trailing white spaces and }. */
721 do
722 {
723 i--;
724 if (ISSPACE (str[i]) || str[i] == '}')
725 str[i] = '\0';
726 else
727 break;
728 }
729 while (i != 0);
730
731 last = str + i;
732
733 /* Find operand_types. */
734 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
735 {
736 if (str >= last)
737 {
738 operand_types [i] = NULL;
739 break;
740 }
741
742 operand_types [i] = next_field (str, ',', &str);
743 if (*operand_types[i] == '0')
744 {
745 if (i != 0)
746 operand_types[i] = NULL;
747 break;
748 }
749 }
750
751 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
752 name, operands, base_opcode, extension_opcode,
753 opcode_length);
754
755 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
756
757 process_i386_opcode_modifier (table, opcode_modifier);
758
759 fprintf (table, " { ");
760
761 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
762 {
763 if (operand_types[i] == NULL
764 || *operand_types[i] == '0')
765 {
766 if (i == 0)
767 process_i386_operand_type (table, "0", 0, "\t ");
768 break;
769 }
770
771 if (i != 0)
772 fprintf (table, ",\n ");
773
774 process_i386_operand_type (table, operand_types[i], 0,
775 "\t ");
776 }
777 fprintf (table, " } },\n");
778 }
779
780 fclose (fp);
781
782 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
783
784 process_i386_cpu_flag (table, "0", 0, ",", " ");
785
786 process_i386_opcode_modifier (table, "0");
787
788 fprintf (table, " { ");
789 process_i386_operand_type (table, "0", 0, "\t ");
790 fprintf (table, " } }\n");
791
792 fprintf (table, "};\n");
793 }
794
795 static void
796 process_i386_registers (FILE *table)
797 {
798 FILE *fp;
799 char buf[2048];
800 char *str, *p, *last;
801 char *reg_name, *reg_type, *reg_flags, *reg_num;
802
803 filename = "i386-reg.tbl";
804 fp = fopen (filename, "r");
805 if (fp == NULL)
806 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
807 xstrerror (errno));
808
809 fprintf (table, "\n/* i386 register table. */\n\n");
810 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
811
812 while (!feof (fp))
813 {
814 if (fgets (buf, sizeof (buf), fp) == NULL)
815 break;
816
817 lineno++;
818
819 p = remove_leading_whitespaces (buf);
820
821 /* Skip comments. */
822 str = strstr (p, "//");
823 if (str != NULL)
824 str[0] = '\0';
825
826 /* Remove trailing white spaces. */
827 remove_trailing_whitespaces (p);
828
829 switch (p[0])
830 {
831 case '#':
832 fprintf (table, "%s\n", p);
833 case '\0':
834 continue;
835 break;
836 default:
837 break;
838 }
839
840 last = p + strlen (p);
841
842 /* Find reg_name. */
843 reg_name = next_field (p, ',', &str);
844
845 if (str >= last)
846 abort ();
847
848 /* Find reg_type. */
849 reg_type = next_field (str, ',', &str);
850
851 if (str >= last)
852 abort ();
853
854 /* Find reg_flags. */
855 reg_flags = next_field (str, ',', &str);
856
857 if (str >= last)
858 abort ();
859
860 /* Find reg_num. */
861 reg_num = next_field (str, ',', &str);
862
863 fprintf (table, " { \"%s\",\n ", reg_name);
864
865 process_i386_operand_type (table, reg_type, 0, "\t");
866
867 fprintf (table, ",\n %s, %s },\n", reg_flags, reg_num);
868 }
869
870 fclose (fp);
871
872 fprintf (table, "};\n");
873
874 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
875 }
876
877 static void
878 process_i386_initializers (void)
879 {
880 unsigned int i;
881 FILE *fp = fopen ("i386-init.h", "w");
882 char *init;
883
884 if (fp == NULL)
885 fail (_("can't create i386-init.h, errno = %s\n"),
886 xstrerror (errno));
887
888 process_copyright (fp);
889
890 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
891 {
892 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
893 init = xstrdup (cpu_flag_init[i].init);
894 process_i386_cpu_flag (fp, init, 1, "", " ");
895 free (init);
896 }
897
898 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
899 {
900 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
901 init = xstrdup (operand_type_init[i].init);
902 process_i386_operand_type (fp, init, 1, " ");
903 free (init);
904 }
905 fprintf (fp, "\n");
906
907 fclose (fp);
908 }
909
910 /* Program options. */
911 #define OPTION_SRCDIR 200
912
913 struct option long_options[] =
914 {
915 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
916 {"debug", no_argument, NULL, 'd'},
917 {"version", no_argument, NULL, 'V'},
918 {"help", no_argument, NULL, 'h'},
919 {0, no_argument, NULL, 0}
920 };
921
922 static void
923 print_version (void)
924 {
925 printf ("%s: version 1.0\n", program_name);
926 xexit (0);
927 }
928
929 static void
930 usage (FILE * stream, int status)
931 {
932 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
933 program_name);
934 xexit (status);
935 }
936
937 int
938 main (int argc, char **argv)
939 {
940 extern int chdir (char *);
941 char *srcdir = NULL;
942 int c;
943 FILE *table;
944
945 program_name = *argv;
946 xmalloc_set_program_name (program_name);
947
948 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
949 switch (c)
950 {
951 case OPTION_SRCDIR:
952 srcdir = optarg;
953 break;
954 case 'V':
955 case 'v':
956 print_version ();
957 break;
958 case 'd':
959 debug = 1;
960 break;
961 case 'h':
962 case '?':
963 usage (stderr, 0);
964 default:
965 case 0:
966 break;
967 }
968
969 if (optind != argc)
970 usage (stdout, 1);
971
972 if (srcdir != NULL)
973 if (chdir (srcdir) != 0)
974 fail (_("unable to change directory to \"%s\", errno = %s\n"),
975 srcdir, xstrerror (errno));
976
977 /* Check the unused bitfield in i386_cpu_flags. */
978 #ifndef CpuUnused
979 c = CpuNumOfBits - CpuMax - 1;
980 if (c)
981 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
982 #endif
983
984 /* Check the unused bitfield in i386_operand_type. */
985 #ifndef OTUnused
986 c = OTNumOfBits - OTMax - 1;
987 if (c)
988 fail (_("%d unused bits in i386_operand_type.\n"), c);
989 #endif
990
991 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
992 compare);
993
994 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
995 sizeof (opcode_modifiers [0]), compare);
996
997 qsort (operand_types, ARRAY_SIZE (operand_types),
998 sizeof (operand_types [0]), compare);
999
1000 table = fopen ("i386-tbl.h", "w");
1001 if (table == NULL)
1002 fail (_("can't create i386-tbl.h, errno = %s\n"),
1003 xstrerror (errno));
1004
1005 process_copyright (table);
1006
1007 process_i386_opcodes (table);
1008 process_i386_registers (table);
1009 process_i386_initializers ();
1010
1011 fclose (table);
1012
1013 exit (0);
1014 }