1 /* Copyright (C) 2007-2019 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|CpuCMOV|CpuFXSR" },
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" },
118 { "CPU_CLFLUSH_FLAGS",
122 { "CPU_SYSCALL_FLAGS",
129 "CPU_SSE_FLAGS|CpuSSE2" },
131 "CPU_SSE2_FLAGS|CpuSSE3" },
133 "CPU_SSE3_FLAGS|CpuSSSE3" },
134 { "CPU_SSE4_1_FLAGS",
135 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
136 { "CPU_SSE4_2_FLAGS",
137 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
144 { "CPU_XSAVEOPT_FLAGS",
145 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
147 "CPU_SSE2_FLAGS|CpuAES" },
148 { "CPU_PCLMUL_FLAGS",
149 "CPU_SSE2_FLAGS|CpuPCLMUL" },
151 "CPU_AVX_FLAGS|CpuFMA" },
153 "CPU_AVX_FLAGS|CpuFMA4" },
155 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
157 "CPU_XSAVE_FLAGS|CpuLWP" },
166 { "CPU_RDTSCP_FLAGS",
170 { "CPU_FSGSBASE_FLAGS",
175 "CPU_AVX_FLAGS|CpuF16C" },
184 { "CPU_INVPCID_FLAGS",
186 { "CPU_VMFUNC_FLAGS",
189 "CPU_MMX_FLAGS|Cpu3dnow" },
190 { "CPU_3DNOWA_FLAGS",
191 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
192 { "CPU_PADLOCK_FLAGS",
197 "CPU_SSE3_FLAGS|CpuSSE4a" },
201 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
203 "CPU_AVX_FLAGS|CpuAVX2" },
204 { "CPU_AVX512F_FLAGS",
205 "CPU_AVX2_FLAGS|CpuAVX512F" },
206 { "CPU_AVX512CD_FLAGS",
207 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
208 { "CPU_AVX512ER_FLAGS",
209 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
210 { "CPU_AVX512PF_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
212 { "CPU_AVX512DQ_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
214 { "CPU_AVX512BW_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
216 { "CPU_AVX512VL_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
218 { "CPU_AVX512IFMA_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
220 { "CPU_AVX512VBMI_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
222 { "CPU_AVX512_4FMAPS_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
224 { "CPU_AVX512_4VNNIW_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
226 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
228 { "CPU_AVX512_VBMI2_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
230 { "CPU_AVX512_VNNI_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
232 { "CPU_AVX512_BITALG_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
234 { "CPU_AVX512_BF16_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
241 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
244 { "CPU_RDSEED_FLAGS",
246 { "CPU_PRFCHW_FLAGS",
251 "CPU_XSAVE_FLAGS|CpuMPX" },
253 "CPU_SSE2_FLAGS|CpuSHA" },
254 { "CPU_CLFLUSHOPT_FLAGS",
256 { "CPU_XSAVES_FLAGS",
257 "CPU_XSAVE_FLAGS|CpuXSAVES" },
258 { "CPU_XSAVEC_FLAGS",
259 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
260 { "CPU_PREFETCHWT1_FLAGS",
266 { "CPU_CLZERO_FLAGS",
268 { "CPU_MWAITX_FLAGS",
271 "CPU_XSAVE_FLAGS|CpuOSPKE" },
274 { "CPU_PTWRITE_FLAGS",
284 { "CPU_VPCLMULQDQ_FLAGS",
286 { "CPU_WBNOINVD_FLAGS",
288 { "CPU_PCONFIG_FLAGS",
290 { "CPU_WAITPKG_FLAGS",
292 { "CPU_CLDEMOTE_FLAGS",
294 { "CPU_MOVDIRI_FLAGS",
296 { "CPU_MOVDIR64B_FLAGS",
298 { "CPU_ENQCMD_FLAGS",
300 { "CPU_AVX512_VP2INTERSECT_FLAGS",
301 "CpuAVX512_VP2INTERSECT" },
302 { "CPU_ANY_X87_FLAGS",
303 "CPU_ANY_287_FLAGS|Cpu8087" },
304 { "CPU_ANY_287_FLAGS",
305 "CPU_ANY_387_FLAGS|Cpu287" },
306 { "CPU_ANY_387_FLAGS",
307 "CPU_ANY_687_FLAGS|Cpu387" },
308 { "CPU_ANY_687_FLAGS",
309 "Cpu687|CpuFISTTP" },
310 { "CPU_ANY_CMOV_FLAGS",
312 { "CPU_ANY_FXSR_FLAGS",
314 { "CPU_ANY_MMX_FLAGS",
315 "CPU_3DNOWA_FLAGS" },
316 { "CPU_ANY_SSE_FLAGS",
317 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
318 { "CPU_ANY_SSE2_FLAGS",
319 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
320 { "CPU_ANY_SSE3_FLAGS",
321 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
322 { "CPU_ANY_SSSE3_FLAGS",
323 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
324 { "CPU_ANY_SSE4_1_FLAGS",
325 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
326 { "CPU_ANY_SSE4_2_FLAGS",
328 { "CPU_ANY_AVX_FLAGS",
329 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
330 { "CPU_ANY_AVX2_FLAGS",
331 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
332 { "CPU_ANY_AVX512F_FLAGS",
333 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
334 { "CPU_ANY_AVX512CD_FLAGS",
336 { "CPU_ANY_AVX512ER_FLAGS",
338 { "CPU_ANY_AVX512PF_FLAGS",
340 { "CPU_ANY_AVX512DQ_FLAGS",
342 { "CPU_ANY_AVX512BW_FLAGS",
344 { "CPU_ANY_AVX512VL_FLAGS",
346 { "CPU_ANY_AVX512IFMA_FLAGS",
348 { "CPU_ANY_AVX512VBMI_FLAGS",
350 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
351 "CpuAVX512_4FMAPS" },
352 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
353 "CpuAVX512_4VNNIW" },
354 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
355 "CpuAVX512_VPOPCNTDQ" },
356 { "CPU_ANY_IBT_FLAGS",
358 { "CPU_ANY_SHSTK_FLAGS",
360 { "CPU_ANY_AVX512_VBMI2_FLAGS",
362 { "CPU_ANY_AVX512_VNNI_FLAGS",
364 { "CPU_ANY_AVX512_BITALG_FLAGS",
365 "CpuAVX512_BITALG" },
366 { "CPU_ANY_AVX512_BF16_FLAGS",
368 { "CPU_ANY_MOVDIRI_FLAGS",
370 { "CPU_ANY_MOVDIR64B_FLAGS",
372 { "CPU_ANY_ENQCMD_FLAGS",
374 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
375 "CpuAVX512_VP2INTERSECT" },
378 static const initializer operand_type_shorthands[] =
380 { "Reg8", "Reg|Byte" },
381 { "Reg16", "Reg|Word" },
382 { "Reg32", "Reg|Dword" },
383 { "Reg64", "Reg|Qword" },
384 { "FloatAcc", "Acc|Tbyte" },
385 { "FloatReg", "Reg|Tbyte" },
386 { "RegXMM", "RegSIMD|Xmmword" },
387 { "RegYMM", "RegSIMD|Ymmword" },
388 { "RegZMM", "RegSIMD|Zmmword" },
391 static initializer operand_type_init[] =
393 { "OPERAND_TYPE_NONE",
395 { "OPERAND_TYPE_REG8",
397 { "OPERAND_TYPE_REG16",
399 { "OPERAND_TYPE_REG32",
401 { "OPERAND_TYPE_REG64",
403 { "OPERAND_TYPE_IMM1",
405 { "OPERAND_TYPE_IMM8",
407 { "OPERAND_TYPE_IMM8S",
409 { "OPERAND_TYPE_IMM16",
411 { "OPERAND_TYPE_IMM32",
413 { "OPERAND_TYPE_IMM32S",
415 { "OPERAND_TYPE_IMM64",
417 { "OPERAND_TYPE_BASEINDEX",
419 { "OPERAND_TYPE_DISP8",
421 { "OPERAND_TYPE_DISP16",
423 { "OPERAND_TYPE_DISP32",
425 { "OPERAND_TYPE_DISP32S",
427 { "OPERAND_TYPE_DISP64",
429 { "OPERAND_TYPE_INOUTPORTREG",
431 { "OPERAND_TYPE_SHIFTCOUNT",
433 { "OPERAND_TYPE_CONTROL",
435 { "OPERAND_TYPE_TEST",
437 { "OPERAND_TYPE_DEBUG",
439 { "OPERAND_TYPE_FLOATREG",
441 { "OPERAND_TYPE_FLOATACC",
443 { "OPERAND_TYPE_SREG2",
445 { "OPERAND_TYPE_SREG3",
447 { "OPERAND_TYPE_JUMPABSOLUTE",
449 { "OPERAND_TYPE_REGMMX",
451 { "OPERAND_TYPE_REGXMM",
453 { "OPERAND_TYPE_REGYMM",
455 { "OPERAND_TYPE_REGZMM",
457 { "OPERAND_TYPE_REGMASK",
459 { "OPERAND_TYPE_ESSEG",
461 { "OPERAND_TYPE_ACC8",
463 { "OPERAND_TYPE_ACC16",
465 { "OPERAND_TYPE_ACC32",
467 { "OPERAND_TYPE_ACC64",
469 { "OPERAND_TYPE_DISP16_32",
471 { "OPERAND_TYPE_ANYDISP",
472 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
473 { "OPERAND_TYPE_IMM16_32",
475 { "OPERAND_TYPE_IMM16_32S",
477 { "OPERAND_TYPE_IMM16_32_32S",
478 "Imm16|Imm32|Imm32S" },
479 { "OPERAND_TYPE_IMM32_64",
481 { "OPERAND_TYPE_IMM32_32S_DISP32",
482 "Imm32|Imm32S|Disp32" },
483 { "OPERAND_TYPE_IMM64_DISP64",
485 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
486 "Imm32|Imm32S|Imm64|Disp32" },
487 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
488 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
489 { "OPERAND_TYPE_VEC_IMM4",
491 { "OPERAND_TYPE_REGBND",
495 typedef struct bitfield
502 #define BITFIELD(n) { n, 0, #n }
504 static bitfield cpu_flags[] =
514 BITFIELD (CpuClflush),
516 BITFIELD (CpuSYSCALL),
521 BITFIELD (CpuFISTTP),
527 BITFIELD (CpuSSE4_1),
528 BITFIELD (CpuSSE4_2),
531 BITFIELD (CpuAVX512F),
532 BITFIELD (CpuAVX512CD),
533 BITFIELD (CpuAVX512ER),
534 BITFIELD (CpuAVX512PF),
535 BITFIELD (CpuAVX512VL),
536 BITFIELD (CpuAVX512DQ),
537 BITFIELD (CpuAVX512BW),
543 BITFIELD (Cpu3dnowA),
544 BITFIELD (CpuPadLock),
550 BITFIELD (CpuXsaveopt),
552 BITFIELD (CpuPCLMUL),
563 BITFIELD (CpuRdtscp),
564 BITFIELD (CpuFSGSBase),
571 BITFIELD (CpuINVPCID),
572 BITFIELD (CpuVMFUNC),
573 BITFIELD (CpuRDSEED),
575 BITFIELD (CpuPRFCHW),
578 BITFIELD (CpuClflushOpt),
579 BITFIELD (CpuXSAVES),
580 BITFIELD (CpuXSAVEC),
581 BITFIELD (CpuPREFETCHWT1),
587 BITFIELD (CpuAVX512IFMA),
588 BITFIELD (CpuAVX512VBMI),
589 BITFIELD (CpuAVX512_4FMAPS),
590 BITFIELD (CpuAVX512_4VNNIW),
591 BITFIELD (CpuAVX512_VPOPCNTDQ),
592 BITFIELD (CpuAVX512_VBMI2),
593 BITFIELD (CpuAVX512_VNNI),
594 BITFIELD (CpuAVX512_BITALG),
595 BITFIELD (CpuAVX512_BF16),
596 BITFIELD (CpuAVX512_VP2INTERSECT),
597 BITFIELD (CpuMWAITX),
598 BITFIELD (CpuCLZERO),
601 BITFIELD (CpuPTWRITE),
606 BITFIELD (CpuVPCLMULQDQ),
607 BITFIELD (CpuWBNOINVD),
608 BITFIELD (CpuPCONFIG),
609 BITFIELD (CpuWAITPKG),
610 BITFIELD (CpuCLDEMOTE),
611 BITFIELD (CpuMOVDIRI),
612 BITFIELD (CpuMOVDIR64B),
613 BITFIELD (CpuENQCMD),
615 BITFIELD (CpuUnused),
619 static bitfield opcode_modifiers[] =
625 BITFIELD (ShortForm),
627 BITFIELD (JumpDword),
629 BITFIELD (JumpInterSegment),
633 BITFIELD (CheckRegSize),
634 BITFIELD (IgnoreSize),
635 BITFIELD (DefaultSize),
644 BITFIELD (BNDPrefixOk),
645 BITFIELD (NoTrackPrefixOk),
646 BITFIELD (IsLockable),
647 BITFIELD (RegKludge),
648 BITFIELD (Implicit1stXmm0),
649 BITFIELD (RepPrefixOk),
650 BITFIELD (HLEPrefixOk),
653 BITFIELD (AddrPrefixOpReg),
662 BITFIELD (VexOpcode),
663 BITFIELD (VexSources),
669 BITFIELD (Broadcast),
670 BITFIELD (StaticRounding),
672 BITFIELD (Disp8MemShift),
673 BITFIELD (NoDefMask),
674 BITFIELD (ImplicitQuadGroup),
676 BITFIELD (ATTMnemonic),
677 BITFIELD (ATTSyntax),
678 BITFIELD (IntelSyntax),
683 static bitfield operand_types[] =
696 BITFIELD (BaseIndex),
702 BITFIELD (InOutPortReg),
703 BITFIELD (ShiftCount),
710 BITFIELD (JumpAbsolute),
722 BITFIELD (Unspecified),
731 static const char *filename;
732 static i386_cpu_flags active_cpu_flags;
733 static int active_isstring;
736 compare (const void *x, const void *y)
738 const bitfield *xp = (const bitfield *) x;
739 const bitfield *yp = (const bitfield *) y;
740 return xp->position - yp->position;
744 fail (const char *message, ...)
748 va_start (args, message);
749 fprintf (stderr, _("%s: error: "), program_name);
750 vfprintf (stderr, message, args);
756 process_copyright (FILE *fp)
758 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
759 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
761 This file is part of the GNU opcodes library.\n\
763 This library is free software; you can redistribute it and/or modify\n\
764 it under the terms of the GNU General Public License as published by\n\
765 the Free Software Foundation; either version 3, or (at your option)\n\
766 any later version.\n\
768 It is distributed in the hope that it will be useful, but WITHOUT\n\
769 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
770 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
771 License for more details.\n\
773 You should have received a copy of the GNU General Public License\n\
774 along with this program; if not, write to the Free Software\n\
775 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
776 MA 02110-1301, USA. */\n");
779 /* Remove leading white spaces. */
782 remove_leading_whitespaces (char *str)
784 while (ISSPACE (*str))
789 /* Remove trailing white spaces. */
792 remove_trailing_whitespaces (char *str)
794 size_t last = strlen (str);
802 if (ISSPACE (str [last]))
810 /* Find next field separated by SEP and terminate it. Return a
811 pointer to the one after it. */
814 next_field (char *str, char sep, char **next, char *last)
818 p = remove_leading_whitespaces (str);
819 for (str = p; *str != sep && *str != '\0'; str++);
822 remove_trailing_whitespaces (p);
832 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
835 set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
838 char *str, *next, *last;
841 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
842 if (strcmp (cpu_flag_init[i].name, f) == 0)
844 /* Turn on selective bits. */
845 char *init = xstrdup (cpu_flag_init[i].init);
846 last = init + strlen (init);
847 for (next = init; next && next < last; )
849 str = next_field (next, '|', &next, last);
851 set_bitfield (str, array, 1, size, lineno);
857 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
858 if (strcmp (operand_type_shorthands[i].name, f) == 0)
860 /* Turn on selective bits. */
861 char *init = xstrdup (operand_type_shorthands[i].init);
862 last = init + strlen (init);
863 for (next = init; next && next < last; )
865 str = next_field (next, '|', &next, last);
867 set_bitfield (str, array, 1, size, lineno);
877 set_bitfield (char *f, bitfield *array, int value,
878 unsigned int size, int lineno)
882 if (strcmp (f, "CpuFP") == 0)
884 set_bitfield("Cpu387", array, value, size, lineno);
885 set_bitfield("Cpu287", array, value, size, lineno);
888 else if (strcmp (f, "Mmword") == 0)
890 else if (strcmp (f, "Oword") == 0)
893 for (i = 0; i < size; i++)
894 if (strcasecmp (array[i].name, f) == 0)
896 array[i].value = value;
902 const char *v = strchr (f, '=');
909 for (i = 0; i < size; i++)
910 if (strncasecmp (array[i].name, f, n) == 0)
912 value = strtol (v + 1, &end, 0);
915 array[i].value = value;
923 /* Handle shorthands. */
924 if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno))
928 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
930 fail (_("unknown bitfield: %s\n"), f);
934 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
935 int macro, const char *comma, const char *indent)
939 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
941 fprintf (table, "%s{ { ", indent);
943 for (i = 0; i < size - 1; i++)
945 if (((i + 1) % 20) != 0)
946 fprintf (table, "%d, ", flags[i].value);
948 fprintf (table, "%d,", flags[i].value);
949 if (((i + 1) % 20) == 0)
951 /* We need \\ for macro. */
953 fprintf (table, " \\\n %s", indent);
955 fprintf (table, "\n %s", indent);
958 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
961 fprintf (table, "%d } }%s\n", flags[i].value, comma);
965 process_i386_cpu_flag (FILE *table, char *flag, int macro,
966 const char *comma, const char *indent,
969 char *str, *next, *last;
971 bitfield flags [ARRAY_SIZE (cpu_flags)];
973 /* Copy the default cpu flags. */
974 memcpy (flags, cpu_flags, sizeof (cpu_flags));
976 if (strcasecmp (flag, "unknown") == 0)
978 /* We turn on everything except for cpu64 in case of
979 CPU_UNKNOWN_FLAGS. */
980 for (i = 0; i < ARRAY_SIZE (flags); i++)
981 if (flags[i].position != Cpu64)
984 else if (flag[0] == '~')
986 last = flag + strlen (flag);
993 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
1000 /* First we turn on everything except for cpu64. */
1001 for (i = 0; i < ARRAY_SIZE (flags); i++)
1002 if (flags[i].position != Cpu64)
1005 /* Turn off selective bits. */
1006 for (; next && next < last; )
1008 str = next_field (next, '|', &next, last);
1010 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1013 else if (strcmp (flag, "0"))
1015 /* Turn on selective bits. */
1016 last = flag + strlen (flag);
1017 for (next = flag; next && next < last; )
1019 str = next_field (next, '|', &next, last);
1021 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1025 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1030 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1034 fprintf (table, " { ");
1036 for (i = 0; i < size - 1; i++)
1038 if (((i + 1) % 20) != 0)
1039 fprintf (table, "%d, ", modifier[i].value);
1041 fprintf (table, "%d,", modifier[i].value);
1042 if (((i + 1) % 20) == 0)
1043 fprintf (table, "\n ");
1046 fprintf (table, "%d },\n", modifier[i].value);
1050 adjust_broadcast_modifier (char **opnd)
1052 char *str, *next, *last, *op;
1053 int bcst_type = INT_MAX;
1055 /* Skip the immediate operand. */
1057 if (strcasecmp(op, "Imm8") == 0)
1061 last = op + strlen (op);
1062 for (next = op; next && next < last; )
1064 str = next_field (next, '|', &next, last);
1067 if (strcasecmp(str, "Byte") == 0)
1069 /* The smalest broadcast type, no need to check
1071 bcst_type = BYTE_BROADCAST;
1074 else if (strcasecmp(str, "Word") == 0)
1076 if (bcst_type > WORD_BROADCAST)
1077 bcst_type = WORD_BROADCAST;
1079 else if (strcasecmp(str, "Dword") == 0)
1081 if (bcst_type > DWORD_BROADCAST)
1082 bcst_type = DWORD_BROADCAST;
1084 else if (strcasecmp(str, "Qword") == 0)
1086 if (bcst_type > QWORD_BROADCAST)
1087 bcst_type = QWORD_BROADCAST;
1093 if (bcst_type == INT_MAX)
1094 fail (_("unknown broadcast operand: %s\n"), op);
1100 process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
1102 char *str, *next, *last;
1103 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1105 active_isstring = 0;
1107 /* Copy the default opcode modifier. */
1108 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1110 if (strcmp (mod, "0"))
1112 last = mod + strlen (mod);
1113 for (next = mod; next && next < last; )
1115 str = next_field (next, '|', &next, last);
1119 if (strcasecmp(str, "Broadcast") == 0)
1120 val = adjust_broadcast_modifier (opnd);
1121 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1123 if (strcasecmp(str, "IsString") == 0)
1124 active_isstring = 1;
1128 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1138 output_operand_type (FILE *table, bitfield *types, unsigned int size,
1139 enum stage stage, const char *indent)
1143 fprintf (table, "{ { ");
1145 for (i = 0; i < size - 1; i++)
1147 if (((i + 1) % 20) != 0)
1148 fprintf (table, "%d, ", types[i].value);
1150 fprintf (table, "%d,", types[i].value);
1151 if (((i + 1) % 20) == 0)
1153 /* We need \\ for macro. */
1154 if (stage == stage_macros)
1155 fprintf (table, " \\\n%s", indent);
1157 fprintf (table, "\n%s", indent);
1161 fprintf (table, "%d } }", types[i].value);
1165 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1166 const char *indent, int lineno)
1168 char *str, *next, *last;
1169 bitfield types [ARRAY_SIZE (operand_types)];
1171 /* Copy the default operand type. */
1172 memcpy (types, operand_types, sizeof (types));
1174 if (strcmp (op, "0"))
1178 last = op + strlen (op);
1179 for (next = op; next && next < last; )
1181 str = next_field (next, '|', &next, last);
1184 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1185 if (strcasecmp(str, "BaseIndex") == 0)
1190 if (stage == stage_opcodes && baseindex && !active_isstring)
1192 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1193 if (!active_cpu_flags.bitfield.cpu64
1194 && !active_cpu_flags.bitfield.cpumpx)
1195 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1196 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1197 if (!active_cpu_flags.bitfield.cpuno64)
1198 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1201 output_operand_type (table, types, ARRAY_SIZE (types), stage,
1206 output_i386_opcode (FILE *table, const char *name, char *str,
1207 char *last, int lineno)
1210 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1211 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1213 /* Find number of operands. */
1214 operands = next_field (str, ',', &str, last);
1216 /* Find base_opcode. */
1217 base_opcode = next_field (str, ',', &str, last);
1219 /* Find extension_opcode. */
1220 extension_opcode = next_field (str, ',', &str, last);
1222 /* Find opcode_length. */
1223 opcode_length = next_field (str, ',', &str, last);
1225 /* Find cpu_flags. */
1226 cpu_flags = next_field (str, ',', &str, last);
1228 /* Find opcode_modifier. */
1229 opcode_modifier = next_field (str, ',', &str, last);
1231 /* Remove the first {. */
1232 str = remove_leading_whitespaces (str);
1235 str = remove_leading_whitespaces (str + 1);
1239 /* There are at least "X}". */
1243 /* Remove trailing white spaces and }. */
1247 if (ISSPACE (str[i]) || str[i] == '}')
1256 /* Find operand_types. */
1257 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1261 operand_types [i] = NULL;
1265 operand_types [i] = next_field (str, ',', &str, last);
1266 if (*operand_types[i] == '0')
1269 operand_types[i] = NULL;
1274 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1275 name, operands, base_opcode, extension_opcode,
1278 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1280 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
1282 fprintf (table, " { ");
1284 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1286 if (operand_types[i] == NULL || *operand_types[i] == '0')
1289 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1295 fprintf (table, ",\n ");
1297 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1300 fprintf (table, " } },\n");
1303 struct opcode_hash_entry
1305 struct opcode_hash_entry *next;
1311 /* Calculate the hash value of an opcode hash entry P. */
1314 opcode_hash_hash (const void *p)
1316 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1317 return htab_hash_string (entry->name);
1320 /* Compare a string Q against an opcode hash entry P. */
1323 opcode_hash_eq (const void *p, const void *q)
1325 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1326 const char *name = (const char *) q;
1327 return strcmp (name, entry->name) == 0;
1331 process_i386_opcodes (FILE *table)
1336 char *str, *p, *last, *name;
1337 struct opcode_hash_entry **hash_slot, **entry, *next;
1338 htab_t opcode_hash_table;
1339 struct opcode_hash_entry **opcode_array;
1340 unsigned int opcode_array_size = 1024;
1341 int lineno = 0, marker = 0;
1343 filename = "i386-opc.tbl";
1347 opcode_array = (struct opcode_hash_entry **)
1348 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1350 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1351 opcode_hash_eq, NULL,
1354 fprintf (table, "\n/* i386 opcode table. */\n\n");
1355 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1357 /* Put everything on opcode array. */
1360 if (fgets (buf, sizeof (buf), fp) == NULL)
1365 p = remove_leading_whitespaces (buf);
1367 /* Skip comments. */
1368 str = strstr (p, "//");
1372 /* Remove trailing white spaces. */
1373 remove_trailing_whitespaces (p);
1378 if (!strcmp("### MARKER ###", buf))
1382 /* Since we ignore all included files (we only care about their
1383 #define-s here), we don't need to monitor filenames. The final
1384 line number directive is going to refer to the main source file
1389 p = remove_leading_whitespaces (p + 1);
1390 if (!strncmp(p, "line", 4))
1392 ln = strtoul (p, &end, 10);
1393 if (ln > 1 && ln < INT_MAX
1394 && *remove_leading_whitespaces (end) == '"')
1397 /* Ignore comments. */
1407 last = p + strlen (p);
1410 name = next_field (p, ',', &str, last);
1412 /* Get the slot in hash table. */
1413 hash_slot = (struct opcode_hash_entry **)
1414 htab_find_slot_with_hash (opcode_hash_table, name,
1415 htab_hash_string (name),
1418 if (*hash_slot == NULL)
1420 /* It is the new one. Put it on opcode array. */
1421 if (i >= opcode_array_size)
1423 /* Grow the opcode array when needed. */
1424 opcode_array_size += 1024;
1425 opcode_array = (struct opcode_hash_entry **)
1426 xrealloc (opcode_array,
1427 sizeof (*opcode_array) * opcode_array_size);
1430 opcode_array[i] = (struct opcode_hash_entry *)
1431 xmalloc (sizeof (struct opcode_hash_entry));
1432 opcode_array[i]->next = NULL;
1433 opcode_array[i]->name = xstrdup (name);
1434 opcode_array[i]->opcode = xstrdup (str);
1435 opcode_array[i]->lineno = lineno;
1436 *hash_slot = opcode_array[i];
1441 /* Append it to the existing one. */
1443 while ((*entry) != NULL)
1444 entry = &(*entry)->next;
1445 *entry = (struct opcode_hash_entry *)
1446 xmalloc (sizeof (struct opcode_hash_entry));
1447 (*entry)->next = NULL;
1448 (*entry)->name = (*hash_slot)->name;
1449 (*entry)->opcode = xstrdup (str);
1450 (*entry)->lineno = lineno;
1454 /* Process opcode array. */
1455 for (j = 0; j < i; j++)
1457 for (next = opcode_array[j]; next; next = next->next)
1461 lineno = next->lineno;
1462 last = str + strlen (str);
1463 output_i386_opcode (table, name, str, last, lineno);
1469 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1471 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1473 process_i386_opcode_modifier (table, "0", NULL, -1);
1475 fprintf (table, " { ");
1476 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1477 fprintf (table, " } }\n");
1479 fprintf (table, "};\n");
1483 process_i386_registers (FILE *table)
1487 char *str, *p, *last;
1488 char *reg_name, *reg_type, *reg_flags, *reg_num;
1489 char *dw2_32_num, *dw2_64_num;
1492 filename = "i386-reg.tbl";
1493 fp = fopen (filename, "r");
1495 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1498 fprintf (table, "\n/* i386 register table. */\n\n");
1499 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1503 if (fgets (buf, sizeof (buf), fp) == NULL)
1508 p = remove_leading_whitespaces (buf);
1510 /* Skip comments. */
1511 str = strstr (p, "//");
1515 /* Remove trailing white spaces. */
1516 remove_trailing_whitespaces (p);
1521 fprintf (table, "%s\n", p);
1529 last = p + strlen (p);
1531 /* Find reg_name. */
1532 reg_name = next_field (p, ',', &str, last);
1534 /* Find reg_type. */
1535 reg_type = next_field (str, ',', &str, last);
1537 /* Find reg_flags. */
1538 reg_flags = next_field (str, ',', &str, last);
1541 reg_num = next_field (str, ',', &str, last);
1543 fprintf (table, " { \"%s\",\n ", reg_name);
1545 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1548 /* Find 32-bit Dwarf2 register number. */
1549 dw2_32_num = next_field (str, ',', &str, last);
1551 /* Find 64-bit Dwarf2 register number. */
1552 dw2_64_num = next_field (str, ',', &str, last);
1554 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1555 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1560 fprintf (table, "};\n");
1562 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1566 process_i386_initializers (void)
1569 FILE *fp = fopen ("i386-init.h", "w");
1573 fail (_("can't create i386-init.h, errno = %s\n"),
1576 process_copyright (fp);
1578 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1580 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1581 init = xstrdup (cpu_flag_init[i].init);
1582 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1586 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1588 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1589 init = xstrdup (operand_type_init[i].init);
1590 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1598 /* Program options. */
1599 #define OPTION_SRCDIR 200
1601 struct option long_options[] =
1603 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1604 {"debug", no_argument, NULL, 'd'},
1605 {"version", no_argument, NULL, 'V'},
1606 {"help", no_argument, NULL, 'h'},
1607 {0, no_argument, NULL, 0}
1611 print_version (void)
1613 printf ("%s: version 1.0\n", program_name);
1618 usage (FILE * stream, int status)
1620 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1626 main (int argc, char **argv)
1628 extern int chdir (char *);
1629 char *srcdir = NULL;
1631 unsigned int i, cpumax;
1634 program_name = *argv;
1635 xmalloc_set_program_name (program_name);
1637 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1662 if (chdir (srcdir) != 0)
1663 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1664 srcdir, xstrerror (errno));
1666 /* cpu_flags isn't sorted by position. */
1668 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1669 if (cpu_flags[i].position > cpumax)
1670 cpumax = cpu_flags[i].position;
1672 /* Check the unused bitfield in i386_cpu_flags. */
1674 if ((cpumax - 1) != CpuMax)
1675 fail (_("CpuMax != %d!\n"), cpumax);
1677 if (cpumax != CpuMax)
1678 fail (_("CpuMax != %d!\n"), cpumax);
1680 c = CpuNumOfBits - CpuMax - 1;
1682 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1685 /* Check the unused bitfield in i386_operand_type. */
1687 c = OTNumOfBits - OTMax - 1;
1689 fail (_("%d unused bits in i386_operand_type.\n"), c);
1692 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1695 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1696 sizeof (opcode_modifiers [0]), compare);
1698 qsort (operand_types, ARRAY_SIZE (operand_types),
1699 sizeof (operand_types [0]), compare);
1701 table = fopen ("i386-tbl.h", "w");
1703 fail (_("can't create i386-tbl.h, errno = %s\n"),
1706 process_copyright (table);
1708 process_i386_opcodes (table);
1709 process_i386_registers (table);
1710 process_i386_initializers ();