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|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" },
228 { "CPU_AVX512_VNNI_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
230 { "CPU_AVX512_BITALG_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
237 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
240 { "CPU_RDSEED_FLAGS",
242 { "CPU_PRFCHW_FLAGS",
249 "CPU_SSE2_FLAGS|CpuSHA" },
250 { "CPU_CLFLUSHOPT_FLAGS",
252 { "CPU_XSAVES_FLAGS",
253 "CPU_XSAVE_FLAGS|CpuXSAVES" },
254 { "CPU_XSAVEC_FLAGS",
255 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
256 { "CPU_PREFETCHWT1_FLAGS",
262 { "CPU_CLZERO_FLAGS",
264 { "CPU_MWAITX_FLAGS",
270 { "CPU_PTWRITE_FLAGS",
280 { "CPU_VPCLMULQDQ_FLAGS",
282 { "CPU_WBNOINVD_FLAGS",
284 { "CPU_PCONFIG_FLAGS",
286 { "CPU_ANY_X87_FLAGS",
287 "CPU_ANY_287_FLAGS|Cpu8087" },
288 { "CPU_ANY_287_FLAGS",
289 "CPU_ANY_387_FLAGS|Cpu287" },
290 { "CPU_ANY_387_FLAGS",
291 "CPU_ANY_687_FLAGS|Cpu387" },
292 { "CPU_ANY_687_FLAGS",
293 "Cpu687|CpuFISTTP" },
294 { "CPU_ANY_MMX_FLAGS",
295 "CPU_3DNOWA_FLAGS" },
296 { "CPU_ANY_SSE_FLAGS",
297 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
298 { "CPU_ANY_SSE2_FLAGS",
299 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
300 { "CPU_ANY_SSE3_FLAGS",
301 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
302 { "CPU_ANY_SSSE3_FLAGS",
303 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
304 { "CPU_ANY_SSE4_1_FLAGS",
305 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
306 { "CPU_ANY_SSE4_2_FLAGS",
308 { "CPU_ANY_AVX_FLAGS",
309 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
310 { "CPU_ANY_AVX2_FLAGS",
312 { "CPU_ANY_AVX512F_FLAGS",
313 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512F" },
314 { "CPU_ANY_AVX512CD_FLAGS",
316 { "CPU_ANY_AVX512ER_FLAGS",
318 { "CPU_ANY_AVX512PF_FLAGS",
320 { "CPU_ANY_AVX512DQ_FLAGS",
322 { "CPU_ANY_AVX512BW_FLAGS",
324 { "CPU_ANY_AVX512VL_FLAGS",
326 { "CPU_ANY_AVX512IFMA_FLAGS",
328 { "CPU_ANY_AVX512VBMI_FLAGS",
330 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
331 "CpuAVX512_4FMAPS" },
332 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
333 "CpuAVX512_4VNNIW" },
334 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
335 "CpuAVX512_VPOPCNTDQ" },
336 { "CPU_ANY_IBT_FLAGS",
338 { "CPU_ANY_SHSTK_FLAGS",
340 { "CPU_ANY_AVX512_VBMI2_FLAGS",
342 { "CPU_ANY_AVX512_VNNI_FLAGS",
344 { "CPU_ANY_AVX512_BITALG_FLAGS",
345 "CpuAVX512_BITALG" },
348 static const initializer operand_type_shorthands[] =
350 { "Reg8", "Reg|Byte" },
351 { "Reg16", "Reg|Word" },
352 { "Reg32", "Reg|Dword" },
353 { "Reg64", "Reg|Qword" },
354 { "FloatAcc", "Acc|Tbyte" },
355 { "FloatReg", "Reg|Tbyte" },
356 { "RegXMM", "RegSIMD|Xmmword" },
357 { "RegYMM", "RegSIMD|Ymmword" },
358 { "RegZMM", "RegSIMD|Zmmword" },
361 static initializer operand_type_init[] =
363 { "OPERAND_TYPE_NONE",
365 { "OPERAND_TYPE_REG8",
367 { "OPERAND_TYPE_REG16",
369 { "OPERAND_TYPE_REG32",
371 { "OPERAND_TYPE_REG64",
373 { "OPERAND_TYPE_IMM1",
375 { "OPERAND_TYPE_IMM8",
377 { "OPERAND_TYPE_IMM8S",
379 { "OPERAND_TYPE_IMM16",
381 { "OPERAND_TYPE_IMM32",
383 { "OPERAND_TYPE_IMM32S",
385 { "OPERAND_TYPE_IMM64",
387 { "OPERAND_TYPE_BASEINDEX",
389 { "OPERAND_TYPE_DISP8",
391 { "OPERAND_TYPE_DISP16",
393 { "OPERAND_TYPE_DISP32",
395 { "OPERAND_TYPE_DISP32S",
397 { "OPERAND_TYPE_DISP64",
399 { "OPERAND_TYPE_INOUTPORTREG",
401 { "OPERAND_TYPE_SHIFTCOUNT",
403 { "OPERAND_TYPE_CONTROL",
405 { "OPERAND_TYPE_TEST",
407 { "OPERAND_TYPE_DEBUG",
409 { "OPERAND_TYPE_FLOATREG",
411 { "OPERAND_TYPE_FLOATACC",
413 { "OPERAND_TYPE_SREG2",
415 { "OPERAND_TYPE_SREG3",
417 { "OPERAND_TYPE_ACC",
419 { "OPERAND_TYPE_JUMPABSOLUTE",
421 { "OPERAND_TYPE_REGMMX",
423 { "OPERAND_TYPE_REGXMM",
425 { "OPERAND_TYPE_REGYMM",
427 { "OPERAND_TYPE_REGZMM",
429 { "OPERAND_TYPE_REGMASK",
431 { "OPERAND_TYPE_ESSEG",
433 { "OPERAND_TYPE_ACC32",
435 { "OPERAND_TYPE_ACC64",
437 { "OPERAND_TYPE_INOUTPORTREG",
439 { "OPERAND_TYPE_REG16_INOUTPORTREG",
440 "Reg16|InOutPortReg" },
441 { "OPERAND_TYPE_DISP16_32",
443 { "OPERAND_TYPE_ANYDISP",
444 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
445 { "OPERAND_TYPE_IMM16_32",
447 { "OPERAND_TYPE_IMM16_32S",
449 { "OPERAND_TYPE_IMM16_32_32S",
450 "Imm16|Imm32|Imm32S" },
451 { "OPERAND_TYPE_IMM32_64",
453 { "OPERAND_TYPE_IMM32_32S_DISP32",
454 "Imm32|Imm32S|Disp32" },
455 { "OPERAND_TYPE_IMM64_DISP64",
457 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
458 "Imm32|Imm32S|Imm64|Disp32" },
459 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
460 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
461 { "OPERAND_TYPE_VEC_IMM4",
463 { "OPERAND_TYPE_REGBND",
467 typedef struct bitfield
474 #define BITFIELD(n) { n, 0, #n }
476 static bitfield cpu_flags[] =
484 BITFIELD (CpuClflush),
486 BITFIELD (CpuSYSCALL),
491 BITFIELD (CpuFISTTP),
497 BITFIELD (CpuSSE4_1),
498 BITFIELD (CpuSSE4_2),
501 BITFIELD (CpuAVX512F),
502 BITFIELD (CpuAVX512CD),
503 BITFIELD (CpuAVX512ER),
504 BITFIELD (CpuAVX512PF),
505 BITFIELD (CpuAVX512VL),
506 BITFIELD (CpuAVX512DQ),
507 BITFIELD (CpuAVX512BW),
513 BITFIELD (Cpu3dnowA),
514 BITFIELD (CpuPadLock),
520 BITFIELD (CpuXsaveopt),
522 BITFIELD (CpuPCLMUL),
533 BITFIELD (CpuRdtscp),
534 BITFIELD (CpuFSGSBase),
541 BITFIELD (CpuINVPCID),
542 BITFIELD (CpuVMFUNC),
543 BITFIELD (CpuRDSEED),
545 BITFIELD (CpuPRFCHW),
549 BITFIELD (CpuClflushOpt),
550 BITFIELD (CpuXSAVES),
551 BITFIELD (CpuXSAVEC),
552 BITFIELD (CpuPREFETCHWT1),
558 BITFIELD (CpuAVX512IFMA),
559 BITFIELD (CpuAVX512VBMI),
560 BITFIELD (CpuAVX512_4FMAPS),
561 BITFIELD (CpuAVX512_4VNNIW),
562 BITFIELD (CpuAVX512_VPOPCNTDQ),
563 BITFIELD (CpuAVX512_VBMI2),
564 BITFIELD (CpuAVX512_VNNI),
565 BITFIELD (CpuAVX512_BITALG),
566 BITFIELD (CpuMWAITX),
567 BITFIELD (CpuCLZERO),
570 BITFIELD (CpuPTWRITE),
575 BITFIELD (CpuVPCLMULQDQ),
576 BITFIELD (CpuWBNOINVD),
577 BITFIELD (CpuPCONFIG),
578 BITFIELD (CpuRegMMX),
579 BITFIELD (CpuRegXMM),
580 BITFIELD (CpuRegYMM),
581 BITFIELD (CpuRegZMM),
582 BITFIELD (CpuRegMask),
584 BITFIELD (CpuUnused),
588 static bitfield opcode_modifiers[] =
594 BITFIELD (ShortForm),
596 BITFIELD (JumpDword),
598 BITFIELD (JumpInterSegment),
604 BITFIELD (CheckRegSize),
605 BITFIELD (IgnoreSize),
606 BITFIELD (DefaultSize),
615 BITFIELD (BNDPrefixOk),
616 BITFIELD (NoTrackPrefixOk),
617 BITFIELD (IsLockable),
618 BITFIELD (RegKludge),
619 BITFIELD (Implicit1stXmm0),
620 BITFIELD (RepPrefixOk),
621 BITFIELD (HLEPrefixOk),
624 BITFIELD (AddrPrefixOp0),
633 BITFIELD (VexOpcode),
634 BITFIELD (VexSources),
635 BITFIELD (VexImmExt),
642 BITFIELD (Broadcast),
643 BITFIELD (StaticRounding),
645 BITFIELD (Disp8MemShift),
646 BITFIELD (NoDefMask),
647 BITFIELD (ImplicitQuadGroup),
650 BITFIELD (ATTMnemonic),
651 BITFIELD (ATTSyntax),
652 BITFIELD (IntelSyntax),
657 static bitfield operand_types[] =
670 BITFIELD (BaseIndex),
676 BITFIELD (InOutPortReg),
677 BITFIELD (ShiftCount),
684 BITFIELD (JumpAbsolute),
697 BITFIELD (Unspecified),
706 static const char *filename;
707 static i386_cpu_flags active_cpu_flags;
708 static int active_isstring;
711 compare (const void *x, const void *y)
713 const bitfield *xp = (const bitfield *) x;
714 const bitfield *yp = (const bitfield *) y;
715 return xp->position - yp->position;
719 fail (const char *message, ...)
723 va_start (args, message);
724 fprintf (stderr, _("%s: error: "), program_name);
725 vfprintf (stderr, message, args);
731 process_copyright (FILE *fp)
733 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
734 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
736 This file is part of the GNU opcodes library.\n\
738 This library is free software; you can redistribute it and/or modify\n\
739 it under the terms of the GNU General Public License as published by\n\
740 the Free Software Foundation; either version 3, or (at your option)\n\
741 any later version.\n\
743 It is distributed in the hope that it will be useful, but WITHOUT\n\
744 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
745 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
746 License for more details.\n\
748 You should have received a copy of the GNU General Public License\n\
749 along with this program; if not, write to the Free Software\n\
750 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
751 MA 02110-1301, USA. */\n");
754 /* Remove leading white spaces. */
757 remove_leading_whitespaces (char *str)
759 while (ISSPACE (*str))
764 /* Remove trailing white spaces. */
767 remove_trailing_whitespaces (char *str)
769 size_t last = strlen (str);
777 if (ISSPACE (str [last]))
785 /* Find next field separated by SEP and terminate it. Return a
786 pointer to the one after it. */
789 next_field (char *str, char sep, char **next, char *last)
793 p = remove_leading_whitespaces (str);
794 for (str = p; *str != sep && *str != '\0'; str++);
797 remove_trailing_whitespaces (p);
807 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
810 set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
813 char *str, *next, *last;
816 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
817 if (strcmp (cpu_flag_init[i].name, f) == 0)
819 /* Turn on selective bits. */
820 char *init = xstrdup (cpu_flag_init[i].init);
821 last = init + strlen (init);
822 for (next = init; next && next < last; )
824 str = next_field (next, '|', &next, last);
826 set_bitfield (str, array, 1, size, lineno);
832 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
833 if (strcmp (operand_type_shorthands[i].name, f) == 0)
835 /* Turn on selective bits. */
836 char *init = xstrdup (operand_type_shorthands[i].init);
837 last = init + strlen (init);
838 for (next = init; next && next < last; )
840 str = next_field (next, '|', &next, last);
842 set_bitfield (str, array, 1, size, lineno);
852 set_bitfield (char *f, bitfield *array, int value,
853 unsigned int size, int lineno)
857 if (strcmp (f, "CpuFP") == 0)
859 set_bitfield("Cpu387", array, value, size, lineno);
860 set_bitfield("Cpu287", array, value, size, lineno);
863 else if (strcmp (f, "Mmword") == 0)
865 else if (strcmp (f, "Oword") == 0)
868 for (i = 0; i < size; i++)
869 if (strcasecmp (array[i].name, f) == 0)
871 array[i].value = value;
877 const char *v = strchr (f, '=');
884 for (i = 0; i < size; i++)
885 if (strncasecmp (array[i].name, f, n) == 0)
887 value = strtol (v + 1, &end, 0);
890 array[i].value = value;
898 /* Handle shorthands. */
899 if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno))
903 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
905 fail (_("unknown bitfield: %s\n"), f);
909 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
910 int macro, const char *comma, const char *indent)
914 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
916 fprintf (table, "%s{ { ", indent);
918 for (i = 0; i < size - 1; i++)
920 if (((i + 1) % 20) != 0)
921 fprintf (table, "%d, ", flags[i].value);
923 fprintf (table, "%d,", flags[i].value);
924 if (((i + 1) % 20) == 0)
926 /* We need \\ for macro. */
928 fprintf (table, " \\\n %s", indent);
930 fprintf (table, "\n %s", indent);
933 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
936 fprintf (table, "%d } }%s\n", flags[i].value, comma);
940 process_i386_cpu_flag (FILE *table, char *flag, int macro,
941 const char *comma, const char *indent,
944 char *str, *next, *last;
946 bitfield flags [ARRAY_SIZE (cpu_flags)];
948 /* Copy the default cpu flags. */
949 memcpy (flags, cpu_flags, sizeof (cpu_flags));
951 if (strcasecmp (flag, "unknown") == 0)
953 /* We turn on everything except for cpu64 in case of
954 CPU_UNKNOWN_FLAGS. */
955 for (i = 0; i < ARRAY_SIZE (flags); i++)
956 if (flags[i].position != Cpu64)
959 else if (flag[0] == '~')
961 last = flag + strlen (flag);
968 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
975 /* First we turn on everything except for cpu64. */
976 for (i = 0; i < ARRAY_SIZE (flags); i++)
977 if (flags[i].position != Cpu64)
980 /* Turn off selective bits. */
981 for (; next && next < last; )
983 str = next_field (next, '|', &next, last);
985 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
988 else if (strcmp (flag, "0"))
990 /* Turn on selective bits. */
991 last = flag + strlen (flag);
992 for (next = flag; next && next < last; )
994 str = next_field (next, '|', &next, last);
996 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1000 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1005 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1009 fprintf (table, " { ");
1011 for (i = 0; i < size - 1; i++)
1013 if (((i + 1) % 20) != 0)
1014 fprintf (table, "%d, ", modifier[i].value);
1016 fprintf (table, "%d,", modifier[i].value);
1017 if (((i + 1) % 20) == 0)
1018 fprintf (table, "\n ");
1021 fprintf (table, "%d },\n", modifier[i].value);
1025 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
1027 char *str, *next, *last;
1028 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1030 active_isstring = 0;
1032 /* Copy the default opcode modifier. */
1033 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1035 if (strcmp (mod, "0"))
1037 last = mod + strlen (mod);
1038 for (next = mod; next && next < last; )
1040 str = next_field (next, '|', &next, last);
1043 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
1045 if (strcasecmp(str, "IsString") == 0)
1046 active_isstring = 1;
1050 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1060 output_operand_type (FILE *table, bitfield *types, unsigned int size,
1061 enum stage stage, const char *indent)
1065 fprintf (table, "{ { ");
1067 for (i = 0; i < size - 1; i++)
1069 if (((i + 1) % 20) != 0)
1070 fprintf (table, "%d, ", types[i].value);
1072 fprintf (table, "%d,", types[i].value);
1073 if (((i + 1) % 20) == 0)
1075 /* We need \\ for macro. */
1076 if (stage == stage_macros)
1077 fprintf (table, " \\\n%s", indent);
1079 fprintf (table, "\n%s", indent);
1083 fprintf (table, "%d } }", types[i].value);
1087 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1088 const char *indent, int lineno)
1090 char *str, *next, *last;
1091 bitfield types [ARRAY_SIZE (operand_types)];
1093 /* Copy the default operand type. */
1094 memcpy (types, operand_types, sizeof (types));
1096 if (strcmp (op, "0"))
1100 last = op + strlen (op);
1101 for (next = op; next && next < last; )
1103 str = next_field (next, '|', &next, last);
1106 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1107 if (strcasecmp(str, "BaseIndex") == 0)
1112 if (stage == stage_opcodes && baseindex && !active_isstring)
1114 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1115 if (!active_cpu_flags.bitfield.cpu64
1116 && !active_cpu_flags.bitfield.cpumpx)
1117 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1118 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1119 if (!active_cpu_flags.bitfield.cpuno64)
1120 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1123 output_operand_type (table, types, ARRAY_SIZE (types), stage,
1128 output_i386_opcode (FILE *table, const char *name, char *str,
1129 char *last, int lineno)
1132 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1133 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1135 /* Find number of operands. */
1136 operands = next_field (str, ',', &str, last);
1138 /* Find base_opcode. */
1139 base_opcode = next_field (str, ',', &str, last);
1141 /* Find extension_opcode. */
1142 extension_opcode = next_field (str, ',', &str, last);
1144 /* Find opcode_length. */
1145 opcode_length = next_field (str, ',', &str, last);
1147 /* Find cpu_flags. */
1148 cpu_flags = next_field (str, ',', &str, last);
1150 /* Find opcode_modifier. */
1151 opcode_modifier = next_field (str, ',', &str, last);
1153 /* Remove the first {. */
1154 str = remove_leading_whitespaces (str);
1157 str = remove_leading_whitespaces (str + 1);
1161 /* There are at least "X}". */
1165 /* Remove trailing white spaces and }. */
1169 if (ISSPACE (str[i]) || str[i] == '}')
1178 /* Find operand_types. */
1179 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1183 operand_types [i] = NULL;
1187 operand_types [i] = next_field (str, ',', &str, last);
1188 if (*operand_types[i] == '0')
1191 operand_types[i] = NULL;
1196 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1197 name, operands, base_opcode, extension_opcode,
1200 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1202 process_i386_opcode_modifier (table, opcode_modifier, lineno);
1204 fprintf (table, " { ");
1206 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1208 if (operand_types[i] == NULL || *operand_types[i] == '0')
1211 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1217 fprintf (table, ",\n ");
1219 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1222 fprintf (table, " } },\n");
1225 struct opcode_hash_entry
1227 struct opcode_hash_entry *next;
1233 /* Calculate the hash value of an opcode hash entry P. */
1236 opcode_hash_hash (const void *p)
1238 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1239 return htab_hash_string (entry->name);
1242 /* Compare a string Q against an opcode hash entry P. */
1245 opcode_hash_eq (const void *p, const void *q)
1247 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1248 const char *name = (const char *) q;
1249 return strcmp (name, entry->name) == 0;
1253 process_i386_opcodes (FILE *table)
1258 char *str, *p, *last, *name;
1259 struct opcode_hash_entry **hash_slot, **entry, *next;
1260 htab_t opcode_hash_table;
1261 struct opcode_hash_entry **opcode_array;
1262 unsigned int opcode_array_size = 1024;
1265 filename = "i386-opc.tbl";
1266 fp = fopen (filename, "r");
1269 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1273 opcode_array = (struct opcode_hash_entry **)
1274 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1276 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1277 opcode_hash_eq, NULL,
1280 fprintf (table, "\n/* i386 opcode table. */\n\n");
1281 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1283 /* Put everything on opcode array. */
1286 if (fgets (buf, sizeof (buf), fp) == NULL)
1291 p = remove_leading_whitespaces (buf);
1293 /* Skip comments. */
1294 str = strstr (p, "//");
1298 /* Remove trailing white spaces. */
1299 remove_trailing_whitespaces (p);
1304 /* Ignore comments. */
1312 last = p + strlen (p);
1315 name = next_field (p, ',', &str, last);
1317 /* Get the slot in hash table. */
1318 hash_slot = (struct opcode_hash_entry **)
1319 htab_find_slot_with_hash (opcode_hash_table, name,
1320 htab_hash_string (name),
1323 if (*hash_slot == NULL)
1325 /* It is the new one. Put it on opcode array. */
1326 if (i >= opcode_array_size)
1328 /* Grow the opcode array when needed. */
1329 opcode_array_size += 1024;
1330 opcode_array = (struct opcode_hash_entry **)
1331 xrealloc (opcode_array,
1332 sizeof (*opcode_array) * opcode_array_size);
1335 opcode_array[i] = (struct opcode_hash_entry *)
1336 xmalloc (sizeof (struct opcode_hash_entry));
1337 opcode_array[i]->next = NULL;
1338 opcode_array[i]->name = xstrdup (name);
1339 opcode_array[i]->opcode = xstrdup (str);
1340 opcode_array[i]->lineno = lineno;
1341 *hash_slot = opcode_array[i];
1346 /* Append it to the existing one. */
1348 while ((*entry) != NULL)
1349 entry = &(*entry)->next;
1350 *entry = (struct opcode_hash_entry *)
1351 xmalloc (sizeof (struct opcode_hash_entry));
1352 (*entry)->next = NULL;
1353 (*entry)->name = (*hash_slot)->name;
1354 (*entry)->opcode = xstrdup (str);
1355 (*entry)->lineno = lineno;
1359 /* Process opcode array. */
1360 for (j = 0; j < i; j++)
1362 for (next = opcode_array[j]; next; next = next->next)
1366 lineno = next->lineno;
1367 last = str + strlen (str);
1368 output_i386_opcode (table, name, str, last, lineno);
1374 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1376 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1378 process_i386_opcode_modifier (table, "0", -1);
1380 fprintf (table, " { ");
1381 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1382 fprintf (table, " } }\n");
1384 fprintf (table, "};\n");
1388 process_i386_registers (FILE *table)
1392 char *str, *p, *last;
1393 char *reg_name, *reg_type, *reg_flags, *reg_num;
1394 char *dw2_32_num, *dw2_64_num;
1397 filename = "i386-reg.tbl";
1398 fp = fopen (filename, "r");
1400 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1403 fprintf (table, "\n/* i386 register table. */\n\n");
1404 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1408 if (fgets (buf, sizeof (buf), fp) == NULL)
1413 p = remove_leading_whitespaces (buf);
1415 /* Skip comments. */
1416 str = strstr (p, "//");
1420 /* Remove trailing white spaces. */
1421 remove_trailing_whitespaces (p);
1426 fprintf (table, "%s\n", p);
1434 last = p + strlen (p);
1436 /* Find reg_name. */
1437 reg_name = next_field (p, ',', &str, last);
1439 /* Find reg_type. */
1440 reg_type = next_field (str, ',', &str, last);
1442 /* Find reg_flags. */
1443 reg_flags = next_field (str, ',', &str, last);
1446 reg_num = next_field (str, ',', &str, last);
1448 fprintf (table, " { \"%s\",\n ", reg_name);
1450 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1453 /* Find 32-bit Dwarf2 register number. */
1454 dw2_32_num = next_field (str, ',', &str, last);
1456 /* Find 64-bit Dwarf2 register number. */
1457 dw2_64_num = next_field (str, ',', &str, last);
1459 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1460 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1465 fprintf (table, "};\n");
1467 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1471 process_i386_initializers (void)
1474 FILE *fp = fopen ("i386-init.h", "w");
1478 fail (_("can't create i386-init.h, errno = %s\n"),
1481 process_copyright (fp);
1483 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1485 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1486 init = xstrdup (cpu_flag_init[i].init);
1487 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1491 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1493 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1494 init = xstrdup (operand_type_init[i].init);
1495 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1503 /* Program options. */
1504 #define OPTION_SRCDIR 200
1506 struct option long_options[] =
1508 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1509 {"debug", no_argument, NULL, 'd'},
1510 {"version", no_argument, NULL, 'V'},
1511 {"help", no_argument, NULL, 'h'},
1512 {0, no_argument, NULL, 0}
1516 print_version (void)
1518 printf ("%s: version 1.0\n", program_name);
1523 usage (FILE * stream, int status)
1525 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1531 main (int argc, char **argv)
1533 extern int chdir (char *);
1534 char *srcdir = NULL;
1536 unsigned int i, cpumax;
1539 program_name = *argv;
1540 xmalloc_set_program_name (program_name);
1542 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1567 if (chdir (srcdir) != 0)
1568 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1569 srcdir, xstrerror (errno));
1571 /* cpu_flags isn't sorted by position. */
1573 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1574 if (cpu_flags[i].position > cpumax)
1575 cpumax = cpu_flags[i].position;
1577 /* Check the unused bitfield in i386_cpu_flags. */
1579 if ((cpumax - 1) != CpuMax)
1580 fail (_("CpuMax != %d!\n"), cpumax);
1582 if (cpumax != CpuMax)
1583 fail (_("CpuMax != %d!\n"), cpumax);
1585 c = CpuNumOfBits - CpuMax - 1;
1587 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1590 /* Check the unused bitfield in i386_operand_type. */
1592 c = OTNumOfBits - OTMax - 1;
1594 fail (_("%d unused bits in i386_operand_type.\n"), c);
1597 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1600 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1601 sizeof (opcode_modifiers [0]), compare);
1603 qsort (operand_types, ARRAY_SIZE (operand_types),
1604 sizeof (operand_types [0]), compare);
1606 table = fopen ("i386-tbl.h", "w");
1608 fail (_("can't create i386-tbl.h, errno = %s\n"),
1611 process_copyright (table);
1613 process_i386_opcodes (table);
1614 process_i386_registers (table);
1615 process_i386_initializers ();