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_INOUTPORTREG",
449 { "OPERAND_TYPE_REG16_INOUTPORTREG",
450 "Reg16|InOutPortReg" },
451 { "OPERAND_TYPE_DISP16_32",
453 { "OPERAND_TYPE_ANYDISP",
454 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
455 { "OPERAND_TYPE_IMM16_32",
457 { "OPERAND_TYPE_IMM16_32S",
459 { "OPERAND_TYPE_IMM16_32_32S",
460 "Imm16|Imm32|Imm32S" },
461 { "OPERAND_TYPE_IMM32_64",
463 { "OPERAND_TYPE_IMM32_32S_DISP32",
464 "Imm32|Imm32S|Disp32" },
465 { "OPERAND_TYPE_IMM64_DISP64",
467 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
468 "Imm32|Imm32S|Imm64|Disp32" },
469 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
470 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
471 { "OPERAND_TYPE_VEC_IMM4",
473 { "OPERAND_TYPE_REGBND",
477 typedef struct bitfield
484 #define BITFIELD(n) { n, 0, #n }
486 static bitfield cpu_flags[] =
494 BITFIELD (CpuClflush),
496 BITFIELD (CpuSYSCALL),
501 BITFIELD (CpuFISTTP),
507 BITFIELD (CpuSSE4_1),
508 BITFIELD (CpuSSE4_2),
511 BITFIELD (CpuAVX512F),
512 BITFIELD (CpuAVX512CD),
513 BITFIELD (CpuAVX512ER),
514 BITFIELD (CpuAVX512PF),
515 BITFIELD (CpuAVX512VL),
516 BITFIELD (CpuAVX512DQ),
517 BITFIELD (CpuAVX512BW),
523 BITFIELD (Cpu3dnowA),
524 BITFIELD (CpuPadLock),
530 BITFIELD (CpuXsaveopt),
532 BITFIELD (CpuPCLMUL),
543 BITFIELD (CpuRdtscp),
544 BITFIELD (CpuFSGSBase),
551 BITFIELD (CpuINVPCID),
552 BITFIELD (CpuVMFUNC),
553 BITFIELD (CpuRDSEED),
555 BITFIELD (CpuPRFCHW),
559 BITFIELD (CpuClflushOpt),
560 BITFIELD (CpuXSAVES),
561 BITFIELD (CpuXSAVEC),
562 BITFIELD (CpuPREFETCHWT1),
568 BITFIELD (CpuAVX512IFMA),
569 BITFIELD (CpuAVX512VBMI),
570 BITFIELD (CpuAVX512_4FMAPS),
571 BITFIELD (CpuAVX512_4VNNIW),
572 BITFIELD (CpuAVX512_VPOPCNTDQ),
573 BITFIELD (CpuAVX512_VBMI2),
574 BITFIELD (CpuAVX512_VNNI),
575 BITFIELD (CpuAVX512_BITALG),
576 BITFIELD (CpuMWAITX),
577 BITFIELD (CpuCLZERO),
580 BITFIELD (CpuPTWRITE),
585 BITFIELD (CpuVPCLMULQDQ),
586 BITFIELD (CpuWBNOINVD),
587 BITFIELD (CpuPCONFIG),
588 BITFIELD (CpuWAITPKG),
589 BITFIELD (CpuCLDEMOTE),
590 BITFIELD (CpuMOVDIRI),
591 BITFIELD (CpuMOVDIR64B),
593 BITFIELD (CpuUnused),
597 static bitfield opcode_modifiers[] =
603 BITFIELD (ShortForm),
605 BITFIELD (JumpDword),
607 BITFIELD (JumpInterSegment),
613 BITFIELD (CheckRegSize),
614 BITFIELD (IgnoreSize),
615 BITFIELD (DefaultSize),
624 BITFIELD (BNDPrefixOk),
625 BITFIELD (NoTrackPrefixOk),
626 BITFIELD (IsLockable),
627 BITFIELD (RegKludge),
628 BITFIELD (Implicit1stXmm0),
629 BITFIELD (RepPrefixOk),
630 BITFIELD (HLEPrefixOk),
633 BITFIELD (AddrPrefixOpReg),
642 BITFIELD (VexOpcode),
643 BITFIELD (VexSources),
649 BITFIELD (Broadcast),
650 BITFIELD (StaticRounding),
652 BITFIELD (Disp8MemShift),
653 BITFIELD (NoDefMask),
654 BITFIELD (ImplicitQuadGroup),
656 BITFIELD (ATTMnemonic),
657 BITFIELD (ATTSyntax),
658 BITFIELD (IntelSyntax),
663 static bitfield operand_types[] =
676 BITFIELD (BaseIndex),
682 BITFIELD (InOutPortReg),
683 BITFIELD (ShiftCount),
690 BITFIELD (JumpAbsolute),
703 BITFIELD (Unspecified),
712 static const char *filename;
713 static i386_cpu_flags active_cpu_flags;
714 static int active_isstring;
717 compare (const void *x, const void *y)
719 const bitfield *xp = (const bitfield *) x;
720 const bitfield *yp = (const bitfield *) y;
721 return xp->position - yp->position;
725 fail (const char *message, ...)
729 va_start (args, message);
730 fprintf (stderr, _("%s: error: "), program_name);
731 vfprintf (stderr, message, args);
737 process_copyright (FILE *fp)
739 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
740 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
742 This file is part of the GNU opcodes library.\n\
744 This library is free software; you can redistribute it and/or modify\n\
745 it under the terms of the GNU General Public License as published by\n\
746 the Free Software Foundation; either version 3, or (at your option)\n\
747 any later version.\n\
749 It is distributed in the hope that it will be useful, but WITHOUT\n\
750 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
751 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
752 License for more details.\n\
754 You should have received a copy of the GNU General Public License\n\
755 along with this program; if not, write to the Free Software\n\
756 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
757 MA 02110-1301, USA. */\n");
760 /* Remove leading white spaces. */
763 remove_leading_whitespaces (char *str)
765 while (ISSPACE (*str))
770 /* Remove trailing white spaces. */
773 remove_trailing_whitespaces (char *str)
775 size_t last = strlen (str);
783 if (ISSPACE (str [last]))
791 /* Find next field separated by SEP and terminate it. Return a
792 pointer to the one after it. */
795 next_field (char *str, char sep, char **next, char *last)
799 p = remove_leading_whitespaces (str);
800 for (str = p; *str != sep && *str != '\0'; str++);
803 remove_trailing_whitespaces (p);
813 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
816 set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
819 char *str, *next, *last;
822 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
823 if (strcmp (cpu_flag_init[i].name, f) == 0)
825 /* Turn on selective bits. */
826 char *init = xstrdup (cpu_flag_init[i].init);
827 last = init + strlen (init);
828 for (next = init; next && next < last; )
830 str = next_field (next, '|', &next, last);
832 set_bitfield (str, array, 1, size, lineno);
838 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
839 if (strcmp (operand_type_shorthands[i].name, f) == 0)
841 /* Turn on selective bits. */
842 char *init = xstrdup (operand_type_shorthands[i].init);
843 last = init + strlen (init);
844 for (next = init; next && next < last; )
846 str = next_field (next, '|', &next, last);
848 set_bitfield (str, array, 1, size, lineno);
858 set_bitfield (char *f, bitfield *array, int value,
859 unsigned int size, int lineno)
863 if (strcmp (f, "CpuFP") == 0)
865 set_bitfield("Cpu387", array, value, size, lineno);
866 set_bitfield("Cpu287", array, value, size, lineno);
869 else if (strcmp (f, "Mmword") == 0)
871 else if (strcmp (f, "Oword") == 0)
874 for (i = 0; i < size; i++)
875 if (strcasecmp (array[i].name, f) == 0)
877 array[i].value = value;
883 const char *v = strchr (f, '=');
890 for (i = 0; i < size; i++)
891 if (strncasecmp (array[i].name, f, n) == 0)
893 value = strtol (v + 1, &end, 0);
896 array[i].value = value;
904 /* Handle shorthands. */
905 if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno))
909 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
911 fail (_("unknown bitfield: %s\n"), f);
915 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
916 int macro, const char *comma, const char *indent)
920 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
922 fprintf (table, "%s{ { ", indent);
924 for (i = 0; i < size - 1; i++)
926 if (((i + 1) % 20) != 0)
927 fprintf (table, "%d, ", flags[i].value);
929 fprintf (table, "%d,", flags[i].value);
930 if (((i + 1) % 20) == 0)
932 /* We need \\ for macro. */
934 fprintf (table, " \\\n %s", indent);
936 fprintf (table, "\n %s", indent);
939 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
942 fprintf (table, "%d } }%s\n", flags[i].value, comma);
946 process_i386_cpu_flag (FILE *table, char *flag, int macro,
947 const char *comma, const char *indent,
950 char *str, *next, *last;
952 bitfield flags [ARRAY_SIZE (cpu_flags)];
954 /* Copy the default cpu flags. */
955 memcpy (flags, cpu_flags, sizeof (cpu_flags));
957 if (strcasecmp (flag, "unknown") == 0)
959 /* We turn on everything except for cpu64 in case of
960 CPU_UNKNOWN_FLAGS. */
961 for (i = 0; i < ARRAY_SIZE (flags); i++)
962 if (flags[i].position != Cpu64)
965 else if (flag[0] == '~')
967 last = flag + strlen (flag);
974 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
981 /* First we turn on everything except for cpu64. */
982 for (i = 0; i < ARRAY_SIZE (flags); i++)
983 if (flags[i].position != Cpu64)
986 /* Turn off selective bits. */
987 for (; next && next < last; )
989 str = next_field (next, '|', &next, last);
991 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
994 else if (strcmp (flag, "0"))
996 /* Turn on selective bits. */
997 last = flag + strlen (flag);
998 for (next = flag; next && next < last; )
1000 str = next_field (next, '|', &next, last);
1002 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1006 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1011 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1015 fprintf (table, " { ");
1017 for (i = 0; i < size - 1; i++)
1019 if (((i + 1) % 20) != 0)
1020 fprintf (table, "%d, ", modifier[i].value);
1022 fprintf (table, "%d,", modifier[i].value);
1023 if (((i + 1) % 20) == 0)
1024 fprintf (table, "\n ");
1027 fprintf (table, "%d },\n", modifier[i].value);
1031 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
1033 char *str, *next, *last;
1034 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1036 active_isstring = 0;
1038 /* Copy the default opcode modifier. */
1039 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1041 if (strcmp (mod, "0"))
1043 last = mod + strlen (mod);
1044 for (next = mod; next && next < last; )
1046 str = next_field (next, '|', &next, last);
1049 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
1051 if (strcasecmp(str, "IsString") == 0)
1052 active_isstring = 1;
1056 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1066 output_operand_type (FILE *table, bitfield *types, unsigned int size,
1067 enum stage stage, const char *indent)
1071 fprintf (table, "{ { ");
1073 for (i = 0; i < size - 1; i++)
1075 if (((i + 1) % 20) != 0)
1076 fprintf (table, "%d, ", types[i].value);
1078 fprintf (table, "%d,", types[i].value);
1079 if (((i + 1) % 20) == 0)
1081 /* We need \\ for macro. */
1082 if (stage == stage_macros)
1083 fprintf (table, " \\\n%s", indent);
1085 fprintf (table, "\n%s", indent);
1089 fprintf (table, "%d } }", types[i].value);
1093 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1094 const char *indent, int lineno)
1096 char *str, *next, *last;
1097 bitfield types [ARRAY_SIZE (operand_types)];
1099 /* Copy the default operand type. */
1100 memcpy (types, operand_types, sizeof (types));
1102 if (strcmp (op, "0"))
1106 last = op + strlen (op);
1107 for (next = op; next && next < last; )
1109 str = next_field (next, '|', &next, last);
1112 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1113 if (strcasecmp(str, "BaseIndex") == 0)
1118 if (stage == stage_opcodes && baseindex && !active_isstring)
1120 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1121 if (!active_cpu_flags.bitfield.cpu64
1122 && !active_cpu_flags.bitfield.cpumpx)
1123 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1124 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1125 if (!active_cpu_flags.bitfield.cpuno64)
1126 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1129 output_operand_type (table, types, ARRAY_SIZE (types), stage,
1134 output_i386_opcode (FILE *table, const char *name, char *str,
1135 char *last, int lineno)
1138 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1139 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1141 /* Find number of operands. */
1142 operands = next_field (str, ',', &str, last);
1144 /* Find base_opcode. */
1145 base_opcode = next_field (str, ',', &str, last);
1147 /* Find extension_opcode. */
1148 extension_opcode = next_field (str, ',', &str, last);
1150 /* Find opcode_length. */
1151 opcode_length = next_field (str, ',', &str, last);
1153 /* Find cpu_flags. */
1154 cpu_flags = next_field (str, ',', &str, last);
1156 /* Find opcode_modifier. */
1157 opcode_modifier = next_field (str, ',', &str, last);
1159 /* Remove the first {. */
1160 str = remove_leading_whitespaces (str);
1163 str = remove_leading_whitespaces (str + 1);
1167 /* There are at least "X}". */
1171 /* Remove trailing white spaces and }. */
1175 if (ISSPACE (str[i]) || str[i] == '}')
1184 /* Find operand_types. */
1185 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1189 operand_types [i] = NULL;
1193 operand_types [i] = next_field (str, ',', &str, last);
1194 if (*operand_types[i] == '0')
1197 operand_types[i] = NULL;
1202 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1203 name, operands, base_opcode, extension_opcode,
1206 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1208 process_i386_opcode_modifier (table, opcode_modifier, lineno);
1210 fprintf (table, " { ");
1212 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1214 if (operand_types[i] == NULL || *operand_types[i] == '0')
1217 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1223 fprintf (table, ",\n ");
1225 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1228 fprintf (table, " } },\n");
1231 struct opcode_hash_entry
1233 struct opcode_hash_entry *next;
1239 /* Calculate the hash value of an opcode hash entry P. */
1242 opcode_hash_hash (const void *p)
1244 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1245 return htab_hash_string (entry->name);
1248 /* Compare a string Q against an opcode hash entry P. */
1251 opcode_hash_eq (const void *p, const void *q)
1253 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1254 const char *name = (const char *) q;
1255 return strcmp (name, entry->name) == 0;
1259 process_i386_opcodes (FILE *table)
1264 char *str, *p, *last, *name;
1265 struct opcode_hash_entry **hash_slot, **entry, *next;
1266 htab_t opcode_hash_table;
1267 struct opcode_hash_entry **opcode_array;
1268 unsigned int opcode_array_size = 1024;
1271 filename = "i386-opc.tbl";
1272 fp = fopen (filename, "r");
1275 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1279 opcode_array = (struct opcode_hash_entry **)
1280 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1282 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1283 opcode_hash_eq, NULL,
1286 fprintf (table, "\n/* i386 opcode table. */\n\n");
1287 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1289 /* Put everything on opcode array. */
1292 if (fgets (buf, sizeof (buf), fp) == NULL)
1297 p = remove_leading_whitespaces (buf);
1299 /* Skip comments. */
1300 str = strstr (p, "//");
1304 /* Remove trailing white spaces. */
1305 remove_trailing_whitespaces (p);
1310 /* Ignore comments. */
1318 last = p + strlen (p);
1321 name = next_field (p, ',', &str, last);
1323 /* Get the slot in hash table. */
1324 hash_slot = (struct opcode_hash_entry **)
1325 htab_find_slot_with_hash (opcode_hash_table, name,
1326 htab_hash_string (name),
1329 if (*hash_slot == NULL)
1331 /* It is the new one. Put it on opcode array. */
1332 if (i >= opcode_array_size)
1334 /* Grow the opcode array when needed. */
1335 opcode_array_size += 1024;
1336 opcode_array = (struct opcode_hash_entry **)
1337 xrealloc (opcode_array,
1338 sizeof (*opcode_array) * opcode_array_size);
1341 opcode_array[i] = (struct opcode_hash_entry *)
1342 xmalloc (sizeof (struct opcode_hash_entry));
1343 opcode_array[i]->next = NULL;
1344 opcode_array[i]->name = xstrdup (name);
1345 opcode_array[i]->opcode = xstrdup (str);
1346 opcode_array[i]->lineno = lineno;
1347 *hash_slot = opcode_array[i];
1352 /* Append it to the existing one. */
1354 while ((*entry) != NULL)
1355 entry = &(*entry)->next;
1356 *entry = (struct opcode_hash_entry *)
1357 xmalloc (sizeof (struct opcode_hash_entry));
1358 (*entry)->next = NULL;
1359 (*entry)->name = (*hash_slot)->name;
1360 (*entry)->opcode = xstrdup (str);
1361 (*entry)->lineno = lineno;
1365 /* Process opcode array. */
1366 for (j = 0; j < i; j++)
1368 for (next = opcode_array[j]; next; next = next->next)
1372 lineno = next->lineno;
1373 last = str + strlen (str);
1374 output_i386_opcode (table, name, str, last, lineno);
1380 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1382 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1384 process_i386_opcode_modifier (table, "0", -1);
1386 fprintf (table, " { ");
1387 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1388 fprintf (table, " } }\n");
1390 fprintf (table, "};\n");
1394 process_i386_registers (FILE *table)
1398 char *str, *p, *last;
1399 char *reg_name, *reg_type, *reg_flags, *reg_num;
1400 char *dw2_32_num, *dw2_64_num;
1403 filename = "i386-reg.tbl";
1404 fp = fopen (filename, "r");
1406 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1409 fprintf (table, "\n/* i386 register table. */\n\n");
1410 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1414 if (fgets (buf, sizeof (buf), fp) == NULL)
1419 p = remove_leading_whitespaces (buf);
1421 /* Skip comments. */
1422 str = strstr (p, "//");
1426 /* Remove trailing white spaces. */
1427 remove_trailing_whitespaces (p);
1432 fprintf (table, "%s\n", p);
1440 last = p + strlen (p);
1442 /* Find reg_name. */
1443 reg_name = next_field (p, ',', &str, last);
1445 /* Find reg_type. */
1446 reg_type = next_field (str, ',', &str, last);
1448 /* Find reg_flags. */
1449 reg_flags = next_field (str, ',', &str, last);
1452 reg_num = next_field (str, ',', &str, last);
1454 fprintf (table, " { \"%s\",\n ", reg_name);
1456 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1459 /* Find 32-bit Dwarf2 register number. */
1460 dw2_32_num = next_field (str, ',', &str, last);
1462 /* Find 64-bit Dwarf2 register number. */
1463 dw2_64_num = next_field (str, ',', &str, last);
1465 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1466 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1471 fprintf (table, "};\n");
1473 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1477 process_i386_initializers (void)
1480 FILE *fp = fopen ("i386-init.h", "w");
1484 fail (_("can't create i386-init.h, errno = %s\n"),
1487 process_copyright (fp);
1489 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1491 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1492 init = xstrdup (cpu_flag_init[i].init);
1493 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1497 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1499 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1500 init = xstrdup (operand_type_init[i].init);
1501 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1509 /* Program options. */
1510 #define OPTION_SRCDIR 200
1512 struct option long_options[] =
1514 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1515 {"debug", no_argument, NULL, 'd'},
1516 {"version", no_argument, NULL, 'V'},
1517 {"help", no_argument, NULL, 'h'},
1518 {0, no_argument, NULL, 0}
1522 print_version (void)
1524 printf ("%s: version 1.0\n", program_name);
1529 usage (FILE * stream, int status)
1531 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1537 main (int argc, char **argv)
1539 extern int chdir (char *);
1540 char *srcdir = NULL;
1542 unsigned int i, cpumax;
1545 program_name = *argv;
1546 xmalloc_set_program_name (program_name);
1548 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1573 if (chdir (srcdir) != 0)
1574 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1575 srcdir, xstrerror (errno));
1577 /* cpu_flags isn't sorted by position. */
1579 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1580 if (cpu_flags[i].position > cpumax)
1581 cpumax = cpu_flags[i].position;
1583 /* Check the unused bitfield in i386_cpu_flags. */
1585 if ((cpumax - 1) != CpuMax)
1586 fail (_("CpuMax != %d!\n"), cpumax);
1588 if (cpumax != CpuMax)
1589 fail (_("CpuMax != %d!\n"), cpumax);
1591 c = CpuNumOfBits - CpuMax - 1;
1593 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1596 /* Check the unused bitfield in i386_operand_type. */
1598 c = OTNumOfBits - OTMax - 1;
1600 fail (_("%d unused bits in i386_operand_type.\n"), c);
1603 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1606 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1607 sizeof (opcode_modifiers [0]), compare);
1609 qsort (operand_types, ARRAY_SIZE (operand_types),
1610 sizeof (operand_types [0]), compare);
1612 table = fopen ("i386-tbl.h", "w");
1614 fail (_("can't create i386-tbl.h, errno = %s\n"),
1617 process_copyright (table);
1619 process_i386_opcodes (table);
1620 process_i386_registers (table);
1621 process_i386_initializers ();