gas/
[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),
7ce189b3 275 BITFIELD (No_ldSuf),
40fb9820
L
276 BITFIELD (FWait),
277 BITFIELD (IsString),
278 BITFIELD (RegKludge),
e2ec9d29 279 BITFIELD (FirstXmm0),
ca61edf2
L
280 BITFIELD (ByteOkIntel),
281 BITFIELD (ToDword),
282 BITFIELD (ToQword),
283 BITFIELD (AddrPrefixOp0),
40fb9820
L
284 BITFIELD (IsPrefix),
285 BITFIELD (ImmExt),
286 BITFIELD (NoRex64),
287 BITFIELD (Rex64),
288 BITFIELD (Ugh),
85f10a01
MM
289 BITFIELD (Drex),
290 BITFIELD (Drexv),
291 BITFIELD (Drexc),
1efbbeb4
L
292 BITFIELD (OldGcc),
293 BITFIELD (ATTMnemonic),
294 BITFIELD (IntelMnemonic),
40fb9820
L
295};
296
297static bitfield operand_types[] =
298{
299 BITFIELD (Reg8),
300 BITFIELD (Reg16),
301 BITFIELD (Reg32),
302 BITFIELD (Reg64),
303 BITFIELD (FloatReg),
304 BITFIELD (RegMMX),
305 BITFIELD (RegXMM),
306 BITFIELD (Imm8),
307 BITFIELD (Imm8S),
308 BITFIELD (Imm16),
309 BITFIELD (Imm32),
310 BITFIELD (Imm32S),
311 BITFIELD (Imm64),
312 BITFIELD (Imm1),
313 BITFIELD (BaseIndex),
314 BITFIELD (Disp8),
315 BITFIELD (Disp16),
316 BITFIELD (Disp32),
317 BITFIELD (Disp32S),
318 BITFIELD (Disp64),
319 BITFIELD (InOutPortReg),
320 BITFIELD (ShiftCount),
321 BITFIELD (Control),
322 BITFIELD (Debug),
323 BITFIELD (Test),
324 BITFIELD (SReg2),
325 BITFIELD (SReg3),
326 BITFIELD (Acc),
327 BITFIELD (FloatAcc),
328 BITFIELD (JumpAbsolute),
329 BITFIELD (EsSeg),
330 BITFIELD (RegMem),
331#ifdef OTUnused
332 BITFIELD (OTUnused),
333#endif
334};
335
336static int
337compare (const void *x, const void *y)
338{
339 const bitfield *xp = (const bitfield *) x;
340 const bitfield *yp = (const bitfield *) y;
341 return xp->position - yp->position;
342}
343
40b8e679
L
344static void
345fail (const char *message, ...)
346{
347 va_list args;
348
349 va_start (args, message);
350 fprintf (stderr, _("%s: Error: "), program_name);
351 vfprintf (stderr, message, args);
352 va_end (args);
353 xexit (1);
354}
355
72ffa0fb
L
356static void
357process_copyright (FILE *fp)
358{
359 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
360/* Copyright 2007 Free Software Foundation, Inc.\n\
361\n\
362 This file is part of the GNU opcodes library.\n\
363\n\
364 This library is free software; you can redistribute it and/or modify\n\
365 it under the terms of the GNU General Public License as published by\n\
366 the Free Software Foundation; either version 3, or (at your option)\n\
367 any later version.\n\
368\n\
369 It is distributed in the hope that it will be useful, but WITHOUT\n\
370 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
371 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
372 License for more details.\n\
373\n\
374 You should have received a copy of the GNU General Public License\n\
375 along with this program; if not, write to the Free Software\n\
376 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
377 MA 02110-1301, USA. */\n");
378}
379
40b8e679
L
380/* Remove leading white spaces. */
381
382static char *
383remove_leading_whitespaces (char *str)
384{
385 while (ISSPACE (*str))
386 str++;
387 return str;
388}
389
390/* Remove trailing white spaces. */
391
392static void
393remove_trailing_whitespaces (char *str)
394{
395 size_t last = strlen (str);
396
397 if (last == 0)
398 return;
399
400 do
401 {
402 last--;
403 if (ISSPACE (str [last]))
404 str[last] = '\0';
405 else
406 break;
407 }
408 while (last != 0);
409}
410
93b1ec2c 411/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
412 pointer to the one after it. */
413
414static char *
93b1ec2c 415next_field (char *str, char sep, char **next)
40b8e679
L
416{
417 char *p;
418
419 p = remove_leading_whitespaces (str);
93b1ec2c 420 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
421
422 *str = '\0';
423 remove_trailing_whitespaces (p);
424
425 *next = str + 1;
426
427 return p;
428}
429
40fb9820
L
430static void
431set_bitfield (const char *f, bitfield *array, unsigned int size)
432{
433 unsigned int i;
434
435 if (strcmp (f, "CpuSledgehammer") == 0)
436 f= "CpuK8";
437
438 for (i = 0; i < size; i++)
439 if (strcasecmp (array[i].name, f) == 0)
440 {
441 array[i].value = 1;
442 return;
443 }
444
445 printf ("Unknown bitfield: %s\n", f);
446 abort ();
447}
448
449static void
450output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
451 int macro, const char *comma, const char *indent)
452{
453 unsigned int i;
454
455 fprintf (table, "%s{ { ", indent);
456
457 for (i = 0; i < size - 1; i++)
458 {
459 fprintf (table, "%d, ", flags[i].value);
460 if (((i + 1) % 20) == 0)
461 {
462 /* We need \\ for macro. */
463 if (macro)
464 fprintf (table, " \\\n %s", indent);
465 else
466 fprintf (table, "\n %s", indent);
467 }
468 }
469
470 fprintf (table, "%d } }%s\n", flags[i].value, comma);
471}
472
473static void
474process_i386_cpu_flag (FILE *table, char *flag, int macro,
475 const char *comma, const char *indent)
476{
477 char *str, *next, *last;
478 bitfield flags [ARRAY_SIZE (cpu_flags)];
479
480 /* Copy the default cpu flags. */
481 memcpy (flags, cpu_flags, sizeof (cpu_flags));
482
483 if (strcasecmp (flag, "unknown") == 0)
484 {
485 unsigned int i;
486
487 /* We turn on everything except for cpu64 in case of
488 CPU_UNKNOWN_FLAGS. */
489 for (i = 0; i < ARRAY_SIZE (flags); i++)
490 if (flags[i].position != Cpu64)
491 flags[i].value = 1;
492 }
493 else if (strcmp (flag, "0"))
494 {
495 last = flag + strlen (flag);
496 for (next = flag; next && next < last; )
497 {
498 str = next_field (next, '|', &next);
499 if (str)
500 set_bitfield (str, flags, ARRAY_SIZE (flags));
501 }
502 }
503
504 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
505 comma, indent);
506}
507
508static void
509output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
510{
511 unsigned int i;
512
513 fprintf (table, " { ");
514
515 for (i = 0; i < size - 1; i++)
516 {
517 fprintf (table, "%d, ", modifier[i].value);
518 if (((i + 1) % 20) == 0)
519 fprintf (table, "\n ");
520 }
521
522 fprintf (table, "%d },\n", modifier[i].value);
523}
524
525static void
526process_i386_opcode_modifier (FILE *table, char *mod)
527{
528 char *str, *next, *last;
529 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
530
531 /* Copy the default opcode modifier. */
532 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
533
534 if (strcmp (mod, "0"))
535 {
536 last = mod + strlen (mod);
537 for (next = mod; next && next < last; )
538 {
539 str = next_field (next, '|', &next);
540 if (str)
541 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
542 }
543 }
544 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
545}
546
547static void
548output_operand_type (FILE *table, bitfield *types, unsigned int size,
549 int macro, const char *indent)
550{
551 unsigned int i;
552
553 fprintf (table, "{ { ");
554
555 for (i = 0; i < size - 1; i++)
556 {
557 fprintf (table, "%d, ", types[i].value);
558 if (((i + 1) % 20) == 0)
559 {
560 /* We need \\ for macro. */
561 if (macro)
562 fprintf (table, "\\\n%s", indent);
563 else
564 fprintf (table, "\n%s", indent);
565 }
566 }
567
568 fprintf (table, "%d } }", types[i].value);
569}
570
571static void
572process_i386_operand_type (FILE *table, char *op, int macro,
573 const char *indent)
574{
575 char *str, *next, *last;
576 bitfield types [ARRAY_SIZE (operand_types)];
577
578 /* Copy the default operand type. */
579 memcpy (types, operand_types, sizeof (types));
580
581 if (strcmp (op, "0"))
582 {
583 last = op + strlen (op);
584 for (next = op; next && next < last; )
585 {
586 str = next_field (next, '|', &next);
587 if (str)
588 set_bitfield (str, types, ARRAY_SIZE (types));
589 }
590 }
591 output_operand_type (table, types, ARRAY_SIZE (types), macro,
592 indent);
593}
594
40b8e679 595static void
72ffa0fb 596process_i386_opcodes (FILE *table)
40b8e679
L
597{
598 FILE *fp = fopen ("i386-opc.tbl", "r");
599 char buf[2048];
600 unsigned int i;
601 char *str, *p, *last;
602 char *name, *operands, *base_opcode, *extension_opcode;
4dffcebc 603 char *opcode_length;
40b8e679
L
604 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
605
606 if (fp == NULL)
34edb9ad 607 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
40fb9820 608 xstrerror (errno));
40b8e679 609
34edb9ad
L
610 fprintf (table, "\n/* i386 opcode table. */\n\n");
611 fprintf (table, "const template i386_optab[] =\n{\n");
40b8e679
L
612
613 while (!feof (fp))
614 {
615 if (fgets (buf, sizeof (buf), fp) == NULL)
616 break;
617
618 p = remove_leading_whitespaces (buf);
619
620 /* Skip comments. */
621 str = strstr (p, "//");
622 if (str != NULL)
623 str[0] = '\0';
624
625 /* Remove trailing white spaces. */
626 remove_trailing_whitespaces (p);
627
628 switch (p[0])
629 {
630 case '#':
34edb9ad 631 fprintf (table, "%s\n", p);
40b8e679
L
632 case '\0':
633 continue;
634 break;
635 default:
636 break;
637 }
638
639 last = p + strlen (p);
640
641 /* Find name. */
93b1ec2c 642 name = next_field (p, ',', &str);
40b8e679
L
643
644 if (str >= last)
645 abort ();
646
647 /* Find number of operands. */
93b1ec2c 648 operands = next_field (str, ',', &str);
40b8e679
L
649
650 if (str >= last)
651 abort ();
652
653 /* Find base_opcode. */
93b1ec2c 654 base_opcode = next_field (str, ',', &str);
40b8e679
L
655
656 if (str >= last)
657 abort ();
658
659 /* Find extension_opcode. */
93b1ec2c 660 extension_opcode = next_field (str, ',', &str);
40b8e679 661
4dffcebc
L
662 if (str >= last)
663 abort ();
664
665 /* Find opcode_length. */
666 opcode_length = next_field (str, ',', &str);
667
40b8e679
L
668 if (str >= last)
669 abort ();
670
671 /* Find cpu_flags. */
93b1ec2c 672 cpu_flags = next_field (str, ',', &str);
40b8e679
L
673
674 if (str >= last)
675 abort ();
676
677 /* Find opcode_modifier. */
93b1ec2c 678 opcode_modifier = next_field (str, ',', &str);
40b8e679
L
679
680 if (str >= last)
681 abort ();
682
683 /* Remove the first {. */
684 str = remove_leading_whitespaces (str);
685 if (*str != '{')
686 abort ();
687 str = remove_leading_whitespaces (str + 1);
688
689 i = strlen (str);
690
691 /* There are at least "X}". */
692 if (i < 2)
693 abort ();
694
695 /* Remove trailing white spaces and }. */
696 do
697 {
698 i--;
699 if (ISSPACE (str[i]) || str[i] == '}')
700 str[i] = '\0';
701 else
702 break;
703 }
704 while (i != 0);
705
706 last = str + i;
707
708 /* Find operand_types. */
709 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
710 {
711 if (str >= last)
712 {
713 operand_types [i] = NULL;
714 break;
715 }
716
93b1ec2c 717 operand_types [i] = next_field (str, ',', &str);
40b8e679
L
718 if (*operand_types[i] == '0')
719 {
720 if (i != 0)
721 operand_types[i] = NULL;
722 break;
723 }
724 }
725
4dffcebc
L
726 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
727 name, operands, base_opcode, extension_opcode,
728 opcode_length);
40fb9820
L
729
730 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
40b8e679 731
40fb9820 732 process_i386_opcode_modifier (table, opcode_modifier);
40b8e679 733
34edb9ad 734 fprintf (table, " { ");
40b8e679
L
735
736 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
737 {
738 if (operand_types[i] == NULL
739 || *operand_types[i] == '0')
740 {
741 if (i == 0)
40fb9820 742 process_i386_operand_type (table, "0", 0, "\t ");
40b8e679
L
743 break;
744 }
745
746 if (i != 0)
34edb9ad 747 fprintf (table, ",\n ");
40b8e679 748
40fb9820
L
749 process_i386_operand_type (table, operand_types[i], 0,
750 "\t ");
40b8e679 751 }
34edb9ad 752 fprintf (table, " } },\n");
40b8e679
L
753 }
754
34edb9ad
L
755 fclose (fp);
756
4dffcebc 757 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820
L
758
759 process_i386_cpu_flag (table, "0", 0, ",", " ");
760
761 process_i386_opcode_modifier (table, "0");
762
763 fprintf (table, " { ");
764 process_i386_operand_type (table, "0", 0, "\t ");
765 fprintf (table, " } }\n");
766
34edb9ad 767 fprintf (table, "};\n");
40b8e679
L
768}
769
770static void
72ffa0fb 771process_i386_registers (FILE *table)
40b8e679
L
772{
773 FILE *fp = fopen ("i386-reg.tbl", "r");
774 char buf[2048];
775 char *str, *p, *last;
776 char *reg_name, *reg_type, *reg_flags, *reg_num;
777
778 if (fp == NULL)
34edb9ad 779 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 780 xstrerror (errno));
40b8e679 781
34edb9ad
L
782 fprintf (table, "\n/* i386 register table. */\n\n");
783 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
784
785 while (!feof (fp))
786 {
787 if (fgets (buf, sizeof (buf), fp) == NULL)
788 break;
789
790 p = remove_leading_whitespaces (buf);
791
792 /* Skip comments. */
793 str = strstr (p, "//");
794 if (str != NULL)
795 str[0] = '\0';
796
797 /* Remove trailing white spaces. */
798 remove_trailing_whitespaces (p);
799
800 switch (p[0])
801 {
802 case '#':
34edb9ad 803 fprintf (table, "%s\n", p);
40b8e679
L
804 case '\0':
805 continue;
806 break;
807 default:
808 break;
809 }
810
811 last = p + strlen (p);
812
813 /* Find reg_name. */
93b1ec2c 814 reg_name = next_field (p, ',', &str);
40b8e679
L
815
816 if (str >= last)
817 abort ();
818
819 /* Find reg_type. */
93b1ec2c 820 reg_type = next_field (str, ',', &str);
40b8e679
L
821
822 if (str >= last)
823 abort ();
824
825 /* Find reg_flags. */
93b1ec2c 826 reg_flags = next_field (str, ',', &str);
40b8e679
L
827
828 if (str >= last)
829 abort ();
830
831 /* Find reg_num. */
93b1ec2c 832 reg_num = next_field (str, ',', &str);
40b8e679 833
40fb9820
L
834 fprintf (table, " { \"%s\",\n ", reg_name);
835
836 process_i386_operand_type (table, reg_type, 0, "\t");
837
838 fprintf (table, ",\n %s, %s },\n", reg_flags, reg_num);
40b8e679
L
839 }
840
34edb9ad
L
841 fclose (fp);
842
843 fprintf (table, "};\n");
40b8e679 844
34edb9ad 845 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
846}
847
40fb9820
L
848static void
849process_i386_initializers (void)
850{
851 unsigned int i;
852 FILE *fp = fopen ("i386-init.h", "w");
853 char *init;
854
855 if (fp == NULL)
856 fail (_("can't create i386-init.h, errno = %s\n"),
857 xstrerror (errno));
858
859 process_copyright (fp);
860
861 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
862 {
863 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
864 init = xstrdup (cpu_flag_init[i].init);
865 process_i386_cpu_flag (fp, init, 1, "", " ");
866 free (init);
867 }
868
869 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
870 {
871 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
872 init = xstrdup (operand_type_init[i].init);
873 process_i386_operand_type (fp, init, 1, " ");
874 free (init);
875 }
876 fprintf (fp, "\n");
877
878 fclose (fp);
879}
880
40b8e679
L
881/* Program options. */
882#define OPTION_SRCDIR 200
883
884struct option long_options[] =
885{
886 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
887 {"debug", no_argument, NULL, 'd'},
888 {"version", no_argument, NULL, 'V'},
889 {"help", no_argument, NULL, 'h'},
890 {0, no_argument, NULL, 0}
891};
892
893static void
894print_version (void)
895{
896 printf ("%s: version 1.0\n", program_name);
897 xexit (0);
898}
899
900static void
901usage (FILE * stream, int status)
902{
903 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
904 program_name);
905 xexit (status);
906}
907
908int
909main (int argc, char **argv)
910{
911 extern int chdir (char *);
912 char *srcdir = NULL;
8b40d594 913 int c;
72ffa0fb 914 FILE *table;
40b8e679
L
915
916 program_name = *argv;
917 xmalloc_set_program_name (program_name);
918
919 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
920 switch (c)
921 {
922 case OPTION_SRCDIR:
923 srcdir = optarg;
924 break;
925 case 'V':
926 case 'v':
927 print_version ();
928 break;
929 case 'd':
930 debug = 1;
931 break;
932 case 'h':
933 case '?':
934 usage (stderr, 0);
935 default:
936 case 0:
937 break;
938 }
939
940 if (optind != argc)
941 usage (stdout, 1);
942
943 if (srcdir != NULL)
944 if (chdir (srcdir) != 0)
945 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
946 srcdir, xstrerror (errno));
947
948 /* Check the unused bitfield in i386_cpu_flags. */
949#ifndef CpuUnused
8b40d594
L
950 c = CpuNumOfBits - CpuMax - 1;
951 if (c)
952 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
953#endif
954
955 /* Check the unused bitfield in i386_operand_type. */
956#ifndef OTUnused
8b40d594
L
957 c = OTNumOfBits - OTMax - 1;
958 if (c)
959 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
960#endif
961
962 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
963 compare);
964
965 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
966 sizeof (opcode_modifiers [0]), compare);
967
968 qsort (operand_types, ARRAY_SIZE (operand_types),
969 sizeof (operand_types [0]), compare);
40b8e679 970
34edb9ad
L
971 table = fopen ("i386-tbl.h", "w");
972 if (table == NULL)
40fb9820
L
973 fail (_("can't create i386-tbl.h, errno = %s\n"),
974 xstrerror (errno));
34edb9ad 975
72ffa0fb 976 process_copyright (table);
40b8e679 977
72ffa0fb
L
978 process_i386_opcodes (table);
979 process_i386_registers (table);
40fb9820 980 process_i386_initializers ();
40b8e679 981
34edb9ad
L
982 fclose (table);
983
40b8e679
L
984 exit (0);
985}
This page took 0.086509 seconds and 4 git commands to generate.