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