1 /* Copyright (C) 2007-2017 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|CPU_387_FLAGS|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_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuFMA4|CpuXOP|CpuLWP|CpuSVME|CpuXsave|CpuAES|CpuAVX|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_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_BTVER1_FLAGS",
101 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
102 { "CPU_BTVER2_FLAGS",
103 "CPU_BTVER1_FLAGS|CPU_SSE4_2_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW" },
107 "CPU_8087_FLAGS|Cpu287" },
109 "CPU_287_FLAGS|Cpu387" },
111 "CPU_387_FLAGS|Cpu687" },
112 { "CPU_CLFLUSH_FLAGS",
116 { "CPU_SYSCALL_FLAGS",
119 "CpuRegMMX|CpuMMX" },
121 "CpuRegXMM|CpuSSE" },
123 "CPU_SSE_FLAGS|CpuSSE2" },
125 "CPU_SSE2_FLAGS|CpuSSE3" },
127 "CPU_SSE3_FLAGS|CpuSSSE3" },
128 { "CPU_SSE4_1_FLAGS",
129 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
130 { "CPU_SSE4_2_FLAGS",
131 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
138 { "CPU_XSAVEOPT_FLAGS",
139 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
141 "CPU_SSE2_FLAGS|CpuAES" },
142 { "CPU_PCLMUL_FLAGS",
143 "CPU_SSE2_FLAGS|CpuPCLMUL" },
145 "CPU_AVX_FLAGS|CpuFMA" },
147 "CPU_AVX_FLAGS|CpuFMA4" },
149 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
160 { "CPU_RDTSCP_FLAGS",
164 { "CPU_FSGSBASE_FLAGS",
169 "CPU_AVX_FLAGS|CpuF16C" },
178 { "CPU_INVPCID_FLAGS",
180 { "CPU_VMFUNC_FLAGS",
183 "CPU_MMX_FLAGS|Cpu3dnow" },
184 { "CPU_3DNOWA_FLAGS",
185 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
186 { "CPU_PADLOCK_FLAGS",
191 "CPU_SSE3_FLAGS|CpuSSE4a" },
195 "CPU_SSE4_2_FLAGS|CpuRegYMM|CpuAVX" },
197 "CPU_AVX_FLAGS|CpuAVX2" },
198 /* Don't use CPU_AVX2_FLAGS on CPU_AVX512F_FLAGS since AVX512F doesn't
199 support YMM registers. */
200 { "CPU_AVX512F_FLAGS",
201 "CpuVREX|CPU_SSE4_2_FLAGS|CpuRegZMM|CpuRegMask|CpuAVX|CpuAVX2|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 /* Use CPU_AVX2_FLAGS on CPU_AVX512VL_FLAGS since AVX512VL supports YMM
215 "CPU_AVX512F_FLAGS|CPU_AVX2_FLAGS|CpuAVX512VL" },
216 { "CPU_AVX512IFMA_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
218 { "CPU_AVX512VBMI_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
220 { "CPU_AVX512_4FMAPS_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
222 { "CPU_AVX512_4VNNIW_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
224 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
226 { "CPU_AVX512_VBMI2_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
233 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
236 { "CPU_RDSEED_FLAGS",
238 { "CPU_PRFCHW_FLAGS",
245 "CPU_SSE2_FLAGS|CpuSHA" },
246 { "CPU_CLFLUSHOPT_FLAGS",
248 { "CPU_XSAVES_FLAGS",
249 "CPU_XSAVE_FLAGS|CpuXSAVES" },
250 { "CPU_XSAVEC_FLAGS",
251 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
252 { "CPU_PREFETCHWT1_FLAGS",
258 { "CPU_CLZERO_FLAGS",
260 { "CPU_MWAITX_FLAGS",
266 { "CPU_PTWRITE_FLAGS",
272 { "CPU_ANY_X87_FLAGS",
273 "CPU_ANY_287_FLAGS|Cpu8087" },
274 { "CPU_ANY_287_FLAGS",
275 "CPU_ANY_387_FLAGS|Cpu287" },
276 { "CPU_ANY_387_FLAGS",
277 "CPU_ANY_687_FLAGS|Cpu387" },
278 { "CPU_ANY_687_FLAGS",
279 "Cpu687|CpuFISTTP" },
280 { "CPU_ANY_MMX_FLAGS",
281 "CPU_3DNOWA_FLAGS" },
282 { "CPU_ANY_SSE_FLAGS",
283 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
284 { "CPU_ANY_SSE2_FLAGS",
285 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
286 { "CPU_ANY_SSE3_FLAGS",
287 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
288 { "CPU_ANY_SSSE3_FLAGS",
289 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
290 { "CPU_ANY_SSE4_1_FLAGS",
291 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
292 { "CPU_ANY_SSE4_2_FLAGS",
294 { "CPU_ANY_AVX_FLAGS",
295 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
296 { "CPU_ANY_AVX2_FLAGS",
298 { "CPU_ANY_AVX512F_FLAGS",
299 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512F" },
300 { "CPU_ANY_AVX512CD_FLAGS",
302 { "CPU_ANY_AVX512ER_FLAGS",
304 { "CPU_ANY_AVX512PF_FLAGS",
306 { "CPU_ANY_AVX512DQ_FLAGS",
308 { "CPU_ANY_AVX512BW_FLAGS",
310 { "CPU_ANY_AVX512VL_FLAGS",
312 { "CPU_ANY_AVX512IFMA_FLAGS",
314 { "CPU_ANY_AVX512VBMI_FLAGS",
316 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
317 "CpuAVX512_4FMAPS" },
318 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
319 "CpuAVX512_4VNNIW" },
320 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
321 "CpuAVX512_VPOPCNTDQ" },
322 { "CPU_ANY_AVX512_VBMI2_FLAGS",
326 static initializer operand_type_init[] =
328 { "OPERAND_TYPE_NONE",
330 { "OPERAND_TYPE_REG8",
332 { "OPERAND_TYPE_REG16",
334 { "OPERAND_TYPE_REG32",
336 { "OPERAND_TYPE_REG64",
338 { "OPERAND_TYPE_IMM1",
340 { "OPERAND_TYPE_IMM8",
342 { "OPERAND_TYPE_IMM8S",
344 { "OPERAND_TYPE_IMM16",
346 { "OPERAND_TYPE_IMM32",
348 { "OPERAND_TYPE_IMM32S",
350 { "OPERAND_TYPE_IMM64",
352 { "OPERAND_TYPE_BASEINDEX",
354 { "OPERAND_TYPE_DISP8",
356 { "OPERAND_TYPE_DISP16",
358 { "OPERAND_TYPE_DISP32",
360 { "OPERAND_TYPE_DISP32S",
362 { "OPERAND_TYPE_DISP64",
364 { "OPERAND_TYPE_INOUTPORTREG",
366 { "OPERAND_TYPE_SHIFTCOUNT",
368 { "OPERAND_TYPE_CONTROL",
370 { "OPERAND_TYPE_TEST",
372 { "OPERAND_TYPE_DEBUG",
374 { "OPERAND_TYPE_FLOATREG",
376 { "OPERAND_TYPE_FLOATACC",
378 { "OPERAND_TYPE_SREG2",
380 { "OPERAND_TYPE_SREG3",
382 { "OPERAND_TYPE_ACC",
384 { "OPERAND_TYPE_JUMPABSOLUTE",
386 { "OPERAND_TYPE_REGMMX",
388 { "OPERAND_TYPE_REGXMM",
390 { "OPERAND_TYPE_REGYMM",
392 { "OPERAND_TYPE_REGZMM",
394 { "OPERAND_TYPE_REGMASK",
396 { "OPERAND_TYPE_ESSEG",
398 { "OPERAND_TYPE_ACC32",
400 { "OPERAND_TYPE_ACC64",
402 { "OPERAND_TYPE_INOUTPORTREG",
404 { "OPERAND_TYPE_REG16_INOUTPORTREG",
405 "Reg16|InOutPortReg" },
406 { "OPERAND_TYPE_DISP16_32",
408 { "OPERAND_TYPE_ANYDISP",
409 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
410 { "OPERAND_TYPE_IMM16_32",
412 { "OPERAND_TYPE_IMM16_32S",
414 { "OPERAND_TYPE_IMM16_32_32S",
415 "Imm16|Imm32|Imm32S" },
416 { "OPERAND_TYPE_IMM32_64",
418 { "OPERAND_TYPE_IMM32_32S_DISP32",
419 "Imm32|Imm32S|Disp32" },
420 { "OPERAND_TYPE_IMM64_DISP64",
422 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
423 "Imm32|Imm32S|Imm64|Disp32" },
424 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
425 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
426 { "OPERAND_TYPE_VEC_IMM4",
428 { "OPERAND_TYPE_REGBND",
430 { "OPERAND_TYPE_VEC_DISP8",
434 typedef struct bitfield
441 #define BITFIELD(n) { n, 0, #n }
443 static bitfield cpu_flags[] =
451 BITFIELD (CpuClflush),
453 BITFIELD (CpuSYSCALL),
458 BITFIELD (CpuFISTTP),
464 BITFIELD (CpuSSE4_1),
465 BITFIELD (CpuSSE4_2),
468 BITFIELD (CpuAVX512F),
469 BITFIELD (CpuAVX512CD),
470 BITFIELD (CpuAVX512ER),
471 BITFIELD (CpuAVX512PF),
472 BITFIELD (CpuAVX512VL),
473 BITFIELD (CpuAVX512DQ),
474 BITFIELD (CpuAVX512BW),
480 BITFIELD (Cpu3dnowA),
481 BITFIELD (CpuPadLock),
487 BITFIELD (CpuXsaveopt),
489 BITFIELD (CpuPCLMUL),
500 BITFIELD (CpuRdtscp),
501 BITFIELD (CpuFSGSBase),
508 BITFIELD (CpuINVPCID),
509 BITFIELD (CpuVMFUNC),
510 BITFIELD (CpuRDSEED),
512 BITFIELD (CpuPRFCHW),
516 BITFIELD (CpuClflushOpt),
517 BITFIELD (CpuXSAVES),
518 BITFIELD (CpuXSAVEC),
519 BITFIELD (CpuPREFETCHWT1),
525 BITFIELD (CpuAVX512IFMA),
526 BITFIELD (CpuAVX512VBMI),
527 BITFIELD (CpuAVX512_4FMAPS),
528 BITFIELD (CpuAVX512_4VNNIW),
529 BITFIELD (CpuAVX512_VPOPCNTDQ),
530 BITFIELD (CpuAVX512_VBMI2),
531 BITFIELD (CpuMWAITX),
532 BITFIELD (CpuCLZERO),
535 BITFIELD (CpuPTWRITE),
538 BITFIELD (CpuRegMMX),
539 BITFIELD (CpuRegXMM),
540 BITFIELD (CpuRegYMM),
541 BITFIELD (CpuRegZMM),
542 BITFIELD (CpuRegMask),
544 BITFIELD (CpuUnused),
548 static bitfield opcode_modifiers[] =
554 BITFIELD (ShortForm),
556 BITFIELD (JumpDword),
558 BITFIELD (JumpInterSegment),
565 BITFIELD (CheckRegSize),
566 BITFIELD (IgnoreSize),
567 BITFIELD (DefaultSize),
576 BITFIELD (BNDPrefixOk),
577 BITFIELD (NoTrackPrefixOk),
578 BITFIELD (IsLockable),
579 BITFIELD (RegKludge),
580 BITFIELD (FirstXmm0),
581 BITFIELD (Implicit1stXmm0),
582 BITFIELD (RepPrefixOk),
583 BITFIELD (HLEPrefixOk),
586 BITFIELD (AddrPrefixOp0),
595 BITFIELD (VexOpcode),
596 BITFIELD (VexSources),
597 BITFIELD (VexImmExt),
604 BITFIELD (Broadcast),
605 BITFIELD (StaticRounding),
607 BITFIELD (Disp8MemShift),
608 BITFIELD (NoDefMask),
609 BITFIELD (ImplicitQuadGroup),
611 BITFIELD (ATTMnemonic),
612 BITFIELD (ATTSyntax),
613 BITFIELD (IntelSyntax),
618 static bitfield operand_types[] =
637 BITFIELD (BaseIndex),
643 BITFIELD (InOutPortReg),
644 BITFIELD (ShiftCount),
652 BITFIELD (JumpAbsolute),
665 BITFIELD (Unspecified),
669 BITFIELD (Vec_Disp8),
675 static const char *filename;
678 compare (const void *x, const void *y)
680 const bitfield *xp = (const bitfield *) x;
681 const bitfield *yp = (const bitfield *) y;
682 return xp->position - yp->position;
686 fail (const char *message, ...)
690 va_start (args, message);
691 fprintf (stderr, _("%s: Error: "), program_name);
692 vfprintf (stderr, message, args);
698 process_copyright (FILE *fp)
700 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
701 /* Copyright (C) 2007-2017 Free Software Foundation, Inc.\n\
703 This file is part of the GNU opcodes library.\n\
705 This library is free software; you can redistribute it and/or modify\n\
706 it under the terms of the GNU General Public License as published by\n\
707 the Free Software Foundation; either version 3, or (at your option)\n\
708 any later version.\n\
710 It is distributed in the hope that it will be useful, but WITHOUT\n\
711 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
712 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
713 License for more details.\n\
715 You should have received a copy of the GNU General Public License\n\
716 along with this program; if not, write to the Free Software\n\
717 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
718 MA 02110-1301, USA. */\n");
721 /* Remove leading white spaces. */
724 remove_leading_whitespaces (char *str)
726 while (ISSPACE (*str))
731 /* Remove trailing white spaces. */
734 remove_trailing_whitespaces (char *str)
736 size_t last = strlen (str);
744 if (ISSPACE (str [last]))
752 /* Find next field separated by SEP and terminate it. Return a
753 pointer to the one after it. */
756 next_field (char *str, char sep, char **next, char *last)
760 p = remove_leading_whitespaces (str);
761 for (str = p; *str != sep && *str != '\0'; str++);
764 remove_trailing_whitespaces (p);
774 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
777 set_bitfield_from_cpu_flag_init (char *f, bitfield *array,
778 int value, unsigned int size,
781 char *str, *next, *last;
784 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
785 if (strcmp (cpu_flag_init[i].name, f) == 0)
787 /* Turn on selective bits. */
788 char *init = xstrdup (cpu_flag_init[i].init);
789 last = init + strlen (init);
790 for (next = init; next && next < last; )
792 str = next_field (next, '|', &next, last);
794 set_bitfield (str, array, 1, size, lineno);
804 set_bitfield (char *f, bitfield *array, int value,
805 unsigned int size, int lineno)
809 if (strcmp (f, "CpuFP") == 0)
811 set_bitfield("Cpu387", array, value, size, lineno);
812 set_bitfield("Cpu287", array, value, size, lineno);
815 else if (strcmp (f, "Mmword") == 0)
817 else if (strcmp (f, "Oword") == 0)
820 for (i = 0; i < size; i++)
821 if (strcasecmp (array[i].name, f) == 0)
823 array[i].value = value;
829 const char *v = strchr (f, '=');
836 for (i = 0; i < size; i++)
837 if (strncasecmp (array[i].name, f, n) == 0)
839 value = strtol (v + 1, &end, 0);
842 array[i].value = value;
850 /* Handle CPU_XXX_FLAGS. */
851 if (!set_bitfield_from_cpu_flag_init (f, array, value, size, lineno))
855 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
857 fail (_("Unknown bitfield: %s\n"), f);
861 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
862 int macro, const char *comma, const char *indent)
866 fprintf (table, "%s{ { ", indent);
868 for (i = 0; i < size - 1; i++)
870 if (((i + 1) % 20) != 0)
871 fprintf (table, "%d, ", flags[i].value);
873 fprintf (table, "%d,", flags[i].value);
874 if (((i + 1) % 20) == 0)
876 /* We need \\ for macro. */
878 fprintf (table, " \\\n %s", indent);
880 fprintf (table, "\n %s", indent);
884 fprintf (table, "%d } }%s\n", flags[i].value, comma);
888 process_i386_cpu_flag (FILE *table, char *flag, int macro,
889 const char *comma, const char *indent,
892 char *str, *next, *last;
894 bitfield flags [ARRAY_SIZE (cpu_flags)];
896 /* Copy the default cpu flags. */
897 memcpy (flags, cpu_flags, sizeof (cpu_flags));
899 if (strcasecmp (flag, "unknown") == 0)
901 /* We turn on everything except for cpu64 in case of
902 CPU_UNKNOWN_FLAGS. */
903 for (i = 0; i < ARRAY_SIZE (flags); i++)
904 if (flags[i].position != Cpu64)
907 else if (flag[0] == '~')
909 last = flag + strlen (flag);
916 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
923 /* First we turn on everything except for cpu64. */
924 for (i = 0; i < ARRAY_SIZE (flags); i++)
925 if (flags[i].position != Cpu64)
928 /* Turn off selective bits. */
929 for (; next && next < last; )
931 str = next_field (next, '|', &next, last);
933 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
936 else if (strcmp (flag, "0"))
938 /* Turn on selective bits. */
939 last = flag + strlen (flag);
940 for (next = flag; next && next < last; )
942 str = next_field (next, '|', &next, last);
944 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
948 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
953 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
957 fprintf (table, " { ");
959 for (i = 0; i < size - 1; i++)
961 if (((i + 1) % 20) != 0)
962 fprintf (table, "%d, ", modifier[i].value);
964 fprintf (table, "%d,", modifier[i].value);
965 if (((i + 1) % 20) == 0)
966 fprintf (table, "\n ");
969 fprintf (table, "%d },\n", modifier[i].value);
973 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
975 char *str, *next, *last;
976 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
978 /* Copy the default opcode modifier. */
979 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
981 if (strcmp (mod, "0"))
983 last = mod + strlen (mod);
984 for (next = mod; next && next < last; )
986 str = next_field (next, '|', &next, last);
988 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
992 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
996 output_operand_type (FILE *table, bitfield *types, unsigned int size,
997 int macro, const char *indent)
1001 fprintf (table, "{ { ");
1003 for (i = 0; i < size - 1; i++)
1005 if (((i + 1) % 20) != 0)
1006 fprintf (table, "%d, ", types[i].value);
1008 fprintf (table, "%d,", types[i].value);
1009 if (((i + 1) % 20) == 0)
1011 /* We need \\ for macro. */
1013 fprintf (table, " \\\n%s", indent);
1015 fprintf (table, "\n%s", indent);
1019 fprintf (table, "%d } }", types[i].value);
1023 process_i386_operand_type (FILE *table, char *op, int macro,
1024 const char *indent, int lineno)
1026 char *str, *next, *last;
1027 bitfield types [ARRAY_SIZE (operand_types)];
1029 /* Copy the default operand type. */
1030 memcpy (types, operand_types, sizeof (types));
1032 if (strcmp (op, "0"))
1034 last = op + strlen (op);
1035 for (next = op; next && next < last; )
1037 str = next_field (next, '|', &next, last);
1039 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1042 output_operand_type (table, types, ARRAY_SIZE (types), macro,
1047 output_i386_opcode (FILE *table, const char *name, char *str,
1048 char *last, int lineno)
1051 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1052 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1054 /* Find number of operands. */
1055 operands = next_field (str, ',', &str, last);
1057 /* Find base_opcode. */
1058 base_opcode = next_field (str, ',', &str, last);
1060 /* Find extension_opcode. */
1061 extension_opcode = next_field (str, ',', &str, last);
1063 /* Find opcode_length. */
1064 opcode_length = next_field (str, ',', &str, last);
1066 /* Find cpu_flags. */
1067 cpu_flags = next_field (str, ',', &str, last);
1069 /* Find opcode_modifier. */
1070 opcode_modifier = next_field (str, ',', &str, last);
1072 /* Remove the first {. */
1073 str = remove_leading_whitespaces (str);
1076 str = remove_leading_whitespaces (str + 1);
1080 /* There are at least "X}". */
1084 /* Remove trailing white spaces and }. */
1088 if (ISSPACE (str[i]) || str[i] == '}')
1097 /* Find operand_types. */
1098 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1102 operand_types [i] = NULL;
1106 operand_types [i] = next_field (str, ',', &str, last);
1107 if (*operand_types[i] == '0')
1110 operand_types[i] = NULL;
1115 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1116 name, operands, base_opcode, extension_opcode,
1119 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1121 process_i386_opcode_modifier (table, opcode_modifier, lineno);
1123 fprintf (table, " { ");
1125 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1127 if (operand_types[i] == NULL || *operand_types[i] == '0')
1130 process_i386_operand_type (table, "0", 0, "\t ", lineno);
1135 fprintf (table, ",\n ");
1137 process_i386_operand_type (table, operand_types[i], 0,
1140 fprintf (table, " } },\n");
1143 struct opcode_hash_entry
1145 struct opcode_hash_entry *next;
1151 /* Calculate the hash value of an opcode hash entry P. */
1154 opcode_hash_hash (const void *p)
1156 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1157 return htab_hash_string (entry->name);
1160 /* Compare a string Q against an opcode hash entry P. */
1163 opcode_hash_eq (const void *p, const void *q)
1165 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1166 const char *name = (const char *) q;
1167 return strcmp (name, entry->name) == 0;
1171 process_i386_opcodes (FILE *table)
1176 char *str, *p, *last, *name;
1177 struct opcode_hash_entry **hash_slot, **entry, *next;
1178 htab_t opcode_hash_table;
1179 struct opcode_hash_entry **opcode_array;
1180 unsigned int opcode_array_size = 1024;
1183 filename = "i386-opc.tbl";
1184 fp = fopen (filename, "r");
1187 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1191 opcode_array = (struct opcode_hash_entry **)
1192 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1194 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1195 opcode_hash_eq, NULL,
1198 fprintf (table, "\n/* i386 opcode table. */\n\n");
1199 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1201 /* Put everything on opcode array. */
1204 if (fgets (buf, sizeof (buf), fp) == NULL)
1209 p = remove_leading_whitespaces (buf);
1211 /* Skip comments. */
1212 str = strstr (p, "//");
1216 /* Remove trailing white spaces. */
1217 remove_trailing_whitespaces (p);
1222 /* Ignore comments. */
1230 last = p + strlen (p);
1233 name = next_field (p, ',', &str, last);
1235 /* Get the slot in hash table. */
1236 hash_slot = (struct opcode_hash_entry **)
1237 htab_find_slot_with_hash (opcode_hash_table, name,
1238 htab_hash_string (name),
1241 if (*hash_slot == NULL)
1243 /* It is the new one. Put it on opcode array. */
1244 if (i >= opcode_array_size)
1246 /* Grow the opcode array when needed. */
1247 opcode_array_size += 1024;
1248 opcode_array = (struct opcode_hash_entry **)
1249 xrealloc (opcode_array,
1250 sizeof (*opcode_array) * opcode_array_size);
1253 opcode_array[i] = (struct opcode_hash_entry *)
1254 xmalloc (sizeof (struct opcode_hash_entry));
1255 opcode_array[i]->next = NULL;
1256 opcode_array[i]->name = xstrdup (name);
1257 opcode_array[i]->opcode = xstrdup (str);
1258 opcode_array[i]->lineno = lineno;
1259 *hash_slot = opcode_array[i];
1264 /* Append it to the existing one. */
1266 while ((*entry) != NULL)
1267 entry = &(*entry)->next;
1268 *entry = (struct opcode_hash_entry *)
1269 xmalloc (sizeof (struct opcode_hash_entry));
1270 (*entry)->next = NULL;
1271 (*entry)->name = (*hash_slot)->name;
1272 (*entry)->opcode = xstrdup (str);
1273 (*entry)->lineno = lineno;
1277 /* Process opcode array. */
1278 for (j = 0; j < i; j++)
1280 for (next = opcode_array[j]; next; next = next->next)
1284 lineno = next->lineno;
1285 last = str + strlen (str);
1286 output_i386_opcode (table, name, str, last, lineno);
1292 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1294 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1296 process_i386_opcode_modifier (table, "0", -1);
1298 fprintf (table, " { ");
1299 process_i386_operand_type (table, "0", 0, "\t ", -1);
1300 fprintf (table, " } }\n");
1302 fprintf (table, "};\n");
1306 process_i386_registers (FILE *table)
1310 char *str, *p, *last;
1311 char *reg_name, *reg_type, *reg_flags, *reg_num;
1312 char *dw2_32_num, *dw2_64_num;
1315 filename = "i386-reg.tbl";
1316 fp = fopen (filename, "r");
1318 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1321 fprintf (table, "\n/* i386 register table. */\n\n");
1322 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1326 if (fgets (buf, sizeof (buf), fp) == NULL)
1331 p = remove_leading_whitespaces (buf);
1333 /* Skip comments. */
1334 str = strstr (p, "//");
1338 /* Remove trailing white spaces. */
1339 remove_trailing_whitespaces (p);
1344 fprintf (table, "%s\n", p);
1352 last = p + strlen (p);
1354 /* Find reg_name. */
1355 reg_name = next_field (p, ',', &str, last);
1357 /* Find reg_type. */
1358 reg_type = next_field (str, ',', &str, last);
1360 /* Find reg_flags. */
1361 reg_flags = next_field (str, ',', &str, last);
1364 reg_num = next_field (str, ',', &str, last);
1366 fprintf (table, " { \"%s\",\n ", reg_name);
1368 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1370 /* Find 32-bit Dwarf2 register number. */
1371 dw2_32_num = next_field (str, ',', &str, last);
1373 /* Find 64-bit Dwarf2 register number. */
1374 dw2_64_num = next_field (str, ',', &str, last);
1376 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1377 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1382 fprintf (table, "};\n");
1384 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1388 process_i386_initializers (void)
1391 FILE *fp = fopen ("i386-init.h", "w");
1395 fail (_("can't create i386-init.h, errno = %s\n"),
1398 process_copyright (fp);
1400 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1402 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1403 init = xstrdup (cpu_flag_init[i].init);
1404 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1408 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1410 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1411 init = xstrdup (operand_type_init[i].init);
1412 process_i386_operand_type (fp, init, 1, " ", -1);
1420 /* Program options. */
1421 #define OPTION_SRCDIR 200
1423 struct option long_options[] =
1425 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1426 {"debug", no_argument, NULL, 'd'},
1427 {"version", no_argument, NULL, 'V'},
1428 {"help", no_argument, NULL, 'h'},
1429 {0, no_argument, NULL, 0}
1433 print_version (void)
1435 printf ("%s: version 1.0\n", program_name);
1440 usage (FILE * stream, int status)
1442 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1448 main (int argc, char **argv)
1450 extern int chdir (char *);
1451 char *srcdir = NULL;
1453 unsigned int i, cpumax;
1456 program_name = *argv;
1457 xmalloc_set_program_name (program_name);
1459 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1484 if (chdir (srcdir) != 0)
1485 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1486 srcdir, xstrerror (errno));
1488 /* cpu_flags isn't sorted by position. */
1490 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1491 if (cpu_flags[i].position > cpumax)
1492 cpumax = cpu_flags[i].position;
1494 /* Check the unused bitfield in i386_cpu_flags. */
1496 if ((cpumax - 1) != CpuMax)
1497 fail (_("CpuMax != %d!\n"), cpumax);
1499 if (cpumax != CpuMax)
1500 fail (_("CpuMax != %d!\n"), cpumax);
1502 c = CpuNumOfBits - CpuMax - 1;
1504 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1507 /* Check the unused bitfield in i386_operand_type. */
1509 c = OTNumOfBits - OTMax - 1;
1511 fail (_("%d unused bits in i386_operand_type.\n"), c);
1514 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1517 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1518 sizeof (opcode_modifiers [0]), compare);
1520 qsort (operand_types, ARRAY_SIZE (operand_types),
1521 sizeof (operand_types [0]), compare);
1523 table = fopen ("i386-tbl.h", "w");
1525 fail (_("can't create i386-tbl.h, errno = %s\n"),
1528 process_copyright (table);
1530 process_i386_opcodes (table);
1531 process_i386_registers (table);
1532 process_i386_initializers ();