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|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 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG" },
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_DISP16_32",
449 { "OPERAND_TYPE_ANYDISP",
450 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
451 { "OPERAND_TYPE_IMM16_32",
453 { "OPERAND_TYPE_IMM16_32S",
455 { "OPERAND_TYPE_IMM16_32_32S",
456 "Imm16|Imm32|Imm32S" },
457 { "OPERAND_TYPE_IMM32_64",
459 { "OPERAND_TYPE_IMM32_32S_DISP32",
460 "Imm32|Imm32S|Disp32" },
461 { "OPERAND_TYPE_IMM64_DISP64",
463 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
464 "Imm32|Imm32S|Imm64|Disp32" },
465 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
466 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
467 { "OPERAND_TYPE_VEC_IMM4",
469 { "OPERAND_TYPE_REGBND",
473 typedef struct bitfield
480 #define BITFIELD(n) { n, 0, #n }
482 static bitfield cpu_flags
[] =
490 BITFIELD (CpuClflush
),
492 BITFIELD (CpuSYSCALL
),
497 BITFIELD (CpuFISTTP
),
503 BITFIELD (CpuSSE4_1
),
504 BITFIELD (CpuSSE4_2
),
507 BITFIELD (CpuAVX512F
),
508 BITFIELD (CpuAVX512CD
),
509 BITFIELD (CpuAVX512ER
),
510 BITFIELD (CpuAVX512PF
),
511 BITFIELD (CpuAVX512VL
),
512 BITFIELD (CpuAVX512DQ
),
513 BITFIELD (CpuAVX512BW
),
519 BITFIELD (Cpu3dnowA
),
520 BITFIELD (CpuPadLock
),
526 BITFIELD (CpuXsaveopt
),
528 BITFIELD (CpuPCLMUL
),
539 BITFIELD (CpuRdtscp
),
540 BITFIELD (CpuFSGSBase
),
547 BITFIELD (CpuINVPCID
),
548 BITFIELD (CpuVMFUNC
),
549 BITFIELD (CpuRDSEED
),
551 BITFIELD (CpuPRFCHW
),
554 BITFIELD (CpuClflushOpt
),
555 BITFIELD (CpuXSAVES
),
556 BITFIELD (CpuXSAVEC
),
557 BITFIELD (CpuPREFETCHWT1
),
563 BITFIELD (CpuAVX512IFMA
),
564 BITFIELD (CpuAVX512VBMI
),
565 BITFIELD (CpuAVX512_4FMAPS
),
566 BITFIELD (CpuAVX512_4VNNIW
),
567 BITFIELD (CpuAVX512_VPOPCNTDQ
),
568 BITFIELD (CpuAVX512_VBMI2
),
569 BITFIELD (CpuAVX512_VNNI
),
570 BITFIELD (CpuAVX512_BITALG
),
571 BITFIELD (CpuMWAITX
),
572 BITFIELD (CpuCLZERO
),
575 BITFIELD (CpuPTWRITE
),
580 BITFIELD (CpuVPCLMULQDQ
),
581 BITFIELD (CpuWBNOINVD
),
582 BITFIELD (CpuPCONFIG
),
583 BITFIELD (CpuWAITPKG
),
584 BITFIELD (CpuCLDEMOTE
),
585 BITFIELD (CpuMOVDIRI
),
586 BITFIELD (CpuMOVDIR64B
),
588 BITFIELD (CpuUnused
),
592 static bitfield opcode_modifiers
[] =
598 BITFIELD (ShortForm
),
600 BITFIELD (JumpDword
),
602 BITFIELD (JumpInterSegment
),
608 BITFIELD (CheckRegSize
),
609 BITFIELD (IgnoreSize
),
610 BITFIELD (DefaultSize
),
619 BITFIELD (BNDPrefixOk
),
620 BITFIELD (NoTrackPrefixOk
),
621 BITFIELD (IsLockable
),
622 BITFIELD (RegKludge
),
623 BITFIELD (Implicit1stXmm0
),
624 BITFIELD (RepPrefixOk
),
625 BITFIELD (HLEPrefixOk
),
628 BITFIELD (AddrPrefixOpReg
),
637 BITFIELD (VexOpcode
),
638 BITFIELD (VexSources
),
644 BITFIELD (Broadcast
),
645 BITFIELD (StaticRounding
),
647 BITFIELD (Disp8MemShift
),
648 BITFIELD (NoDefMask
),
649 BITFIELD (ImplicitQuadGroup
),
651 BITFIELD (ATTMnemonic
),
652 BITFIELD (ATTSyntax
),
653 BITFIELD (IntelSyntax
),
658 static bitfield operand_types
[] =
671 BITFIELD (BaseIndex
),
677 BITFIELD (InOutPortReg
),
678 BITFIELD (ShiftCount
),
685 BITFIELD (JumpAbsolute
),
698 BITFIELD (Unspecified
),
707 static const char *filename
;
708 static i386_cpu_flags active_cpu_flags
;
709 static int active_isstring
;
712 compare (const void *x
, const void *y
)
714 const bitfield
*xp
= (const bitfield
*) x
;
715 const bitfield
*yp
= (const bitfield
*) y
;
716 return xp
->position
- yp
->position
;
720 fail (const char *message
, ...)
724 va_start (args
, message
);
725 fprintf (stderr
, _("%s: error: "), program_name
);
726 vfprintf (stderr
, message
, args
);
732 process_copyright (FILE *fp
)
734 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
735 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
737 This file is part of the GNU opcodes library.\n\
739 This library is free software; you can redistribute it and/or modify\n\
740 it under the terms of the GNU General Public License as published by\n\
741 the Free Software Foundation; either version 3, or (at your option)\n\
742 any later version.\n\
744 It is distributed in the hope that it will be useful, but WITHOUT\n\
745 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
746 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
747 License for more details.\n\
749 You should have received a copy of the GNU General Public License\n\
750 along with this program; if not, write to the Free Software\n\
751 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
752 MA 02110-1301, USA. */\n");
755 /* Remove leading white spaces. */
758 remove_leading_whitespaces (char *str
)
760 while (ISSPACE (*str
))
765 /* Remove trailing white spaces. */
768 remove_trailing_whitespaces (char *str
)
770 size_t last
= strlen (str
);
778 if (ISSPACE (str
[last
]))
786 /* Find next field separated by SEP and terminate it. Return a
787 pointer to the one after it. */
790 next_field (char *str
, char sep
, char **next
, char *last
)
794 p
= remove_leading_whitespaces (str
);
795 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
798 remove_trailing_whitespaces (p
);
808 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
811 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
814 char *str
, *next
, *last
;
817 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
818 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
820 /* Turn on selective bits. */
821 char *init
= xstrdup (cpu_flag_init
[i
].init
);
822 last
= init
+ strlen (init
);
823 for (next
= init
; next
&& next
< last
; )
825 str
= next_field (next
, '|', &next
, last
);
827 set_bitfield (str
, array
, 1, size
, lineno
);
833 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
834 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
836 /* Turn on selective bits. */
837 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
838 last
= init
+ strlen (init
);
839 for (next
= init
; next
&& next
< last
; )
841 str
= next_field (next
, '|', &next
, last
);
843 set_bitfield (str
, array
, 1, size
, lineno
);
853 set_bitfield (char *f
, bitfield
*array
, int value
,
854 unsigned int size
, int lineno
)
858 if (strcmp (f
, "CpuFP") == 0)
860 set_bitfield("Cpu387", array
, value
, size
, lineno
);
861 set_bitfield("Cpu287", array
, value
, size
, lineno
);
864 else if (strcmp (f
, "Mmword") == 0)
866 else if (strcmp (f
, "Oword") == 0)
869 for (i
= 0; i
< size
; i
++)
870 if (strcasecmp (array
[i
].name
, f
) == 0)
872 array
[i
].value
= value
;
878 const char *v
= strchr (f
, '=');
885 for (i
= 0; i
< size
; i
++)
886 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
888 value
= strtol (v
+ 1, &end
, 0);
891 array
[i
].value
= value
;
899 /* Handle shorthands. */
900 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
904 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
906 fail (_("unknown bitfield: %s\n"), f
);
910 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
911 int macro
, const char *comma
, const char *indent
)
915 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
917 fprintf (table
, "%s{ { ", indent
);
919 for (i
= 0; i
< size
- 1; i
++)
921 if (((i
+ 1) % 20) != 0)
922 fprintf (table
, "%d, ", flags
[i
].value
);
924 fprintf (table
, "%d,", flags
[i
].value
);
925 if (((i
+ 1) % 20) == 0)
927 /* We need \\ for macro. */
929 fprintf (table
, " \\\n %s", indent
);
931 fprintf (table
, "\n %s", indent
);
934 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
937 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
941 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
942 const char *comma
, const char *indent
,
945 char *str
, *next
, *last
;
947 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
949 /* Copy the default cpu flags. */
950 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
952 if (strcasecmp (flag
, "unknown") == 0)
954 /* We turn on everything except for cpu64 in case of
955 CPU_UNKNOWN_FLAGS. */
956 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
957 if (flags
[i
].position
!= Cpu64
)
960 else if (flag
[0] == '~')
962 last
= flag
+ strlen (flag
);
969 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
976 /* First we turn on everything except for cpu64. */
977 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
978 if (flags
[i
].position
!= Cpu64
)
981 /* Turn off selective bits. */
982 for (; next
&& next
< last
; )
984 str
= next_field (next
, '|', &next
, last
);
986 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
989 else if (strcmp (flag
, "0"))
991 /* Turn on selective bits. */
992 last
= flag
+ strlen (flag
);
993 for (next
= flag
; next
&& next
< last
; )
995 str
= next_field (next
, '|', &next
, last
);
997 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1001 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1006 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1010 fprintf (table
, " { ");
1012 for (i
= 0; i
< size
- 1; i
++)
1014 if (((i
+ 1) % 20) != 0)
1015 fprintf (table
, "%d, ", modifier
[i
].value
);
1017 fprintf (table
, "%d,", modifier
[i
].value
);
1018 if (((i
+ 1) % 20) == 0)
1019 fprintf (table
, "\n ");
1022 fprintf (table
, "%d },\n", modifier
[i
].value
);
1026 adjust_broadcast_modifier (char **opnd
)
1028 char *str
, *next
, *last
, *op
;
1029 int bcst_type
= INT_MAX
;
1031 /* Skip the immediate operand. */
1033 if (strcasecmp(op
, "Imm8") == 0)
1037 last
= op
+ strlen (op
);
1038 for (next
= op
; next
&& next
< last
; )
1040 str
= next_field (next
, '|', &next
, last
);
1043 if (strcasecmp(str
, "Byte") == 0)
1045 /* The smalest broadcast type, no need to check
1047 bcst_type
= BYTE_BROADCAST
;
1050 else if (strcasecmp(str
, "Word") == 0)
1052 if (bcst_type
> WORD_BROADCAST
)
1053 bcst_type
= WORD_BROADCAST
;
1055 else if (strcasecmp(str
, "Dword") == 0)
1057 if (bcst_type
> DWORD_BROADCAST
)
1058 bcst_type
= DWORD_BROADCAST
;
1060 else if (strcasecmp(str
, "Qword") == 0)
1062 if (bcst_type
> QWORD_BROADCAST
)
1063 bcst_type
= QWORD_BROADCAST
;
1069 if (bcst_type
== INT_MAX
)
1070 fail (_("unknown broadcast operand: %s\n"), op
);
1076 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1078 char *str
, *next
, *last
;
1079 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1081 active_isstring
= 0;
1083 /* Copy the default opcode modifier. */
1084 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1086 if (strcmp (mod
, "0"))
1088 last
= mod
+ strlen (mod
);
1089 for (next
= mod
; next
&& next
< last
; )
1091 str
= next_field (next
, '|', &next
, last
);
1095 if (strcasecmp(str
, "Broadcast") == 0)
1096 val
= adjust_broadcast_modifier (opnd
);
1097 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1099 if (strcasecmp(str
, "IsString") == 0)
1100 active_isstring
= 1;
1104 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1114 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1115 enum stage stage
, const char *indent
)
1119 fprintf (table
, "{ { ");
1121 for (i
= 0; i
< size
- 1; i
++)
1123 if (((i
+ 1) % 20) != 0)
1124 fprintf (table
, "%d, ", types
[i
].value
);
1126 fprintf (table
, "%d,", types
[i
].value
);
1127 if (((i
+ 1) % 20) == 0)
1129 /* We need \\ for macro. */
1130 if (stage
== stage_macros
)
1131 fprintf (table
, " \\\n%s", indent
);
1133 fprintf (table
, "\n%s", indent
);
1137 fprintf (table
, "%d } }", types
[i
].value
);
1141 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1142 const char *indent
, int lineno
)
1144 char *str
, *next
, *last
;
1145 bitfield types
[ARRAY_SIZE (operand_types
)];
1147 /* Copy the default operand type. */
1148 memcpy (types
, operand_types
, sizeof (types
));
1150 if (strcmp (op
, "0"))
1154 last
= op
+ strlen (op
);
1155 for (next
= op
; next
&& next
< last
; )
1157 str
= next_field (next
, '|', &next
, last
);
1160 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1161 if (strcasecmp(str
, "BaseIndex") == 0)
1166 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1168 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1169 if (!active_cpu_flags
.bitfield
.cpu64
1170 && !active_cpu_flags
.bitfield
.cpumpx
)
1171 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1172 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1173 if (!active_cpu_flags
.bitfield
.cpuno64
)
1174 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1177 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1182 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1183 char *last
, int lineno
)
1186 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1187 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1189 /* Find number of operands. */
1190 operands
= next_field (str
, ',', &str
, last
);
1192 /* Find base_opcode. */
1193 base_opcode
= next_field (str
, ',', &str
, last
);
1195 /* Find extension_opcode. */
1196 extension_opcode
= next_field (str
, ',', &str
, last
);
1198 /* Find opcode_length. */
1199 opcode_length
= next_field (str
, ',', &str
, last
);
1201 /* Find cpu_flags. */
1202 cpu_flags
= next_field (str
, ',', &str
, last
);
1204 /* Find opcode_modifier. */
1205 opcode_modifier
= next_field (str
, ',', &str
, last
);
1207 /* Remove the first {. */
1208 str
= remove_leading_whitespaces (str
);
1211 str
= remove_leading_whitespaces (str
+ 1);
1215 /* There are at least "X}". */
1219 /* Remove trailing white spaces and }. */
1223 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1232 /* Find operand_types. */
1233 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1237 operand_types
[i
] = NULL
;
1241 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1242 if (*operand_types
[i
] == '0')
1245 operand_types
[i
] = NULL
;
1250 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1251 name
, operands
, base_opcode
, extension_opcode
,
1254 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1256 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1258 fprintf (table
, " { ");
1260 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1262 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1265 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1271 fprintf (table
, ",\n ");
1273 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1276 fprintf (table
, " } },\n");
1279 struct opcode_hash_entry
1281 struct opcode_hash_entry
*next
;
1287 /* Calculate the hash value of an opcode hash entry P. */
1290 opcode_hash_hash (const void *p
)
1292 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1293 return htab_hash_string (entry
->name
);
1296 /* Compare a string Q against an opcode hash entry P. */
1299 opcode_hash_eq (const void *p
, const void *q
)
1301 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1302 const char *name
= (const char *) q
;
1303 return strcmp (name
, entry
->name
) == 0;
1307 process_i386_opcodes (FILE *table
)
1312 char *str
, *p
, *last
, *name
;
1313 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1314 htab_t opcode_hash_table
;
1315 struct opcode_hash_entry
**opcode_array
;
1316 unsigned int opcode_array_size
= 1024;
1317 int lineno
= 0, marker
= 0;
1319 filename
= "i386-opc.tbl";
1323 opcode_array
= (struct opcode_hash_entry
**)
1324 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1326 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1327 opcode_hash_eq
, NULL
,
1330 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1331 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1333 /* Put everything on opcode array. */
1336 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1341 p
= remove_leading_whitespaces (buf
);
1343 /* Skip comments. */
1344 str
= strstr (p
, "//");
1348 /* Remove trailing white spaces. */
1349 remove_trailing_whitespaces (p
);
1354 if (!strcmp("### MARKER ###", buf
))
1358 /* Since we ignore all included files (we only care about their
1359 #define-s here), we don't need to monitor filenames. The final
1360 line number directive is going to refer to the main source file
1365 p
= remove_leading_whitespaces (p
+ 1);
1366 if (!strncmp(p
, "line", 4))
1368 ln
= strtoul (p
, &end
, 10);
1369 if (ln
> 1 && ln
< INT_MAX
1370 && *remove_leading_whitespaces (end
) == '"')
1373 /* Ignore comments. */
1383 last
= p
+ strlen (p
);
1386 name
= next_field (p
, ',', &str
, last
);
1388 /* Get the slot in hash table. */
1389 hash_slot
= (struct opcode_hash_entry
**)
1390 htab_find_slot_with_hash (opcode_hash_table
, name
,
1391 htab_hash_string (name
),
1394 if (*hash_slot
== NULL
)
1396 /* It is the new one. Put it on opcode array. */
1397 if (i
>= opcode_array_size
)
1399 /* Grow the opcode array when needed. */
1400 opcode_array_size
+= 1024;
1401 opcode_array
= (struct opcode_hash_entry
**)
1402 xrealloc (opcode_array
,
1403 sizeof (*opcode_array
) * opcode_array_size
);
1406 opcode_array
[i
] = (struct opcode_hash_entry
*)
1407 xmalloc (sizeof (struct opcode_hash_entry
));
1408 opcode_array
[i
]->next
= NULL
;
1409 opcode_array
[i
]->name
= xstrdup (name
);
1410 opcode_array
[i
]->opcode
= xstrdup (str
);
1411 opcode_array
[i
]->lineno
= lineno
;
1412 *hash_slot
= opcode_array
[i
];
1417 /* Append it to the existing one. */
1419 while ((*entry
) != NULL
)
1420 entry
= &(*entry
)->next
;
1421 *entry
= (struct opcode_hash_entry
*)
1422 xmalloc (sizeof (struct opcode_hash_entry
));
1423 (*entry
)->next
= NULL
;
1424 (*entry
)->name
= (*hash_slot
)->name
;
1425 (*entry
)->opcode
= xstrdup (str
);
1426 (*entry
)->lineno
= lineno
;
1430 /* Process opcode array. */
1431 for (j
= 0; j
< i
; j
++)
1433 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1437 lineno
= next
->lineno
;
1438 last
= str
+ strlen (str
);
1439 output_i386_opcode (table
, name
, str
, last
, lineno
);
1445 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1447 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1449 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1451 fprintf (table
, " { ");
1452 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1453 fprintf (table
, " } }\n");
1455 fprintf (table
, "};\n");
1459 process_i386_registers (FILE *table
)
1463 char *str
, *p
, *last
;
1464 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1465 char *dw2_32_num
, *dw2_64_num
;
1468 filename
= "i386-reg.tbl";
1469 fp
= fopen (filename
, "r");
1471 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1474 fprintf (table
, "\n/* i386 register table. */\n\n");
1475 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1479 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1484 p
= remove_leading_whitespaces (buf
);
1486 /* Skip comments. */
1487 str
= strstr (p
, "//");
1491 /* Remove trailing white spaces. */
1492 remove_trailing_whitespaces (p
);
1497 fprintf (table
, "%s\n", p
);
1505 last
= p
+ strlen (p
);
1507 /* Find reg_name. */
1508 reg_name
= next_field (p
, ',', &str
, last
);
1510 /* Find reg_type. */
1511 reg_type
= next_field (str
, ',', &str
, last
);
1513 /* Find reg_flags. */
1514 reg_flags
= next_field (str
, ',', &str
, last
);
1517 reg_num
= next_field (str
, ',', &str
, last
);
1519 fprintf (table
, " { \"%s\",\n ", reg_name
);
1521 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1524 /* Find 32-bit Dwarf2 register number. */
1525 dw2_32_num
= next_field (str
, ',', &str
, last
);
1527 /* Find 64-bit Dwarf2 register number. */
1528 dw2_64_num
= next_field (str
, ',', &str
, last
);
1530 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1531 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1536 fprintf (table
, "};\n");
1538 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1542 process_i386_initializers (void)
1545 FILE *fp
= fopen ("i386-init.h", "w");
1549 fail (_("can't create i386-init.h, errno = %s\n"),
1552 process_copyright (fp
);
1554 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1556 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1557 init
= xstrdup (cpu_flag_init
[i
].init
);
1558 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1562 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1564 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1565 init
= xstrdup (operand_type_init
[i
].init
);
1566 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1574 /* Program options. */
1575 #define OPTION_SRCDIR 200
1577 struct option long_options
[] =
1579 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1580 {"debug", no_argument
, NULL
, 'd'},
1581 {"version", no_argument
, NULL
, 'V'},
1582 {"help", no_argument
, NULL
, 'h'},
1583 {0, no_argument
, NULL
, 0}
1587 print_version (void)
1589 printf ("%s: version 1.0\n", program_name
);
1594 usage (FILE * stream
, int status
)
1596 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1602 main (int argc
, char **argv
)
1604 extern int chdir (char *);
1605 char *srcdir
= NULL
;
1607 unsigned int i
, cpumax
;
1610 program_name
= *argv
;
1611 xmalloc_set_program_name (program_name
);
1613 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1638 if (chdir (srcdir
) != 0)
1639 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1640 srcdir
, xstrerror (errno
));
1642 /* cpu_flags isn't sorted by position. */
1644 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1645 if (cpu_flags
[i
].position
> cpumax
)
1646 cpumax
= cpu_flags
[i
].position
;
1648 /* Check the unused bitfield in i386_cpu_flags. */
1650 if ((cpumax
- 1) != CpuMax
)
1651 fail (_("CpuMax != %d!\n"), cpumax
);
1653 if (cpumax
!= CpuMax
)
1654 fail (_("CpuMax != %d!\n"), cpumax
);
1656 c
= CpuNumOfBits
- CpuMax
- 1;
1658 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1661 /* Check the unused bitfield in i386_operand_type. */
1663 c
= OTNumOfBits
- OTMax
- 1;
1665 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1668 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1671 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1672 sizeof (opcode_modifiers
[0]), compare
);
1674 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1675 sizeof (operand_types
[0]), compare
);
1677 table
= fopen ("i386-tbl.h", "w");
1679 fail (_("can't create i386-tbl.h, errno = %s\n"),
1682 process_copyright (table
);
1684 process_i386_opcodes (table
);
1685 process_i386_registers (table
);
1686 process_i386_initializers ();