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