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