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