1 /* Copyright (C) 2007-2014 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
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)
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.
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. */
24 #include "libiberty.h"
26 #include "safe-ctype.h"
31 #define _(String) gettext (String)
33 static const char *program_name = NULL;
36 typedef struct initializer
42 static initializer cpu_flag_init[] =
44 { "CPU_UNKNOWN_FLAGS",
45 "~(CpuL1OM|CpuK1OM)" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
57 "Cpu186|Cpu286|Cpu386" },
59 "Cpu186|Cpu286|Cpu386|Cpu486" },
61 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu387" },
63 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
67 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
69 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
71 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
73 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM|CpuCX16" },
75 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuCX16" },
77 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM|CpuCX16" },
79 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM|CpuCX16" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
83 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
87 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
91 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
95 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase" },
97 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd" },
99 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
100 { "CPU_BTVER2_FLAGS",
101 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuSSE4_1|CpuSSE4_2|CpuABM|CpuLM|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
109 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
110 { "CPU_CLFLUSH_FLAGS",
114 { "CPU_SYSCALL_FLAGS",
121 "CpuMMX|CpuSSE|CpuSSE2" },
123 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
125 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
126 { "CPU_SSE4_1_FLAGS",
127 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
128 { "CPU_SSE4_2_FLAGS",
129 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
130 { "CPU_ANY_SSE_FLAGS",
131 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
138 { "CPU_XSAVEOPT_FLAGS",
141 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
142 { "CPU_PCLMUL_FLAGS",
143 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
145 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
147 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
149 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
160 { "CPU_RDTSCP_FLAGS",
164 { "CPU_FSGSBASE_FLAGS",
178 { "CPU_INVPCID_FLAGS",
180 { "CPU_VMFUNC_FLAGS",
184 { "CPU_3DNOWA_FLAGS",
185 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
186 { "CPU_PADLOCK_FLAGS",
191 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
195 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
197 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
198 { "CPU_AVX512F_FLAGS",
199 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F" },
200 { "CPU_AVX512CD_FLAGS",
201 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD" },
202 { "CPU_AVX512ER_FLAGS",
203 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512ER" },
204 { "CPU_AVX512PF_FLAGS",
205 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512PF" },
206 { "CPU_ANY_AVX_FLAGS",
207 "CpuAVX|CpuAVX2|CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF" },
214 { "CPU_RDSEED_FLAGS",
216 { "CPU_PRFCHW_FLAGS",
224 { "CPU_CLFLUSHOPT_FLAGS",
226 { "CPU_XSAVES_FLAGS",
228 { "CPU_XSAVEC_FLAGS",
230 { "CPU_PREFETCHWT1_FLAGS",
234 static initializer operand_type_init[] =
236 { "OPERAND_TYPE_NONE",
238 { "OPERAND_TYPE_REG8",
240 { "OPERAND_TYPE_REG16",
242 { "OPERAND_TYPE_REG32",
244 { "OPERAND_TYPE_REG64",
246 { "OPERAND_TYPE_IMM1",
248 { "OPERAND_TYPE_IMM8",
250 { "OPERAND_TYPE_IMM8S",
252 { "OPERAND_TYPE_IMM16",
254 { "OPERAND_TYPE_IMM32",
256 { "OPERAND_TYPE_IMM32S",
258 { "OPERAND_TYPE_IMM64",
260 { "OPERAND_TYPE_BASEINDEX",
262 { "OPERAND_TYPE_DISP8",
264 { "OPERAND_TYPE_DISP16",
266 { "OPERAND_TYPE_DISP32",
268 { "OPERAND_TYPE_DISP32S",
270 { "OPERAND_TYPE_DISP64",
272 { "OPERAND_TYPE_INOUTPORTREG",
274 { "OPERAND_TYPE_SHIFTCOUNT",
276 { "OPERAND_TYPE_CONTROL",
278 { "OPERAND_TYPE_TEST",
280 { "OPERAND_TYPE_DEBUG",
282 { "OPERAND_TYPE_FLOATREG",
284 { "OPERAND_TYPE_FLOATACC",
286 { "OPERAND_TYPE_SREG2",
288 { "OPERAND_TYPE_SREG3",
290 { "OPERAND_TYPE_ACC",
292 { "OPERAND_TYPE_JUMPABSOLUTE",
294 { "OPERAND_TYPE_REGMMX",
296 { "OPERAND_TYPE_REGXMM",
298 { "OPERAND_TYPE_REGYMM",
300 { "OPERAND_TYPE_REGZMM",
302 { "OPERAND_TYPE_REGMASK",
304 { "OPERAND_TYPE_ESSEG",
306 { "OPERAND_TYPE_ACC32",
308 { "OPERAND_TYPE_ACC64",
310 { "OPERAND_TYPE_INOUTPORTREG",
312 { "OPERAND_TYPE_REG16_INOUTPORTREG",
313 "Reg16|InOutPortReg" },
314 { "OPERAND_TYPE_DISP16_32",
316 { "OPERAND_TYPE_ANYDISP",
317 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
318 { "OPERAND_TYPE_IMM16_32",
320 { "OPERAND_TYPE_IMM16_32S",
322 { "OPERAND_TYPE_IMM16_32_32S",
323 "Imm16|Imm32|Imm32S" },
324 { "OPERAND_TYPE_IMM32_64",
326 { "OPERAND_TYPE_IMM32_32S_DISP32",
327 "Imm32|Imm32S|Disp32" },
328 { "OPERAND_TYPE_IMM64_DISP64",
330 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
331 "Imm32|Imm32S|Imm64|Disp32" },
332 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
333 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
334 { "OPERAND_TYPE_VEC_IMM4",
336 { "OPERAND_TYPE_REGBND",
338 { "OPERAND_TYPE_VEC_DISP8",
342 typedef struct bitfield
349 #define BITFIELD(n) { n, 0, #n }
351 static bitfield cpu_flags[] =
359 BITFIELD (CpuClflush),
361 BITFIELD (CpuSYSCALL),
366 BITFIELD (CpuFISTTP),
372 BITFIELD (CpuSSE4_1),
373 BITFIELD (CpuSSE4_2),
376 BITFIELD (CpuAVX512F),
377 BITFIELD (CpuAVX512CD),
378 BITFIELD (CpuAVX512ER),
379 BITFIELD (CpuAVX512PF),
384 BITFIELD (Cpu3dnowA),
385 BITFIELD (CpuPadLock),
391 BITFIELD (CpuXsaveopt),
393 BITFIELD (CpuPCLMUL),
404 BITFIELD (CpuRdtscp),
405 BITFIELD (CpuFSGSBase),
412 BITFIELD (CpuINVPCID),
413 BITFIELD (CpuVMFUNC),
414 BITFIELD (CpuRDSEED),
416 BITFIELD (CpuPRFCHW),
420 BITFIELD (CpuClflushOpt),
421 BITFIELD (CpuXSAVES),
422 BITFIELD (CpuXSAVEC),
423 BITFIELD (CpuPREFETCHWT1),
428 BITFIELD (CpuUnused),
432 static bitfield opcode_modifiers[] =
438 BITFIELD (ShortForm),
440 BITFIELD (JumpDword),
442 BITFIELD (JumpInterSegment),
449 BITFIELD (CheckRegSize),
450 BITFIELD (IgnoreSize),
451 BITFIELD (DefaultSize),
460 BITFIELD (BNDPrefixOk),
461 BITFIELD (IsLockable),
462 BITFIELD (RegKludge),
463 BITFIELD (FirstXmm0),
464 BITFIELD (Implicit1stXmm0),
465 BITFIELD (RepPrefixOk),
466 BITFIELD (HLEPrefixOk),
469 BITFIELD (AddrPrefixOp0),
478 BITFIELD (VexOpcode),
479 BITFIELD (VexSources),
480 BITFIELD (VexImmExt),
487 BITFIELD (Broadcast),
488 BITFIELD (StaticRounding),
490 BITFIELD (Disp8MemShift),
491 BITFIELD (NoDefMask),
493 BITFIELD (ATTMnemonic),
494 BITFIELD (ATTSyntax),
495 BITFIELD (IntelSyntax),
498 static bitfield operand_types[] =
517 BITFIELD (BaseIndex),
523 BITFIELD (InOutPortReg),
524 BITFIELD (ShiftCount),
532 BITFIELD (JumpAbsolute),
545 BITFIELD (Unspecified),
549 BITFIELD (Vec_Disp8),
555 static const char *filename;
558 compare (const void *x, const void *y)
560 const bitfield *xp = (const bitfield *) x;
561 const bitfield *yp = (const bitfield *) y;
562 return xp->position - yp->position;
566 fail (const char *message, ...)
570 va_start (args, message);
571 fprintf (stderr, _("%s: Error: "), program_name);
572 vfprintf (stderr, message, args);
578 process_copyright (FILE *fp)
580 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
581 /* Copyright (C) 2007-2014 Free Software Foundation, Inc.\n\
583 This file is part of the GNU opcodes library.\n\
585 This library is free software; you can redistribute it and/or modify\n\
586 it under the terms of the GNU General Public License as published by\n\
587 the Free Software Foundation; either version 3, or (at your option)\n\
588 any later version.\n\
590 It is distributed in the hope that it will be useful, but WITHOUT\n\
591 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
592 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
593 License for more details.\n\
595 You should have received a copy of the GNU General Public License\n\
596 along with this program; if not, write to the Free Software\n\
597 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
598 MA 02110-1301, USA. */\n");
601 /* Remove leading white spaces. */
604 remove_leading_whitespaces (char *str)
606 while (ISSPACE (*str))
611 /* Remove trailing white spaces. */
614 remove_trailing_whitespaces (char *str)
616 size_t last = strlen (str);
624 if (ISSPACE (str [last]))
632 /* Find next field separated by SEP and terminate it. Return a
633 pointer to the one after it. */
636 next_field (char *str, char sep, char **next, char *last)
640 p = remove_leading_whitespaces (str);
641 for (str = p; *str != sep && *str != '\0'; str++);
644 remove_trailing_whitespaces (p);
655 set_bitfield (const char *f, bitfield *array, int value,
656 unsigned int size, int lineno)
660 if (strcmp (f, "CpuFP") == 0)
662 set_bitfield("Cpu387", array, value, size, lineno);
663 set_bitfield("Cpu287", array, value, size, lineno);
666 else if (strcmp (f, "Mmword") == 0)
668 else if (strcmp (f, "Oword") == 0)
671 for (i = 0; i < size; i++)
672 if (strcasecmp (array[i].name, f) == 0)
674 array[i].value = value;
680 const char *v = strchr (f, '=');
687 for (i = 0; i < size; i++)
688 if (strncasecmp (array[i].name, f, n) == 0)
690 value = strtol (v + 1, &end, 0);
693 array[i].value = value;
702 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
704 fail (_("Unknown bitfield: %s\n"), f);
708 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
709 int macro, const char *comma, const char *indent)
713 fprintf (table, "%s{ { ", indent);
715 for (i = 0; i < size - 1; i++)
717 if (((i + 1) % 20) != 0)
718 fprintf (table, "%d, ", flags[i].value);
720 fprintf (table, "%d,", flags[i].value);
721 if (((i + 1) % 20) == 0)
723 /* We need \\ for macro. */
725 fprintf (table, " \\\n %s", indent);
727 fprintf (table, "\n %s", indent);
731 fprintf (table, "%d } }%s\n", flags[i].value, comma);
735 process_i386_cpu_flag (FILE *table, char *flag, int macro,
736 const char *comma, const char *indent,
739 char *str, *next, *last;
741 bitfield flags [ARRAY_SIZE (cpu_flags)];
743 /* Copy the default cpu flags. */
744 memcpy (flags, cpu_flags, sizeof (cpu_flags));
746 if (strcasecmp (flag, "unknown") == 0)
748 /* We turn on everything except for cpu64 in case of
749 CPU_UNKNOWN_FLAGS. */
750 for (i = 0; i < ARRAY_SIZE (flags); i++)
751 if (flags[i].position != Cpu64)
754 else if (flag[0] == '~')
756 last = flag + strlen (flag);
763 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
770 /* First we turn on everything except for cpu64. */
771 for (i = 0; i < ARRAY_SIZE (flags); i++)
772 if (flags[i].position != Cpu64)
775 /* Turn off selective bits. */
776 for (; next && next < last; )
778 str = next_field (next, '|', &next, last);
780 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
783 else if (strcmp (flag, "0"))
785 /* Turn on selective bits. */
786 last = flag + strlen (flag);
787 for (next = flag; next && next < last; )
789 str = next_field (next, '|', &next, last);
791 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
795 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
800 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
804 fprintf (table, " { ");
806 for (i = 0; i < size - 1; i++)
808 if (((i + 1) % 20) != 0)
809 fprintf (table, "%d, ", modifier[i].value);
811 fprintf (table, "%d,", modifier[i].value);
812 if (((i + 1) % 20) == 0)
813 fprintf (table, "\n ");
816 fprintf (table, "%d },\n", modifier[i].value);
820 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
822 char *str, *next, *last;
823 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
825 /* Copy the default opcode modifier. */
826 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
828 if (strcmp (mod, "0"))
830 last = mod + strlen (mod);
831 for (next = mod; next && next < last; )
833 str = next_field (next, '|', &next, last);
835 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
839 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
843 output_operand_type (FILE *table, bitfield *types, unsigned int size,
844 int macro, const char *indent)
848 fprintf (table, "{ { ");
850 for (i = 0; i < size - 1; i++)
852 if (((i + 1) % 20) != 0)
853 fprintf (table, "%d, ", types[i].value);
855 fprintf (table, "%d,", types[i].value);
856 if (((i + 1) % 20) == 0)
858 /* We need \\ for macro. */
860 fprintf (table, " \\\n%s", indent);
862 fprintf (table, "\n%s", indent);
866 fprintf (table, "%d } }", types[i].value);
870 process_i386_operand_type (FILE *table, char *op, int macro,
871 const char *indent, int lineno)
873 char *str, *next, *last;
874 bitfield types [ARRAY_SIZE (operand_types)];
876 /* Copy the default operand type. */
877 memcpy (types, operand_types, sizeof (types));
879 if (strcmp (op, "0"))
881 last = op + strlen (op);
882 for (next = op; next && next < last; )
884 str = next_field (next, '|', &next, last);
886 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
889 output_operand_type (table, types, ARRAY_SIZE (types), macro,
894 output_i386_opcode (FILE *table, const char *name, char *str,
895 char *last, int lineno)
898 char *operands, *base_opcode, *extension_opcode, *opcode_length;
899 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
901 /* Find number of operands. */
902 operands = next_field (str, ',', &str, last);
904 /* Find base_opcode. */
905 base_opcode = next_field (str, ',', &str, last);
907 /* Find extension_opcode. */
908 extension_opcode = next_field (str, ',', &str, last);
910 /* Find opcode_length. */
911 opcode_length = next_field (str, ',', &str, last);
913 /* Find cpu_flags. */
914 cpu_flags = next_field (str, ',', &str, last);
916 /* Find opcode_modifier. */
917 opcode_modifier = next_field (str, ',', &str, last);
919 /* Remove the first {. */
920 str = remove_leading_whitespaces (str);
923 str = remove_leading_whitespaces (str + 1);
927 /* There are at least "X}". */
931 /* Remove trailing white spaces and }. */
935 if (ISSPACE (str[i]) || str[i] == '}')
944 /* Find operand_types. */
945 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
949 operand_types [i] = NULL;
953 operand_types [i] = next_field (str, ',', &str, last);
954 if (*operand_types[i] == '0')
957 operand_types[i] = NULL;
962 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
963 name, operands, base_opcode, extension_opcode,
966 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
968 process_i386_opcode_modifier (table, opcode_modifier, lineno);
970 fprintf (table, " { ");
972 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
974 if (operand_types[i] == NULL || *operand_types[i] == '0')
977 process_i386_operand_type (table, "0", 0, "\t ", lineno);
982 fprintf (table, ",\n ");
984 process_i386_operand_type (table, operand_types[i], 0,
987 fprintf (table, " } },\n");
990 struct opcode_hash_entry
992 struct opcode_hash_entry *next;
998 /* Calculate the hash value of an opcode hash entry P. */
1001 opcode_hash_hash (const void *p)
1003 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1004 return htab_hash_string (entry->name);
1007 /* Compare a string Q against an opcode hash entry P. */
1010 opcode_hash_eq (const void *p, const void *q)
1012 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1013 const char *name = (const char *) q;
1014 return strcmp (name, entry->name) == 0;
1018 process_i386_opcodes (FILE *table)
1023 char *str, *p, *last, *name;
1024 struct opcode_hash_entry **hash_slot, **entry, *next;
1025 htab_t opcode_hash_table;
1026 struct opcode_hash_entry **opcode_array;
1027 unsigned int opcode_array_size = 1024;
1030 filename = "i386-opc.tbl";
1031 fp = fopen (filename, "r");
1034 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1038 opcode_array = (struct opcode_hash_entry **)
1039 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1041 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1042 opcode_hash_eq, NULL,
1045 fprintf (table, "\n/* i386 opcode table. */\n\n");
1046 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1048 /* Put everything on opcode array. */
1051 if (fgets (buf, sizeof (buf), fp) == NULL)
1056 p = remove_leading_whitespaces (buf);
1058 /* Skip comments. */
1059 str = strstr (p, "//");
1063 /* Remove trailing white spaces. */
1064 remove_trailing_whitespaces (p);
1069 /* Ignore comments. */
1077 last = p + strlen (p);
1080 name = next_field (p, ',', &str, last);
1082 /* Get the slot in hash table. */
1083 hash_slot = (struct opcode_hash_entry **)
1084 htab_find_slot_with_hash (opcode_hash_table, name,
1085 htab_hash_string (name),
1088 if (*hash_slot == NULL)
1090 /* It is the new one. Put it on opcode array. */
1091 if (i >= opcode_array_size)
1093 /* Grow the opcode array when needed. */
1094 opcode_array_size += 1024;
1095 opcode_array = (struct opcode_hash_entry **)
1096 xrealloc (opcode_array,
1097 sizeof (*opcode_array) * opcode_array_size);
1100 opcode_array[i] = (struct opcode_hash_entry *)
1101 xmalloc (sizeof (struct opcode_hash_entry));
1102 opcode_array[i]->next = NULL;
1103 opcode_array[i]->name = xstrdup (name);
1104 opcode_array[i]->opcode = xstrdup (str);
1105 opcode_array[i]->lineno = lineno;
1106 *hash_slot = opcode_array[i];
1111 /* Append it to the existing one. */
1113 while ((*entry) != NULL)
1114 entry = &(*entry)->next;
1115 *entry = (struct opcode_hash_entry *)
1116 xmalloc (sizeof (struct opcode_hash_entry));
1117 (*entry)->next = NULL;
1118 (*entry)->name = (*hash_slot)->name;
1119 (*entry)->opcode = xstrdup (str);
1120 (*entry)->lineno = lineno;
1124 /* Process opcode array. */
1125 for (j = 0; j < i; j++)
1127 for (next = opcode_array[j]; next; next = next->next)
1131 lineno = next->lineno;
1132 last = str + strlen (str);
1133 output_i386_opcode (table, name, str, last, lineno);
1139 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1141 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1143 process_i386_opcode_modifier (table, "0", -1);
1145 fprintf (table, " { ");
1146 process_i386_operand_type (table, "0", 0, "\t ", -1);
1147 fprintf (table, " } }\n");
1149 fprintf (table, "};\n");
1153 process_i386_registers (FILE *table)
1157 char *str, *p, *last;
1158 char *reg_name, *reg_type, *reg_flags, *reg_num;
1159 char *dw2_32_num, *dw2_64_num;
1162 filename = "i386-reg.tbl";
1163 fp = fopen (filename, "r");
1165 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1168 fprintf (table, "\n/* i386 register table. */\n\n");
1169 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1173 if (fgets (buf, sizeof (buf), fp) == NULL)
1178 p = remove_leading_whitespaces (buf);
1180 /* Skip comments. */
1181 str = strstr (p, "//");
1185 /* Remove trailing white spaces. */
1186 remove_trailing_whitespaces (p);
1191 fprintf (table, "%s\n", p);
1199 last = p + strlen (p);
1201 /* Find reg_name. */
1202 reg_name = next_field (p, ',', &str, last);
1204 /* Find reg_type. */
1205 reg_type = next_field (str, ',', &str, last);
1207 /* Find reg_flags. */
1208 reg_flags = next_field (str, ',', &str, last);
1211 reg_num = next_field (str, ',', &str, last);
1213 fprintf (table, " { \"%s\",\n ", reg_name);
1215 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1217 /* Find 32-bit Dwarf2 register number. */
1218 dw2_32_num = next_field (str, ',', &str, last);
1220 /* Find 64-bit Dwarf2 register number. */
1221 dw2_64_num = next_field (str, ',', &str, last);
1223 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1224 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1229 fprintf (table, "};\n");
1231 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1235 process_i386_initializers (void)
1238 FILE *fp = fopen ("i386-init.h", "w");
1242 fail (_("can't create i386-init.h, errno = %s\n"),
1245 process_copyright (fp);
1247 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1249 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1250 init = xstrdup (cpu_flag_init[i].init);
1251 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1255 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1257 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1258 init = xstrdup (operand_type_init[i].init);
1259 process_i386_operand_type (fp, init, 1, " ", -1);
1267 /* Program options. */
1268 #define OPTION_SRCDIR 200
1270 struct option long_options[] =
1272 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1273 {"debug", no_argument, NULL, 'd'},
1274 {"version", no_argument, NULL, 'V'},
1275 {"help", no_argument, NULL, 'h'},
1276 {0, no_argument, NULL, 0}
1280 print_version (void)
1282 printf ("%s: version 1.0\n", program_name);
1287 usage (FILE * stream, int status)
1289 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1295 main (int argc, char **argv)
1297 extern int chdir (char *);
1298 char *srcdir = NULL;
1302 program_name = *argv;
1303 xmalloc_set_program_name (program_name);
1305 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1330 if (chdir (srcdir) != 0)
1331 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1332 srcdir, xstrerror (errno));
1334 /* Check the unused bitfield in i386_cpu_flags. */
1336 c = CpuNumOfBits - CpuMax - 1;
1338 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1341 /* Check the unused bitfield in i386_operand_type. */
1343 c = OTNumOfBits - OTMax - 1;
1345 fail (_("%d unused bits in i386_operand_type.\n"), c);
1348 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1351 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1352 sizeof (opcode_modifiers [0]), compare);
1354 qsort (operand_types, ARRAY_SIZE (operand_types),
1355 sizeof (operand_types [0]), compare);
1357 table = fopen ("i386-tbl.h", "w");
1359 fail (_("can't create i386-tbl.h, errno = %s\n"),
1362 process_copyright (table);
1364 process_i386_opcodes (table);
1365 process_i386_registers (table);
1366 process_i386_initializers ();