1 /* Copyright (C) 2007-2019 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|CpuCMOV|CpuFXSR" },
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" },
118 { "CPU_CLFLUSH_FLAGS",
122 { "CPU_SYSCALL_FLAGS",
129 "CPU_SSE_FLAGS|CpuSSE2" },
131 "CPU_SSE2_FLAGS|CpuSSE3" },
133 "CPU_SSE3_FLAGS|CpuSSSE3" },
134 { "CPU_SSE4_1_FLAGS",
135 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
136 { "CPU_SSE4_2_FLAGS",
137 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
144 { "CPU_XSAVEOPT_FLAGS",
145 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
147 "CPU_SSE2_FLAGS|CpuAES" },
148 { "CPU_PCLMUL_FLAGS",
149 "CPU_SSE2_FLAGS|CpuPCLMUL" },
151 "CPU_AVX_FLAGS|CpuFMA" },
153 "CPU_AVX_FLAGS|CpuFMA4" },
155 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
157 "CPU_XSAVE_FLAGS|CpuLWP" },
166 { "CPU_RDTSCP_FLAGS",
170 { "CPU_FSGSBASE_FLAGS",
175 "CPU_AVX_FLAGS|CpuF16C" },
184 { "CPU_INVPCID_FLAGS",
186 { "CPU_VMFUNC_FLAGS",
189 "CPU_MMX_FLAGS|Cpu3dnow" },
190 { "CPU_3DNOWA_FLAGS",
191 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
192 { "CPU_PADLOCK_FLAGS",
197 "CPU_SSE3_FLAGS|CpuSSE4a" },
201 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
203 "CPU_AVX_FLAGS|CpuAVX2" },
204 { "CPU_AVX512F_FLAGS",
205 "CPU_AVX2_FLAGS|CpuAVX512F" },
206 { "CPU_AVX512CD_FLAGS",
207 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
208 { "CPU_AVX512ER_FLAGS",
209 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
210 { "CPU_AVX512PF_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
212 { "CPU_AVX512DQ_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
214 { "CPU_AVX512BW_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
216 { "CPU_AVX512VL_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
218 { "CPU_AVX512IFMA_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
220 { "CPU_AVX512VBMI_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
222 { "CPU_AVX512_4FMAPS_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
224 { "CPU_AVX512_4VNNIW_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
226 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
228 { "CPU_AVX512_VBMI2_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
230 { "CPU_AVX512_VNNI_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
232 { "CPU_AVX512_BITALG_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
234 { "CPU_AVX512_BF16_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
241 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
244 { "CPU_RDSEED_FLAGS",
246 { "CPU_PRFCHW_FLAGS",
251 "CPU_XSAVE_FLAGS|CpuMPX" },
253 "CPU_SSE2_FLAGS|CpuSHA" },
254 { "CPU_CLFLUSHOPT_FLAGS",
256 { "CPU_XSAVES_FLAGS",
257 "CPU_XSAVE_FLAGS|CpuXSAVES" },
258 { "CPU_XSAVEC_FLAGS",
259 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
260 { "CPU_PREFETCHWT1_FLAGS",
266 { "CPU_CLZERO_FLAGS",
268 { "CPU_MWAITX_FLAGS",
271 "CPU_XSAVE_FLAGS|CpuOSPKE" },
274 { "CPU_PTWRITE_FLAGS",
284 { "CPU_VPCLMULQDQ_FLAGS",
286 { "CPU_WBNOINVD_FLAGS",
288 { "CPU_PCONFIG_FLAGS",
290 { "CPU_WAITPKG_FLAGS",
292 { "CPU_CLDEMOTE_FLAGS",
294 { "CPU_MOVDIRI_FLAGS",
296 { "CPU_MOVDIR64B_FLAGS",
298 { "CPU_ENQCMD_FLAGS",
300 { "CPU_AVX512_VP2INTERSECT_FLAGS",
301 "CpuAVX512_VP2INTERSECT" },
302 { "CPU_ANY_X87_FLAGS",
303 "CPU_ANY_287_FLAGS|Cpu8087" },
304 { "CPU_ANY_287_FLAGS",
305 "CPU_ANY_387_FLAGS|Cpu287" },
306 { "CPU_ANY_387_FLAGS",
307 "CPU_ANY_687_FLAGS|Cpu387" },
308 { "CPU_ANY_687_FLAGS",
309 "Cpu687|CpuFISTTP" },
310 { "CPU_ANY_CMOV_FLAGS",
312 { "CPU_ANY_FXSR_FLAGS",
314 { "CPU_ANY_MMX_FLAGS",
315 "CPU_3DNOWA_FLAGS" },
316 { "CPU_ANY_SSE_FLAGS",
317 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
318 { "CPU_ANY_SSE2_FLAGS",
319 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
320 { "CPU_ANY_SSE3_FLAGS",
321 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
322 { "CPU_ANY_SSSE3_FLAGS",
323 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
324 { "CPU_ANY_SSE4_1_FLAGS",
325 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
326 { "CPU_ANY_SSE4_2_FLAGS",
328 { "CPU_ANY_AVX_FLAGS",
329 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
330 { "CPU_ANY_AVX2_FLAGS",
331 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
332 { "CPU_ANY_AVX512F_FLAGS",
333 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
334 { "CPU_ANY_AVX512CD_FLAGS",
336 { "CPU_ANY_AVX512ER_FLAGS",
338 { "CPU_ANY_AVX512PF_FLAGS",
340 { "CPU_ANY_AVX512DQ_FLAGS",
342 { "CPU_ANY_AVX512BW_FLAGS",
344 { "CPU_ANY_AVX512VL_FLAGS",
346 { "CPU_ANY_AVX512IFMA_FLAGS",
348 { "CPU_ANY_AVX512VBMI_FLAGS",
350 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
351 "CpuAVX512_4FMAPS" },
352 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
353 "CpuAVX512_4VNNIW" },
354 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
355 "CpuAVX512_VPOPCNTDQ" },
356 { "CPU_ANY_IBT_FLAGS",
358 { "CPU_ANY_SHSTK_FLAGS",
360 { "CPU_ANY_AVX512_VBMI2_FLAGS",
362 { "CPU_ANY_AVX512_VNNI_FLAGS",
364 { "CPU_ANY_AVX512_BITALG_FLAGS",
365 "CpuAVX512_BITALG" },
366 { "CPU_ANY_AVX512_BF16_FLAGS",
368 { "CPU_ANY_MOVDIRI_FLAGS",
370 { "CPU_ANY_MOVDIR64B_FLAGS",
372 { "CPU_ANY_ENQCMD_FLAGS",
374 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
375 "CpuAVX512_VP2INTERSECT" },
378 static const initializer operand_type_shorthands
[] =
380 { "Reg8", "Reg|Byte" },
381 { "Reg16", "Reg|Word" },
382 { "Reg32", "Reg|Dword" },
383 { "Reg64", "Reg|Qword" },
384 { "FloatAcc", "Acc|Tbyte" },
385 { "FloatReg", "Reg|Tbyte" },
386 { "RegXMM", "RegSIMD|Xmmword" },
387 { "RegYMM", "RegSIMD|Ymmword" },
388 { "RegZMM", "RegSIMD|Zmmword" },
391 static initializer operand_type_init
[] =
393 { "OPERAND_TYPE_NONE",
395 { "OPERAND_TYPE_REG8",
397 { "OPERAND_TYPE_REG16",
399 { "OPERAND_TYPE_REG32",
401 { "OPERAND_TYPE_REG64",
403 { "OPERAND_TYPE_IMM1",
405 { "OPERAND_TYPE_IMM8",
407 { "OPERAND_TYPE_IMM8S",
409 { "OPERAND_TYPE_IMM16",
411 { "OPERAND_TYPE_IMM32",
413 { "OPERAND_TYPE_IMM32S",
415 { "OPERAND_TYPE_IMM64",
417 { "OPERAND_TYPE_BASEINDEX",
419 { "OPERAND_TYPE_DISP8",
421 { "OPERAND_TYPE_DISP16",
423 { "OPERAND_TYPE_DISP32",
425 { "OPERAND_TYPE_DISP32S",
427 { "OPERAND_TYPE_DISP64",
429 { "OPERAND_TYPE_INOUTPORTREG",
431 { "OPERAND_TYPE_SHIFTCOUNT",
433 { "OPERAND_TYPE_CONTROL",
435 { "OPERAND_TYPE_TEST",
437 { "OPERAND_TYPE_DEBUG",
439 { "OPERAND_TYPE_FLOATREG",
441 { "OPERAND_TYPE_FLOATACC",
443 { "OPERAND_TYPE_SREG",
445 { "OPERAND_TYPE_JUMPABSOLUTE",
447 { "OPERAND_TYPE_REGMMX",
449 { "OPERAND_TYPE_REGXMM",
451 { "OPERAND_TYPE_REGYMM",
453 { "OPERAND_TYPE_REGZMM",
455 { "OPERAND_TYPE_REGMASK",
457 { "OPERAND_TYPE_ESSEG",
459 { "OPERAND_TYPE_ACC8",
461 { "OPERAND_TYPE_ACC16",
463 { "OPERAND_TYPE_ACC32",
465 { "OPERAND_TYPE_ACC64",
467 { "OPERAND_TYPE_DISP16_32",
469 { "OPERAND_TYPE_ANYDISP",
470 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
471 { "OPERAND_TYPE_IMM16_32",
473 { "OPERAND_TYPE_IMM16_32S",
475 { "OPERAND_TYPE_IMM16_32_32S",
476 "Imm16|Imm32|Imm32S" },
477 { "OPERAND_TYPE_IMM32_64",
479 { "OPERAND_TYPE_IMM32_32S_DISP32",
480 "Imm32|Imm32S|Disp32" },
481 { "OPERAND_TYPE_IMM64_DISP64",
483 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
484 "Imm32|Imm32S|Imm64|Disp32" },
485 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
486 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
487 { "OPERAND_TYPE_REGBND",
491 typedef struct bitfield
498 #define BITFIELD(n) { n, 0, #n }
500 static bitfield cpu_flags
[] =
510 BITFIELD (CpuClflush
),
512 BITFIELD (CpuSYSCALL
),
517 BITFIELD (CpuFISTTP
),
523 BITFIELD (CpuSSE4_1
),
524 BITFIELD (CpuSSE4_2
),
527 BITFIELD (CpuAVX512F
),
528 BITFIELD (CpuAVX512CD
),
529 BITFIELD (CpuAVX512ER
),
530 BITFIELD (CpuAVX512PF
),
531 BITFIELD (CpuAVX512VL
),
532 BITFIELD (CpuAVX512DQ
),
533 BITFIELD (CpuAVX512BW
),
539 BITFIELD (Cpu3dnowA
),
540 BITFIELD (CpuPadLock
),
546 BITFIELD (CpuXsaveopt
),
548 BITFIELD (CpuPCLMUL
),
559 BITFIELD (CpuRdtscp
),
560 BITFIELD (CpuFSGSBase
),
567 BITFIELD (CpuINVPCID
),
568 BITFIELD (CpuVMFUNC
),
569 BITFIELD (CpuRDSEED
),
571 BITFIELD (CpuPRFCHW
),
574 BITFIELD (CpuClflushOpt
),
575 BITFIELD (CpuXSAVES
),
576 BITFIELD (CpuXSAVEC
),
577 BITFIELD (CpuPREFETCHWT1
),
583 BITFIELD (CpuAVX512IFMA
),
584 BITFIELD (CpuAVX512VBMI
),
585 BITFIELD (CpuAVX512_4FMAPS
),
586 BITFIELD (CpuAVX512_4VNNIW
),
587 BITFIELD (CpuAVX512_VPOPCNTDQ
),
588 BITFIELD (CpuAVX512_VBMI2
),
589 BITFIELD (CpuAVX512_VNNI
),
590 BITFIELD (CpuAVX512_BITALG
),
591 BITFIELD (CpuAVX512_BF16
),
592 BITFIELD (CpuAVX512_VP2INTERSECT
),
593 BITFIELD (CpuMWAITX
),
594 BITFIELD (CpuCLZERO
),
597 BITFIELD (CpuPTWRITE
),
602 BITFIELD (CpuVPCLMULQDQ
),
603 BITFIELD (CpuWBNOINVD
),
604 BITFIELD (CpuPCONFIG
),
605 BITFIELD (CpuWAITPKG
),
606 BITFIELD (CpuCLDEMOTE
),
607 BITFIELD (CpuMOVDIRI
),
608 BITFIELD (CpuMOVDIR64B
),
609 BITFIELD (CpuENQCMD
),
611 BITFIELD (CpuUnused
),
615 static bitfield opcode_modifiers
[] =
621 BITFIELD (ShortForm
),
623 BITFIELD (JumpDword
),
625 BITFIELD (JumpInterSegment
),
629 BITFIELD (CheckRegSize
),
630 BITFIELD (IgnoreSize
),
631 BITFIELD (DefaultSize
),
640 BITFIELD (BNDPrefixOk
),
641 BITFIELD (NoTrackPrefixOk
),
642 BITFIELD (IsLockable
),
643 BITFIELD (RegKludge
),
644 BITFIELD (Implicit1stXmm0
),
645 BITFIELD (RepPrefixOk
),
646 BITFIELD (HLEPrefixOk
),
649 BITFIELD (AddrPrefixOpReg
),
658 BITFIELD (VexOpcode
),
659 BITFIELD (VexSources
),
665 BITFIELD (Broadcast
),
666 BITFIELD (StaticRounding
),
668 BITFIELD (Disp8MemShift
),
669 BITFIELD (NoDefMask
),
670 BITFIELD (ImplicitQuadGroup
),
672 BITFIELD (ATTMnemonic
),
673 BITFIELD (ATTSyntax
),
674 BITFIELD (IntelSyntax
),
679 static bitfield operand_types
[] =
692 BITFIELD (BaseIndex
),
698 BITFIELD (InOutPortReg
),
699 BITFIELD (ShiftCount
),
705 BITFIELD (JumpAbsolute
),
717 BITFIELD (Unspecified
),
725 static const char *filename
;
726 static i386_cpu_flags active_cpu_flags
;
727 static int active_isstring
;
730 compare (const void *x
, const void *y
)
732 const bitfield
*xp
= (const bitfield
*) x
;
733 const bitfield
*yp
= (const bitfield
*) y
;
734 return xp
->position
- yp
->position
;
738 fail (const char *message
, ...)
742 va_start (args
, message
);
743 fprintf (stderr
, _("%s: error: "), program_name
);
744 vfprintf (stderr
, message
, args
);
750 process_copyright (FILE *fp
)
752 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
753 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
755 This file is part of the GNU opcodes library.\n\
757 This library is free software; you can redistribute it and/or modify\n\
758 it under the terms of the GNU General Public License as published by\n\
759 the Free Software Foundation; either version 3, or (at your option)\n\
760 any later version.\n\
762 It is distributed in the hope that it will be useful, but WITHOUT\n\
763 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
764 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
765 License for more details.\n\
767 You should have received a copy of the GNU General Public License\n\
768 along with this program; if not, write to the Free Software\n\
769 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
770 MA 02110-1301, USA. */\n");
773 /* Remove leading white spaces. */
776 remove_leading_whitespaces (char *str
)
778 while (ISSPACE (*str
))
783 /* Remove trailing white spaces. */
786 remove_trailing_whitespaces (char *str
)
788 size_t last
= strlen (str
);
796 if (ISSPACE (str
[last
]))
804 /* Find next field separated by SEP and terminate it. Return a
805 pointer to the one after it. */
808 next_field (char *str
, char sep
, char **next
, char *last
)
812 p
= remove_leading_whitespaces (str
);
813 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
816 remove_trailing_whitespaces (p
);
826 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
829 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
832 char *str
, *next
, *last
;
835 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
836 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
838 /* Turn on selective bits. */
839 char *init
= xstrdup (cpu_flag_init
[i
].init
);
840 last
= init
+ strlen (init
);
841 for (next
= init
; next
&& next
< last
; )
843 str
= next_field (next
, '|', &next
, last
);
845 set_bitfield (str
, array
, 1, size
, lineno
);
851 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
852 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
854 /* Turn on selective bits. */
855 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
856 last
= init
+ strlen (init
);
857 for (next
= init
; next
&& next
< last
; )
859 str
= next_field (next
, '|', &next
, last
);
861 set_bitfield (str
, array
, 1, size
, lineno
);
871 set_bitfield (char *f
, bitfield
*array
, int value
,
872 unsigned int size
, int lineno
)
876 if (strcmp (f
, "CpuFP") == 0)
878 set_bitfield("Cpu387", array
, value
, size
, lineno
);
879 set_bitfield("Cpu287", array
, value
, size
, lineno
);
882 else if (strcmp (f
, "Mmword") == 0)
884 else if (strcmp (f
, "Oword") == 0)
887 for (i
= 0; i
< size
; i
++)
888 if (strcasecmp (array
[i
].name
, f
) == 0)
890 array
[i
].value
= value
;
896 const char *v
= strchr (f
, '=');
903 for (i
= 0; i
< size
; i
++)
904 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
906 value
= strtol (v
+ 1, &end
, 0);
909 array
[i
].value
= value
;
917 /* Handle shorthands. */
918 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
922 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
924 fail (_("unknown bitfield: %s\n"), f
);
928 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
929 int macro
, const char *comma
, const char *indent
)
933 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
935 fprintf (table
, "%s{ { ", indent
);
937 for (i
= 0; i
< size
- 1; i
++)
939 if (((i
+ 1) % 20) != 0)
940 fprintf (table
, "%d, ", flags
[i
].value
);
942 fprintf (table
, "%d,", flags
[i
].value
);
943 if (((i
+ 1) % 20) == 0)
945 /* We need \\ for macro. */
947 fprintf (table
, " \\\n %s", indent
);
949 fprintf (table
, "\n %s", indent
);
952 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
955 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
959 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
960 const char *comma
, const char *indent
,
963 char *str
, *next
, *last
;
965 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
967 /* Copy the default cpu flags. */
968 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
970 if (strcasecmp (flag
, "unknown") == 0)
972 /* We turn on everything except for cpu64 in case of
973 CPU_UNKNOWN_FLAGS. */
974 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
975 if (flags
[i
].position
!= Cpu64
)
978 else if (flag
[0] == '~')
980 last
= flag
+ strlen (flag
);
987 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
994 /* First we turn on everything except for cpu64. */
995 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
996 if (flags
[i
].position
!= Cpu64
)
999 /* Turn off selective bits. */
1000 for (; next
&& next
< last
; )
1002 str
= next_field (next
, '|', &next
, last
);
1004 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1007 else if (strcmp (flag
, "0"))
1009 /* Turn on selective bits. */
1010 last
= flag
+ strlen (flag
);
1011 for (next
= flag
; next
&& next
< last
; )
1013 str
= next_field (next
, '|', &next
, last
);
1015 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1019 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1024 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1028 fprintf (table
, " { ");
1030 for (i
= 0; i
< size
- 1; i
++)
1032 if (((i
+ 1) % 20) != 0)
1033 fprintf (table
, "%d, ", modifier
[i
].value
);
1035 fprintf (table
, "%d,", modifier
[i
].value
);
1036 if (((i
+ 1) % 20) == 0)
1037 fprintf (table
, "\n ");
1040 fprintf (table
, "%d },\n", modifier
[i
].value
);
1044 adjust_broadcast_modifier (char **opnd
)
1046 char *str
, *next
, *last
, *op
;
1047 int bcst_type
= INT_MAX
;
1049 /* Skip the immediate operand. */
1051 if (strcasecmp(op
, "Imm8") == 0)
1055 last
= op
+ strlen (op
);
1056 for (next
= op
; next
&& next
< last
; )
1058 str
= next_field (next
, '|', &next
, last
);
1061 if (strcasecmp(str
, "Byte") == 0)
1063 /* The smalest broadcast type, no need to check
1065 bcst_type
= BYTE_BROADCAST
;
1068 else if (strcasecmp(str
, "Word") == 0)
1070 if (bcst_type
> WORD_BROADCAST
)
1071 bcst_type
= WORD_BROADCAST
;
1073 else if (strcasecmp(str
, "Dword") == 0)
1075 if (bcst_type
> DWORD_BROADCAST
)
1076 bcst_type
= DWORD_BROADCAST
;
1078 else if (strcasecmp(str
, "Qword") == 0)
1080 if (bcst_type
> QWORD_BROADCAST
)
1081 bcst_type
= QWORD_BROADCAST
;
1087 if (bcst_type
== INT_MAX
)
1088 fail (_("unknown broadcast operand: %s\n"), op
);
1094 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1096 char *str
, *next
, *last
;
1097 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1099 active_isstring
= 0;
1101 /* Copy the default opcode modifier. */
1102 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1104 if (strcmp (mod
, "0"))
1106 last
= mod
+ strlen (mod
);
1107 for (next
= mod
; next
&& next
< last
; )
1109 str
= next_field (next
, '|', &next
, last
);
1113 if (strcasecmp(str
, "Broadcast") == 0)
1114 val
= adjust_broadcast_modifier (opnd
);
1115 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1117 if (strcasecmp(str
, "IsString") == 0)
1118 active_isstring
= 1;
1122 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1132 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1133 enum stage stage
, const char *indent
)
1137 fprintf (table
, "{ { ");
1139 for (i
= 0; i
< size
- 1; i
++)
1141 if (((i
+ 1) % 20) != 0)
1142 fprintf (table
, "%d, ", types
[i
].value
);
1144 fprintf (table
, "%d,", types
[i
].value
);
1145 if (((i
+ 1) % 20) == 0)
1147 /* We need \\ for macro. */
1148 if (stage
== stage_macros
)
1149 fprintf (table
, " \\\n%s", indent
);
1151 fprintf (table
, "\n%s", indent
);
1155 fprintf (table
, "%d } }", types
[i
].value
);
1159 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1160 const char *indent
, int lineno
)
1162 char *str
, *next
, *last
;
1163 bitfield types
[ARRAY_SIZE (operand_types
)];
1165 /* Copy the default operand type. */
1166 memcpy (types
, operand_types
, sizeof (types
));
1168 if (strcmp (op
, "0"))
1172 last
= op
+ strlen (op
);
1173 for (next
= op
; next
&& next
< last
; )
1175 str
= next_field (next
, '|', &next
, last
);
1178 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1179 if (strcasecmp(str
, "BaseIndex") == 0)
1184 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1186 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1187 if (!active_cpu_flags
.bitfield
.cpu64
1188 && !active_cpu_flags
.bitfield
.cpumpx
)
1189 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1190 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1191 if (!active_cpu_flags
.bitfield
.cpuno64
)
1192 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1195 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1200 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1201 char *last
, int lineno
)
1204 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1205 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1207 /* Find number of operands. */
1208 operands
= next_field (str
, ',', &str
, last
);
1210 /* Find base_opcode. */
1211 base_opcode
= next_field (str
, ',', &str
, last
);
1213 /* Find extension_opcode. */
1214 extension_opcode
= next_field (str
, ',', &str
, last
);
1216 /* Find opcode_length. */
1217 opcode_length
= next_field (str
, ',', &str
, last
);
1219 /* Find cpu_flags. */
1220 cpu_flags
= next_field (str
, ',', &str
, last
);
1222 /* Find opcode_modifier. */
1223 opcode_modifier
= next_field (str
, ',', &str
, last
);
1225 /* Remove the first {. */
1226 str
= remove_leading_whitespaces (str
);
1229 str
= remove_leading_whitespaces (str
+ 1);
1233 /* There are at least "X}". */
1237 /* Remove trailing white spaces and }. */
1241 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1250 /* Find operand_types. */
1251 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1255 operand_types
[i
] = NULL
;
1259 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1260 if (*operand_types
[i
] == '0')
1263 operand_types
[i
] = NULL
;
1268 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1269 name
, operands
, base_opcode
, extension_opcode
,
1272 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1274 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1276 fprintf (table
, " { ");
1278 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1280 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1283 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1289 fprintf (table
, ",\n ");
1291 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1294 fprintf (table
, " } },\n");
1297 struct opcode_hash_entry
1299 struct opcode_hash_entry
*next
;
1305 /* Calculate the hash value of an opcode hash entry P. */
1308 opcode_hash_hash (const void *p
)
1310 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1311 return htab_hash_string (entry
->name
);
1314 /* Compare a string Q against an opcode hash entry P. */
1317 opcode_hash_eq (const void *p
, const void *q
)
1319 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1320 const char *name
= (const char *) q
;
1321 return strcmp (name
, entry
->name
) == 0;
1325 process_i386_opcodes (FILE *table
)
1330 char *str
, *p
, *last
, *name
;
1331 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1332 htab_t opcode_hash_table
;
1333 struct opcode_hash_entry
**opcode_array
;
1334 unsigned int opcode_array_size
= 1024;
1335 int lineno
= 0, marker
= 0;
1337 filename
= "i386-opc.tbl";
1341 opcode_array
= (struct opcode_hash_entry
**)
1342 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1344 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1345 opcode_hash_eq
, NULL
,
1348 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1349 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1351 /* Put everything on opcode array. */
1354 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1359 p
= remove_leading_whitespaces (buf
);
1361 /* Skip comments. */
1362 str
= strstr (p
, "//");
1366 /* Remove trailing white spaces. */
1367 remove_trailing_whitespaces (p
);
1372 if (!strcmp("### MARKER ###", buf
))
1376 /* Since we ignore all included files (we only care about their
1377 #define-s here), we don't need to monitor filenames. The final
1378 line number directive is going to refer to the main source file
1383 p
= remove_leading_whitespaces (p
+ 1);
1384 if (!strncmp(p
, "line", 4))
1386 ln
= strtoul (p
, &end
, 10);
1387 if (ln
> 1 && ln
< INT_MAX
1388 && *remove_leading_whitespaces (end
) == '"')
1391 /* Ignore comments. */
1401 last
= p
+ strlen (p
);
1404 name
= next_field (p
, ',', &str
, last
);
1406 /* Get the slot in hash table. */
1407 hash_slot
= (struct opcode_hash_entry
**)
1408 htab_find_slot_with_hash (opcode_hash_table
, name
,
1409 htab_hash_string (name
),
1412 if (*hash_slot
== NULL
)
1414 /* It is the new one. Put it on opcode array. */
1415 if (i
>= opcode_array_size
)
1417 /* Grow the opcode array when needed. */
1418 opcode_array_size
+= 1024;
1419 opcode_array
= (struct opcode_hash_entry
**)
1420 xrealloc (opcode_array
,
1421 sizeof (*opcode_array
) * opcode_array_size
);
1424 opcode_array
[i
] = (struct opcode_hash_entry
*)
1425 xmalloc (sizeof (struct opcode_hash_entry
));
1426 opcode_array
[i
]->next
= NULL
;
1427 opcode_array
[i
]->name
= xstrdup (name
);
1428 opcode_array
[i
]->opcode
= xstrdup (str
);
1429 opcode_array
[i
]->lineno
= lineno
;
1430 *hash_slot
= opcode_array
[i
];
1435 /* Append it to the existing one. */
1437 while ((*entry
) != NULL
)
1438 entry
= &(*entry
)->next
;
1439 *entry
= (struct opcode_hash_entry
*)
1440 xmalloc (sizeof (struct opcode_hash_entry
));
1441 (*entry
)->next
= NULL
;
1442 (*entry
)->name
= (*hash_slot
)->name
;
1443 (*entry
)->opcode
= xstrdup (str
);
1444 (*entry
)->lineno
= lineno
;
1448 /* Process opcode array. */
1449 for (j
= 0; j
< i
; j
++)
1451 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1455 lineno
= next
->lineno
;
1456 last
= str
+ strlen (str
);
1457 output_i386_opcode (table
, name
, str
, last
, lineno
);
1463 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1465 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1467 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1469 fprintf (table
, " { ");
1470 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1471 fprintf (table
, " } }\n");
1473 fprintf (table
, "};\n");
1477 process_i386_registers (FILE *table
)
1481 char *str
, *p
, *last
;
1482 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1483 char *dw2_32_num
, *dw2_64_num
;
1486 filename
= "i386-reg.tbl";
1487 fp
= fopen (filename
, "r");
1489 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1492 fprintf (table
, "\n/* i386 register table. */\n\n");
1493 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1497 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1502 p
= remove_leading_whitespaces (buf
);
1504 /* Skip comments. */
1505 str
= strstr (p
, "//");
1509 /* Remove trailing white spaces. */
1510 remove_trailing_whitespaces (p
);
1515 fprintf (table
, "%s\n", p
);
1523 last
= p
+ strlen (p
);
1525 /* Find reg_name. */
1526 reg_name
= next_field (p
, ',', &str
, last
);
1528 /* Find reg_type. */
1529 reg_type
= next_field (str
, ',', &str
, last
);
1531 /* Find reg_flags. */
1532 reg_flags
= next_field (str
, ',', &str
, last
);
1535 reg_num
= next_field (str
, ',', &str
, last
);
1537 fprintf (table
, " { \"%s\",\n ", reg_name
);
1539 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1542 /* Find 32-bit Dwarf2 register number. */
1543 dw2_32_num
= next_field (str
, ',', &str
, last
);
1545 /* Find 64-bit Dwarf2 register number. */
1546 dw2_64_num
= next_field (str
, ',', &str
, last
);
1548 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1549 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1554 fprintf (table
, "};\n");
1556 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1560 process_i386_initializers (void)
1563 FILE *fp
= fopen ("i386-init.h", "w");
1567 fail (_("can't create i386-init.h, errno = %s\n"),
1570 process_copyright (fp
);
1572 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1574 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1575 init
= xstrdup (cpu_flag_init
[i
].init
);
1576 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1580 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1582 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1583 init
= xstrdup (operand_type_init
[i
].init
);
1584 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1592 /* Program options. */
1593 #define OPTION_SRCDIR 200
1595 struct option long_options
[] =
1597 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1598 {"debug", no_argument
, NULL
, 'd'},
1599 {"version", no_argument
, NULL
, 'V'},
1600 {"help", no_argument
, NULL
, 'h'},
1601 {0, no_argument
, NULL
, 0}
1605 print_version (void)
1607 printf ("%s: version 1.0\n", program_name
);
1612 usage (FILE * stream
, int status
)
1614 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1620 main (int argc
, char **argv
)
1622 extern int chdir (char *);
1623 char *srcdir
= NULL
;
1625 unsigned int i
, cpumax
;
1628 program_name
= *argv
;
1629 xmalloc_set_program_name (program_name
);
1631 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1656 if (chdir (srcdir
) != 0)
1657 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1658 srcdir
, xstrerror (errno
));
1660 /* cpu_flags isn't sorted by position. */
1662 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1663 if (cpu_flags
[i
].position
> cpumax
)
1664 cpumax
= cpu_flags
[i
].position
;
1666 /* Check the unused bitfield in i386_cpu_flags. */
1668 if ((cpumax
- 1) != CpuMax
)
1669 fail (_("CpuMax != %d!\n"), cpumax
);
1671 if (cpumax
!= CpuMax
)
1672 fail (_("CpuMax != %d!\n"), cpumax
);
1674 c
= CpuNumOfBits
- CpuMax
- 1;
1676 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1679 /* Check the unused bitfield in i386_operand_type. */
1681 c
= OTNumOfBits
- OTMax
- 1;
1683 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1686 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1689 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1690 sizeof (opcode_modifiers
[0]), compare
);
1692 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1693 sizeof (operand_types
[0]), compare
);
1695 table
= fopen ("i386-tbl.h", "w");
1697 fail (_("can't create i386-tbl.h, errno = %s\n"),
1700 process_copyright (table
);
1702 process_i386_opcodes (table
);
1703 process_i386_registers (table
);
1704 process_i386_initializers ();