1 /* Copyright (C) 2007-2016 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" },
229 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
232 { "CPU_RDSEED_FLAGS",
234 { "CPU_PRFCHW_FLAGS",
241 "CPU_SSE2_FLAGS|CpuSHA" },
242 { "CPU_CLFLUSHOPT_FLAGS",
244 { "CPU_XSAVES_FLAGS",
245 "CPU_XSAVE_FLAGS|CpuXSAVES" },
246 { "CPU_XSAVEC_FLAGS",
247 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
248 { "CPU_PREFETCHWT1_FLAGS",
254 { "CPU_CLZERO_FLAGS",
256 { "CPU_MWAITX_FLAGS",
262 { "CPU_PTWRITE_FLAGS",
264 { "CPU_ANY_X87_FLAGS",
265 "CPU_ANY_287_FLAGS|Cpu8087" },
266 { "CPU_ANY_287_FLAGS",
267 "CPU_ANY_387_FLAGS|Cpu287" },
268 { "CPU_ANY_387_FLAGS",
269 "CPU_ANY_687_FLAGS|Cpu387" },
270 { "CPU_ANY_687_FLAGS",
271 "Cpu687|CpuFISTTP" },
272 { "CPU_ANY_MMX_FLAGS",
273 "CPU_3DNOWA_FLAGS" },
274 { "CPU_ANY_SSE_FLAGS",
275 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
276 { "CPU_ANY_SSE2_FLAGS",
277 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
278 { "CPU_ANY_SSE3_FLAGS",
279 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
280 { "CPU_ANY_SSSE3_FLAGS",
281 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
282 { "CPU_ANY_SSE4_1_FLAGS",
283 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
284 { "CPU_ANY_SSE4_2_FLAGS",
286 { "CPU_ANY_AVX_FLAGS",
287 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
288 { "CPU_ANY_AVX2_FLAGS",
290 { "CPU_ANY_AVX512F_FLAGS",
291 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512F" },
292 { "CPU_ANY_AVX512CD_FLAGS",
294 { "CPU_ANY_AVX512ER_FLAGS",
296 { "CPU_ANY_AVX512PF_FLAGS",
298 { "CPU_ANY_AVX512DQ_FLAGS",
300 { "CPU_ANY_AVX512BW_FLAGS",
302 { "CPU_ANY_AVX512VL_FLAGS",
304 { "CPU_ANY_AVX512IFMA_FLAGS",
306 { "CPU_ANY_AVX512VBMI_FLAGS",
308 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
309 "CpuAVX512_4FMAPS" },
310 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
311 "CpuAVX512_4VNNIW" },
314 static initializer operand_type_init[] =
316 { "OPERAND_TYPE_NONE",
318 { "OPERAND_TYPE_REG8",
320 { "OPERAND_TYPE_REG16",
322 { "OPERAND_TYPE_REG32",
324 { "OPERAND_TYPE_REG64",
326 { "OPERAND_TYPE_IMM1",
328 { "OPERAND_TYPE_IMM8",
330 { "OPERAND_TYPE_IMM8S",
332 { "OPERAND_TYPE_IMM16",
334 { "OPERAND_TYPE_IMM32",
336 { "OPERAND_TYPE_IMM32S",
338 { "OPERAND_TYPE_IMM64",
340 { "OPERAND_TYPE_BASEINDEX",
342 { "OPERAND_TYPE_DISP8",
344 { "OPERAND_TYPE_DISP16",
346 { "OPERAND_TYPE_DISP32",
348 { "OPERAND_TYPE_DISP32S",
350 { "OPERAND_TYPE_DISP64",
352 { "OPERAND_TYPE_INOUTPORTREG",
354 { "OPERAND_TYPE_SHIFTCOUNT",
356 { "OPERAND_TYPE_CONTROL",
358 { "OPERAND_TYPE_TEST",
360 { "OPERAND_TYPE_DEBUG",
362 { "OPERAND_TYPE_FLOATREG",
364 { "OPERAND_TYPE_FLOATACC",
366 { "OPERAND_TYPE_SREG2",
368 { "OPERAND_TYPE_SREG3",
370 { "OPERAND_TYPE_ACC",
372 { "OPERAND_TYPE_JUMPABSOLUTE",
374 { "OPERAND_TYPE_REGMMX",
376 { "OPERAND_TYPE_REGXMM",
378 { "OPERAND_TYPE_REGYMM",
380 { "OPERAND_TYPE_REGZMM",
382 { "OPERAND_TYPE_REGMASK",
384 { "OPERAND_TYPE_ESSEG",
386 { "OPERAND_TYPE_ACC32",
388 { "OPERAND_TYPE_ACC64",
390 { "OPERAND_TYPE_INOUTPORTREG",
392 { "OPERAND_TYPE_REG16_INOUTPORTREG",
393 "Reg16|InOutPortReg" },
394 { "OPERAND_TYPE_DISP16_32",
396 { "OPERAND_TYPE_ANYDISP",
397 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
398 { "OPERAND_TYPE_IMM16_32",
400 { "OPERAND_TYPE_IMM16_32S",
402 { "OPERAND_TYPE_IMM16_32_32S",
403 "Imm16|Imm32|Imm32S" },
404 { "OPERAND_TYPE_IMM32_64",
406 { "OPERAND_TYPE_IMM32_32S_DISP32",
407 "Imm32|Imm32S|Disp32" },
408 { "OPERAND_TYPE_IMM64_DISP64",
410 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
411 "Imm32|Imm32S|Imm64|Disp32" },
412 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
413 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
414 { "OPERAND_TYPE_VEC_IMM4",
416 { "OPERAND_TYPE_REGBND",
418 { "OPERAND_TYPE_VEC_DISP8",
422 typedef struct bitfield
429 #define BITFIELD(n) { n, 0, #n }
431 static bitfield cpu_flags[] =
439 BITFIELD (CpuClflush),
441 BITFIELD (CpuSYSCALL),
446 BITFIELD (CpuFISTTP),
452 BITFIELD (CpuSSE4_1),
453 BITFIELD (CpuSSE4_2),
456 BITFIELD (CpuAVX512F),
457 BITFIELD (CpuAVX512CD),
458 BITFIELD (CpuAVX512ER),
459 BITFIELD (CpuAVX512PF),
460 BITFIELD (CpuAVX512VL),
461 BITFIELD (CpuAVX512DQ),
462 BITFIELD (CpuAVX512BW),
468 BITFIELD (Cpu3dnowA),
469 BITFIELD (CpuPadLock),
475 BITFIELD (CpuXsaveopt),
477 BITFIELD (CpuPCLMUL),
488 BITFIELD (CpuRdtscp),
489 BITFIELD (CpuFSGSBase),
496 BITFIELD (CpuINVPCID),
497 BITFIELD (CpuVMFUNC),
498 BITFIELD (CpuRDSEED),
500 BITFIELD (CpuPRFCHW),
504 BITFIELD (CpuClflushOpt),
505 BITFIELD (CpuXSAVES),
506 BITFIELD (CpuXSAVEC),
507 BITFIELD (CpuPREFETCHWT1),
513 BITFIELD (CpuAVX512IFMA),
514 BITFIELD (CpuAVX512VBMI),
515 BITFIELD (CpuAVX512_4FMAPS),
516 BITFIELD (CpuAVX512_4VNNIW),
517 BITFIELD (CpuMWAITX),
518 BITFIELD (CpuCLZERO),
521 BITFIELD (CpuPTWRITE),
522 BITFIELD (CpuRegMMX),
523 BITFIELD (CpuRegXMM),
524 BITFIELD (CpuRegYMM),
525 BITFIELD (CpuRegZMM),
526 BITFIELD (CpuRegMask),
528 BITFIELD (CpuUnused),
532 static bitfield opcode_modifiers[] =
538 BITFIELD (ShortForm),
540 BITFIELD (JumpDword),
542 BITFIELD (JumpInterSegment),
549 BITFIELD (CheckRegSize),
550 BITFIELD (IgnoreSize),
551 BITFIELD (DefaultSize),
560 BITFIELD (BNDPrefixOk),
561 BITFIELD (IsLockable),
562 BITFIELD (RegKludge),
563 BITFIELD (FirstXmm0),
564 BITFIELD (Implicit1stXmm0),
565 BITFIELD (RepPrefixOk),
566 BITFIELD (HLEPrefixOk),
569 BITFIELD (AddrPrefixOp0),
578 BITFIELD (VexOpcode),
579 BITFIELD (VexSources),
580 BITFIELD (VexImmExt),
587 BITFIELD (Broadcast),
588 BITFIELD (StaticRounding),
590 BITFIELD (Disp8MemShift),
591 BITFIELD (NoDefMask),
592 BITFIELD (ImplicitQuadGroup),
594 BITFIELD (ATTMnemonic),
595 BITFIELD (ATTSyntax),
596 BITFIELD (IntelSyntax),
601 static bitfield operand_types[] =
620 BITFIELD (BaseIndex),
626 BITFIELD (InOutPortReg),
627 BITFIELD (ShiftCount),
635 BITFIELD (JumpAbsolute),
648 BITFIELD (Unspecified),
652 BITFIELD (Vec_Disp8),
658 static const char *filename;
661 compare (const void *x, const void *y)
663 const bitfield *xp = (const bitfield *) x;
664 const bitfield *yp = (const bitfield *) y;
665 return xp->position - yp->position;
669 fail (const char *message, ...)
673 va_start (args, message);
674 fprintf (stderr, _("%s: Error: "), program_name);
675 vfprintf (stderr, message, args);
681 process_copyright (FILE *fp)
683 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
684 /* Copyright (C) 2007-2016 Free Software Foundation, Inc.\n\
686 This file is part of the GNU opcodes library.\n\
688 This library is free software; you can redistribute it and/or modify\n\
689 it under the terms of the GNU General Public License as published by\n\
690 the Free Software Foundation; either version 3, or (at your option)\n\
691 any later version.\n\
693 It is distributed in the hope that it will be useful, but WITHOUT\n\
694 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
695 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
696 License for more details.\n\
698 You should have received a copy of the GNU General Public License\n\
699 along with this program; if not, write to the Free Software\n\
700 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
701 MA 02110-1301, USA. */\n");
704 /* Remove leading white spaces. */
707 remove_leading_whitespaces (char *str)
709 while (ISSPACE (*str))
714 /* Remove trailing white spaces. */
717 remove_trailing_whitespaces (char *str)
719 size_t last = strlen (str);
727 if (ISSPACE (str [last]))
735 /* Find next field separated by SEP and terminate it. Return a
736 pointer to the one after it. */
739 next_field (char *str, char sep, char **next, char *last)
743 p = remove_leading_whitespaces (str);
744 for (str = p; *str != sep && *str != '\0'; str++);
747 remove_trailing_whitespaces (p);
757 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
760 set_bitfield_from_cpu_flag_init (char *f, bitfield *array,
761 int value, unsigned int size,
764 char *str, *next, *last;
767 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
768 if (strcmp (cpu_flag_init[i].name, f) == 0)
770 /* Turn on selective bits. */
771 char *init = xstrdup (cpu_flag_init[i].init);
772 last = init + strlen (init);
773 for (next = init; next && next < last; )
775 str = next_field (next, '|', &next, last);
777 set_bitfield (str, array, 1, size, lineno);
787 set_bitfield (char *f, bitfield *array, int value,
788 unsigned int size, int lineno)
792 if (strcmp (f, "CpuFP") == 0)
794 set_bitfield("Cpu387", array, value, size, lineno);
795 set_bitfield("Cpu287", array, value, size, lineno);
798 else if (strcmp (f, "Mmword") == 0)
800 else if (strcmp (f, "Oword") == 0)
803 for (i = 0; i < size; i++)
804 if (strcasecmp (array[i].name, f) == 0)
806 array[i].value = value;
812 const char *v = strchr (f, '=');
819 for (i = 0; i < size; i++)
820 if (strncasecmp (array[i].name, f, n) == 0)
822 value = strtol (v + 1, &end, 0);
825 array[i].value = value;
833 /* Handle CPU_XXX_FLAGS. */
834 if (!set_bitfield_from_cpu_flag_init (f, array, value, size, lineno))
838 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
840 fail (_("Unknown bitfield: %s\n"), f);
844 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
845 int macro, const char *comma, const char *indent)
849 fprintf (table, "%s{ { ", indent);
851 for (i = 0; i < size - 1; i++)
853 if (((i + 1) % 20) != 0)
854 fprintf (table, "%d, ", flags[i].value);
856 fprintf (table, "%d,", flags[i].value);
857 if (((i + 1) % 20) == 0)
859 /* We need \\ for macro. */
861 fprintf (table, " \\\n %s", indent);
863 fprintf (table, "\n %s", indent);
867 fprintf (table, "%d } }%s\n", flags[i].value, comma);
871 process_i386_cpu_flag (FILE *table, char *flag, int macro,
872 const char *comma, const char *indent,
875 char *str, *next, *last;
877 bitfield flags [ARRAY_SIZE (cpu_flags)];
879 /* Copy the default cpu flags. */
880 memcpy (flags, cpu_flags, sizeof (cpu_flags));
882 if (strcasecmp (flag, "unknown") == 0)
884 /* We turn on everything except for cpu64 in case of
885 CPU_UNKNOWN_FLAGS. */
886 for (i = 0; i < ARRAY_SIZE (flags); i++)
887 if (flags[i].position != Cpu64)
890 else if (flag[0] == '~')
892 last = flag + strlen (flag);
899 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
906 /* First we turn on everything except for cpu64. */
907 for (i = 0; i < ARRAY_SIZE (flags); i++)
908 if (flags[i].position != Cpu64)
911 /* Turn off selective bits. */
912 for (; next && next < last; )
914 str = next_field (next, '|', &next, last);
916 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
919 else if (strcmp (flag, "0"))
921 /* Turn on selective bits. */
922 last = flag + strlen (flag);
923 for (next = flag; next && next < last; )
925 str = next_field (next, '|', &next, last);
927 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
931 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
936 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
940 fprintf (table, " { ");
942 for (i = 0; i < size - 1; i++)
944 if (((i + 1) % 20) != 0)
945 fprintf (table, "%d, ", modifier[i].value);
947 fprintf (table, "%d,", modifier[i].value);
948 if (((i + 1) % 20) == 0)
949 fprintf (table, "\n ");
952 fprintf (table, "%d },\n", modifier[i].value);
956 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
958 char *str, *next, *last;
959 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
961 /* Copy the default opcode modifier. */
962 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
964 if (strcmp (mod, "0"))
966 last = mod + strlen (mod);
967 for (next = mod; next && next < last; )
969 str = next_field (next, '|', &next, last);
971 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
975 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
979 output_operand_type (FILE *table, bitfield *types, unsigned int size,
980 int macro, const char *indent)
984 fprintf (table, "{ { ");
986 for (i = 0; i < size - 1; i++)
988 if (((i + 1) % 20) != 0)
989 fprintf (table, "%d, ", types[i].value);
991 fprintf (table, "%d,", types[i].value);
992 if (((i + 1) % 20) == 0)
994 /* We need \\ for macro. */
996 fprintf (table, " \\\n%s", indent);
998 fprintf (table, "\n%s", indent);
1002 fprintf (table, "%d } }", types[i].value);
1006 process_i386_operand_type (FILE *table, char *op, int macro,
1007 const char *indent, int lineno)
1009 char *str, *next, *last;
1010 bitfield types [ARRAY_SIZE (operand_types)];
1012 /* Copy the default operand type. */
1013 memcpy (types, operand_types, sizeof (types));
1015 if (strcmp (op, "0"))
1017 last = op + strlen (op);
1018 for (next = op; next && next < last; )
1020 str = next_field (next, '|', &next, last);
1022 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1025 output_operand_type (table, types, ARRAY_SIZE (types), macro,
1030 output_i386_opcode (FILE *table, const char *name, char *str,
1031 char *last, int lineno)
1034 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1035 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1037 /* Find number of operands. */
1038 operands = next_field (str, ',', &str, last);
1040 /* Find base_opcode. */
1041 base_opcode = next_field (str, ',', &str, last);
1043 /* Find extension_opcode. */
1044 extension_opcode = next_field (str, ',', &str, last);
1046 /* Find opcode_length. */
1047 opcode_length = next_field (str, ',', &str, last);
1049 /* Find cpu_flags. */
1050 cpu_flags = next_field (str, ',', &str, last);
1052 /* Find opcode_modifier. */
1053 opcode_modifier = next_field (str, ',', &str, last);
1055 /* Remove the first {. */
1056 str = remove_leading_whitespaces (str);
1059 str = remove_leading_whitespaces (str + 1);
1063 /* There are at least "X}". */
1067 /* Remove trailing white spaces and }. */
1071 if (ISSPACE (str[i]) || str[i] == '}')
1080 /* Find operand_types. */
1081 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1085 operand_types [i] = NULL;
1089 operand_types [i] = next_field (str, ',', &str, last);
1090 if (*operand_types[i] == '0')
1093 operand_types[i] = NULL;
1098 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1099 name, operands, base_opcode, extension_opcode,
1102 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1104 process_i386_opcode_modifier (table, opcode_modifier, lineno);
1106 fprintf (table, " { ");
1108 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1110 if (operand_types[i] == NULL || *operand_types[i] == '0')
1113 process_i386_operand_type (table, "0", 0, "\t ", lineno);
1118 fprintf (table, ",\n ");
1120 process_i386_operand_type (table, operand_types[i], 0,
1123 fprintf (table, " } },\n");
1126 struct opcode_hash_entry
1128 struct opcode_hash_entry *next;
1134 /* Calculate the hash value of an opcode hash entry P. */
1137 opcode_hash_hash (const void *p)
1139 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1140 return htab_hash_string (entry->name);
1143 /* Compare a string Q against an opcode hash entry P. */
1146 opcode_hash_eq (const void *p, const void *q)
1148 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1149 const char *name = (const char *) q;
1150 return strcmp (name, entry->name) == 0;
1154 process_i386_opcodes (FILE *table)
1159 char *str, *p, *last, *name;
1160 struct opcode_hash_entry **hash_slot, **entry, *next;
1161 htab_t opcode_hash_table;
1162 struct opcode_hash_entry **opcode_array;
1163 unsigned int opcode_array_size = 1024;
1166 filename = "i386-opc.tbl";
1167 fp = fopen (filename, "r");
1170 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1174 opcode_array = (struct opcode_hash_entry **)
1175 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1177 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1178 opcode_hash_eq, NULL,
1181 fprintf (table, "\n/* i386 opcode table. */\n\n");
1182 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1184 /* Put everything on opcode array. */
1187 if (fgets (buf, sizeof (buf), fp) == NULL)
1192 p = remove_leading_whitespaces (buf);
1194 /* Skip comments. */
1195 str = strstr (p, "//");
1199 /* Remove trailing white spaces. */
1200 remove_trailing_whitespaces (p);
1205 /* Ignore comments. */
1213 last = p + strlen (p);
1216 name = next_field (p, ',', &str, last);
1218 /* Get the slot in hash table. */
1219 hash_slot = (struct opcode_hash_entry **)
1220 htab_find_slot_with_hash (opcode_hash_table, name,
1221 htab_hash_string (name),
1224 if (*hash_slot == NULL)
1226 /* It is the new one. Put it on opcode array. */
1227 if (i >= opcode_array_size)
1229 /* Grow the opcode array when needed. */
1230 opcode_array_size += 1024;
1231 opcode_array = (struct opcode_hash_entry **)
1232 xrealloc (opcode_array,
1233 sizeof (*opcode_array) * opcode_array_size);
1236 opcode_array[i] = (struct opcode_hash_entry *)
1237 xmalloc (sizeof (struct opcode_hash_entry));
1238 opcode_array[i]->next = NULL;
1239 opcode_array[i]->name = xstrdup (name);
1240 opcode_array[i]->opcode = xstrdup (str);
1241 opcode_array[i]->lineno = lineno;
1242 *hash_slot = opcode_array[i];
1247 /* Append it to the existing one. */
1249 while ((*entry) != NULL)
1250 entry = &(*entry)->next;
1251 *entry = (struct opcode_hash_entry *)
1252 xmalloc (sizeof (struct opcode_hash_entry));
1253 (*entry)->next = NULL;
1254 (*entry)->name = (*hash_slot)->name;
1255 (*entry)->opcode = xstrdup (str);
1256 (*entry)->lineno = lineno;
1260 /* Process opcode array. */
1261 for (j = 0; j < i; j++)
1263 for (next = opcode_array[j]; next; next = next->next)
1267 lineno = next->lineno;
1268 last = str + strlen (str);
1269 output_i386_opcode (table, name, str, last, lineno);
1275 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1277 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1279 process_i386_opcode_modifier (table, "0", -1);
1281 fprintf (table, " { ");
1282 process_i386_operand_type (table, "0", 0, "\t ", -1);
1283 fprintf (table, " } }\n");
1285 fprintf (table, "};\n");
1289 process_i386_registers (FILE *table)
1293 char *str, *p, *last;
1294 char *reg_name, *reg_type, *reg_flags, *reg_num;
1295 char *dw2_32_num, *dw2_64_num;
1298 filename = "i386-reg.tbl";
1299 fp = fopen (filename, "r");
1301 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1304 fprintf (table, "\n/* i386 register table. */\n\n");
1305 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1309 if (fgets (buf, sizeof (buf), fp) == NULL)
1314 p = remove_leading_whitespaces (buf);
1316 /* Skip comments. */
1317 str = strstr (p, "//");
1321 /* Remove trailing white spaces. */
1322 remove_trailing_whitespaces (p);
1327 fprintf (table, "%s\n", p);
1335 last = p + strlen (p);
1337 /* Find reg_name. */
1338 reg_name = next_field (p, ',', &str, last);
1340 /* Find reg_type. */
1341 reg_type = next_field (str, ',', &str, last);
1343 /* Find reg_flags. */
1344 reg_flags = next_field (str, ',', &str, last);
1347 reg_num = next_field (str, ',', &str, last);
1349 fprintf (table, " { \"%s\",\n ", reg_name);
1351 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1353 /* Find 32-bit Dwarf2 register number. */
1354 dw2_32_num = next_field (str, ',', &str, last);
1356 /* Find 64-bit Dwarf2 register number. */
1357 dw2_64_num = next_field (str, ',', &str, last);
1359 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1360 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1365 fprintf (table, "};\n");
1367 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1371 process_i386_initializers (void)
1374 FILE *fp = fopen ("i386-init.h", "w");
1378 fail (_("can't create i386-init.h, errno = %s\n"),
1381 process_copyright (fp);
1383 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1385 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1386 init = xstrdup (cpu_flag_init[i].init);
1387 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1391 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1393 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1394 init = xstrdup (operand_type_init[i].init);
1395 process_i386_operand_type (fp, init, 1, " ", -1);
1403 /* Program options. */
1404 #define OPTION_SRCDIR 200
1406 struct option long_options[] =
1408 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1409 {"debug", no_argument, NULL, 'd'},
1410 {"version", no_argument, NULL, 'V'},
1411 {"help", no_argument, NULL, 'h'},
1412 {0, no_argument, NULL, 0}
1416 print_version (void)
1418 printf ("%s: version 1.0\n", program_name);
1423 usage (FILE * stream, int status)
1425 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1431 main (int argc, char **argv)
1433 extern int chdir (char *);
1434 char *srcdir = NULL;
1436 unsigned int i, cpumax;
1439 program_name = *argv;
1440 xmalloc_set_program_name (program_name);
1442 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1467 if (chdir (srcdir) != 0)
1468 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1469 srcdir, xstrerror (errno));
1471 /* cpu_flags isn't sorted by position. */
1473 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1474 if (cpu_flags[i].position > cpumax)
1475 cpumax = cpu_flags[i].position;
1477 /* Check the unused bitfield in i386_cpu_flags. */
1479 if ((cpumax - 1) != CpuMax)
1480 fail (_("CpuMax != %d!\n"), cpumax);
1482 if (cpumax != CpuMax)
1483 fail (_("CpuMax != %d!\n"), cpumax);
1485 c = CpuNumOfBits - CpuMax - 1;
1487 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1490 /* Check the unused bitfield in i386_operand_type. */
1492 c = OTNumOfBits - OTMax - 1;
1494 fail (_("%d unused bits in i386_operand_type.\n"), c);
1497 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1500 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1501 sizeof (opcode_modifiers [0]), compare);
1503 qsort (operand_types, ARRAY_SIZE (operand_types),
1504 sizeof (operand_types [0]), compare);
1506 table = fopen ("i386-tbl.h", "w");
1508 fail (_("can't create i386-tbl.h, errno = %s\n"),
1511 process_copyright (table);
1513 process_i386_opcodes (table);
1514 process_i386_registers (table);
1515 process_i386_initializers ();