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