* dwarf_reader.cc (Sized_dwarf_line_info::read_header_prolog,
[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",
599121aa 48 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
40fb9820
L
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",
115c7c25 66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE" },
40fb9820 67 { "CPU_P4_FLAGS",
115c7c25 68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2" },
40fb9820 69 { "CPU_NOCONA_FLAGS",
115c7c25 70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
40fb9820 71 { "CPU_CORE_FLAGS",
115c7c25 72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
40fb9820 73 { "CPU_CORE2_FLAGS",
115c7c25 74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
40fb9820
L
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",
115c7c25 80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuMMX|Cpu3dnow|Cpu3dnowA" },
40fb9820 81 { "CPU_K8_FLAGS",
115c7c25 82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
40fb9820 83 { "CPU_AMDFAM10_FLAGS",
115c7c25 84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
40fb9820
L
85 { "CPU_MMX_FLAGS",
86 "CpuMMX" },
87 { "CPU_SSE_FLAGS",
115c7c25 88 "CpuMMX|CpuSSE" },
40fb9820 89 { "CPU_SSE2_FLAGS",
115c7c25 90 "CpuMMX|CpuSSE|CpuSSE2" },
40fb9820 91 { "CPU_SSE3_FLAGS",
115c7c25 92 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
40fb9820 93 { "CPU_SSSE3_FLAGS",
115c7c25 94 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
40fb9820 95 { "CPU_SSE4_1_FLAGS",
115c7c25 96 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
40fb9820 97 { "CPU_SSE4_2_FLAGS",
115c7c25 98 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
6305a203
L
99 { "CPU_VMX_FLAGS",
100 "CpuVMX" },
101 { "CPU_SMX_FLAGS",
102 "CpuSMX" },
f03fe4c1
L
103 { "CPU_XSAVE_FLAGS",
104 "CpuXsave" },
40fb9820
L
105 { "CPU_3DNOW_FLAGS",
106 "CpuMMX|Cpu3dnow" },
107 { "CPU_3DNOWA_FLAGS",
115c7c25 108 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
40fb9820
L
109 { "CPU_PADLOCK_FLAGS",
110 "CpuPadLock" },
111 { "CPU_SVME_FLAGS",
112 "CpuSVME" },
113 { "CPU_SSE4A_FLAGS",
115c7c25 114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
40fb9820 115 { "CPU_ABM_FLAGS",
3629bb00 116 "CpuABM" },
85f10a01 117 { "CPU_SSE5_FLAGS",
115c7c25 118 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
40fb9820
L
119};
120
121static 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",
7d5e4556 188 "Reg32|Acc|Dword" },
40fb9820 189 { "OPERAND_TYPE_ACC64",
7d5e4556 190 "Reg64|Acc|Qword" },
65da13b5
L
191 { "OPERAND_TYPE_INOUTPORTREG",
192 "InOutPortReg" },
40fb9820
L
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
215typedef struct bitfield
216{
217 int position;
218 int value;
219 const char *name;
220} bitfield;
221
222#define BITFIELD(n) { n, 0, #n }
223
224static 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),
40fb9820
L
236 BITFIELD (CpuSSE),
237 BITFIELD (CpuSSE2),
238 BITFIELD (CpuSSE3),
239 BITFIELD (CpuSSSE3),
240 BITFIELD (CpuSSE4_1),
241 BITFIELD (CpuSSE4_2),
242 BITFIELD (CpuSSE4a),
85f10a01 243 BITFIELD (CpuSSE5),
40fb9820
L
244 BITFIELD (Cpu3dnow),
245 BITFIELD (Cpu3dnowA),
246 BITFIELD (CpuPadLock),
247 BITFIELD (CpuSVME),
248 BITFIELD (CpuVMX),
47dd174c 249 BITFIELD (CpuSMX),
40fb9820
L
250 BITFIELD (CpuABM),
251 BITFIELD (CpuLM),
475a2301 252 BITFIELD (CpuXsave),
40fb9820
L
253 BITFIELD (Cpu64),
254 BITFIELD (CpuNo64),
255#ifdef CpuUnused
256 BITFIELD (CpuUnused),
257#endif
258};
259
260static 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),
7ce189b3 283 BITFIELD (No_ldSuf),
40fb9820
L
284 BITFIELD (FWait),
285 BITFIELD (IsString),
286 BITFIELD (RegKludge),
e2ec9d29 287 BITFIELD (FirstXmm0),
ca61edf2
L
288 BITFIELD (ByteOkIntel),
289 BITFIELD (ToDword),
290 BITFIELD (ToQword),
291 BITFIELD (AddrPrefixOp0),
40fb9820
L
292 BITFIELD (IsPrefix),
293 BITFIELD (ImmExt),
294 BITFIELD (NoRex64),
295 BITFIELD (Rex64),
296 BITFIELD (Ugh),
85f10a01
MM
297 BITFIELD (Drex),
298 BITFIELD (Drexv),
299 BITFIELD (Drexc),
1efbbeb4
L
300 BITFIELD (OldGcc),
301 BITFIELD (ATTMnemonic),
e1d4d893 302 BITFIELD (ATTSyntax),
5c07affc 303 BITFIELD (IntelSyntax),
40fb9820
L
304};
305
306static 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),
5c07affc 340 BITFIELD (Mem),
7d5e4556
L
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),
40fb9820
L
350#ifdef OTUnused
351 BITFIELD (OTUnused),
352#endif
353};
354
3d4d5afa
L
355static int lineno;
356static const char *filename;
357
40fb9820
L
358static int
359compare (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
40b8e679
L
366static void
367fail (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
72ffa0fb
L
378static void
379process_copyright (FILE *fp)
380{
381 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
6f143e4d 382/* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
72ffa0fb
L
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
40b8e679
L
402/* Remove leading white spaces. */
403
404static char *
405remove_leading_whitespaces (char *str)
406{
407 while (ISSPACE (*str))
408 str++;
409 return str;
410}
411
412/* Remove trailing white spaces. */
413
414static void
415remove_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
93b1ec2c 433/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
434 pointer to the one after it. */
435
436static char *
93b1ec2c 437next_field (char *str, char sep, char **next)
40b8e679
L
438{
439 char *p;
440
441 p = remove_leading_whitespaces (str);
93b1ec2c 442 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
443
444 *str = '\0';
445 remove_trailing_whitespaces (p);
446
447 *next = str + 1;
448
449 return p;
450}
451
40fb9820
L
452static void
453set_bitfield (const char *f, bitfield *array, unsigned int size)
454{
455 unsigned int i;
456
457 if (strcmp (f, "CpuSledgehammer") == 0)
458 f= "CpuK8";
7d5e4556
L
459 else if (strcmp (f, "Mmword") == 0)
460 f= "Qword";
461 else if (strcmp (f, "Oword") == 0)
462 f= "Xmmword";
40fb9820
L
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
50e8458f 471 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
40fb9820
L
472}
473
474static void
475output_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
498static void
499process_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
533static void
534output_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
550static void
551process_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
572static void
573output_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
596static void
597process_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
40b8e679 620static void
72ffa0fb 621process_i386_opcodes (FILE *table)
40b8e679 622{
3d4d5afa 623 FILE *fp;
40b8e679
L
624 char buf[2048];
625 unsigned int i;
626 char *str, *p, *last;
627 char *name, *operands, *base_opcode, *extension_opcode;
4dffcebc 628 char *opcode_length;
40b8e679
L
629 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
630
3d4d5afa
L
631 filename = "i386-opc.tbl";
632 fp = fopen (filename, "r");
633
40b8e679 634 if (fp == NULL)
34edb9ad 635 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
40fb9820 636 xstrerror (errno));
40b8e679 637
34edb9ad
L
638 fprintf (table, "\n/* i386 opcode table. */\n\n");
639 fprintf (table, "const template i386_optab[] =\n{\n");
40b8e679
L
640
641 while (!feof (fp))
642 {
643 if (fgets (buf, sizeof (buf), fp) == NULL)
644 break;
645
3d4d5afa
L
646 lineno++;
647
40b8e679
L
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 '#':
34edb9ad 661 fprintf (table, "%s\n", p);
40b8e679
L
662 case '\0':
663 continue;
664 break;
665 default:
666 break;
667 }
668
669 last = p + strlen (p);
670
671 /* Find name. */
93b1ec2c 672 name = next_field (p, ',', &str);
40b8e679
L
673
674 if (str >= last)
675 abort ();
676
677 /* Find number of operands. */
93b1ec2c 678 operands = next_field (str, ',', &str);
40b8e679
L
679
680 if (str >= last)
681 abort ();
682
683 /* Find base_opcode. */
93b1ec2c 684 base_opcode = next_field (str, ',', &str);
40b8e679
L
685
686 if (str >= last)
687 abort ();
688
689 /* Find extension_opcode. */
93b1ec2c 690 extension_opcode = next_field (str, ',', &str);
40b8e679 691
4dffcebc
L
692 if (str >= last)
693 abort ();
694
695 /* Find opcode_length. */
696 opcode_length = next_field (str, ',', &str);
697
40b8e679
L
698 if (str >= last)
699 abort ();
700
701 /* Find cpu_flags. */
93b1ec2c 702 cpu_flags = next_field (str, ',', &str);
40b8e679
L
703
704 if (str >= last)
705 abort ();
706
707 /* Find opcode_modifier. */
93b1ec2c 708 opcode_modifier = next_field (str, ',', &str);
40b8e679
L
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
93b1ec2c 747 operand_types [i] = next_field (str, ',', &str);
40b8e679
L
748 if (*operand_types[i] == '0')
749 {
750 if (i != 0)
751 operand_types[i] = NULL;
752 break;
753 }
754 }
755
4dffcebc
L
756 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
757 name, operands, base_opcode, extension_opcode,
758 opcode_length);
40fb9820
L
759
760 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
40b8e679 761
40fb9820 762 process_i386_opcode_modifier (table, opcode_modifier);
40b8e679 763
34edb9ad 764 fprintf (table, " { ");
40b8e679
L
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)
40fb9820 772 process_i386_operand_type (table, "0", 0, "\t ");
40b8e679
L
773 break;
774 }
775
776 if (i != 0)
34edb9ad 777 fprintf (table, ",\n ");
40b8e679 778
40fb9820
L
779 process_i386_operand_type (table, operand_types[i], 0,
780 "\t ");
40b8e679 781 }
34edb9ad 782 fprintf (table, " } },\n");
40b8e679
L
783 }
784
34edb9ad
L
785 fclose (fp);
786
4dffcebc 787 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820
L
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
34edb9ad 797 fprintf (table, "};\n");
40b8e679
L
798}
799
800static void
72ffa0fb 801process_i386_registers (FILE *table)
40b8e679 802{
3d4d5afa 803 FILE *fp;
40b8e679
L
804 char buf[2048];
805 char *str, *p, *last;
806 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 807 char *dw2_32_num, *dw2_64_num;
40b8e679 808
3d4d5afa
L
809 filename = "i386-reg.tbl";
810 fp = fopen (filename, "r");
40b8e679 811 if (fp == NULL)
34edb9ad 812 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 813 xstrerror (errno));
40b8e679 814
34edb9ad
L
815 fprintf (table, "\n/* i386 register table. */\n\n");
816 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
817
818 while (!feof (fp))
819 {
820 if (fgets (buf, sizeof (buf), fp) == NULL)
821 break;
822
3d4d5afa
L
823 lineno++;
824
40b8e679
L
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 '#':
34edb9ad 838 fprintf (table, "%s\n", p);
40b8e679
L
839 case '\0':
840 continue;
841 break;
842 default:
843 break;
844 }
845
846 last = p + strlen (p);
847
848 /* Find reg_name. */
93b1ec2c 849 reg_name = next_field (p, ',', &str);
40b8e679
L
850
851 if (str >= last)
852 abort ();
853
854 /* Find reg_type. */
93b1ec2c 855 reg_type = next_field (str, ',', &str);
40b8e679
L
856
857 if (str >= last)
858 abort ();
859
860 /* Find reg_flags. */
93b1ec2c 861 reg_flags = next_field (str, ',', &str);
40b8e679
L
862
863 if (str >= last)
864 abort ();
865
866 /* Find reg_num. */
93b1ec2c 867 reg_num = next_field (str, ',', &str);
40b8e679 868
a60de03c
JB
869 if (str >= last)
870 abort ();
871
40fb9820
L
872 fprintf (table, " { \"%s\",\n ", reg_name);
873
874 process_i386_operand_type (table, reg_type, 0, "\t");
875
a60de03c
JB
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);
40b8e679
L
887 }
888
34edb9ad
L
889 fclose (fp);
890
891 fprintf (table, "};\n");
40b8e679 892
34edb9ad 893 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
894}
895
40fb9820
L
896static void
897process_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
40b8e679
L
929/* Program options. */
930#define OPTION_SRCDIR 200
931
932struct 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
941static void
942print_version (void)
943{
944 printf ("%s: version 1.0\n", program_name);
945 xexit (0);
946}
947
948static void
949usage (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
956int
957main (int argc, char **argv)
958{
959 extern int chdir (char *);
960 char *srcdir = NULL;
8b40d594 961 int c;
72ffa0fb 962 FILE *table;
40b8e679
L
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"),
40fb9820
L
994 srcdir, xstrerror (errno));
995
996 /* Check the unused bitfield in i386_cpu_flags. */
997#ifndef CpuUnused
8b40d594
L
998 c = CpuNumOfBits - CpuMax - 1;
999 if (c)
1000 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
1001#endif
1002
1003 /* Check the unused bitfield in i386_operand_type. */
1004#ifndef OTUnused
8b40d594
L
1005 c = OTNumOfBits - OTMax - 1;
1006 if (c)
1007 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
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);
40b8e679 1018
34edb9ad
L
1019 table = fopen ("i386-tbl.h", "w");
1020 if (table == NULL)
40fb9820
L
1021 fail (_("can't create i386-tbl.h, errno = %s\n"),
1022 xstrerror (errno));
34edb9ad 1023
72ffa0fb 1024 process_copyright (table);
40b8e679 1025
72ffa0fb
L
1026 process_i386_opcodes (table);
1027 process_i386_registers (table);
40fb9820 1028 process_i386_initializers ();
40b8e679 1029
34edb9ad
L
1030 fclose (table);
1031
40b8e679
L
1032 exit (0);
1033}
This page took 0.097404 seconds and 4 git commands to generate.