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" },
239 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
242 { "CPU_RDSEED_FLAGS",
244 { "CPU_PRFCHW_FLAGS",
249 "CPU_XSAVE_FLAGS|CpuMPX" },
251 "CPU_SSE2_FLAGS|CpuSHA" },
252 { "CPU_CLFLUSHOPT_FLAGS",
254 { "CPU_XSAVES_FLAGS",
255 "CPU_XSAVE_FLAGS|CpuXSAVES" },
256 { "CPU_XSAVEC_FLAGS",
257 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
258 { "CPU_PREFETCHWT1_FLAGS",
264 { "CPU_CLZERO_FLAGS",
266 { "CPU_MWAITX_FLAGS",
269 "CPU_XSAVE_FLAGS|CpuOSPKE" },
272 { "CPU_PTWRITE_FLAGS",
282 { "CPU_VPCLMULQDQ_FLAGS",
284 { "CPU_WBNOINVD_FLAGS",
286 { "CPU_PCONFIG_FLAGS",
288 { "CPU_WAITPKG_FLAGS",
290 { "CPU_CLDEMOTE_FLAGS",
292 { "CPU_MOVDIRI_FLAGS",
294 { "CPU_MOVDIR64B_FLAGS",
296 { "CPU_ANY_X87_FLAGS",
297 "CPU_ANY_287_FLAGS|Cpu8087" },
298 { "CPU_ANY_287_FLAGS",
299 "CPU_ANY_387_FLAGS|Cpu287" },
300 { "CPU_ANY_387_FLAGS",
301 "CPU_ANY_687_FLAGS|Cpu387" },
302 { "CPU_ANY_687_FLAGS",
303 "Cpu687|CpuFISTTP" },
304 { "CPU_ANY_CMOV_FLAGS",
306 { "CPU_ANY_FXSR_FLAGS",
308 { "CPU_ANY_MMX_FLAGS",
309 "CPU_3DNOWA_FLAGS" },
310 { "CPU_ANY_SSE_FLAGS",
311 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
312 { "CPU_ANY_SSE2_FLAGS",
313 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
314 { "CPU_ANY_SSE3_FLAGS",
315 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
316 { "CPU_ANY_SSSE3_FLAGS",
317 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
318 { "CPU_ANY_SSE4_1_FLAGS",
319 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
320 { "CPU_ANY_SSE4_2_FLAGS",
322 { "CPU_ANY_AVX_FLAGS",
323 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
324 { "CPU_ANY_AVX2_FLAGS",
326 { "CPU_ANY_AVX512F_FLAGS",
327 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG" },
328 { "CPU_ANY_AVX512CD_FLAGS",
330 { "CPU_ANY_AVX512ER_FLAGS",
332 { "CPU_ANY_AVX512PF_FLAGS",
334 { "CPU_ANY_AVX512DQ_FLAGS",
336 { "CPU_ANY_AVX512BW_FLAGS",
338 { "CPU_ANY_AVX512VL_FLAGS",
340 { "CPU_ANY_AVX512IFMA_FLAGS",
342 { "CPU_ANY_AVX512VBMI_FLAGS",
344 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
345 "CpuAVX512_4FMAPS" },
346 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
347 "CpuAVX512_4VNNIW" },
348 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
349 "CpuAVX512_VPOPCNTDQ" },
350 { "CPU_ANY_IBT_FLAGS",
352 { "CPU_ANY_SHSTK_FLAGS",
354 { "CPU_ANY_AVX512_VBMI2_FLAGS",
356 { "CPU_ANY_AVX512_VNNI_FLAGS",
358 { "CPU_ANY_AVX512_BITALG_FLAGS",
359 "CpuAVX512_BITALG" },
360 { "CPU_ANY_MOVDIRI_FLAGS",
362 { "CPU_ANY_MOVDIR64B_FLAGS",
366 static const initializer operand_type_shorthands
[] =
368 { "Reg8", "Reg|Byte" },
369 { "Reg16", "Reg|Word" },
370 { "Reg32", "Reg|Dword" },
371 { "Reg64", "Reg|Qword" },
372 { "FloatAcc", "Acc|Tbyte" },
373 { "FloatReg", "Reg|Tbyte" },
374 { "RegXMM", "RegSIMD|Xmmword" },
375 { "RegYMM", "RegSIMD|Ymmword" },
376 { "RegZMM", "RegSIMD|Zmmword" },
379 static initializer operand_type_init
[] =
381 { "OPERAND_TYPE_NONE",
383 { "OPERAND_TYPE_REG8",
385 { "OPERAND_TYPE_REG16",
387 { "OPERAND_TYPE_REG32",
389 { "OPERAND_TYPE_REG64",
391 { "OPERAND_TYPE_IMM1",
393 { "OPERAND_TYPE_IMM8",
395 { "OPERAND_TYPE_IMM8S",
397 { "OPERAND_TYPE_IMM16",
399 { "OPERAND_TYPE_IMM32",
401 { "OPERAND_TYPE_IMM32S",
403 { "OPERAND_TYPE_IMM64",
405 { "OPERAND_TYPE_BASEINDEX",
407 { "OPERAND_TYPE_DISP8",
409 { "OPERAND_TYPE_DISP16",
411 { "OPERAND_TYPE_DISP32",
413 { "OPERAND_TYPE_DISP32S",
415 { "OPERAND_TYPE_DISP64",
417 { "OPERAND_TYPE_INOUTPORTREG",
419 { "OPERAND_TYPE_SHIFTCOUNT",
421 { "OPERAND_TYPE_CONTROL",
423 { "OPERAND_TYPE_TEST",
425 { "OPERAND_TYPE_DEBUG",
427 { "OPERAND_TYPE_FLOATREG",
429 { "OPERAND_TYPE_FLOATACC",
431 { "OPERAND_TYPE_SREG2",
433 { "OPERAND_TYPE_SREG3",
435 { "OPERAND_TYPE_ACC",
437 { "OPERAND_TYPE_JUMPABSOLUTE",
439 { "OPERAND_TYPE_REGMMX",
441 { "OPERAND_TYPE_REGXMM",
443 { "OPERAND_TYPE_REGYMM",
445 { "OPERAND_TYPE_REGZMM",
447 { "OPERAND_TYPE_REGMASK",
449 { "OPERAND_TYPE_ESSEG",
451 { "OPERAND_TYPE_ACC32",
453 { "OPERAND_TYPE_ACC64",
455 { "OPERAND_TYPE_DISP16_32",
457 { "OPERAND_TYPE_ANYDISP",
458 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
459 { "OPERAND_TYPE_IMM16_32",
461 { "OPERAND_TYPE_IMM16_32S",
463 { "OPERAND_TYPE_IMM16_32_32S",
464 "Imm16|Imm32|Imm32S" },
465 { "OPERAND_TYPE_IMM32_64",
467 { "OPERAND_TYPE_IMM32_32S_DISP32",
468 "Imm32|Imm32S|Disp32" },
469 { "OPERAND_TYPE_IMM64_DISP64",
471 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
472 "Imm32|Imm32S|Imm64|Disp32" },
473 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
474 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
475 { "OPERAND_TYPE_VEC_IMM4",
477 { "OPERAND_TYPE_REGBND",
481 typedef struct bitfield
488 #define BITFIELD(n) { n, 0, #n }
490 static bitfield cpu_flags
[] =
500 BITFIELD (CpuClflush
),
502 BITFIELD (CpuSYSCALL
),
507 BITFIELD (CpuFISTTP
),
513 BITFIELD (CpuSSE4_1
),
514 BITFIELD (CpuSSE4_2
),
517 BITFIELD (CpuAVX512F
),
518 BITFIELD (CpuAVX512CD
),
519 BITFIELD (CpuAVX512ER
),
520 BITFIELD (CpuAVX512PF
),
521 BITFIELD (CpuAVX512VL
),
522 BITFIELD (CpuAVX512DQ
),
523 BITFIELD (CpuAVX512BW
),
529 BITFIELD (Cpu3dnowA
),
530 BITFIELD (CpuPadLock
),
536 BITFIELD (CpuXsaveopt
),
538 BITFIELD (CpuPCLMUL
),
549 BITFIELD (CpuRdtscp
),
550 BITFIELD (CpuFSGSBase
),
557 BITFIELD (CpuINVPCID
),
558 BITFIELD (CpuVMFUNC
),
559 BITFIELD (CpuRDSEED
),
561 BITFIELD (CpuPRFCHW
),
564 BITFIELD (CpuClflushOpt
),
565 BITFIELD (CpuXSAVES
),
566 BITFIELD (CpuXSAVEC
),
567 BITFIELD (CpuPREFETCHWT1
),
573 BITFIELD (CpuAVX512IFMA
),
574 BITFIELD (CpuAVX512VBMI
),
575 BITFIELD (CpuAVX512_4FMAPS
),
576 BITFIELD (CpuAVX512_4VNNIW
),
577 BITFIELD (CpuAVX512_VPOPCNTDQ
),
578 BITFIELD (CpuAVX512_VBMI2
),
579 BITFIELD (CpuAVX512_VNNI
),
580 BITFIELD (CpuAVX512_BITALG
),
581 BITFIELD (CpuMWAITX
),
582 BITFIELD (CpuCLZERO
),
585 BITFIELD (CpuPTWRITE
),
590 BITFIELD (CpuVPCLMULQDQ
),
591 BITFIELD (CpuWBNOINVD
),
592 BITFIELD (CpuPCONFIG
),
593 BITFIELD (CpuWAITPKG
),
594 BITFIELD (CpuCLDEMOTE
),
595 BITFIELD (CpuMOVDIRI
),
596 BITFIELD (CpuMOVDIR64B
),
598 BITFIELD (CpuUnused
),
602 static bitfield opcode_modifiers
[] =
608 BITFIELD (ShortForm
),
610 BITFIELD (JumpDword
),
612 BITFIELD (JumpInterSegment
),
616 BITFIELD (CheckRegSize
),
617 BITFIELD (IgnoreSize
),
618 BITFIELD (DefaultSize
),
627 BITFIELD (BNDPrefixOk
),
628 BITFIELD (NoTrackPrefixOk
),
629 BITFIELD (IsLockable
),
630 BITFIELD (RegKludge
),
631 BITFIELD (Implicit1stXmm0
),
632 BITFIELD (RepPrefixOk
),
633 BITFIELD (HLEPrefixOk
),
636 BITFIELD (AddrPrefixOpReg
),
645 BITFIELD (VexOpcode
),
646 BITFIELD (VexSources
),
652 BITFIELD (Broadcast
),
653 BITFIELD (StaticRounding
),
655 BITFIELD (Disp8MemShift
),
656 BITFIELD (NoDefMask
),
657 BITFIELD (ImplicitQuadGroup
),
659 BITFIELD (ATTMnemonic
),
660 BITFIELD (ATTSyntax
),
661 BITFIELD (IntelSyntax
),
666 static bitfield operand_types
[] =
679 BITFIELD (BaseIndex
),
685 BITFIELD (InOutPortReg
),
686 BITFIELD (ShiftCount
),
693 BITFIELD (JumpAbsolute
),
705 BITFIELD (Unspecified
),
714 static const char *filename
;
715 static i386_cpu_flags active_cpu_flags
;
716 static int active_isstring
;
719 compare (const void *x
, const void *y
)
721 const bitfield
*xp
= (const bitfield
*) x
;
722 const bitfield
*yp
= (const bitfield
*) y
;
723 return xp
->position
- yp
->position
;
727 fail (const char *message
, ...)
731 va_start (args
, message
);
732 fprintf (stderr
, _("%s: error: "), program_name
);
733 vfprintf (stderr
, message
, args
);
739 process_copyright (FILE *fp
)
741 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
742 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
744 This file is part of the GNU opcodes library.\n\
746 This library is free software; you can redistribute it and/or modify\n\
747 it under the terms of the GNU General Public License as published by\n\
748 the Free Software Foundation; either version 3, or (at your option)\n\
749 any later version.\n\
751 It is distributed in the hope that it will be useful, but WITHOUT\n\
752 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
753 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
754 License for more details.\n\
756 You should have received a copy of the GNU General Public License\n\
757 along with this program; if not, write to the Free Software\n\
758 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
759 MA 02110-1301, USA. */\n");
762 /* Remove leading white spaces. */
765 remove_leading_whitespaces (char *str
)
767 while (ISSPACE (*str
))
772 /* Remove trailing white spaces. */
775 remove_trailing_whitespaces (char *str
)
777 size_t last
= strlen (str
);
785 if (ISSPACE (str
[last
]))
793 /* Find next field separated by SEP and terminate it. Return a
794 pointer to the one after it. */
797 next_field (char *str
, char sep
, char **next
, char *last
)
801 p
= remove_leading_whitespaces (str
);
802 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
805 remove_trailing_whitespaces (p
);
815 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
818 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
821 char *str
, *next
, *last
;
824 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
825 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
827 /* Turn on selective bits. */
828 char *init
= xstrdup (cpu_flag_init
[i
].init
);
829 last
= init
+ strlen (init
);
830 for (next
= init
; next
&& next
< last
; )
832 str
= next_field (next
, '|', &next
, last
);
834 set_bitfield (str
, array
, 1, size
, lineno
);
840 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
841 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
843 /* Turn on selective bits. */
844 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
845 last
= init
+ strlen (init
);
846 for (next
= init
; next
&& next
< last
; )
848 str
= next_field (next
, '|', &next
, last
);
850 set_bitfield (str
, array
, 1, size
, lineno
);
860 set_bitfield (char *f
, bitfield
*array
, int value
,
861 unsigned int size
, int lineno
)
865 if (strcmp (f
, "CpuFP") == 0)
867 set_bitfield("Cpu387", array
, value
, size
, lineno
);
868 set_bitfield("Cpu287", array
, value
, size
, lineno
);
871 else if (strcmp (f
, "Mmword") == 0)
873 else if (strcmp (f
, "Oword") == 0)
876 for (i
= 0; i
< size
; i
++)
877 if (strcasecmp (array
[i
].name
, f
) == 0)
879 array
[i
].value
= value
;
885 const char *v
= strchr (f
, '=');
892 for (i
= 0; i
< size
; i
++)
893 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
895 value
= strtol (v
+ 1, &end
, 0);
898 array
[i
].value
= value
;
906 /* Handle shorthands. */
907 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
911 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
913 fail (_("unknown bitfield: %s\n"), f
);
917 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
918 int macro
, const char *comma
, const char *indent
)
922 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
924 fprintf (table
, "%s{ { ", indent
);
926 for (i
= 0; i
< size
- 1; i
++)
928 if (((i
+ 1) % 20) != 0)
929 fprintf (table
, "%d, ", flags
[i
].value
);
931 fprintf (table
, "%d,", flags
[i
].value
);
932 if (((i
+ 1) % 20) == 0)
934 /* We need \\ for macro. */
936 fprintf (table
, " \\\n %s", indent
);
938 fprintf (table
, "\n %s", indent
);
941 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
944 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
948 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
949 const char *comma
, const char *indent
,
952 char *str
, *next
, *last
;
954 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
956 /* Copy the default cpu flags. */
957 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
959 if (strcasecmp (flag
, "unknown") == 0)
961 /* We turn on everything except for cpu64 in case of
962 CPU_UNKNOWN_FLAGS. */
963 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
964 if (flags
[i
].position
!= Cpu64
)
967 else if (flag
[0] == '~')
969 last
= flag
+ strlen (flag
);
976 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
983 /* First we turn on everything except for cpu64. */
984 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
985 if (flags
[i
].position
!= Cpu64
)
988 /* Turn off selective bits. */
989 for (; next
&& next
< last
; )
991 str
= next_field (next
, '|', &next
, last
);
993 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
996 else if (strcmp (flag
, "0"))
998 /* Turn on selective bits. */
999 last
= flag
+ strlen (flag
);
1000 for (next
= flag
; next
&& next
< last
; )
1002 str
= next_field (next
, '|', &next
, last
);
1004 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1008 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1013 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1017 fprintf (table
, " { ");
1019 for (i
= 0; i
< size
- 1; i
++)
1021 if (((i
+ 1) % 20) != 0)
1022 fprintf (table
, "%d, ", modifier
[i
].value
);
1024 fprintf (table
, "%d,", modifier
[i
].value
);
1025 if (((i
+ 1) % 20) == 0)
1026 fprintf (table
, "\n ");
1029 fprintf (table
, "%d },\n", modifier
[i
].value
);
1033 adjust_broadcast_modifier (char **opnd
)
1035 char *str
, *next
, *last
, *op
;
1036 int bcst_type
= INT_MAX
;
1038 /* Skip the immediate operand. */
1040 if (strcasecmp(op
, "Imm8") == 0)
1044 last
= op
+ strlen (op
);
1045 for (next
= op
; next
&& next
< last
; )
1047 str
= next_field (next
, '|', &next
, last
);
1050 if (strcasecmp(str
, "Byte") == 0)
1052 /* The smalest broadcast type, no need to check
1054 bcst_type
= BYTE_BROADCAST
;
1057 else if (strcasecmp(str
, "Word") == 0)
1059 if (bcst_type
> WORD_BROADCAST
)
1060 bcst_type
= WORD_BROADCAST
;
1062 else if (strcasecmp(str
, "Dword") == 0)
1064 if (bcst_type
> DWORD_BROADCAST
)
1065 bcst_type
= DWORD_BROADCAST
;
1067 else if (strcasecmp(str
, "Qword") == 0)
1069 if (bcst_type
> QWORD_BROADCAST
)
1070 bcst_type
= QWORD_BROADCAST
;
1076 if (bcst_type
== INT_MAX
)
1077 fail (_("unknown broadcast operand: %s\n"), op
);
1083 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1085 char *str
, *next
, *last
;
1086 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1088 active_isstring
= 0;
1090 /* Copy the default opcode modifier. */
1091 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1093 if (strcmp (mod
, "0"))
1095 last
= mod
+ strlen (mod
);
1096 for (next
= mod
; next
&& next
< last
; )
1098 str
= next_field (next
, '|', &next
, last
);
1102 if (strcasecmp(str
, "Broadcast") == 0)
1103 val
= adjust_broadcast_modifier (opnd
);
1104 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1106 if (strcasecmp(str
, "IsString") == 0)
1107 active_isstring
= 1;
1111 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1121 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1122 enum stage stage
, const char *indent
)
1126 fprintf (table
, "{ { ");
1128 for (i
= 0; i
< size
- 1; i
++)
1130 if (((i
+ 1) % 20) != 0)
1131 fprintf (table
, "%d, ", types
[i
].value
);
1133 fprintf (table
, "%d,", types
[i
].value
);
1134 if (((i
+ 1) % 20) == 0)
1136 /* We need \\ for macro. */
1137 if (stage
== stage_macros
)
1138 fprintf (table
, " \\\n%s", indent
);
1140 fprintf (table
, "\n%s", indent
);
1144 fprintf (table
, "%d } }", types
[i
].value
);
1148 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1149 const char *indent
, int lineno
)
1151 char *str
, *next
, *last
;
1152 bitfield types
[ARRAY_SIZE (operand_types
)];
1154 /* Copy the default operand type. */
1155 memcpy (types
, operand_types
, sizeof (types
));
1157 if (strcmp (op
, "0"))
1161 last
= op
+ strlen (op
);
1162 for (next
= op
; next
&& next
< last
; )
1164 str
= next_field (next
, '|', &next
, last
);
1167 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1168 if (strcasecmp(str
, "BaseIndex") == 0)
1173 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1175 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1176 if (!active_cpu_flags
.bitfield
.cpu64
1177 && !active_cpu_flags
.bitfield
.cpumpx
)
1178 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1179 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1180 if (!active_cpu_flags
.bitfield
.cpuno64
)
1181 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1184 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1189 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1190 char *last
, int lineno
)
1193 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1194 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1196 /* Find number of operands. */
1197 operands
= next_field (str
, ',', &str
, last
);
1199 /* Find base_opcode. */
1200 base_opcode
= next_field (str
, ',', &str
, last
);
1202 /* Find extension_opcode. */
1203 extension_opcode
= next_field (str
, ',', &str
, last
);
1205 /* Find opcode_length. */
1206 opcode_length
= next_field (str
, ',', &str
, last
);
1208 /* Find cpu_flags. */
1209 cpu_flags
= next_field (str
, ',', &str
, last
);
1211 /* Find opcode_modifier. */
1212 opcode_modifier
= next_field (str
, ',', &str
, last
);
1214 /* Remove the first {. */
1215 str
= remove_leading_whitespaces (str
);
1218 str
= remove_leading_whitespaces (str
+ 1);
1222 /* There are at least "X}". */
1226 /* Remove trailing white spaces and }. */
1230 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1239 /* Find operand_types. */
1240 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1244 operand_types
[i
] = NULL
;
1248 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1249 if (*operand_types
[i
] == '0')
1252 operand_types
[i
] = NULL
;
1257 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1258 name
, operands
, base_opcode
, extension_opcode
,
1261 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1263 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1265 fprintf (table
, " { ");
1267 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1269 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1272 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1278 fprintf (table
, ",\n ");
1280 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1283 fprintf (table
, " } },\n");
1286 struct opcode_hash_entry
1288 struct opcode_hash_entry
*next
;
1294 /* Calculate the hash value of an opcode hash entry P. */
1297 opcode_hash_hash (const void *p
)
1299 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1300 return htab_hash_string (entry
->name
);
1303 /* Compare a string Q against an opcode hash entry P. */
1306 opcode_hash_eq (const void *p
, const void *q
)
1308 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1309 const char *name
= (const char *) q
;
1310 return strcmp (name
, entry
->name
) == 0;
1314 process_i386_opcodes (FILE *table
)
1319 char *str
, *p
, *last
, *name
;
1320 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1321 htab_t opcode_hash_table
;
1322 struct opcode_hash_entry
**opcode_array
;
1323 unsigned int opcode_array_size
= 1024;
1324 int lineno
= 0, marker
= 0;
1326 filename
= "i386-opc.tbl";
1330 opcode_array
= (struct opcode_hash_entry
**)
1331 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1333 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1334 opcode_hash_eq
, NULL
,
1337 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1338 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1340 /* Put everything on opcode array. */
1343 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1348 p
= remove_leading_whitespaces (buf
);
1350 /* Skip comments. */
1351 str
= strstr (p
, "//");
1355 /* Remove trailing white spaces. */
1356 remove_trailing_whitespaces (p
);
1361 if (!strcmp("### MARKER ###", buf
))
1365 /* Since we ignore all included files (we only care about their
1366 #define-s here), we don't need to monitor filenames. The final
1367 line number directive is going to refer to the main source file
1372 p
= remove_leading_whitespaces (p
+ 1);
1373 if (!strncmp(p
, "line", 4))
1375 ln
= strtoul (p
, &end
, 10);
1376 if (ln
> 1 && ln
< INT_MAX
1377 && *remove_leading_whitespaces (end
) == '"')
1380 /* Ignore comments. */
1390 last
= p
+ strlen (p
);
1393 name
= next_field (p
, ',', &str
, last
);
1395 /* Get the slot in hash table. */
1396 hash_slot
= (struct opcode_hash_entry
**)
1397 htab_find_slot_with_hash (opcode_hash_table
, name
,
1398 htab_hash_string (name
),
1401 if (*hash_slot
== NULL
)
1403 /* It is the new one. Put it on opcode array. */
1404 if (i
>= opcode_array_size
)
1406 /* Grow the opcode array when needed. */
1407 opcode_array_size
+= 1024;
1408 opcode_array
= (struct opcode_hash_entry
**)
1409 xrealloc (opcode_array
,
1410 sizeof (*opcode_array
) * opcode_array_size
);
1413 opcode_array
[i
] = (struct opcode_hash_entry
*)
1414 xmalloc (sizeof (struct opcode_hash_entry
));
1415 opcode_array
[i
]->next
= NULL
;
1416 opcode_array
[i
]->name
= xstrdup (name
);
1417 opcode_array
[i
]->opcode
= xstrdup (str
);
1418 opcode_array
[i
]->lineno
= lineno
;
1419 *hash_slot
= opcode_array
[i
];
1424 /* Append it to the existing one. */
1426 while ((*entry
) != NULL
)
1427 entry
= &(*entry
)->next
;
1428 *entry
= (struct opcode_hash_entry
*)
1429 xmalloc (sizeof (struct opcode_hash_entry
));
1430 (*entry
)->next
= NULL
;
1431 (*entry
)->name
= (*hash_slot
)->name
;
1432 (*entry
)->opcode
= xstrdup (str
);
1433 (*entry
)->lineno
= lineno
;
1437 /* Process opcode array. */
1438 for (j
= 0; j
< i
; j
++)
1440 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1444 lineno
= next
->lineno
;
1445 last
= str
+ strlen (str
);
1446 output_i386_opcode (table
, name
, str
, last
, lineno
);
1452 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1454 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1456 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1458 fprintf (table
, " { ");
1459 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1460 fprintf (table
, " } }\n");
1462 fprintf (table
, "};\n");
1466 process_i386_registers (FILE *table
)
1470 char *str
, *p
, *last
;
1471 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1472 char *dw2_32_num
, *dw2_64_num
;
1475 filename
= "i386-reg.tbl";
1476 fp
= fopen (filename
, "r");
1478 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1481 fprintf (table
, "\n/* i386 register table. */\n\n");
1482 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1486 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1491 p
= remove_leading_whitespaces (buf
);
1493 /* Skip comments. */
1494 str
= strstr (p
, "//");
1498 /* Remove trailing white spaces. */
1499 remove_trailing_whitespaces (p
);
1504 fprintf (table
, "%s\n", p
);
1512 last
= p
+ strlen (p
);
1514 /* Find reg_name. */
1515 reg_name
= next_field (p
, ',', &str
, last
);
1517 /* Find reg_type. */
1518 reg_type
= next_field (str
, ',', &str
, last
);
1520 /* Find reg_flags. */
1521 reg_flags
= next_field (str
, ',', &str
, last
);
1524 reg_num
= next_field (str
, ',', &str
, last
);
1526 fprintf (table
, " { \"%s\",\n ", reg_name
);
1528 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1531 /* Find 32-bit Dwarf2 register number. */
1532 dw2_32_num
= next_field (str
, ',', &str
, last
);
1534 /* Find 64-bit Dwarf2 register number. */
1535 dw2_64_num
= next_field (str
, ',', &str
, last
);
1537 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1538 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1543 fprintf (table
, "};\n");
1545 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1549 process_i386_initializers (void)
1552 FILE *fp
= fopen ("i386-init.h", "w");
1556 fail (_("can't create i386-init.h, errno = %s\n"),
1559 process_copyright (fp
);
1561 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1563 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1564 init
= xstrdup (cpu_flag_init
[i
].init
);
1565 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1569 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1571 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1572 init
= xstrdup (operand_type_init
[i
].init
);
1573 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1581 /* Program options. */
1582 #define OPTION_SRCDIR 200
1584 struct option long_options
[] =
1586 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1587 {"debug", no_argument
, NULL
, 'd'},
1588 {"version", no_argument
, NULL
, 'V'},
1589 {"help", no_argument
, NULL
, 'h'},
1590 {0, no_argument
, NULL
, 0}
1594 print_version (void)
1596 printf ("%s: version 1.0\n", program_name
);
1601 usage (FILE * stream
, int status
)
1603 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1609 main (int argc
, char **argv
)
1611 extern int chdir (char *);
1612 char *srcdir
= NULL
;
1614 unsigned int i
, cpumax
;
1617 program_name
= *argv
;
1618 xmalloc_set_program_name (program_name
);
1620 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1645 if (chdir (srcdir
) != 0)
1646 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1647 srcdir
, xstrerror (errno
));
1649 /* cpu_flags isn't sorted by position. */
1651 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1652 if (cpu_flags
[i
].position
> cpumax
)
1653 cpumax
= cpu_flags
[i
].position
;
1655 /* Check the unused bitfield in i386_cpu_flags. */
1657 if ((cpumax
- 1) != CpuMax
)
1658 fail (_("CpuMax != %d!\n"), cpumax
);
1660 if (cpumax
!= CpuMax
)
1661 fail (_("CpuMax != %d!\n"), cpumax
);
1663 c
= CpuNumOfBits
- CpuMax
- 1;
1665 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1668 /* Check the unused bitfield in i386_operand_type. */
1670 c
= OTNumOfBits
- OTMax
- 1;
1672 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1675 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1678 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1679 sizeof (opcode_modifiers
[0]), compare
);
1681 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1682 sizeof (operand_types
[0]), compare
);
1684 table
= fopen ("i386-tbl.h", "w");
1686 fail (_("can't create i386-tbl.h, errno = %s\n"),
1689 process_copyright (table
);
1691 process_i386_opcodes (table
);
1692 process_i386_registers (table
);
1693 process_i386_initializers ();