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