1 /* Copyright (C) 2007-2018 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 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
55 "CPU_I186_FLAGS|Cpu286" },
57 "CPU_I286_FLAGS|Cpu386" },
59 "CPU_I386_FLAGS|Cpu486" },
61 "CPU_I486_FLAGS|Cpu387|Cpu586" },
63 "CPU_I586_FLAGS|Cpu686|Cpu687" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "CPU_I686_FLAGS|CpuNop" },
67 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
69 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
71 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
73 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
75 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
77 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
79 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
83 "CPU_K6_FLAGS|Cpu3dnow" },
85 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
87 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
91 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
95 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
97 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
99 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_ZNVER2_FLAGS",
101 "CPU_ZNVER1_FLAGS|CpuRDPID|CpuWBNOINVD|CpuCLWB" },
102 { "CPU_BTVER1_FLAGS",
103 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
104 { "CPU_BTVER2_FLAGS",
105 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
113 "CPU_387_FLAGS|Cpu687" },
114 { "CPU_CLFLUSH_FLAGS",
118 { "CPU_SYSCALL_FLAGS",
125 "CPU_SSE_FLAGS|CpuSSE2" },
127 "CPU_SSE2_FLAGS|CpuSSE3" },
129 "CPU_SSE3_FLAGS|CpuSSSE3" },
130 { "CPU_SSE4_1_FLAGS",
131 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
132 { "CPU_SSE4_2_FLAGS",
133 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
140 { "CPU_XSAVEOPT_FLAGS",
141 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
143 "CPU_SSE2_FLAGS|CpuAES" },
144 { "CPU_PCLMUL_FLAGS",
145 "CPU_SSE2_FLAGS|CpuPCLMUL" },
147 "CPU_AVX_FLAGS|CpuFMA" },
149 "CPU_AVX_FLAGS|CpuFMA4" },
151 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
153 "CPU_XSAVE_FLAGS|CpuLWP" },
162 { "CPU_RDTSCP_FLAGS",
166 { "CPU_FSGSBASE_FLAGS",
171 "CPU_AVX_FLAGS|CpuF16C" },
180 { "CPU_INVPCID_FLAGS",
182 { "CPU_VMFUNC_FLAGS",
185 "CPU_MMX_FLAGS|Cpu3dnow" },
186 { "CPU_3DNOWA_FLAGS",
187 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
188 { "CPU_PADLOCK_FLAGS",
193 "CPU_SSE3_FLAGS|CpuSSE4a" },
197 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
199 "CPU_AVX_FLAGS|CpuAVX2" },
200 { "CPU_AVX512F_FLAGS",
201 "CPU_AVX2_FLAGS|CpuVREX|CpuAVX512F" },
202 { "CPU_AVX512CD_FLAGS",
203 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
204 { "CPU_AVX512ER_FLAGS",
205 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
206 { "CPU_AVX512PF_FLAGS",
207 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
208 { "CPU_AVX512DQ_FLAGS",
209 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
210 { "CPU_AVX512BW_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
212 { "CPU_AVX512VL_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
214 { "CPU_AVX512IFMA_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
216 { "CPU_AVX512VBMI_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
218 { "CPU_AVX512_4FMAPS_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
220 { "CPU_AVX512_4VNNIW_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
222 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
224 { "CPU_AVX512_VBMI2_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
226 { "CPU_AVX512_VNNI_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
228 { "CPU_AVX512_BITALG_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
235 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
238 { "CPU_RDSEED_FLAGS",
240 { "CPU_PRFCHW_FLAGS",
245 "CPU_XSAVE_FLAGS|CpuMPX" },
247 "CPU_SSE2_FLAGS|CpuSHA" },
248 { "CPU_CLFLUSHOPT_FLAGS",
250 { "CPU_XSAVES_FLAGS",
251 "CPU_XSAVE_FLAGS|CpuXSAVES" },
252 { "CPU_XSAVEC_FLAGS",
253 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
254 { "CPU_PREFETCHWT1_FLAGS",
260 { "CPU_CLZERO_FLAGS",
262 { "CPU_MWAITX_FLAGS",
265 "CPU_XSAVE_FLAGS|CpuOSPKE" },
268 { "CPU_PTWRITE_FLAGS",
278 { "CPU_VPCLMULQDQ_FLAGS",
280 { "CPU_WBNOINVD_FLAGS",
282 { "CPU_PCONFIG_FLAGS",
284 { "CPU_WAITPKG_FLAGS",
286 { "CPU_CLDEMOTE_FLAGS",
288 { "CPU_MOVDIRI_FLAGS",
290 { "CPU_MOVDIR64B_FLAGS",
292 { "CPU_ANY_X87_FLAGS",
293 "CPU_ANY_287_FLAGS|Cpu8087" },
294 { "CPU_ANY_287_FLAGS",
295 "CPU_ANY_387_FLAGS|Cpu287" },
296 { "CPU_ANY_387_FLAGS",
297 "CPU_ANY_687_FLAGS|Cpu387" },
298 { "CPU_ANY_687_FLAGS",
299 "Cpu687|CpuFISTTP" },
300 { "CPU_ANY_MMX_FLAGS",
301 "CPU_3DNOWA_FLAGS" },
302 { "CPU_ANY_SSE_FLAGS",
303 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
304 { "CPU_ANY_SSE2_FLAGS",
305 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
306 { "CPU_ANY_SSE3_FLAGS",
307 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
308 { "CPU_ANY_SSSE3_FLAGS",
309 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
310 { "CPU_ANY_SSE4_1_FLAGS",
311 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
312 { "CPU_ANY_SSE4_2_FLAGS",
314 { "CPU_ANY_AVX_FLAGS",
315 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
316 { "CPU_ANY_AVX2_FLAGS",
318 { "CPU_ANY_AVX512F_FLAGS",
319 "CpuVREX|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512F" },
320 { "CPU_ANY_AVX512CD_FLAGS",
322 { "CPU_ANY_AVX512ER_FLAGS",
324 { "CPU_ANY_AVX512PF_FLAGS",
326 { "CPU_ANY_AVX512DQ_FLAGS",
328 { "CPU_ANY_AVX512BW_FLAGS",
330 { "CPU_ANY_AVX512VL_FLAGS",
332 { "CPU_ANY_AVX512IFMA_FLAGS",
334 { "CPU_ANY_AVX512VBMI_FLAGS",
336 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
337 "CpuAVX512_4FMAPS" },
338 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
339 "CpuAVX512_4VNNIW" },
340 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
341 "CpuAVX512_VPOPCNTDQ" },
342 { "CPU_ANY_IBT_FLAGS",
344 { "CPU_ANY_SHSTK_FLAGS",
346 { "CPU_ANY_AVX512_VBMI2_FLAGS",
348 { "CPU_ANY_AVX512_VNNI_FLAGS",
350 { "CPU_ANY_AVX512_BITALG_FLAGS",
351 "CpuAVX512_BITALG" },
352 { "CPU_ANY_MOVDIRI_FLAGS",
354 { "CPU_ANY_MOVDIR64B_FLAGS",
358 static const initializer operand_type_shorthands[] =
360 { "Reg8", "Reg|Byte" },
361 { "Reg16", "Reg|Word" },
362 { "Reg32", "Reg|Dword" },
363 { "Reg64", "Reg|Qword" },
364 { "FloatAcc", "Acc|Tbyte" },
365 { "FloatReg", "Reg|Tbyte" },
366 { "RegXMM", "RegSIMD|Xmmword" },
367 { "RegYMM", "RegSIMD|Ymmword" },
368 { "RegZMM", "RegSIMD|Zmmword" },
371 static initializer operand_type_init[] =
373 { "OPERAND_TYPE_NONE",
375 { "OPERAND_TYPE_REG8",
377 { "OPERAND_TYPE_REG16",
379 { "OPERAND_TYPE_REG32",
381 { "OPERAND_TYPE_REG64",
383 { "OPERAND_TYPE_IMM1",
385 { "OPERAND_TYPE_IMM8",
387 { "OPERAND_TYPE_IMM8S",
389 { "OPERAND_TYPE_IMM16",
391 { "OPERAND_TYPE_IMM32",
393 { "OPERAND_TYPE_IMM32S",
395 { "OPERAND_TYPE_IMM64",
397 { "OPERAND_TYPE_BASEINDEX",
399 { "OPERAND_TYPE_DISP8",
401 { "OPERAND_TYPE_DISP16",
403 { "OPERAND_TYPE_DISP32",
405 { "OPERAND_TYPE_DISP32S",
407 { "OPERAND_TYPE_DISP64",
409 { "OPERAND_TYPE_INOUTPORTREG",
411 { "OPERAND_TYPE_SHIFTCOUNT",
413 { "OPERAND_TYPE_CONTROL",
415 { "OPERAND_TYPE_TEST",
417 { "OPERAND_TYPE_DEBUG",
419 { "OPERAND_TYPE_FLOATREG",
421 { "OPERAND_TYPE_FLOATACC",
423 { "OPERAND_TYPE_SREG2",
425 { "OPERAND_TYPE_SREG3",
427 { "OPERAND_TYPE_ACC",
429 { "OPERAND_TYPE_JUMPABSOLUTE",
431 { "OPERAND_TYPE_REGMMX",
433 { "OPERAND_TYPE_REGXMM",
435 { "OPERAND_TYPE_REGYMM",
437 { "OPERAND_TYPE_REGZMM",
439 { "OPERAND_TYPE_REGMASK",
441 { "OPERAND_TYPE_ESSEG",
443 { "OPERAND_TYPE_ACC32",
445 { "OPERAND_TYPE_ACC64",
447 { "OPERAND_TYPE_DISP16_32",
449 { "OPERAND_TYPE_ANYDISP",
450 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
451 { "OPERAND_TYPE_IMM16_32",
453 { "OPERAND_TYPE_IMM16_32S",
455 { "OPERAND_TYPE_IMM16_32_32S",
456 "Imm16|Imm32|Imm32S" },
457 { "OPERAND_TYPE_IMM32_64",
459 { "OPERAND_TYPE_IMM32_32S_DISP32",
460 "Imm32|Imm32S|Disp32" },
461 { "OPERAND_TYPE_IMM64_DISP64",
463 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
464 "Imm32|Imm32S|Imm64|Disp32" },
465 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
466 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
467 { "OPERAND_TYPE_VEC_IMM4",
469 { "OPERAND_TYPE_REGBND",
473 typedef struct bitfield
480 #define BITFIELD(n) { n, 0, #n }
482 static bitfield cpu_flags[] =
490 BITFIELD (CpuClflush),
492 BITFIELD (CpuSYSCALL),
497 BITFIELD (CpuFISTTP),
503 BITFIELD (CpuSSE4_1),
504 BITFIELD (CpuSSE4_2),
507 BITFIELD (CpuAVX512F),
508 BITFIELD (CpuAVX512CD),
509 BITFIELD (CpuAVX512ER),
510 BITFIELD (CpuAVX512PF),
511 BITFIELD (CpuAVX512VL),
512 BITFIELD (CpuAVX512DQ),
513 BITFIELD (CpuAVX512BW),
519 BITFIELD (Cpu3dnowA),
520 BITFIELD (CpuPadLock),
526 BITFIELD (CpuXsaveopt),
528 BITFIELD (CpuPCLMUL),
539 BITFIELD (CpuRdtscp),
540 BITFIELD (CpuFSGSBase),
547 BITFIELD (CpuINVPCID),
548 BITFIELD (CpuVMFUNC),
549 BITFIELD (CpuRDSEED),
551 BITFIELD (CpuPRFCHW),
555 BITFIELD (CpuClflushOpt),
556 BITFIELD (CpuXSAVES),
557 BITFIELD (CpuXSAVEC),
558 BITFIELD (CpuPREFETCHWT1),
564 BITFIELD (CpuAVX512IFMA),
565 BITFIELD (CpuAVX512VBMI),
566 BITFIELD (CpuAVX512_4FMAPS),
567 BITFIELD (CpuAVX512_4VNNIW),
568 BITFIELD (CpuAVX512_VPOPCNTDQ),
569 BITFIELD (CpuAVX512_VBMI2),
570 BITFIELD (CpuAVX512_VNNI),
571 BITFIELD (CpuAVX512_BITALG),
572 BITFIELD (CpuMWAITX),
573 BITFIELD (CpuCLZERO),
576 BITFIELD (CpuPTWRITE),
581 BITFIELD (CpuVPCLMULQDQ),
582 BITFIELD (CpuWBNOINVD),
583 BITFIELD (CpuPCONFIG),
584 BITFIELD (CpuWAITPKG),
585 BITFIELD (CpuCLDEMOTE),
586 BITFIELD (CpuMOVDIRI),
587 BITFIELD (CpuMOVDIR64B),
589 BITFIELD (CpuUnused),
593 static bitfield opcode_modifiers[] =
599 BITFIELD (ShortForm),
601 BITFIELD (JumpDword),
603 BITFIELD (JumpInterSegment),
609 BITFIELD (CheckRegSize),
610 BITFIELD (IgnoreSize),
611 BITFIELD (DefaultSize),
620 BITFIELD (BNDPrefixOk),
621 BITFIELD (NoTrackPrefixOk),
622 BITFIELD (IsLockable),
623 BITFIELD (RegKludge),
624 BITFIELD (Implicit1stXmm0),
625 BITFIELD (RepPrefixOk),
626 BITFIELD (HLEPrefixOk),
629 BITFIELD (AddrPrefixOpReg),
638 BITFIELD (VexOpcode),
639 BITFIELD (VexSources),
645 BITFIELD (Broadcast),
646 BITFIELD (StaticRounding),
648 BITFIELD (Disp8MemShift),
649 BITFIELD (NoDefMask),
650 BITFIELD (ImplicitQuadGroup),
652 BITFIELD (ATTMnemonic),
653 BITFIELD (ATTSyntax),
654 BITFIELD (IntelSyntax),
659 static bitfield operand_types[] =
672 BITFIELD (BaseIndex),
678 BITFIELD (InOutPortReg),
679 BITFIELD (ShiftCount),
686 BITFIELD (JumpAbsolute),
699 BITFIELD (Unspecified),
708 static const char *filename;
709 static i386_cpu_flags active_cpu_flags;
710 static int active_isstring;
713 compare (const void *x, const void *y)
715 const bitfield *xp = (const bitfield *) x;
716 const bitfield *yp = (const bitfield *) y;
717 return xp->position - yp->position;
721 fail (const char *message, ...)
725 va_start (args, message);
726 fprintf (stderr, _("%s: error: "), program_name);
727 vfprintf (stderr, message, args);
733 process_copyright (FILE *fp)
735 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
736 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
738 This file is part of the GNU opcodes library.\n\
740 This library is free software; you can redistribute it and/or modify\n\
741 it under the terms of the GNU General Public License as published by\n\
742 the Free Software Foundation; either version 3, or (at your option)\n\
743 any later version.\n\
745 It is distributed in the hope that it will be useful, but WITHOUT\n\
746 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
747 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
748 License for more details.\n\
750 You should have received a copy of the GNU General Public License\n\
751 along with this program; if not, write to the Free Software\n\
752 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
753 MA 02110-1301, USA. */\n");
756 /* Remove leading white spaces. */
759 remove_leading_whitespaces (char *str)
761 while (ISSPACE (*str))
766 /* Remove trailing white spaces. */
769 remove_trailing_whitespaces (char *str)
771 size_t last = strlen (str);
779 if (ISSPACE (str [last]))
787 /* Find next field separated by SEP and terminate it. Return a
788 pointer to the one after it. */
791 next_field (char *str, char sep, char **next, char *last)
795 p = remove_leading_whitespaces (str);
796 for (str = p; *str != sep && *str != '\0'; str++);
799 remove_trailing_whitespaces (p);
809 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
812 set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
815 char *str, *next, *last;
818 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
819 if (strcmp (cpu_flag_init[i].name, f) == 0)
821 /* Turn on selective bits. */
822 char *init = xstrdup (cpu_flag_init[i].init);
823 last = init + strlen (init);
824 for (next = init; next && next < last; )
826 str = next_field (next, '|', &next, last);
828 set_bitfield (str, array, 1, size, lineno);
834 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
835 if (strcmp (operand_type_shorthands[i].name, f) == 0)
837 /* Turn on selective bits. */
838 char *init = xstrdup (operand_type_shorthands[i].init);
839 last = init + strlen (init);
840 for (next = init; next && next < last; )
842 str = next_field (next, '|', &next, last);
844 set_bitfield (str, array, 1, size, lineno);
854 set_bitfield (char *f, bitfield *array, int value,
855 unsigned int size, int lineno)
859 if (strcmp (f, "CpuFP") == 0)
861 set_bitfield("Cpu387", array, value, size, lineno);
862 set_bitfield("Cpu287", array, value, size, lineno);
865 else if (strcmp (f, "Mmword") == 0)
867 else if (strcmp (f, "Oword") == 0)
870 for (i = 0; i < size; i++)
871 if (strcasecmp (array[i].name, f) == 0)
873 array[i].value = value;
879 const char *v = strchr (f, '=');
886 for (i = 0; i < size; i++)
887 if (strncasecmp (array[i].name, f, n) == 0)
889 value = strtol (v + 1, &end, 0);
892 array[i].value = value;
900 /* Handle shorthands. */
901 if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno))
905 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
907 fail (_("unknown bitfield: %s\n"), f);
911 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
912 int macro, const char *comma, const char *indent)
916 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
918 fprintf (table, "%s{ { ", indent);
920 for (i = 0; i < size - 1; i++)
922 if (((i + 1) % 20) != 0)
923 fprintf (table, "%d, ", flags[i].value);
925 fprintf (table, "%d,", flags[i].value);
926 if (((i + 1) % 20) == 0)
928 /* We need \\ for macro. */
930 fprintf (table, " \\\n %s", indent);
932 fprintf (table, "\n %s", indent);
935 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
938 fprintf (table, "%d } }%s\n", flags[i].value, comma);
942 process_i386_cpu_flag (FILE *table, char *flag, int macro,
943 const char *comma, const char *indent,
946 char *str, *next, *last;
948 bitfield flags [ARRAY_SIZE (cpu_flags)];
950 /* Copy the default cpu flags. */
951 memcpy (flags, cpu_flags, sizeof (cpu_flags));
953 if (strcasecmp (flag, "unknown") == 0)
955 /* We turn on everything except for cpu64 in case of
956 CPU_UNKNOWN_FLAGS. */
957 for (i = 0; i < ARRAY_SIZE (flags); i++)
958 if (flags[i].position != Cpu64)
961 else if (flag[0] == '~')
963 last = flag + strlen (flag);
970 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
977 /* First we turn on everything except for cpu64. */
978 for (i = 0; i < ARRAY_SIZE (flags); i++)
979 if (flags[i].position != Cpu64)
982 /* Turn off selective bits. */
983 for (; next && next < last; )
985 str = next_field (next, '|', &next, last);
987 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
990 else if (strcmp (flag, "0"))
992 /* Turn on selective bits. */
993 last = flag + strlen (flag);
994 for (next = flag; next && next < last; )
996 str = next_field (next, '|', &next, last);
998 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1002 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1007 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1011 fprintf (table, " { ");
1013 for (i = 0; i < size - 1; i++)
1015 if (((i + 1) % 20) != 0)
1016 fprintf (table, "%d, ", modifier[i].value);
1018 fprintf (table, "%d,", modifier[i].value);
1019 if (((i + 1) % 20) == 0)
1020 fprintf (table, "\n ");
1023 fprintf (table, "%d },\n", modifier[i].value);
1027 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
1029 char *str, *next, *last;
1030 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1032 active_isstring = 0;
1034 /* Copy the default opcode modifier. */
1035 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1037 if (strcmp (mod, "0"))
1039 last = mod + strlen (mod);
1040 for (next = mod; next && next < last; )
1042 str = next_field (next, '|', &next, last);
1045 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
1047 if (strcasecmp(str, "IsString") == 0)
1048 active_isstring = 1;
1052 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1062 output_operand_type (FILE *table, bitfield *types, unsigned int size,
1063 enum stage stage, const char *indent)
1067 fprintf (table, "{ { ");
1069 for (i = 0; i < size - 1; i++)
1071 if (((i + 1) % 20) != 0)
1072 fprintf (table, "%d, ", types[i].value);
1074 fprintf (table, "%d,", types[i].value);
1075 if (((i + 1) % 20) == 0)
1077 /* We need \\ for macro. */
1078 if (stage == stage_macros)
1079 fprintf (table, " \\\n%s", indent);
1081 fprintf (table, "\n%s", indent);
1085 fprintf (table, "%d } }", types[i].value);
1089 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1090 const char *indent, int lineno)
1092 char *str, *next, *last;
1093 bitfield types [ARRAY_SIZE (operand_types)];
1095 /* Copy the default operand type. */
1096 memcpy (types, operand_types, sizeof (types));
1098 if (strcmp (op, "0"))
1102 last = op + strlen (op);
1103 for (next = op; next && next < last; )
1105 str = next_field (next, '|', &next, last);
1108 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1109 if (strcasecmp(str, "BaseIndex") == 0)
1114 if (stage == stage_opcodes && baseindex && !active_isstring)
1116 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1117 if (!active_cpu_flags.bitfield.cpu64
1118 && !active_cpu_flags.bitfield.cpumpx)
1119 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1120 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1121 if (!active_cpu_flags.bitfield.cpuno64)
1122 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1125 output_operand_type (table, types, ARRAY_SIZE (types), stage,
1130 output_i386_opcode (FILE *table, const char *name, char *str,
1131 char *last, int lineno)
1134 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1135 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1137 /* Find number of operands. */
1138 operands = next_field (str, ',', &str, last);
1140 /* Find base_opcode. */
1141 base_opcode = next_field (str, ',', &str, last);
1143 /* Find extension_opcode. */
1144 extension_opcode = next_field (str, ',', &str, last);
1146 /* Find opcode_length. */
1147 opcode_length = next_field (str, ',', &str, last);
1149 /* Find cpu_flags. */
1150 cpu_flags = next_field (str, ',', &str, last);
1152 /* Find opcode_modifier. */
1153 opcode_modifier = next_field (str, ',', &str, last);
1155 /* Remove the first {. */
1156 str = remove_leading_whitespaces (str);
1159 str = remove_leading_whitespaces (str + 1);
1163 /* There are at least "X}". */
1167 /* Remove trailing white spaces and }. */
1171 if (ISSPACE (str[i]) || str[i] == '}')
1180 /* Find operand_types. */
1181 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1185 operand_types [i] = NULL;
1189 operand_types [i] = next_field (str, ',', &str, last);
1190 if (*operand_types[i] == '0')
1193 operand_types[i] = NULL;
1198 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1199 name, operands, base_opcode, extension_opcode,
1202 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1204 process_i386_opcode_modifier (table, opcode_modifier, lineno);
1206 fprintf (table, " { ");
1208 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1210 if (operand_types[i] == NULL || *operand_types[i] == '0')
1213 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1219 fprintf (table, ",\n ");
1221 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1224 fprintf (table, " } },\n");
1227 struct opcode_hash_entry
1229 struct opcode_hash_entry *next;
1235 /* Calculate the hash value of an opcode hash entry P. */
1238 opcode_hash_hash (const void *p)
1240 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1241 return htab_hash_string (entry->name);
1244 /* Compare a string Q against an opcode hash entry P. */
1247 opcode_hash_eq (const void *p, const void *q)
1249 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1250 const char *name = (const char *) q;
1251 return strcmp (name, entry->name) == 0;
1255 process_i386_opcodes (FILE *table)
1260 char *str, *p, *last, *name;
1261 struct opcode_hash_entry **hash_slot, **entry, *next;
1262 htab_t opcode_hash_table;
1263 struct opcode_hash_entry **opcode_array;
1264 unsigned int opcode_array_size = 1024;
1265 int lineno = 0, marker = 0;
1267 filename = "i386-opc.tbl";
1271 opcode_array = (struct opcode_hash_entry **)
1272 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1274 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1275 opcode_hash_eq, NULL,
1278 fprintf (table, "\n/* i386 opcode table. */\n\n");
1279 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1281 /* Put everything on opcode array. */
1284 if (fgets (buf, sizeof (buf), fp) == NULL)
1289 p = remove_leading_whitespaces (buf);
1291 /* Skip comments. */
1292 str = strstr (p, "//");
1296 /* Remove trailing white spaces. */
1297 remove_trailing_whitespaces (p);
1302 if (!strcmp("### MARKER ###", buf))
1306 /* Since we ignore all included files (we only care about their
1307 #define-s here), we don't need to monitor filenames. The final
1308 line number directive is going to refer to the main source file
1313 p = remove_leading_whitespaces (p + 1);
1314 if (!strncmp(p, "line", 4))
1316 ln = strtoul (p, &end, 10);
1317 if (ln > 1 && ln < INT_MAX
1318 && *remove_leading_whitespaces (end) == '"')
1321 /* Ignore comments. */
1331 last = p + strlen (p);
1334 name = next_field (p, ',', &str, last);
1336 /* Get the slot in hash table. */
1337 hash_slot = (struct opcode_hash_entry **)
1338 htab_find_slot_with_hash (opcode_hash_table, name,
1339 htab_hash_string (name),
1342 if (*hash_slot == NULL)
1344 /* It is the new one. Put it on opcode array. */
1345 if (i >= opcode_array_size)
1347 /* Grow the opcode array when needed. */
1348 opcode_array_size += 1024;
1349 opcode_array = (struct opcode_hash_entry **)
1350 xrealloc (opcode_array,
1351 sizeof (*opcode_array) * opcode_array_size);
1354 opcode_array[i] = (struct opcode_hash_entry *)
1355 xmalloc (sizeof (struct opcode_hash_entry));
1356 opcode_array[i]->next = NULL;
1357 opcode_array[i]->name = xstrdup (name);
1358 opcode_array[i]->opcode = xstrdup (str);
1359 opcode_array[i]->lineno = lineno;
1360 *hash_slot = opcode_array[i];
1365 /* Append it to the existing one. */
1367 while ((*entry) != NULL)
1368 entry = &(*entry)->next;
1369 *entry = (struct opcode_hash_entry *)
1370 xmalloc (sizeof (struct opcode_hash_entry));
1371 (*entry)->next = NULL;
1372 (*entry)->name = (*hash_slot)->name;
1373 (*entry)->opcode = xstrdup (str);
1374 (*entry)->lineno = lineno;
1378 /* Process opcode array. */
1379 for (j = 0; j < i; j++)
1381 for (next = opcode_array[j]; next; next = next->next)
1385 lineno = next->lineno;
1386 last = str + strlen (str);
1387 output_i386_opcode (table, name, str, last, lineno);
1393 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1395 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1397 process_i386_opcode_modifier (table, "0", -1);
1399 fprintf (table, " { ");
1400 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1401 fprintf (table, " } }\n");
1403 fprintf (table, "};\n");
1407 process_i386_registers (FILE *table)
1411 char *str, *p, *last;
1412 char *reg_name, *reg_type, *reg_flags, *reg_num;
1413 char *dw2_32_num, *dw2_64_num;
1416 filename = "i386-reg.tbl";
1417 fp = fopen (filename, "r");
1419 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1422 fprintf (table, "\n/* i386 register table. */\n\n");
1423 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1427 if (fgets (buf, sizeof (buf), fp) == NULL)
1432 p = remove_leading_whitespaces (buf);
1434 /* Skip comments. */
1435 str = strstr (p, "//");
1439 /* Remove trailing white spaces. */
1440 remove_trailing_whitespaces (p);
1445 fprintf (table, "%s\n", p);
1453 last = p + strlen (p);
1455 /* Find reg_name. */
1456 reg_name = next_field (p, ',', &str, last);
1458 /* Find reg_type. */
1459 reg_type = next_field (str, ',', &str, last);
1461 /* Find reg_flags. */
1462 reg_flags = next_field (str, ',', &str, last);
1465 reg_num = next_field (str, ',', &str, last);
1467 fprintf (table, " { \"%s\",\n ", reg_name);
1469 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1472 /* Find 32-bit Dwarf2 register number. */
1473 dw2_32_num = next_field (str, ',', &str, last);
1475 /* Find 64-bit Dwarf2 register number. */
1476 dw2_64_num = next_field (str, ',', &str, last);
1478 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1479 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1484 fprintf (table, "};\n");
1486 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1490 process_i386_initializers (void)
1493 FILE *fp = fopen ("i386-init.h", "w");
1497 fail (_("can't create i386-init.h, errno = %s\n"),
1500 process_copyright (fp);
1502 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1504 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1505 init = xstrdup (cpu_flag_init[i].init);
1506 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1510 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1512 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1513 init = xstrdup (operand_type_init[i].init);
1514 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1522 /* Program options. */
1523 #define OPTION_SRCDIR 200
1525 struct option long_options[] =
1527 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1528 {"debug", no_argument, NULL, 'd'},
1529 {"version", no_argument, NULL, 'V'},
1530 {"help", no_argument, NULL, 'h'},
1531 {0, no_argument, NULL, 0}
1535 print_version (void)
1537 printf ("%s: version 1.0\n", program_name);
1542 usage (FILE * stream, int status)
1544 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1550 main (int argc, char **argv)
1552 extern int chdir (char *);
1553 char *srcdir = NULL;
1555 unsigned int i, cpumax;
1558 program_name = *argv;
1559 xmalloc_set_program_name (program_name);
1561 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1586 if (chdir (srcdir) != 0)
1587 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1588 srcdir, xstrerror (errno));
1590 /* cpu_flags isn't sorted by position. */
1592 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1593 if (cpu_flags[i].position > cpumax)
1594 cpumax = cpu_flags[i].position;
1596 /* Check the unused bitfield in i386_cpu_flags. */
1598 if ((cpumax - 1) != CpuMax)
1599 fail (_("CpuMax != %d!\n"), cpumax);
1601 if (cpumax != CpuMax)
1602 fail (_("CpuMax != %d!\n"), cpumax);
1604 c = CpuNumOfBits - CpuMax - 1;
1606 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1609 /* Check the unused bitfield in i386_operand_type. */
1611 c = OTNumOfBits - OTMax - 1;
1613 fail (_("%d unused bits in i386_operand_type.\n"), c);
1616 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1619 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1620 sizeof (opcode_modifiers [0]), compare);
1622 qsort (operand_types, ARRAY_SIZE (operand_types),
1623 sizeof (operand_types [0]), compare);
1625 table = fopen ("i386-tbl.h", "w");
1627 fail (_("can't create i386-tbl.h, errno = %s\n"),
1630 process_copyright (table);
1632 process_i386_opcodes (table);
1633 process_i386_registers (table);
1634 process_i386_initializers ();