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