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