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_ANY_X87_FLAGS",
301 "CPU_ANY_287_FLAGS|Cpu8087" },
302 { "CPU_ANY_287_FLAGS",
303 "CPU_ANY_387_FLAGS|Cpu287" },
304 { "CPU_ANY_387_FLAGS",
305 "CPU_ANY_687_FLAGS|Cpu387" },
306 { "CPU_ANY_687_FLAGS",
307 "Cpu687|CpuFISTTP" },
308 { "CPU_ANY_CMOV_FLAGS",
310 { "CPU_ANY_FXSR_FLAGS",
312 { "CPU_ANY_MMX_FLAGS",
313 "CPU_3DNOWA_FLAGS" },
314 { "CPU_ANY_SSE_FLAGS",
315 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
316 { "CPU_ANY_SSE2_FLAGS",
317 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
318 { "CPU_ANY_SSE3_FLAGS",
319 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
320 { "CPU_ANY_SSSE3_FLAGS",
321 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
322 { "CPU_ANY_SSE4_1_FLAGS",
323 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
324 { "CPU_ANY_SSE4_2_FLAGS",
326 { "CPU_ANY_AVX_FLAGS",
327 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
328 { "CPU_ANY_AVX2_FLAGS",
329 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
330 { "CPU_ANY_AVX512F_FLAGS",
331 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16" },
332 { "CPU_ANY_AVX512CD_FLAGS",
334 { "CPU_ANY_AVX512ER_FLAGS",
336 { "CPU_ANY_AVX512PF_FLAGS",
338 { "CPU_ANY_AVX512DQ_FLAGS",
340 { "CPU_ANY_AVX512BW_FLAGS",
342 { "CPU_ANY_AVX512VL_FLAGS",
344 { "CPU_ANY_AVX512IFMA_FLAGS",
346 { "CPU_ANY_AVX512VBMI_FLAGS",
348 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
349 "CpuAVX512_4FMAPS" },
350 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
351 "CpuAVX512_4VNNIW" },
352 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
353 "CpuAVX512_VPOPCNTDQ" },
354 { "CPU_ANY_IBT_FLAGS",
356 { "CPU_ANY_SHSTK_FLAGS",
358 { "CPU_ANY_AVX512_VBMI2_FLAGS",
360 { "CPU_ANY_AVX512_VNNI_FLAGS",
362 { "CPU_ANY_AVX512_BITALG_FLAGS",
363 "CpuAVX512_BITALG" },
364 { "CPU_ANY_AVX512_BF16_FLAGS",
366 { "CPU_ANY_MOVDIRI_FLAGS",
368 { "CPU_ANY_MOVDIR64B_FLAGS",
370 { "CPU_ANY_ENQCMD_FLAGS",
374 static const initializer operand_type_shorthands
[] =
376 { "Reg8", "Reg|Byte" },
377 { "Reg16", "Reg|Word" },
378 { "Reg32", "Reg|Dword" },
379 { "Reg64", "Reg|Qword" },
380 { "FloatAcc", "Acc|Tbyte" },
381 { "FloatReg", "Reg|Tbyte" },
382 { "RegXMM", "RegSIMD|Xmmword" },
383 { "RegYMM", "RegSIMD|Ymmword" },
384 { "RegZMM", "RegSIMD|Zmmword" },
387 static initializer operand_type_init
[] =
389 { "OPERAND_TYPE_NONE",
391 { "OPERAND_TYPE_REG8",
393 { "OPERAND_TYPE_REG16",
395 { "OPERAND_TYPE_REG32",
397 { "OPERAND_TYPE_REG64",
399 { "OPERAND_TYPE_IMM1",
401 { "OPERAND_TYPE_IMM8",
403 { "OPERAND_TYPE_IMM8S",
405 { "OPERAND_TYPE_IMM16",
407 { "OPERAND_TYPE_IMM32",
409 { "OPERAND_TYPE_IMM32S",
411 { "OPERAND_TYPE_IMM64",
413 { "OPERAND_TYPE_BASEINDEX",
415 { "OPERAND_TYPE_DISP8",
417 { "OPERAND_TYPE_DISP16",
419 { "OPERAND_TYPE_DISP32",
421 { "OPERAND_TYPE_DISP32S",
423 { "OPERAND_TYPE_DISP64",
425 { "OPERAND_TYPE_INOUTPORTREG",
427 { "OPERAND_TYPE_SHIFTCOUNT",
429 { "OPERAND_TYPE_CONTROL",
431 { "OPERAND_TYPE_TEST",
433 { "OPERAND_TYPE_DEBUG",
435 { "OPERAND_TYPE_FLOATREG",
437 { "OPERAND_TYPE_FLOATACC",
439 { "OPERAND_TYPE_SREG2",
441 { "OPERAND_TYPE_SREG3",
443 { "OPERAND_TYPE_ACC",
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_ACC32",
461 { "OPERAND_TYPE_ACC64",
463 { "OPERAND_TYPE_DISP16_32",
465 { "OPERAND_TYPE_ANYDISP",
466 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
467 { "OPERAND_TYPE_IMM16_32",
469 { "OPERAND_TYPE_IMM16_32S",
471 { "OPERAND_TYPE_IMM16_32_32S",
472 "Imm16|Imm32|Imm32S" },
473 { "OPERAND_TYPE_IMM32_64",
475 { "OPERAND_TYPE_IMM32_32S_DISP32",
476 "Imm32|Imm32S|Disp32" },
477 { "OPERAND_TYPE_IMM64_DISP64",
479 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
480 "Imm32|Imm32S|Imm64|Disp32" },
481 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
482 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
483 { "OPERAND_TYPE_VEC_IMM4",
485 { "OPERAND_TYPE_REGBND",
489 typedef struct bitfield
496 #define BITFIELD(n) { n, 0, #n }
498 static bitfield cpu_flags
[] =
508 BITFIELD (CpuClflush
),
510 BITFIELD (CpuSYSCALL
),
515 BITFIELD (CpuFISTTP
),
521 BITFIELD (CpuSSE4_1
),
522 BITFIELD (CpuSSE4_2
),
525 BITFIELD (CpuAVX512F
),
526 BITFIELD (CpuAVX512CD
),
527 BITFIELD (CpuAVX512ER
),
528 BITFIELD (CpuAVX512PF
),
529 BITFIELD (CpuAVX512VL
),
530 BITFIELD (CpuAVX512DQ
),
531 BITFIELD (CpuAVX512BW
),
537 BITFIELD (Cpu3dnowA
),
538 BITFIELD (CpuPadLock
),
544 BITFIELD (CpuXsaveopt
),
546 BITFIELD (CpuPCLMUL
),
557 BITFIELD (CpuRdtscp
),
558 BITFIELD (CpuFSGSBase
),
565 BITFIELD (CpuINVPCID
),
566 BITFIELD (CpuVMFUNC
),
567 BITFIELD (CpuRDSEED
),
569 BITFIELD (CpuPRFCHW
),
572 BITFIELD (CpuClflushOpt
),
573 BITFIELD (CpuXSAVES
),
574 BITFIELD (CpuXSAVEC
),
575 BITFIELD (CpuPREFETCHWT1
),
581 BITFIELD (CpuAVX512IFMA
),
582 BITFIELD (CpuAVX512VBMI
),
583 BITFIELD (CpuAVX512_4FMAPS
),
584 BITFIELD (CpuAVX512_4VNNIW
),
585 BITFIELD (CpuAVX512_VPOPCNTDQ
),
586 BITFIELD (CpuAVX512_VBMI2
),
587 BITFIELD (CpuAVX512_VNNI
),
588 BITFIELD (CpuAVX512_BITALG
),
589 BITFIELD (CpuAVX512_BF16
),
590 BITFIELD (CpuMWAITX
),
591 BITFIELD (CpuCLZERO
),
594 BITFIELD (CpuPTWRITE
),
599 BITFIELD (CpuVPCLMULQDQ
),
600 BITFIELD (CpuWBNOINVD
),
601 BITFIELD (CpuPCONFIG
),
602 BITFIELD (CpuWAITPKG
),
603 BITFIELD (CpuCLDEMOTE
),
604 BITFIELD (CpuMOVDIRI
),
605 BITFIELD (CpuMOVDIR64B
),
606 BITFIELD (CpuENQCMD
),
608 BITFIELD (CpuUnused
),
612 static bitfield opcode_modifiers
[] =
618 BITFIELD (ShortForm
),
620 BITFIELD (JumpDword
),
622 BITFIELD (JumpInterSegment
),
626 BITFIELD (CheckRegSize
),
627 BITFIELD (IgnoreSize
),
628 BITFIELD (DefaultSize
),
637 BITFIELD (BNDPrefixOk
),
638 BITFIELD (NoTrackPrefixOk
),
639 BITFIELD (IsLockable
),
640 BITFIELD (RegKludge
),
641 BITFIELD (Implicit1stXmm0
),
642 BITFIELD (RepPrefixOk
),
643 BITFIELD (HLEPrefixOk
),
646 BITFIELD (AddrPrefixOpReg
),
655 BITFIELD (VexOpcode
),
656 BITFIELD (VexSources
),
662 BITFIELD (Broadcast
),
663 BITFIELD (StaticRounding
),
665 BITFIELD (Disp8MemShift
),
666 BITFIELD (NoDefMask
),
667 BITFIELD (ImplicitQuadGroup
),
669 BITFIELD (ATTMnemonic
),
670 BITFIELD (ATTSyntax
),
671 BITFIELD (IntelSyntax
),
676 static bitfield operand_types
[] =
689 BITFIELD (BaseIndex
),
695 BITFIELD (InOutPortReg
),
696 BITFIELD (ShiftCount
),
703 BITFIELD (JumpAbsolute
),
715 BITFIELD (Unspecified
),
724 static const char *filename
;
725 static i386_cpu_flags active_cpu_flags
;
726 static int active_isstring
;
729 compare (const void *x
, const void *y
)
731 const bitfield
*xp
= (const bitfield
*) x
;
732 const bitfield
*yp
= (const bitfield
*) y
;
733 return xp
->position
- yp
->position
;
737 fail (const char *message
, ...)
741 va_start (args
, message
);
742 fprintf (stderr
, _("%s: error: "), program_name
);
743 vfprintf (stderr
, message
, args
);
749 process_copyright (FILE *fp
)
751 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
752 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
754 This file is part of the GNU opcodes library.\n\
756 This library is free software; you can redistribute it and/or modify\n\
757 it under the terms of the GNU General Public License as published by\n\
758 the Free Software Foundation; either version 3, or (at your option)\n\
759 any later version.\n\
761 It is distributed in the hope that it will be useful, but WITHOUT\n\
762 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
763 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
764 License for more details.\n\
766 You should have received a copy of the GNU General Public License\n\
767 along with this program; if not, write to the Free Software\n\
768 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
769 MA 02110-1301, USA. */\n");
772 /* Remove leading white spaces. */
775 remove_leading_whitespaces (char *str
)
777 while (ISSPACE (*str
))
782 /* Remove trailing white spaces. */
785 remove_trailing_whitespaces (char *str
)
787 size_t last
= strlen (str
);
795 if (ISSPACE (str
[last
]))
803 /* Find next field separated by SEP and terminate it. Return a
804 pointer to the one after it. */
807 next_field (char *str
, char sep
, char **next
, char *last
)
811 p
= remove_leading_whitespaces (str
);
812 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
815 remove_trailing_whitespaces (p
);
825 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
828 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
831 char *str
, *next
, *last
;
834 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
835 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
837 /* Turn on selective bits. */
838 char *init
= xstrdup (cpu_flag_init
[i
].init
);
839 last
= init
+ strlen (init
);
840 for (next
= init
; next
&& next
< last
; )
842 str
= next_field (next
, '|', &next
, last
);
844 set_bitfield (str
, array
, 1, size
, lineno
);
850 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
851 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
853 /* Turn on selective bits. */
854 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
855 last
= init
+ strlen (init
);
856 for (next
= init
; next
&& next
< last
; )
858 str
= next_field (next
, '|', &next
, last
);
860 set_bitfield (str
, array
, 1, size
, lineno
);
870 set_bitfield (char *f
, bitfield
*array
, int value
,
871 unsigned int size
, int lineno
)
875 if (strcmp (f
, "CpuFP") == 0)
877 set_bitfield("Cpu387", array
, value
, size
, lineno
);
878 set_bitfield("Cpu287", array
, value
, size
, lineno
);
881 else if (strcmp (f
, "Mmword") == 0)
883 else if (strcmp (f
, "Oword") == 0)
886 for (i
= 0; i
< size
; i
++)
887 if (strcasecmp (array
[i
].name
, f
) == 0)
889 array
[i
].value
= value
;
895 const char *v
= strchr (f
, '=');
902 for (i
= 0; i
< size
; i
++)
903 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
905 value
= strtol (v
+ 1, &end
, 0);
908 array
[i
].value
= value
;
916 /* Handle shorthands. */
917 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
921 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
923 fail (_("unknown bitfield: %s\n"), f
);
927 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
928 int macro
, const char *comma
, const char *indent
)
932 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
934 fprintf (table
, "%s{ { ", indent
);
936 for (i
= 0; i
< size
- 1; i
++)
938 if (((i
+ 1) % 20) != 0)
939 fprintf (table
, "%d, ", flags
[i
].value
);
941 fprintf (table
, "%d,", flags
[i
].value
);
942 if (((i
+ 1) % 20) == 0)
944 /* We need \\ for macro. */
946 fprintf (table
, " \\\n %s", indent
);
948 fprintf (table
, "\n %s", indent
);
951 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
954 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
958 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
959 const char *comma
, const char *indent
,
962 char *str
, *next
, *last
;
964 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
966 /* Copy the default cpu flags. */
967 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
969 if (strcasecmp (flag
, "unknown") == 0)
971 /* We turn on everything except for cpu64 in case of
972 CPU_UNKNOWN_FLAGS. */
973 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
974 if (flags
[i
].position
!= Cpu64
)
977 else if (flag
[0] == '~')
979 last
= flag
+ strlen (flag
);
986 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
993 /* First we turn on everything except for cpu64. */
994 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
995 if (flags
[i
].position
!= Cpu64
)
998 /* Turn off selective bits. */
999 for (; next
&& next
< last
; )
1001 str
= next_field (next
, '|', &next
, last
);
1003 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1006 else if (strcmp (flag
, "0"))
1008 /* Turn on selective bits. */
1009 last
= flag
+ strlen (flag
);
1010 for (next
= flag
; next
&& next
< last
; )
1012 str
= next_field (next
, '|', &next
, last
);
1014 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1018 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1023 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1027 fprintf (table
, " { ");
1029 for (i
= 0; i
< size
- 1; i
++)
1031 if (((i
+ 1) % 20) != 0)
1032 fprintf (table
, "%d, ", modifier
[i
].value
);
1034 fprintf (table
, "%d,", modifier
[i
].value
);
1035 if (((i
+ 1) % 20) == 0)
1036 fprintf (table
, "\n ");
1039 fprintf (table
, "%d },\n", modifier
[i
].value
);
1043 adjust_broadcast_modifier (char **opnd
)
1045 char *str
, *next
, *last
, *op
;
1046 int bcst_type
= INT_MAX
;
1048 /* Skip the immediate operand. */
1050 if (strcasecmp(op
, "Imm8") == 0)
1054 last
= op
+ strlen (op
);
1055 for (next
= op
; next
&& next
< last
; )
1057 str
= next_field (next
, '|', &next
, last
);
1060 if (strcasecmp(str
, "Byte") == 0)
1062 /* The smalest broadcast type, no need to check
1064 bcst_type
= BYTE_BROADCAST
;
1067 else if (strcasecmp(str
, "Word") == 0)
1069 if (bcst_type
> WORD_BROADCAST
)
1070 bcst_type
= WORD_BROADCAST
;
1072 else if (strcasecmp(str
, "Dword") == 0)
1074 if (bcst_type
> DWORD_BROADCAST
)
1075 bcst_type
= DWORD_BROADCAST
;
1077 else if (strcasecmp(str
, "Qword") == 0)
1079 if (bcst_type
> QWORD_BROADCAST
)
1080 bcst_type
= QWORD_BROADCAST
;
1086 if (bcst_type
== INT_MAX
)
1087 fail (_("unknown broadcast operand: %s\n"), op
);
1093 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1095 char *str
, *next
, *last
;
1096 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1098 active_isstring
= 0;
1100 /* Copy the default opcode modifier. */
1101 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1103 if (strcmp (mod
, "0"))
1105 last
= mod
+ strlen (mod
);
1106 for (next
= mod
; next
&& next
< last
; )
1108 str
= next_field (next
, '|', &next
, last
);
1112 if (strcasecmp(str
, "Broadcast") == 0)
1113 val
= adjust_broadcast_modifier (opnd
);
1114 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1116 if (strcasecmp(str
, "IsString") == 0)
1117 active_isstring
= 1;
1121 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1131 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1132 enum stage stage
, const char *indent
)
1136 fprintf (table
, "{ { ");
1138 for (i
= 0; i
< size
- 1; i
++)
1140 if (((i
+ 1) % 20) != 0)
1141 fprintf (table
, "%d, ", types
[i
].value
);
1143 fprintf (table
, "%d,", types
[i
].value
);
1144 if (((i
+ 1) % 20) == 0)
1146 /* We need \\ for macro. */
1147 if (stage
== stage_macros
)
1148 fprintf (table
, " \\\n%s", indent
);
1150 fprintf (table
, "\n%s", indent
);
1154 fprintf (table
, "%d } }", types
[i
].value
);
1158 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1159 const char *indent
, int lineno
)
1161 char *str
, *next
, *last
;
1162 bitfield types
[ARRAY_SIZE (operand_types
)];
1164 /* Copy the default operand type. */
1165 memcpy (types
, operand_types
, sizeof (types
));
1167 if (strcmp (op
, "0"))
1171 last
= op
+ strlen (op
);
1172 for (next
= op
; next
&& next
< last
; )
1174 str
= next_field (next
, '|', &next
, last
);
1177 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1178 if (strcasecmp(str
, "BaseIndex") == 0)
1183 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1185 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1186 if (!active_cpu_flags
.bitfield
.cpu64
1187 && !active_cpu_flags
.bitfield
.cpumpx
)
1188 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1189 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1190 if (!active_cpu_flags
.bitfield
.cpuno64
)
1191 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1194 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1199 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1200 char *last
, int lineno
)
1203 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1204 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1206 /* Find number of operands. */
1207 operands
= next_field (str
, ',', &str
, last
);
1209 /* Find base_opcode. */
1210 base_opcode
= next_field (str
, ',', &str
, last
);
1212 /* Find extension_opcode. */
1213 extension_opcode
= next_field (str
, ',', &str
, last
);
1215 /* Find opcode_length. */
1216 opcode_length
= next_field (str
, ',', &str
, last
);
1218 /* Find cpu_flags. */
1219 cpu_flags
= next_field (str
, ',', &str
, last
);
1221 /* Find opcode_modifier. */
1222 opcode_modifier
= next_field (str
, ',', &str
, last
);
1224 /* Remove the first {. */
1225 str
= remove_leading_whitespaces (str
);
1228 str
= remove_leading_whitespaces (str
+ 1);
1232 /* There are at least "X}". */
1236 /* Remove trailing white spaces and }. */
1240 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1249 /* Find operand_types. */
1250 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1254 operand_types
[i
] = NULL
;
1258 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1259 if (*operand_types
[i
] == '0')
1262 operand_types
[i
] = NULL
;
1267 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1268 name
, operands
, base_opcode
, extension_opcode
,
1271 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1273 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1275 fprintf (table
, " { ");
1277 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1279 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1282 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1288 fprintf (table
, ",\n ");
1290 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1293 fprintf (table
, " } },\n");
1296 struct opcode_hash_entry
1298 struct opcode_hash_entry
*next
;
1304 /* Calculate the hash value of an opcode hash entry P. */
1307 opcode_hash_hash (const void *p
)
1309 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1310 return htab_hash_string (entry
->name
);
1313 /* Compare a string Q against an opcode hash entry P. */
1316 opcode_hash_eq (const void *p
, const void *q
)
1318 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1319 const char *name
= (const char *) q
;
1320 return strcmp (name
, entry
->name
) == 0;
1324 process_i386_opcodes (FILE *table
)
1329 char *str
, *p
, *last
, *name
;
1330 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1331 htab_t opcode_hash_table
;
1332 struct opcode_hash_entry
**opcode_array
;
1333 unsigned int opcode_array_size
= 1024;
1334 int lineno
= 0, marker
= 0;
1336 filename
= "i386-opc.tbl";
1340 opcode_array
= (struct opcode_hash_entry
**)
1341 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1343 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1344 opcode_hash_eq
, NULL
,
1347 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1348 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1350 /* Put everything on opcode array. */
1353 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1358 p
= remove_leading_whitespaces (buf
);
1360 /* Skip comments. */
1361 str
= strstr (p
, "//");
1365 /* Remove trailing white spaces. */
1366 remove_trailing_whitespaces (p
);
1371 if (!strcmp("### MARKER ###", buf
))
1375 /* Since we ignore all included files (we only care about their
1376 #define-s here), we don't need to monitor filenames. The final
1377 line number directive is going to refer to the main source file
1382 p
= remove_leading_whitespaces (p
+ 1);
1383 if (!strncmp(p
, "line", 4))
1385 ln
= strtoul (p
, &end
, 10);
1386 if (ln
> 1 && ln
< INT_MAX
1387 && *remove_leading_whitespaces (end
) == '"')
1390 /* Ignore comments. */
1400 last
= p
+ strlen (p
);
1403 name
= next_field (p
, ',', &str
, last
);
1405 /* Get the slot in hash table. */
1406 hash_slot
= (struct opcode_hash_entry
**)
1407 htab_find_slot_with_hash (opcode_hash_table
, name
,
1408 htab_hash_string (name
),
1411 if (*hash_slot
== NULL
)
1413 /* It is the new one. Put it on opcode array. */
1414 if (i
>= opcode_array_size
)
1416 /* Grow the opcode array when needed. */
1417 opcode_array_size
+= 1024;
1418 opcode_array
= (struct opcode_hash_entry
**)
1419 xrealloc (opcode_array
,
1420 sizeof (*opcode_array
) * opcode_array_size
);
1423 opcode_array
[i
] = (struct opcode_hash_entry
*)
1424 xmalloc (sizeof (struct opcode_hash_entry
));
1425 opcode_array
[i
]->next
= NULL
;
1426 opcode_array
[i
]->name
= xstrdup (name
);
1427 opcode_array
[i
]->opcode
= xstrdup (str
);
1428 opcode_array
[i
]->lineno
= lineno
;
1429 *hash_slot
= opcode_array
[i
];
1434 /* Append it to the existing one. */
1436 while ((*entry
) != NULL
)
1437 entry
= &(*entry
)->next
;
1438 *entry
= (struct opcode_hash_entry
*)
1439 xmalloc (sizeof (struct opcode_hash_entry
));
1440 (*entry
)->next
= NULL
;
1441 (*entry
)->name
= (*hash_slot
)->name
;
1442 (*entry
)->opcode
= xstrdup (str
);
1443 (*entry
)->lineno
= lineno
;
1447 /* Process opcode array. */
1448 for (j
= 0; j
< i
; j
++)
1450 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1454 lineno
= next
->lineno
;
1455 last
= str
+ strlen (str
);
1456 output_i386_opcode (table
, name
, str
, last
, lineno
);
1462 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1464 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1466 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1468 fprintf (table
, " { ");
1469 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1470 fprintf (table
, " } }\n");
1472 fprintf (table
, "};\n");
1476 process_i386_registers (FILE *table
)
1480 char *str
, *p
, *last
;
1481 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1482 char *dw2_32_num
, *dw2_64_num
;
1485 filename
= "i386-reg.tbl";
1486 fp
= fopen (filename
, "r");
1488 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1491 fprintf (table
, "\n/* i386 register table. */\n\n");
1492 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1496 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1501 p
= remove_leading_whitespaces (buf
);
1503 /* Skip comments. */
1504 str
= strstr (p
, "//");
1508 /* Remove trailing white spaces. */
1509 remove_trailing_whitespaces (p
);
1514 fprintf (table
, "%s\n", p
);
1522 last
= p
+ strlen (p
);
1524 /* Find reg_name. */
1525 reg_name
= next_field (p
, ',', &str
, last
);
1527 /* Find reg_type. */
1528 reg_type
= next_field (str
, ',', &str
, last
);
1530 /* Find reg_flags. */
1531 reg_flags
= next_field (str
, ',', &str
, last
);
1534 reg_num
= next_field (str
, ',', &str
, last
);
1536 fprintf (table
, " { \"%s\",\n ", reg_name
);
1538 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1541 /* Find 32-bit Dwarf2 register number. */
1542 dw2_32_num
= next_field (str
, ',', &str
, last
);
1544 /* Find 64-bit Dwarf2 register number. */
1545 dw2_64_num
= next_field (str
, ',', &str
, last
);
1547 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1548 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1553 fprintf (table
, "};\n");
1555 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1559 process_i386_initializers (void)
1562 FILE *fp
= fopen ("i386-init.h", "w");
1566 fail (_("can't create i386-init.h, errno = %s\n"),
1569 process_copyright (fp
);
1571 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1573 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1574 init
= xstrdup (cpu_flag_init
[i
].init
);
1575 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1579 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1581 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1582 init
= xstrdup (operand_type_init
[i
].init
);
1583 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1591 /* Program options. */
1592 #define OPTION_SRCDIR 200
1594 struct option long_options
[] =
1596 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1597 {"debug", no_argument
, NULL
, 'd'},
1598 {"version", no_argument
, NULL
, 'V'},
1599 {"help", no_argument
, NULL
, 'h'},
1600 {0, no_argument
, NULL
, 0}
1604 print_version (void)
1606 printf ("%s: version 1.0\n", program_name
);
1611 usage (FILE * stream
, int status
)
1613 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1619 main (int argc
, char **argv
)
1621 extern int chdir (char *);
1622 char *srcdir
= NULL
;
1624 unsigned int i
, cpumax
;
1627 program_name
= *argv
;
1628 xmalloc_set_program_name (program_name
);
1630 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1655 if (chdir (srcdir
) != 0)
1656 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1657 srcdir
, xstrerror (errno
));
1659 /* cpu_flags isn't sorted by position. */
1661 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1662 if (cpu_flags
[i
].position
> cpumax
)
1663 cpumax
= cpu_flags
[i
].position
;
1665 /* Check the unused bitfield in i386_cpu_flags. */
1667 if ((cpumax
- 1) != CpuMax
)
1668 fail (_("CpuMax != %d!\n"), cpumax
);
1670 if (cpumax
!= CpuMax
)
1671 fail (_("CpuMax != %d!\n"), cpumax
);
1673 c
= CpuNumOfBits
- CpuMax
- 1;
1675 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1678 /* Check the unused bitfield in i386_operand_type. */
1680 c
= OTNumOfBits
- OTMax
- 1;
1682 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1685 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1688 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1689 sizeof (opcode_modifiers
[0]), compare
);
1691 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1692 sizeof (operand_types
[0]), compare
);
1694 table
= fopen ("i386-tbl.h", "w");
1696 fail (_("can't create i386-tbl.h, errno = %s\n"),
1699 process_copyright (table
);
1701 process_i386_opcodes (table
);
1702 process_i386_registers (table
);
1703 process_i386_initializers ();