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_ANY_X87_FLAGS",
299 "CPU_ANY_287_FLAGS|Cpu8087" },
300 { "CPU_ANY_287_FLAGS",
301 "CPU_ANY_387_FLAGS|Cpu287" },
302 { "CPU_ANY_387_FLAGS",
303 "CPU_ANY_687_FLAGS|Cpu387" },
304 { "CPU_ANY_687_FLAGS",
305 "Cpu687|CpuFISTTP" },
306 { "CPU_ANY_CMOV_FLAGS",
308 { "CPU_ANY_FXSR_FLAGS",
310 { "CPU_ANY_MMX_FLAGS",
311 "CPU_3DNOWA_FLAGS" },
312 { "CPU_ANY_SSE_FLAGS",
313 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
314 { "CPU_ANY_SSE2_FLAGS",
315 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
316 { "CPU_ANY_SSE3_FLAGS",
317 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
318 { "CPU_ANY_SSSE3_FLAGS",
319 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
320 { "CPU_ANY_SSE4_1_FLAGS",
321 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
322 { "CPU_ANY_SSE4_2_FLAGS",
324 { "CPU_ANY_AVX_FLAGS",
325 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
326 { "CPU_ANY_AVX2_FLAGS",
327 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
328 { "CPU_ANY_AVX512F_FLAGS",
329 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16" },
330 { "CPU_ANY_AVX512CD_FLAGS",
332 { "CPU_ANY_AVX512ER_FLAGS",
334 { "CPU_ANY_AVX512PF_FLAGS",
336 { "CPU_ANY_AVX512DQ_FLAGS",
338 { "CPU_ANY_AVX512BW_FLAGS",
340 { "CPU_ANY_AVX512VL_FLAGS",
342 { "CPU_ANY_AVX512IFMA_FLAGS",
344 { "CPU_ANY_AVX512VBMI_FLAGS",
346 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
347 "CpuAVX512_4FMAPS" },
348 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
349 "CpuAVX512_4VNNIW" },
350 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
351 "CpuAVX512_VPOPCNTDQ" },
352 { "CPU_ANY_IBT_FLAGS",
354 { "CPU_ANY_SHSTK_FLAGS",
356 { "CPU_ANY_AVX512_VBMI2_FLAGS",
358 { "CPU_ANY_AVX512_VNNI_FLAGS",
360 { "CPU_ANY_AVX512_BITALG_FLAGS",
361 "CpuAVX512_BITALG" },
362 { "CPU_ANY_AVX512_BF16_FLAGS",
364 { "CPU_ANY_MOVDIRI_FLAGS",
366 { "CPU_ANY_MOVDIR64B_FLAGS",
370 static const initializer operand_type_shorthands
[] =
372 { "Reg8", "Reg|Byte" },
373 { "Reg16", "Reg|Word" },
374 { "Reg32", "Reg|Dword" },
375 { "Reg64", "Reg|Qword" },
376 { "FloatAcc", "Acc|Tbyte" },
377 { "FloatReg", "Reg|Tbyte" },
378 { "RegXMM", "RegSIMD|Xmmword" },
379 { "RegYMM", "RegSIMD|Ymmword" },
380 { "RegZMM", "RegSIMD|Zmmword" },
383 static initializer operand_type_init
[] =
385 { "OPERAND_TYPE_NONE",
387 { "OPERAND_TYPE_REG8",
389 { "OPERAND_TYPE_REG16",
391 { "OPERAND_TYPE_REG32",
393 { "OPERAND_TYPE_REG64",
395 { "OPERAND_TYPE_IMM1",
397 { "OPERAND_TYPE_IMM8",
399 { "OPERAND_TYPE_IMM8S",
401 { "OPERAND_TYPE_IMM16",
403 { "OPERAND_TYPE_IMM32",
405 { "OPERAND_TYPE_IMM32S",
407 { "OPERAND_TYPE_IMM64",
409 { "OPERAND_TYPE_BASEINDEX",
411 { "OPERAND_TYPE_DISP8",
413 { "OPERAND_TYPE_DISP16",
415 { "OPERAND_TYPE_DISP32",
417 { "OPERAND_TYPE_DISP32S",
419 { "OPERAND_TYPE_DISP64",
421 { "OPERAND_TYPE_INOUTPORTREG",
423 { "OPERAND_TYPE_SHIFTCOUNT",
425 { "OPERAND_TYPE_CONTROL",
427 { "OPERAND_TYPE_TEST",
429 { "OPERAND_TYPE_DEBUG",
431 { "OPERAND_TYPE_FLOATREG",
433 { "OPERAND_TYPE_FLOATACC",
435 { "OPERAND_TYPE_SREG2",
437 { "OPERAND_TYPE_SREG3",
439 { "OPERAND_TYPE_ACC",
441 { "OPERAND_TYPE_JUMPABSOLUTE",
443 { "OPERAND_TYPE_REGMMX",
445 { "OPERAND_TYPE_REGXMM",
447 { "OPERAND_TYPE_REGYMM",
449 { "OPERAND_TYPE_REGZMM",
451 { "OPERAND_TYPE_REGMASK",
453 { "OPERAND_TYPE_ESSEG",
455 { "OPERAND_TYPE_ACC32",
457 { "OPERAND_TYPE_ACC64",
459 { "OPERAND_TYPE_DISP16_32",
461 { "OPERAND_TYPE_ANYDISP",
462 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
463 { "OPERAND_TYPE_IMM16_32",
465 { "OPERAND_TYPE_IMM16_32S",
467 { "OPERAND_TYPE_IMM16_32_32S",
468 "Imm16|Imm32|Imm32S" },
469 { "OPERAND_TYPE_IMM32_64",
471 { "OPERAND_TYPE_IMM32_32S_DISP32",
472 "Imm32|Imm32S|Disp32" },
473 { "OPERAND_TYPE_IMM64_DISP64",
475 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
476 "Imm32|Imm32S|Imm64|Disp32" },
477 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
478 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
479 { "OPERAND_TYPE_VEC_IMM4",
481 { "OPERAND_TYPE_REGBND",
485 typedef struct bitfield
492 #define BITFIELD(n) { n, 0, #n }
494 static bitfield cpu_flags
[] =
504 BITFIELD (CpuClflush
),
506 BITFIELD (CpuSYSCALL
),
511 BITFIELD (CpuFISTTP
),
517 BITFIELD (CpuSSE4_1
),
518 BITFIELD (CpuSSE4_2
),
521 BITFIELD (CpuAVX512F
),
522 BITFIELD (CpuAVX512CD
),
523 BITFIELD (CpuAVX512ER
),
524 BITFIELD (CpuAVX512PF
),
525 BITFIELD (CpuAVX512VL
),
526 BITFIELD (CpuAVX512DQ
),
527 BITFIELD (CpuAVX512BW
),
533 BITFIELD (Cpu3dnowA
),
534 BITFIELD (CpuPadLock
),
540 BITFIELD (CpuXsaveopt
),
542 BITFIELD (CpuPCLMUL
),
553 BITFIELD (CpuRdtscp
),
554 BITFIELD (CpuFSGSBase
),
561 BITFIELD (CpuINVPCID
),
562 BITFIELD (CpuVMFUNC
),
563 BITFIELD (CpuRDSEED
),
565 BITFIELD (CpuPRFCHW
),
568 BITFIELD (CpuClflushOpt
),
569 BITFIELD (CpuXSAVES
),
570 BITFIELD (CpuXSAVEC
),
571 BITFIELD (CpuPREFETCHWT1
),
577 BITFIELD (CpuAVX512IFMA
),
578 BITFIELD (CpuAVX512VBMI
),
579 BITFIELD (CpuAVX512_4FMAPS
),
580 BITFIELD (CpuAVX512_4VNNIW
),
581 BITFIELD (CpuAVX512_VPOPCNTDQ
),
582 BITFIELD (CpuAVX512_VBMI2
),
583 BITFIELD (CpuAVX512_VNNI
),
584 BITFIELD (CpuAVX512_BITALG
),
585 BITFIELD (CpuAVX512_BF16
),
586 BITFIELD (CpuMWAITX
),
587 BITFIELD (CpuCLZERO
),
590 BITFIELD (CpuPTWRITE
),
595 BITFIELD (CpuVPCLMULQDQ
),
596 BITFIELD (CpuWBNOINVD
),
597 BITFIELD (CpuPCONFIG
),
598 BITFIELD (CpuWAITPKG
),
599 BITFIELD (CpuCLDEMOTE
),
600 BITFIELD (CpuMOVDIRI
),
601 BITFIELD (CpuMOVDIR64B
),
603 BITFIELD (CpuUnused
),
607 static bitfield opcode_modifiers
[] =
613 BITFIELD (ShortForm
),
615 BITFIELD (JumpDword
),
617 BITFIELD (JumpInterSegment
),
621 BITFIELD (CheckRegSize
),
622 BITFIELD (IgnoreSize
),
623 BITFIELD (DefaultSize
),
632 BITFIELD (BNDPrefixOk
),
633 BITFIELD (NoTrackPrefixOk
),
634 BITFIELD (IsLockable
),
635 BITFIELD (RegKludge
),
636 BITFIELD (Implicit1stXmm0
),
637 BITFIELD (RepPrefixOk
),
638 BITFIELD (HLEPrefixOk
),
641 BITFIELD (AddrPrefixOpReg
),
650 BITFIELD (VexOpcode
),
651 BITFIELD (VexSources
),
657 BITFIELD (Broadcast
),
658 BITFIELD (StaticRounding
),
660 BITFIELD (Disp8MemShift
),
661 BITFIELD (NoDefMask
),
662 BITFIELD (ImplicitQuadGroup
),
664 BITFIELD (ATTMnemonic
),
665 BITFIELD (ATTSyntax
),
666 BITFIELD (IntelSyntax
),
671 static bitfield operand_types
[] =
684 BITFIELD (BaseIndex
),
690 BITFIELD (InOutPortReg
),
691 BITFIELD (ShiftCount
),
698 BITFIELD (JumpAbsolute
),
710 BITFIELD (Unspecified
),
719 static const char *filename
;
720 static i386_cpu_flags active_cpu_flags
;
721 static int active_isstring
;
724 compare (const void *x
, const void *y
)
726 const bitfield
*xp
= (const bitfield
*) x
;
727 const bitfield
*yp
= (const bitfield
*) y
;
728 return xp
->position
- yp
->position
;
732 fail (const char *message
, ...)
736 va_start (args
, message
);
737 fprintf (stderr
, _("%s: error: "), program_name
);
738 vfprintf (stderr
, message
, args
);
744 process_copyright (FILE *fp
)
746 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
747 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
749 This file is part of the GNU opcodes library.\n\
751 This library is free software; you can redistribute it and/or modify\n\
752 it under the terms of the GNU General Public License as published by\n\
753 the Free Software Foundation; either version 3, or (at your option)\n\
754 any later version.\n\
756 It is distributed in the hope that it will be useful, but WITHOUT\n\
757 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
758 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
759 License for more details.\n\
761 You should have received a copy of the GNU General Public License\n\
762 along with this program; if not, write to the Free Software\n\
763 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
764 MA 02110-1301, USA. */\n");
767 /* Remove leading white spaces. */
770 remove_leading_whitespaces (char *str
)
772 while (ISSPACE (*str
))
777 /* Remove trailing white spaces. */
780 remove_trailing_whitespaces (char *str
)
782 size_t last
= strlen (str
);
790 if (ISSPACE (str
[last
]))
798 /* Find next field separated by SEP and terminate it. Return a
799 pointer to the one after it. */
802 next_field (char *str
, char sep
, char **next
, char *last
)
806 p
= remove_leading_whitespaces (str
);
807 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
810 remove_trailing_whitespaces (p
);
820 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
823 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
826 char *str
, *next
, *last
;
829 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
830 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
832 /* Turn on selective bits. */
833 char *init
= xstrdup (cpu_flag_init
[i
].init
);
834 last
= init
+ strlen (init
);
835 for (next
= init
; next
&& next
< last
; )
837 str
= next_field (next
, '|', &next
, last
);
839 set_bitfield (str
, array
, 1, size
, lineno
);
845 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
846 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
848 /* Turn on selective bits. */
849 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
850 last
= init
+ strlen (init
);
851 for (next
= init
; next
&& next
< last
; )
853 str
= next_field (next
, '|', &next
, last
);
855 set_bitfield (str
, array
, 1, size
, lineno
);
865 set_bitfield (char *f
, bitfield
*array
, int value
,
866 unsigned int size
, int lineno
)
870 if (strcmp (f
, "CpuFP") == 0)
872 set_bitfield("Cpu387", array
, value
, size
, lineno
);
873 set_bitfield("Cpu287", array
, value
, size
, lineno
);
876 else if (strcmp (f
, "Mmword") == 0)
878 else if (strcmp (f
, "Oword") == 0)
881 for (i
= 0; i
< size
; i
++)
882 if (strcasecmp (array
[i
].name
, f
) == 0)
884 array
[i
].value
= value
;
890 const char *v
= strchr (f
, '=');
897 for (i
= 0; i
< size
; i
++)
898 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
900 value
= strtol (v
+ 1, &end
, 0);
903 array
[i
].value
= value
;
911 /* Handle shorthands. */
912 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
916 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
918 fail (_("unknown bitfield: %s\n"), f
);
922 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
923 int macro
, const char *comma
, const char *indent
)
927 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
929 fprintf (table
, "%s{ { ", indent
);
931 for (i
= 0; i
< size
- 1; i
++)
933 if (((i
+ 1) % 20) != 0)
934 fprintf (table
, "%d, ", flags
[i
].value
);
936 fprintf (table
, "%d,", flags
[i
].value
);
937 if (((i
+ 1) % 20) == 0)
939 /* We need \\ for macro. */
941 fprintf (table
, " \\\n %s", indent
);
943 fprintf (table
, "\n %s", indent
);
946 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
949 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
953 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
954 const char *comma
, const char *indent
,
957 char *str
, *next
, *last
;
959 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
961 /* Copy the default cpu flags. */
962 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
964 if (strcasecmp (flag
, "unknown") == 0)
966 /* We turn on everything except for cpu64 in case of
967 CPU_UNKNOWN_FLAGS. */
968 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
969 if (flags
[i
].position
!= Cpu64
)
972 else if (flag
[0] == '~')
974 last
= flag
+ strlen (flag
);
981 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
988 /* First we turn on everything except for cpu64. */
989 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
990 if (flags
[i
].position
!= Cpu64
)
993 /* Turn off selective bits. */
994 for (; next
&& next
< last
; )
996 str
= next_field (next
, '|', &next
, last
);
998 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1001 else if (strcmp (flag
, "0"))
1003 /* Turn on selective bits. */
1004 last
= flag
+ strlen (flag
);
1005 for (next
= flag
; next
&& next
< last
; )
1007 str
= next_field (next
, '|', &next
, last
);
1009 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1013 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1018 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1022 fprintf (table
, " { ");
1024 for (i
= 0; i
< size
- 1; i
++)
1026 if (((i
+ 1) % 20) != 0)
1027 fprintf (table
, "%d, ", modifier
[i
].value
);
1029 fprintf (table
, "%d,", modifier
[i
].value
);
1030 if (((i
+ 1) % 20) == 0)
1031 fprintf (table
, "\n ");
1034 fprintf (table
, "%d },\n", modifier
[i
].value
);
1038 adjust_broadcast_modifier (char **opnd
)
1040 char *str
, *next
, *last
, *op
;
1041 int bcst_type
= INT_MAX
;
1043 /* Skip the immediate operand. */
1045 if (strcasecmp(op
, "Imm8") == 0)
1049 last
= op
+ strlen (op
);
1050 for (next
= op
; next
&& next
< last
; )
1052 str
= next_field (next
, '|', &next
, last
);
1055 if (strcasecmp(str
, "Byte") == 0)
1057 /* The smalest broadcast type, no need to check
1059 bcst_type
= BYTE_BROADCAST
;
1062 else if (strcasecmp(str
, "Word") == 0)
1064 if (bcst_type
> WORD_BROADCAST
)
1065 bcst_type
= WORD_BROADCAST
;
1067 else if (strcasecmp(str
, "Dword") == 0)
1069 if (bcst_type
> DWORD_BROADCAST
)
1070 bcst_type
= DWORD_BROADCAST
;
1072 else if (strcasecmp(str
, "Qword") == 0)
1074 if (bcst_type
> QWORD_BROADCAST
)
1075 bcst_type
= QWORD_BROADCAST
;
1081 if (bcst_type
== INT_MAX
)
1082 fail (_("unknown broadcast operand: %s\n"), op
);
1088 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1090 char *str
, *next
, *last
;
1091 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1093 active_isstring
= 0;
1095 /* Copy the default opcode modifier. */
1096 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1098 if (strcmp (mod
, "0"))
1100 last
= mod
+ strlen (mod
);
1101 for (next
= mod
; next
&& next
< last
; )
1103 str
= next_field (next
, '|', &next
, last
);
1107 if (strcasecmp(str
, "Broadcast") == 0)
1108 val
= adjust_broadcast_modifier (opnd
);
1109 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1111 if (strcasecmp(str
, "IsString") == 0)
1112 active_isstring
= 1;
1116 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1126 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1127 enum stage stage
, const char *indent
)
1131 fprintf (table
, "{ { ");
1133 for (i
= 0; i
< size
- 1; i
++)
1135 if (((i
+ 1) % 20) != 0)
1136 fprintf (table
, "%d, ", types
[i
].value
);
1138 fprintf (table
, "%d,", types
[i
].value
);
1139 if (((i
+ 1) % 20) == 0)
1141 /* We need \\ for macro. */
1142 if (stage
== stage_macros
)
1143 fprintf (table
, " \\\n%s", indent
);
1145 fprintf (table
, "\n%s", indent
);
1149 fprintf (table
, "%d } }", types
[i
].value
);
1153 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1154 const char *indent
, int lineno
)
1156 char *str
, *next
, *last
;
1157 bitfield types
[ARRAY_SIZE (operand_types
)];
1159 /* Copy the default operand type. */
1160 memcpy (types
, operand_types
, sizeof (types
));
1162 if (strcmp (op
, "0"))
1166 last
= op
+ strlen (op
);
1167 for (next
= op
; next
&& next
< last
; )
1169 str
= next_field (next
, '|', &next
, last
);
1172 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1173 if (strcasecmp(str
, "BaseIndex") == 0)
1178 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1180 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1181 if (!active_cpu_flags
.bitfield
.cpu64
1182 && !active_cpu_flags
.bitfield
.cpumpx
)
1183 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1184 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1185 if (!active_cpu_flags
.bitfield
.cpuno64
)
1186 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1189 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1194 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1195 char *last
, int lineno
)
1198 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1199 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1201 /* Find number of operands. */
1202 operands
= next_field (str
, ',', &str
, last
);
1204 /* Find base_opcode. */
1205 base_opcode
= next_field (str
, ',', &str
, last
);
1207 /* Find extension_opcode. */
1208 extension_opcode
= next_field (str
, ',', &str
, last
);
1210 /* Find opcode_length. */
1211 opcode_length
= next_field (str
, ',', &str
, last
);
1213 /* Find cpu_flags. */
1214 cpu_flags
= next_field (str
, ',', &str
, last
);
1216 /* Find opcode_modifier. */
1217 opcode_modifier
= next_field (str
, ',', &str
, last
);
1219 /* Remove the first {. */
1220 str
= remove_leading_whitespaces (str
);
1223 str
= remove_leading_whitespaces (str
+ 1);
1227 /* There are at least "X}". */
1231 /* Remove trailing white spaces and }. */
1235 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1244 /* Find operand_types. */
1245 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1249 operand_types
[i
] = NULL
;
1253 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1254 if (*operand_types
[i
] == '0')
1257 operand_types
[i
] = NULL
;
1262 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1263 name
, operands
, base_opcode
, extension_opcode
,
1266 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1268 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1270 fprintf (table
, " { ");
1272 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1274 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1277 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1283 fprintf (table
, ",\n ");
1285 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1288 fprintf (table
, " } },\n");
1291 struct opcode_hash_entry
1293 struct opcode_hash_entry
*next
;
1299 /* Calculate the hash value of an opcode hash entry P. */
1302 opcode_hash_hash (const void *p
)
1304 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1305 return htab_hash_string (entry
->name
);
1308 /* Compare a string Q against an opcode hash entry P. */
1311 opcode_hash_eq (const void *p
, const void *q
)
1313 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1314 const char *name
= (const char *) q
;
1315 return strcmp (name
, entry
->name
) == 0;
1319 process_i386_opcodes (FILE *table
)
1324 char *str
, *p
, *last
, *name
;
1325 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1326 htab_t opcode_hash_table
;
1327 struct opcode_hash_entry
**opcode_array
;
1328 unsigned int opcode_array_size
= 1024;
1329 int lineno
= 0, marker
= 0;
1331 filename
= "i386-opc.tbl";
1335 opcode_array
= (struct opcode_hash_entry
**)
1336 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1338 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1339 opcode_hash_eq
, NULL
,
1342 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1343 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1345 /* Put everything on opcode array. */
1348 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1353 p
= remove_leading_whitespaces (buf
);
1355 /* Skip comments. */
1356 str
= strstr (p
, "//");
1360 /* Remove trailing white spaces. */
1361 remove_trailing_whitespaces (p
);
1366 if (!strcmp("### MARKER ###", buf
))
1370 /* Since we ignore all included files (we only care about their
1371 #define-s here), we don't need to monitor filenames. The final
1372 line number directive is going to refer to the main source file
1377 p
= remove_leading_whitespaces (p
+ 1);
1378 if (!strncmp(p
, "line", 4))
1380 ln
= strtoul (p
, &end
, 10);
1381 if (ln
> 1 && ln
< INT_MAX
1382 && *remove_leading_whitespaces (end
) == '"')
1385 /* Ignore comments. */
1395 last
= p
+ strlen (p
);
1398 name
= next_field (p
, ',', &str
, last
);
1400 /* Get the slot in hash table. */
1401 hash_slot
= (struct opcode_hash_entry
**)
1402 htab_find_slot_with_hash (opcode_hash_table
, name
,
1403 htab_hash_string (name
),
1406 if (*hash_slot
== NULL
)
1408 /* It is the new one. Put it on opcode array. */
1409 if (i
>= opcode_array_size
)
1411 /* Grow the opcode array when needed. */
1412 opcode_array_size
+= 1024;
1413 opcode_array
= (struct opcode_hash_entry
**)
1414 xrealloc (opcode_array
,
1415 sizeof (*opcode_array
) * opcode_array_size
);
1418 opcode_array
[i
] = (struct opcode_hash_entry
*)
1419 xmalloc (sizeof (struct opcode_hash_entry
));
1420 opcode_array
[i
]->next
= NULL
;
1421 opcode_array
[i
]->name
= xstrdup (name
);
1422 opcode_array
[i
]->opcode
= xstrdup (str
);
1423 opcode_array
[i
]->lineno
= lineno
;
1424 *hash_slot
= opcode_array
[i
];
1429 /* Append it to the existing one. */
1431 while ((*entry
) != NULL
)
1432 entry
= &(*entry
)->next
;
1433 *entry
= (struct opcode_hash_entry
*)
1434 xmalloc (sizeof (struct opcode_hash_entry
));
1435 (*entry
)->next
= NULL
;
1436 (*entry
)->name
= (*hash_slot
)->name
;
1437 (*entry
)->opcode
= xstrdup (str
);
1438 (*entry
)->lineno
= lineno
;
1442 /* Process opcode array. */
1443 for (j
= 0; j
< i
; j
++)
1445 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1449 lineno
= next
->lineno
;
1450 last
= str
+ strlen (str
);
1451 output_i386_opcode (table
, name
, str
, last
, lineno
);
1457 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1459 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1461 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1463 fprintf (table
, " { ");
1464 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1465 fprintf (table
, " } }\n");
1467 fprintf (table
, "};\n");
1471 process_i386_registers (FILE *table
)
1475 char *str
, *p
, *last
;
1476 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1477 char *dw2_32_num
, *dw2_64_num
;
1480 filename
= "i386-reg.tbl";
1481 fp
= fopen (filename
, "r");
1483 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1486 fprintf (table
, "\n/* i386 register table. */\n\n");
1487 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1491 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1496 p
= remove_leading_whitespaces (buf
);
1498 /* Skip comments. */
1499 str
= strstr (p
, "//");
1503 /* Remove trailing white spaces. */
1504 remove_trailing_whitespaces (p
);
1509 fprintf (table
, "%s\n", p
);
1517 last
= p
+ strlen (p
);
1519 /* Find reg_name. */
1520 reg_name
= next_field (p
, ',', &str
, last
);
1522 /* Find reg_type. */
1523 reg_type
= next_field (str
, ',', &str
, last
);
1525 /* Find reg_flags. */
1526 reg_flags
= next_field (str
, ',', &str
, last
);
1529 reg_num
= next_field (str
, ',', &str
, last
);
1531 fprintf (table
, " { \"%s\",\n ", reg_name
);
1533 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1536 /* Find 32-bit Dwarf2 register number. */
1537 dw2_32_num
= next_field (str
, ',', &str
, last
);
1539 /* Find 64-bit Dwarf2 register number. */
1540 dw2_64_num
= next_field (str
, ',', &str
, last
);
1542 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1543 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1548 fprintf (table
, "};\n");
1550 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1554 process_i386_initializers (void)
1557 FILE *fp
= fopen ("i386-init.h", "w");
1561 fail (_("can't create i386-init.h, errno = %s\n"),
1564 process_copyright (fp
);
1566 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1568 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1569 init
= xstrdup (cpu_flag_init
[i
].init
);
1570 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1574 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1576 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1577 init
= xstrdup (operand_type_init
[i
].init
);
1578 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1586 /* Program options. */
1587 #define OPTION_SRCDIR 200
1589 struct option long_options
[] =
1591 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1592 {"debug", no_argument
, NULL
, 'd'},
1593 {"version", no_argument
, NULL
, 'V'},
1594 {"help", no_argument
, NULL
, 'h'},
1595 {0, no_argument
, NULL
, 0}
1599 print_version (void)
1601 printf ("%s: version 1.0\n", program_name
);
1606 usage (FILE * stream
, int status
)
1608 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1614 main (int argc
, char **argv
)
1616 extern int chdir (char *);
1617 char *srcdir
= NULL
;
1619 unsigned int i
, cpumax
;
1622 program_name
= *argv
;
1623 xmalloc_set_program_name (program_name
);
1625 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1650 if (chdir (srcdir
) != 0)
1651 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1652 srcdir
, xstrerror (errno
));
1654 /* cpu_flags isn't sorted by position. */
1656 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1657 if (cpu_flags
[i
].position
> cpumax
)
1658 cpumax
= cpu_flags
[i
].position
;
1660 /* Check the unused bitfield in i386_cpu_flags. */
1662 if ((cpumax
- 1) != CpuMax
)
1663 fail (_("CpuMax != %d!\n"), cpumax
);
1665 if (cpumax
!= CpuMax
)
1666 fail (_("CpuMax != %d!\n"), cpumax
);
1668 c
= CpuNumOfBits
- CpuMax
- 1;
1670 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1673 /* Check the unused bitfield in i386_operand_type. */
1675 c
= OTNumOfBits
- OTMax
- 1;
1677 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1680 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1683 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1684 sizeof (opcode_modifiers
[0]), compare
);
1686 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1687 sizeof (operand_types
[0]), compare
);
1689 table
= fopen ("i386-tbl.h", "w");
1691 fail (_("can't create i386-tbl.h, errno = %s\n"),
1694 process_copyright (table
);
1696 process_i386_opcodes (table
);
1697 process_i386_registers (table
);
1698 process_i386_initializers ();