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_SREG2",
445 { "OPERAND_TYPE_SREG3",
447 { "OPERAND_TYPE_JUMPABSOLUTE",
449 { "OPERAND_TYPE_REGMMX",
451 { "OPERAND_TYPE_REGXMM",
453 { "OPERAND_TYPE_REGYMM",
455 { "OPERAND_TYPE_REGZMM",
457 { "OPERAND_TYPE_REGMASK",
459 { "OPERAND_TYPE_ESSEG",
461 { "OPERAND_TYPE_ACC8",
463 { "OPERAND_TYPE_ACC16",
465 { "OPERAND_TYPE_ACC32",
467 { "OPERAND_TYPE_ACC64",
469 { "OPERAND_TYPE_DISP16_32",
471 { "OPERAND_TYPE_ANYDISP",
472 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
473 { "OPERAND_TYPE_IMM16_32",
475 { "OPERAND_TYPE_IMM16_32S",
477 { "OPERAND_TYPE_IMM16_32_32S",
478 "Imm16|Imm32|Imm32S" },
479 { "OPERAND_TYPE_IMM32_64",
481 { "OPERAND_TYPE_IMM32_32S_DISP32",
482 "Imm32|Imm32S|Disp32" },
483 { "OPERAND_TYPE_IMM64_DISP64",
485 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
486 "Imm32|Imm32S|Imm64|Disp32" },
487 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
488 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
489 { "OPERAND_TYPE_REGBND",
493 typedef struct bitfield
500 #define BITFIELD(n) { n, 0, #n }
502 static bitfield cpu_flags
[] =
512 BITFIELD (CpuClflush
),
514 BITFIELD (CpuSYSCALL
),
519 BITFIELD (CpuFISTTP
),
525 BITFIELD (CpuSSE4_1
),
526 BITFIELD (CpuSSE4_2
),
529 BITFIELD (CpuAVX512F
),
530 BITFIELD (CpuAVX512CD
),
531 BITFIELD (CpuAVX512ER
),
532 BITFIELD (CpuAVX512PF
),
533 BITFIELD (CpuAVX512VL
),
534 BITFIELD (CpuAVX512DQ
),
535 BITFIELD (CpuAVX512BW
),
541 BITFIELD (Cpu3dnowA
),
542 BITFIELD (CpuPadLock
),
548 BITFIELD (CpuXsaveopt
),
550 BITFIELD (CpuPCLMUL
),
561 BITFIELD (CpuRdtscp
),
562 BITFIELD (CpuFSGSBase
),
569 BITFIELD (CpuINVPCID
),
570 BITFIELD (CpuVMFUNC
),
571 BITFIELD (CpuRDSEED
),
573 BITFIELD (CpuPRFCHW
),
576 BITFIELD (CpuClflushOpt
),
577 BITFIELD (CpuXSAVES
),
578 BITFIELD (CpuXSAVEC
),
579 BITFIELD (CpuPREFETCHWT1
),
585 BITFIELD (CpuAVX512IFMA
),
586 BITFIELD (CpuAVX512VBMI
),
587 BITFIELD (CpuAVX512_4FMAPS
),
588 BITFIELD (CpuAVX512_4VNNIW
),
589 BITFIELD (CpuAVX512_VPOPCNTDQ
),
590 BITFIELD (CpuAVX512_VBMI2
),
591 BITFIELD (CpuAVX512_VNNI
),
592 BITFIELD (CpuAVX512_BITALG
),
593 BITFIELD (CpuAVX512_BF16
),
594 BITFIELD (CpuAVX512_VP2INTERSECT
),
595 BITFIELD (CpuMWAITX
),
596 BITFIELD (CpuCLZERO
),
599 BITFIELD (CpuPTWRITE
),
604 BITFIELD (CpuVPCLMULQDQ
),
605 BITFIELD (CpuWBNOINVD
),
606 BITFIELD (CpuPCONFIG
),
607 BITFIELD (CpuWAITPKG
),
608 BITFIELD (CpuCLDEMOTE
),
609 BITFIELD (CpuMOVDIRI
),
610 BITFIELD (CpuMOVDIR64B
),
611 BITFIELD (CpuENQCMD
),
613 BITFIELD (CpuUnused
),
617 static bitfield opcode_modifiers
[] =
623 BITFIELD (ShortForm
),
625 BITFIELD (JumpDword
),
627 BITFIELD (JumpInterSegment
),
631 BITFIELD (CheckRegSize
),
632 BITFIELD (IgnoreSize
),
633 BITFIELD (DefaultSize
),
642 BITFIELD (BNDPrefixOk
),
643 BITFIELD (NoTrackPrefixOk
),
644 BITFIELD (IsLockable
),
645 BITFIELD (RegKludge
),
646 BITFIELD (Implicit1stXmm0
),
647 BITFIELD (RepPrefixOk
),
648 BITFIELD (HLEPrefixOk
),
651 BITFIELD (AddrPrefixOpReg
),
660 BITFIELD (VexOpcode
),
661 BITFIELD (VexSources
),
667 BITFIELD (Broadcast
),
668 BITFIELD (StaticRounding
),
670 BITFIELD (Disp8MemShift
),
671 BITFIELD (NoDefMask
),
672 BITFIELD (ImplicitQuadGroup
),
674 BITFIELD (ATTMnemonic
),
675 BITFIELD (ATTSyntax
),
676 BITFIELD (IntelSyntax
),
681 static bitfield operand_types
[] =
694 BITFIELD (BaseIndex
),
700 BITFIELD (InOutPortReg
),
701 BITFIELD (ShiftCount
),
708 BITFIELD (JumpAbsolute
),
720 BITFIELD (Unspecified
),
728 static const char *filename
;
729 static i386_cpu_flags active_cpu_flags
;
730 static int active_isstring
;
733 compare (const void *x
, const void *y
)
735 const bitfield
*xp
= (const bitfield
*) x
;
736 const bitfield
*yp
= (const bitfield
*) y
;
737 return xp
->position
- yp
->position
;
741 fail (const char *message
, ...)
745 va_start (args
, message
);
746 fprintf (stderr
, _("%s: error: "), program_name
);
747 vfprintf (stderr
, message
, args
);
753 process_copyright (FILE *fp
)
755 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
756 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
758 This file is part of the GNU opcodes library.\n\
760 This library is free software; you can redistribute it and/or modify\n\
761 it under the terms of the GNU General Public License as published by\n\
762 the Free Software Foundation; either version 3, or (at your option)\n\
763 any later version.\n\
765 It is distributed in the hope that it will be useful, but WITHOUT\n\
766 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
767 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
768 License for more details.\n\
770 You should have received a copy of the GNU General Public License\n\
771 along with this program; if not, write to the Free Software\n\
772 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
773 MA 02110-1301, USA. */\n");
776 /* Remove leading white spaces. */
779 remove_leading_whitespaces (char *str
)
781 while (ISSPACE (*str
))
786 /* Remove trailing white spaces. */
789 remove_trailing_whitespaces (char *str
)
791 size_t last
= strlen (str
);
799 if (ISSPACE (str
[last
]))
807 /* Find next field separated by SEP and terminate it. Return a
808 pointer to the one after it. */
811 next_field (char *str
, char sep
, char **next
, char *last
)
815 p
= remove_leading_whitespaces (str
);
816 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
819 remove_trailing_whitespaces (p
);
829 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
832 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
835 char *str
, *next
, *last
;
838 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
839 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
841 /* Turn on selective bits. */
842 char *init
= xstrdup (cpu_flag_init
[i
].init
);
843 last
= init
+ strlen (init
);
844 for (next
= init
; next
&& next
< last
; )
846 str
= next_field (next
, '|', &next
, last
);
848 set_bitfield (str
, array
, 1, size
, lineno
);
854 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
855 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
857 /* Turn on selective bits. */
858 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
859 last
= init
+ strlen (init
);
860 for (next
= init
; next
&& next
< last
; )
862 str
= next_field (next
, '|', &next
, last
);
864 set_bitfield (str
, array
, 1, size
, lineno
);
874 set_bitfield (char *f
, bitfield
*array
, int value
,
875 unsigned int size
, int lineno
)
879 if (strcmp (f
, "CpuFP") == 0)
881 set_bitfield("Cpu387", array
, value
, size
, lineno
);
882 set_bitfield("Cpu287", array
, value
, size
, lineno
);
885 else if (strcmp (f
, "Mmword") == 0)
887 else if (strcmp (f
, "Oword") == 0)
890 for (i
= 0; i
< size
; i
++)
891 if (strcasecmp (array
[i
].name
, f
) == 0)
893 array
[i
].value
= value
;
899 const char *v
= strchr (f
, '=');
906 for (i
= 0; i
< size
; i
++)
907 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
909 value
= strtol (v
+ 1, &end
, 0);
912 array
[i
].value
= value
;
920 /* Handle shorthands. */
921 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
925 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
927 fail (_("unknown bitfield: %s\n"), f
);
931 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
932 int macro
, const char *comma
, const char *indent
)
936 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
938 fprintf (table
, "%s{ { ", indent
);
940 for (i
= 0; i
< size
- 1; i
++)
942 if (((i
+ 1) % 20) != 0)
943 fprintf (table
, "%d, ", flags
[i
].value
);
945 fprintf (table
, "%d,", flags
[i
].value
);
946 if (((i
+ 1) % 20) == 0)
948 /* We need \\ for macro. */
950 fprintf (table
, " \\\n %s", indent
);
952 fprintf (table
, "\n %s", indent
);
955 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
958 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
962 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
963 const char *comma
, const char *indent
,
966 char *str
, *next
, *last
;
968 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
970 /* Copy the default cpu flags. */
971 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
973 if (strcasecmp (flag
, "unknown") == 0)
975 /* We turn on everything except for cpu64 in case of
976 CPU_UNKNOWN_FLAGS. */
977 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
978 if (flags
[i
].position
!= Cpu64
)
981 else if (flag
[0] == '~')
983 last
= flag
+ strlen (flag
);
990 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
997 /* First we turn on everything except for cpu64. */
998 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
999 if (flags
[i
].position
!= Cpu64
)
1002 /* Turn off selective bits. */
1003 for (; next
&& next
< last
; )
1005 str
= next_field (next
, '|', &next
, last
);
1007 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1010 else if (strcmp (flag
, "0"))
1012 /* Turn on selective bits. */
1013 last
= flag
+ strlen (flag
);
1014 for (next
= flag
; next
&& next
< last
; )
1016 str
= next_field (next
, '|', &next
, last
);
1018 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1022 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1027 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1031 fprintf (table
, " { ");
1033 for (i
= 0; i
< size
- 1; i
++)
1035 if (((i
+ 1) % 20) != 0)
1036 fprintf (table
, "%d, ", modifier
[i
].value
);
1038 fprintf (table
, "%d,", modifier
[i
].value
);
1039 if (((i
+ 1) % 20) == 0)
1040 fprintf (table
, "\n ");
1043 fprintf (table
, "%d },\n", modifier
[i
].value
);
1047 adjust_broadcast_modifier (char **opnd
)
1049 char *str
, *next
, *last
, *op
;
1050 int bcst_type
= INT_MAX
;
1052 /* Skip the immediate operand. */
1054 if (strcasecmp(op
, "Imm8") == 0)
1058 last
= op
+ strlen (op
);
1059 for (next
= op
; next
&& next
< last
; )
1061 str
= next_field (next
, '|', &next
, last
);
1064 if (strcasecmp(str
, "Byte") == 0)
1066 /* The smalest broadcast type, no need to check
1068 bcst_type
= BYTE_BROADCAST
;
1071 else if (strcasecmp(str
, "Word") == 0)
1073 if (bcst_type
> WORD_BROADCAST
)
1074 bcst_type
= WORD_BROADCAST
;
1076 else if (strcasecmp(str
, "Dword") == 0)
1078 if (bcst_type
> DWORD_BROADCAST
)
1079 bcst_type
= DWORD_BROADCAST
;
1081 else if (strcasecmp(str
, "Qword") == 0)
1083 if (bcst_type
> QWORD_BROADCAST
)
1084 bcst_type
= QWORD_BROADCAST
;
1090 if (bcst_type
== INT_MAX
)
1091 fail (_("unknown broadcast operand: %s\n"), op
);
1097 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1099 char *str
, *next
, *last
;
1100 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1102 active_isstring
= 0;
1104 /* Copy the default opcode modifier. */
1105 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1107 if (strcmp (mod
, "0"))
1109 last
= mod
+ strlen (mod
);
1110 for (next
= mod
; next
&& next
< last
; )
1112 str
= next_field (next
, '|', &next
, last
);
1116 if (strcasecmp(str
, "Broadcast") == 0)
1117 val
= adjust_broadcast_modifier (opnd
);
1118 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1120 if (strcasecmp(str
, "IsString") == 0)
1121 active_isstring
= 1;
1125 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1135 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1136 enum stage stage
, const char *indent
)
1140 fprintf (table
, "{ { ");
1142 for (i
= 0; i
< size
- 1; i
++)
1144 if (((i
+ 1) % 20) != 0)
1145 fprintf (table
, "%d, ", types
[i
].value
);
1147 fprintf (table
, "%d,", types
[i
].value
);
1148 if (((i
+ 1) % 20) == 0)
1150 /* We need \\ for macro. */
1151 if (stage
== stage_macros
)
1152 fprintf (table
, " \\\n%s", indent
);
1154 fprintf (table
, "\n%s", indent
);
1158 fprintf (table
, "%d } }", types
[i
].value
);
1162 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1163 const char *indent
, int lineno
)
1165 char *str
, *next
, *last
;
1166 bitfield types
[ARRAY_SIZE (operand_types
)];
1168 /* Copy the default operand type. */
1169 memcpy (types
, operand_types
, sizeof (types
));
1171 if (strcmp (op
, "0"))
1175 last
= op
+ strlen (op
);
1176 for (next
= op
; next
&& next
< last
; )
1178 str
= next_field (next
, '|', &next
, last
);
1181 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1182 if (strcasecmp(str
, "BaseIndex") == 0)
1187 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1189 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1190 if (!active_cpu_flags
.bitfield
.cpu64
1191 && !active_cpu_flags
.bitfield
.cpumpx
)
1192 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1193 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1194 if (!active_cpu_flags
.bitfield
.cpuno64
)
1195 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1198 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1203 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1204 char *last
, int lineno
)
1207 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1208 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1210 /* Find number of operands. */
1211 operands
= next_field (str
, ',', &str
, last
);
1213 /* Find base_opcode. */
1214 base_opcode
= next_field (str
, ',', &str
, last
);
1216 /* Find extension_opcode. */
1217 extension_opcode
= next_field (str
, ',', &str
, last
);
1219 /* Find opcode_length. */
1220 opcode_length
= next_field (str
, ',', &str
, last
);
1222 /* Find cpu_flags. */
1223 cpu_flags
= next_field (str
, ',', &str
, last
);
1225 /* Find opcode_modifier. */
1226 opcode_modifier
= next_field (str
, ',', &str
, last
);
1228 /* Remove the first {. */
1229 str
= remove_leading_whitespaces (str
);
1232 str
= remove_leading_whitespaces (str
+ 1);
1236 /* There are at least "X}". */
1240 /* Remove trailing white spaces and }. */
1244 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1253 /* Find operand_types. */
1254 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1258 operand_types
[i
] = NULL
;
1262 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1263 if (*operand_types
[i
] == '0')
1266 operand_types
[i
] = NULL
;
1271 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1272 name
, operands
, base_opcode
, extension_opcode
,
1275 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1277 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1279 fprintf (table
, " { ");
1281 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1283 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1286 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1292 fprintf (table
, ",\n ");
1294 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1297 fprintf (table
, " } },\n");
1300 struct opcode_hash_entry
1302 struct opcode_hash_entry
*next
;
1308 /* Calculate the hash value of an opcode hash entry P. */
1311 opcode_hash_hash (const void *p
)
1313 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1314 return htab_hash_string (entry
->name
);
1317 /* Compare a string Q against an opcode hash entry P. */
1320 opcode_hash_eq (const void *p
, const void *q
)
1322 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1323 const char *name
= (const char *) q
;
1324 return strcmp (name
, entry
->name
) == 0;
1328 process_i386_opcodes (FILE *table
)
1333 char *str
, *p
, *last
, *name
;
1334 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1335 htab_t opcode_hash_table
;
1336 struct opcode_hash_entry
**opcode_array
;
1337 unsigned int opcode_array_size
= 1024;
1338 int lineno
= 0, marker
= 0;
1340 filename
= "i386-opc.tbl";
1344 opcode_array
= (struct opcode_hash_entry
**)
1345 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1347 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1348 opcode_hash_eq
, NULL
,
1351 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1352 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1354 /* Put everything on opcode array. */
1357 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1362 p
= remove_leading_whitespaces (buf
);
1364 /* Skip comments. */
1365 str
= strstr (p
, "//");
1369 /* Remove trailing white spaces. */
1370 remove_trailing_whitespaces (p
);
1375 if (!strcmp("### MARKER ###", buf
))
1379 /* Since we ignore all included files (we only care about their
1380 #define-s here), we don't need to monitor filenames. The final
1381 line number directive is going to refer to the main source file
1386 p
= remove_leading_whitespaces (p
+ 1);
1387 if (!strncmp(p
, "line", 4))
1389 ln
= strtoul (p
, &end
, 10);
1390 if (ln
> 1 && ln
< INT_MAX
1391 && *remove_leading_whitespaces (end
) == '"')
1394 /* Ignore comments. */
1404 last
= p
+ strlen (p
);
1407 name
= next_field (p
, ',', &str
, last
);
1409 /* Get the slot in hash table. */
1410 hash_slot
= (struct opcode_hash_entry
**)
1411 htab_find_slot_with_hash (opcode_hash_table
, name
,
1412 htab_hash_string (name
),
1415 if (*hash_slot
== NULL
)
1417 /* It is the new one. Put it on opcode array. */
1418 if (i
>= opcode_array_size
)
1420 /* Grow the opcode array when needed. */
1421 opcode_array_size
+= 1024;
1422 opcode_array
= (struct opcode_hash_entry
**)
1423 xrealloc (opcode_array
,
1424 sizeof (*opcode_array
) * opcode_array_size
);
1427 opcode_array
[i
] = (struct opcode_hash_entry
*)
1428 xmalloc (sizeof (struct opcode_hash_entry
));
1429 opcode_array
[i
]->next
= NULL
;
1430 opcode_array
[i
]->name
= xstrdup (name
);
1431 opcode_array
[i
]->opcode
= xstrdup (str
);
1432 opcode_array
[i
]->lineno
= lineno
;
1433 *hash_slot
= opcode_array
[i
];
1438 /* Append it to the existing one. */
1440 while ((*entry
) != NULL
)
1441 entry
= &(*entry
)->next
;
1442 *entry
= (struct opcode_hash_entry
*)
1443 xmalloc (sizeof (struct opcode_hash_entry
));
1444 (*entry
)->next
= NULL
;
1445 (*entry
)->name
= (*hash_slot
)->name
;
1446 (*entry
)->opcode
= xstrdup (str
);
1447 (*entry
)->lineno
= lineno
;
1451 /* Process opcode array. */
1452 for (j
= 0; j
< i
; j
++)
1454 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1458 lineno
= next
->lineno
;
1459 last
= str
+ strlen (str
);
1460 output_i386_opcode (table
, name
, str
, last
, lineno
);
1466 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1468 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1470 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1472 fprintf (table
, " { ");
1473 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1474 fprintf (table
, " } }\n");
1476 fprintf (table
, "};\n");
1480 process_i386_registers (FILE *table
)
1484 char *str
, *p
, *last
;
1485 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1486 char *dw2_32_num
, *dw2_64_num
;
1489 filename
= "i386-reg.tbl";
1490 fp
= fopen (filename
, "r");
1492 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1495 fprintf (table
, "\n/* i386 register table. */\n\n");
1496 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1500 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1505 p
= remove_leading_whitespaces (buf
);
1507 /* Skip comments. */
1508 str
= strstr (p
, "//");
1512 /* Remove trailing white spaces. */
1513 remove_trailing_whitespaces (p
);
1518 fprintf (table
, "%s\n", p
);
1526 last
= p
+ strlen (p
);
1528 /* Find reg_name. */
1529 reg_name
= next_field (p
, ',', &str
, last
);
1531 /* Find reg_type. */
1532 reg_type
= next_field (str
, ',', &str
, last
);
1534 /* Find reg_flags. */
1535 reg_flags
= next_field (str
, ',', &str
, last
);
1538 reg_num
= next_field (str
, ',', &str
, last
);
1540 fprintf (table
, " { \"%s\",\n ", reg_name
);
1542 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1545 /* Find 32-bit Dwarf2 register number. */
1546 dw2_32_num
= next_field (str
, ',', &str
, last
);
1548 /* Find 64-bit Dwarf2 register number. */
1549 dw2_64_num
= next_field (str
, ',', &str
, last
);
1551 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1552 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1557 fprintf (table
, "};\n");
1559 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1563 process_i386_initializers (void)
1566 FILE *fp
= fopen ("i386-init.h", "w");
1570 fail (_("can't create i386-init.h, errno = %s\n"),
1573 process_copyright (fp
);
1575 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1577 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1578 init
= xstrdup (cpu_flag_init
[i
].init
);
1579 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1583 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1585 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1586 init
= xstrdup (operand_type_init
[i
].init
);
1587 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1595 /* Program options. */
1596 #define OPTION_SRCDIR 200
1598 struct option long_options
[] =
1600 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1601 {"debug", no_argument
, NULL
, 'd'},
1602 {"version", no_argument
, NULL
, 'V'},
1603 {"help", no_argument
, NULL
, 'h'},
1604 {0, no_argument
, NULL
, 0}
1608 print_version (void)
1610 printf ("%s: version 1.0\n", program_name
);
1615 usage (FILE * stream
, int status
)
1617 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1623 main (int argc
, char **argv
)
1625 extern int chdir (char *);
1626 char *srcdir
= NULL
;
1628 unsigned int i
, cpumax
;
1631 program_name
= *argv
;
1632 xmalloc_set_program_name (program_name
);
1634 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1659 if (chdir (srcdir
) != 0)
1660 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1661 srcdir
, xstrerror (errno
));
1663 /* cpu_flags isn't sorted by position. */
1665 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1666 if (cpu_flags
[i
].position
> cpumax
)
1667 cpumax
= cpu_flags
[i
].position
;
1669 /* Check the unused bitfield in i386_cpu_flags. */
1671 if ((cpumax
- 1) != CpuMax
)
1672 fail (_("CpuMax != %d!\n"), cpumax
);
1674 if (cpumax
!= CpuMax
)
1675 fail (_("CpuMax != %d!\n"), cpumax
);
1677 c
= CpuNumOfBits
- CpuMax
- 1;
1679 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1682 /* Check the unused bitfield in i386_operand_type. */
1684 c
= OTNumOfBits
- OTMax
- 1;
1686 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1689 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1692 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1693 sizeof (opcode_modifiers
[0]), compare
);
1695 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1696 sizeof (operand_types
[0]), compare
);
1698 table
= fopen ("i386-tbl.h", "w");
1700 fail (_("can't create i386-tbl.h, errno = %s\n"),
1703 process_copyright (table
);
1705 process_i386_opcodes (table
);
1706 process_i386_registers (table
);
1707 process_i386_initializers ();