1 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
24 #include "libiberty.h"
26 #include "safe-ctype.h"
31 #define _(String) gettext (String)
33 static const char *program_name
= NULL
;
36 typedef struct initializer
42 static initializer cpu_flag_init
[] =
44 { "CPU_UNKNOWN_FLAGS",
45 "~(CpuL1OM|CpuK1OM)" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
55 "CPU_I186_FLAGS|Cpu286" },
57 "CPU_I286_FLAGS|Cpu386" },
59 "CPU_I386_FLAGS|Cpu486" },
61 "CPU_I486_FLAGS|Cpu387|Cpu586" },
63 "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "CPU_I686_FLAGS|CpuNop" },
67 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
69 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
71 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
73 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
75 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
77 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
79 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
83 "CPU_K6_FLAGS|Cpu3dnow" },
85 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
87 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
91 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
95 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
97 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
99 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_ZNVER2_FLAGS",
101 "CPU_ZNVER1_FLAGS|CpuRDPID|CpuWBNOINVD|CpuCLWB" },
102 { "CPU_BTVER1_FLAGS",
103 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
104 { "CPU_BTVER2_FLAGS",
105 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
113 "CPU_387_FLAGS|Cpu687" },
118 { "CPU_CLFLUSH_FLAGS",
122 { "CPU_SYSCALL_FLAGS",
129 "CPU_SSE_FLAGS|CpuSSE2" },
131 "CPU_SSE2_FLAGS|CpuSSE3" },
133 "CPU_SSE3_FLAGS|CpuSSSE3" },
134 { "CPU_SSE4_1_FLAGS",
135 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
136 { "CPU_SSE4_2_FLAGS",
137 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
144 { "CPU_XSAVEOPT_FLAGS",
145 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
147 "CPU_SSE2_FLAGS|CpuAES" },
148 { "CPU_PCLMUL_FLAGS",
149 "CPU_SSE2_FLAGS|CpuPCLMUL" },
151 "CPU_AVX_FLAGS|CpuFMA" },
153 "CPU_AVX_FLAGS|CpuFMA4" },
155 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
157 "CPU_XSAVE_FLAGS|CpuLWP" },
166 { "CPU_RDTSCP_FLAGS",
170 { "CPU_FSGSBASE_FLAGS",
175 "CPU_AVX_FLAGS|CpuF16C" },
184 { "CPU_INVPCID_FLAGS",
186 { "CPU_VMFUNC_FLAGS",
189 "CPU_MMX_FLAGS|Cpu3dnow" },
190 { "CPU_3DNOWA_FLAGS",
191 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
192 { "CPU_PADLOCK_FLAGS",
197 "CPU_SSE3_FLAGS|CpuSSE4a" },
201 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
203 "CPU_AVX_FLAGS|CpuAVX2" },
204 { "CPU_AVX512F_FLAGS",
205 "CPU_AVX2_FLAGS|CpuAVX512F" },
206 { "CPU_AVX512CD_FLAGS",
207 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
208 { "CPU_AVX512ER_FLAGS",
209 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
210 { "CPU_AVX512PF_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
212 { "CPU_AVX512DQ_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
214 { "CPU_AVX512BW_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
216 { "CPU_AVX512VL_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
218 { "CPU_AVX512IFMA_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
220 { "CPU_AVX512VBMI_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
222 { "CPU_AVX512_4FMAPS_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
224 { "CPU_AVX512_4VNNIW_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
226 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
228 { "CPU_AVX512_VBMI2_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
230 { "CPU_AVX512_VNNI_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
232 { "CPU_AVX512_BITALG_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
234 { "CPU_AVX512_BF16_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
241 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
244 { "CPU_RDSEED_FLAGS",
246 { "CPU_PRFCHW_FLAGS",
251 "CPU_XSAVE_FLAGS|CpuMPX" },
253 "CPU_SSE2_FLAGS|CpuSHA" },
254 { "CPU_CLFLUSHOPT_FLAGS",
256 { "CPU_XSAVES_FLAGS",
257 "CPU_XSAVE_FLAGS|CpuXSAVES" },
258 { "CPU_XSAVEC_FLAGS",
259 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
260 { "CPU_PREFETCHWT1_FLAGS",
266 { "CPU_CLZERO_FLAGS",
268 { "CPU_MWAITX_FLAGS",
271 "CPU_XSAVE_FLAGS|CpuOSPKE" },
274 { "CPU_PTWRITE_FLAGS",
284 { "CPU_VPCLMULQDQ_FLAGS",
286 { "CPU_WBNOINVD_FLAGS",
288 { "CPU_PCONFIG_FLAGS",
290 { "CPU_WAITPKG_FLAGS",
292 { "CPU_CLDEMOTE_FLAGS",
294 { "CPU_MOVDIRI_FLAGS",
296 { "CPU_MOVDIR64B_FLAGS",
298 { "CPU_ENQCMD_FLAGS",
300 { "CPU_AVX512_VP2INTERSECT_FLAGS",
301 "CpuAVX512_VP2INTERSECT" },
302 { "CPU_ANY_X87_FLAGS",
303 "CPU_ANY_287_FLAGS|Cpu8087" },
304 { "CPU_ANY_287_FLAGS",
305 "CPU_ANY_387_FLAGS|Cpu287" },
306 { "CPU_ANY_387_FLAGS",
307 "CPU_ANY_687_FLAGS|Cpu387" },
308 { "CPU_ANY_687_FLAGS",
309 "Cpu687|CpuFISTTP" },
310 { "CPU_ANY_CMOV_FLAGS",
312 { "CPU_ANY_FXSR_FLAGS",
314 { "CPU_ANY_MMX_FLAGS",
315 "CPU_3DNOWA_FLAGS" },
316 { "CPU_ANY_SSE_FLAGS",
317 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
318 { "CPU_ANY_SSE2_FLAGS",
319 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
320 { "CPU_ANY_SSE3_FLAGS",
321 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
322 { "CPU_ANY_SSSE3_FLAGS",
323 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
324 { "CPU_ANY_SSE4_1_FLAGS",
325 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
326 { "CPU_ANY_SSE4_2_FLAGS",
328 { "CPU_ANY_AVX_FLAGS",
329 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
330 { "CPU_ANY_AVX2_FLAGS",
331 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
332 { "CPU_ANY_AVX512F_FLAGS",
333 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
334 { "CPU_ANY_AVX512CD_FLAGS",
336 { "CPU_ANY_AVX512ER_FLAGS",
338 { "CPU_ANY_AVX512PF_FLAGS",
340 { "CPU_ANY_AVX512DQ_FLAGS",
342 { "CPU_ANY_AVX512BW_FLAGS",
344 { "CPU_ANY_AVX512VL_FLAGS",
346 { "CPU_ANY_AVX512IFMA_FLAGS",
348 { "CPU_ANY_AVX512VBMI_FLAGS",
350 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
351 "CpuAVX512_4FMAPS" },
352 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
353 "CpuAVX512_4VNNIW" },
354 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
355 "CpuAVX512_VPOPCNTDQ" },
356 { "CPU_ANY_IBT_FLAGS",
358 { "CPU_ANY_SHSTK_FLAGS",
360 { "CPU_ANY_AVX512_VBMI2_FLAGS",
362 { "CPU_ANY_AVX512_VNNI_FLAGS",
364 { "CPU_ANY_AVX512_BITALG_FLAGS",
365 "CpuAVX512_BITALG" },
366 { "CPU_ANY_AVX512_BF16_FLAGS",
368 { "CPU_ANY_MOVDIRI_FLAGS",
370 { "CPU_ANY_MOVDIR64B_FLAGS",
372 { "CPU_ANY_ENQCMD_FLAGS",
374 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
375 "CpuAVX512_VP2INTERSECT" },
378 static const initializer operand_type_shorthands
[] =
380 { "Reg8", "Reg|Byte" },
381 { "Reg16", "Reg|Word" },
382 { "Reg32", "Reg|Dword" },
383 { "Reg64", "Reg|Qword" },
384 { "FloatAcc", "Acc|Tbyte" },
385 { "FloatReg", "Reg|Tbyte" },
386 { "RegXMM", "RegSIMD|Xmmword" },
387 { "RegYMM", "RegSIMD|Ymmword" },
388 { "RegZMM", "RegSIMD|Zmmword" },
391 static initializer operand_type_init
[] =
393 { "OPERAND_TYPE_NONE",
395 { "OPERAND_TYPE_REG8",
397 { "OPERAND_TYPE_REG16",
399 { "OPERAND_TYPE_REG32",
401 { "OPERAND_TYPE_REG64",
403 { "OPERAND_TYPE_IMM1",
405 { "OPERAND_TYPE_IMM8",
407 { "OPERAND_TYPE_IMM8S",
409 { "OPERAND_TYPE_IMM16",
411 { "OPERAND_TYPE_IMM32",
413 { "OPERAND_TYPE_IMM32S",
415 { "OPERAND_TYPE_IMM64",
417 { "OPERAND_TYPE_BASEINDEX",
419 { "OPERAND_TYPE_DISP8",
421 { "OPERAND_TYPE_DISP16",
423 { "OPERAND_TYPE_DISP32",
425 { "OPERAND_TYPE_DISP32S",
427 { "OPERAND_TYPE_DISP64",
429 { "OPERAND_TYPE_INOUTPORTREG",
431 { "OPERAND_TYPE_SHIFTCOUNT",
433 { "OPERAND_TYPE_CONTROL",
435 { "OPERAND_TYPE_TEST",
437 { "OPERAND_TYPE_DEBUG",
439 { "OPERAND_TYPE_FLOATREG",
441 { "OPERAND_TYPE_FLOATACC",
443 { "OPERAND_TYPE_SREG2",
445 { "OPERAND_TYPE_SREG3",
447 { "OPERAND_TYPE_ACC",
449 { "OPERAND_TYPE_JUMPABSOLUTE",
451 { "OPERAND_TYPE_REGMMX",
453 { "OPERAND_TYPE_REGXMM",
455 { "OPERAND_TYPE_REGYMM",
457 { "OPERAND_TYPE_REGZMM",
459 { "OPERAND_TYPE_REGMASK",
461 { "OPERAND_TYPE_ESSEG",
463 { "OPERAND_TYPE_ACC32",
465 { "OPERAND_TYPE_ACC64",
467 { "OPERAND_TYPE_DISP16_32",
469 { "OPERAND_TYPE_ANYDISP",
470 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
471 { "OPERAND_TYPE_IMM16_32",
473 { "OPERAND_TYPE_IMM16_32S",
475 { "OPERAND_TYPE_IMM16_32_32S",
476 "Imm16|Imm32|Imm32S" },
477 { "OPERAND_TYPE_IMM32_64",
479 { "OPERAND_TYPE_IMM32_32S_DISP32",
480 "Imm32|Imm32S|Disp32" },
481 { "OPERAND_TYPE_IMM64_DISP64",
483 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
484 "Imm32|Imm32S|Imm64|Disp32" },
485 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
486 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
487 { "OPERAND_TYPE_VEC_IMM4",
489 { "OPERAND_TYPE_REGBND",
493 typedef struct bitfield
500 #define BITFIELD(n) { n, 0, #n }
502 static bitfield cpu_flags
[] =
512 BITFIELD (CpuClflush
),
514 BITFIELD (CpuSYSCALL
),
519 BITFIELD (CpuFISTTP
),
525 BITFIELD (CpuSSE4_1
),
526 BITFIELD (CpuSSE4_2
),
529 BITFIELD (CpuAVX512F
),
530 BITFIELD (CpuAVX512CD
),
531 BITFIELD (CpuAVX512ER
),
532 BITFIELD (CpuAVX512PF
),
533 BITFIELD (CpuAVX512VL
),
534 BITFIELD (CpuAVX512DQ
),
535 BITFIELD (CpuAVX512BW
),
541 BITFIELD (Cpu3dnowA
),
542 BITFIELD (CpuPadLock
),
548 BITFIELD (CpuXsaveopt
),
550 BITFIELD (CpuPCLMUL
),
561 BITFIELD (CpuRdtscp
),
562 BITFIELD (CpuFSGSBase
),
569 BITFIELD (CpuINVPCID
),
570 BITFIELD (CpuVMFUNC
),
571 BITFIELD (CpuRDSEED
),
573 BITFIELD (CpuPRFCHW
),
576 BITFIELD (CpuClflushOpt
),
577 BITFIELD (CpuXSAVES
),
578 BITFIELD (CpuXSAVEC
),
579 BITFIELD (CpuPREFETCHWT1
),
585 BITFIELD (CpuAVX512IFMA
),
586 BITFIELD (CpuAVX512VBMI
),
587 BITFIELD (CpuAVX512_4FMAPS
),
588 BITFIELD (CpuAVX512_4VNNIW
),
589 BITFIELD (CpuAVX512_VPOPCNTDQ
),
590 BITFIELD (CpuAVX512_VBMI2
),
591 BITFIELD (CpuAVX512_VNNI
),
592 BITFIELD (CpuAVX512_BITALG
),
593 BITFIELD (CpuAVX512_BF16
),
594 BITFIELD (CpuAVX512_VP2INTERSECT
),
595 BITFIELD (CpuMWAITX
),
596 BITFIELD (CpuCLZERO
),
599 BITFIELD (CpuPTWRITE
),
604 BITFIELD (CpuVPCLMULQDQ
),
605 BITFIELD (CpuWBNOINVD
),
606 BITFIELD (CpuPCONFIG
),
607 BITFIELD (CpuWAITPKG
),
608 BITFIELD (CpuCLDEMOTE
),
609 BITFIELD (CpuMOVDIRI
),
610 BITFIELD (CpuMOVDIR64B
),
611 BITFIELD (CpuENQCMD
),
613 BITFIELD (CpuUnused
),
617 static bitfield opcode_modifiers
[] =
623 BITFIELD (ShortForm
),
625 BITFIELD (JumpDword
),
627 BITFIELD (JumpInterSegment
),
631 BITFIELD (CheckRegSize
),
632 BITFIELD (IgnoreSize
),
633 BITFIELD (DefaultSize
),
642 BITFIELD (BNDPrefixOk
),
643 BITFIELD (NoTrackPrefixOk
),
644 BITFIELD (IsLockable
),
645 BITFIELD (RegKludge
),
646 BITFIELD (Implicit1stXmm0
),
647 BITFIELD (RepPrefixOk
),
648 BITFIELD (HLEPrefixOk
),
651 BITFIELD (AddrPrefixOpReg
),
660 BITFIELD (VexOpcode
),
661 BITFIELD (VexSources
),
667 BITFIELD (Broadcast
),
668 BITFIELD (StaticRounding
),
670 BITFIELD (Disp8MemShift
),
671 BITFIELD (NoDefMask
),
672 BITFIELD (ImplicitQuadGroup
),
674 BITFIELD (ATTMnemonic
),
675 BITFIELD (ATTSyntax
),
676 BITFIELD (IntelSyntax
),
681 static bitfield operand_types
[] =
694 BITFIELD (BaseIndex
),
700 BITFIELD (InOutPortReg
),
701 BITFIELD (ShiftCount
),
708 BITFIELD (JumpAbsolute
),
720 BITFIELD (Unspecified
),
729 static const char *filename
;
730 static i386_cpu_flags active_cpu_flags
;
731 static int active_isstring
;
734 compare (const void *x
, const void *y
)
736 const bitfield
*xp
= (const bitfield
*) x
;
737 const bitfield
*yp
= (const bitfield
*) y
;
738 return xp
->position
- yp
->position
;
742 fail (const char *message
, ...)
746 va_start (args
, message
);
747 fprintf (stderr
, _("%s: error: "), program_name
);
748 vfprintf (stderr
, message
, args
);
754 process_copyright (FILE *fp
)
756 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
757 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
759 This file is part of the GNU opcodes library.\n\
761 This library is free software; you can redistribute it and/or modify\n\
762 it under the terms of the GNU General Public License as published by\n\
763 the Free Software Foundation; either version 3, or (at your option)\n\
764 any later version.\n\
766 It is distributed in the hope that it will be useful, but WITHOUT\n\
767 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
768 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
769 License for more details.\n\
771 You should have received a copy of the GNU General Public License\n\
772 along with this program; if not, write to the Free Software\n\
773 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
774 MA 02110-1301, USA. */\n");
777 /* Remove leading white spaces. */
780 remove_leading_whitespaces (char *str
)
782 while (ISSPACE (*str
))
787 /* Remove trailing white spaces. */
790 remove_trailing_whitespaces (char *str
)
792 size_t last
= strlen (str
);
800 if (ISSPACE (str
[last
]))
808 /* Find next field separated by SEP and terminate it. Return a
809 pointer to the one after it. */
812 next_field (char *str
, char sep
, char **next
, char *last
)
816 p
= remove_leading_whitespaces (str
);
817 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
820 remove_trailing_whitespaces (p
);
830 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
833 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
836 char *str
, *next
, *last
;
839 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
840 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
842 /* Turn on selective bits. */
843 char *init
= xstrdup (cpu_flag_init
[i
].init
);
844 last
= init
+ strlen (init
);
845 for (next
= init
; next
&& next
< last
; )
847 str
= next_field (next
, '|', &next
, last
);
849 set_bitfield (str
, array
, 1, size
, lineno
);
855 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
856 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
858 /* Turn on selective bits. */
859 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
860 last
= init
+ strlen (init
);
861 for (next
= init
; next
&& next
< last
; )
863 str
= next_field (next
, '|', &next
, last
);
865 set_bitfield (str
, array
, 1, size
, lineno
);
875 set_bitfield (char *f
, bitfield
*array
, int value
,
876 unsigned int size
, int lineno
)
880 if (strcmp (f
, "CpuFP") == 0)
882 set_bitfield("Cpu387", array
, value
, size
, lineno
);
883 set_bitfield("Cpu287", array
, value
, size
, lineno
);
886 else if (strcmp (f
, "Mmword") == 0)
888 else if (strcmp (f
, "Oword") == 0)
891 for (i
= 0; i
< size
; i
++)
892 if (strcasecmp (array
[i
].name
, f
) == 0)
894 array
[i
].value
= value
;
900 const char *v
= strchr (f
, '=');
907 for (i
= 0; i
< size
; i
++)
908 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
910 value
= strtol (v
+ 1, &end
, 0);
913 array
[i
].value
= value
;
921 /* Handle shorthands. */
922 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
926 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
928 fail (_("unknown bitfield: %s\n"), f
);
932 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
933 int macro
, const char *comma
, const char *indent
)
937 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
939 fprintf (table
, "%s{ { ", indent
);
941 for (i
= 0; i
< size
- 1; i
++)
943 if (((i
+ 1) % 20) != 0)
944 fprintf (table
, "%d, ", flags
[i
].value
);
946 fprintf (table
, "%d,", flags
[i
].value
);
947 if (((i
+ 1) % 20) == 0)
949 /* We need \\ for macro. */
951 fprintf (table
, " \\\n %s", indent
);
953 fprintf (table
, "\n %s", indent
);
956 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
959 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
963 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
964 const char *comma
, const char *indent
,
967 char *str
, *next
, *last
;
969 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
971 /* Copy the default cpu flags. */
972 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
974 if (strcasecmp (flag
, "unknown") == 0)
976 /* We turn on everything except for cpu64 in case of
977 CPU_UNKNOWN_FLAGS. */
978 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
979 if (flags
[i
].position
!= Cpu64
)
982 else if (flag
[0] == '~')
984 last
= flag
+ strlen (flag
);
991 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
998 /* First we turn on everything except for cpu64. */
999 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1000 if (flags
[i
].position
!= Cpu64
)
1003 /* Turn off selective bits. */
1004 for (; next
&& next
< last
; )
1006 str
= next_field (next
, '|', &next
, last
);
1008 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1011 else if (strcmp (flag
, "0"))
1013 /* Turn on selective bits. */
1014 last
= flag
+ strlen (flag
);
1015 for (next
= flag
; next
&& next
< last
; )
1017 str
= next_field (next
, '|', &next
, last
);
1019 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1023 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1028 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1032 fprintf (table
, " { ");
1034 for (i
= 0; i
< size
- 1; i
++)
1036 if (((i
+ 1) % 20) != 0)
1037 fprintf (table
, "%d, ", modifier
[i
].value
);
1039 fprintf (table
, "%d,", modifier
[i
].value
);
1040 if (((i
+ 1) % 20) == 0)
1041 fprintf (table
, "\n ");
1044 fprintf (table
, "%d },\n", modifier
[i
].value
);
1048 adjust_broadcast_modifier (char **opnd
)
1050 char *str
, *next
, *last
, *op
;
1051 int bcst_type
= INT_MAX
;
1053 /* Skip the immediate operand. */
1055 if (strcasecmp(op
, "Imm8") == 0)
1059 last
= op
+ strlen (op
);
1060 for (next
= op
; next
&& next
< last
; )
1062 str
= next_field (next
, '|', &next
, last
);
1065 if (strcasecmp(str
, "Byte") == 0)
1067 /* The smalest broadcast type, no need to check
1069 bcst_type
= BYTE_BROADCAST
;
1072 else if (strcasecmp(str
, "Word") == 0)
1074 if (bcst_type
> WORD_BROADCAST
)
1075 bcst_type
= WORD_BROADCAST
;
1077 else if (strcasecmp(str
, "Dword") == 0)
1079 if (bcst_type
> DWORD_BROADCAST
)
1080 bcst_type
= DWORD_BROADCAST
;
1082 else if (strcasecmp(str
, "Qword") == 0)
1084 if (bcst_type
> QWORD_BROADCAST
)
1085 bcst_type
= QWORD_BROADCAST
;
1091 if (bcst_type
== INT_MAX
)
1092 fail (_("unknown broadcast operand: %s\n"), op
);
1098 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1100 char *str
, *next
, *last
;
1101 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1103 active_isstring
= 0;
1105 /* Copy the default opcode modifier. */
1106 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1108 if (strcmp (mod
, "0"))
1110 last
= mod
+ strlen (mod
);
1111 for (next
= mod
; next
&& next
< last
; )
1113 str
= next_field (next
, '|', &next
, last
);
1117 if (strcasecmp(str
, "Broadcast") == 0)
1118 val
= adjust_broadcast_modifier (opnd
);
1119 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1121 if (strcasecmp(str
, "IsString") == 0)
1122 active_isstring
= 1;
1126 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1136 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1137 enum stage stage
, const char *indent
)
1141 fprintf (table
, "{ { ");
1143 for (i
= 0; i
< size
- 1; i
++)
1145 if (((i
+ 1) % 20) != 0)
1146 fprintf (table
, "%d, ", types
[i
].value
);
1148 fprintf (table
, "%d,", types
[i
].value
);
1149 if (((i
+ 1) % 20) == 0)
1151 /* We need \\ for macro. */
1152 if (stage
== stage_macros
)
1153 fprintf (table
, " \\\n%s", indent
);
1155 fprintf (table
, "\n%s", indent
);
1159 fprintf (table
, "%d } }", types
[i
].value
);
1163 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1164 const char *indent
, int lineno
)
1166 char *str
, *next
, *last
;
1167 bitfield types
[ARRAY_SIZE (operand_types
)];
1169 /* Copy the default operand type. */
1170 memcpy (types
, operand_types
, sizeof (types
));
1172 if (strcmp (op
, "0"))
1176 last
= op
+ strlen (op
);
1177 for (next
= op
; next
&& next
< last
; )
1179 str
= next_field (next
, '|', &next
, last
);
1182 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1183 if (strcasecmp(str
, "BaseIndex") == 0)
1188 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1190 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1191 if (!active_cpu_flags
.bitfield
.cpu64
1192 && !active_cpu_flags
.bitfield
.cpumpx
)
1193 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1194 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1195 if (!active_cpu_flags
.bitfield
.cpuno64
)
1196 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1199 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1204 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1205 char *last
, int lineno
)
1208 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1209 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1211 /* Find number of operands. */
1212 operands
= next_field (str
, ',', &str
, last
);
1214 /* Find base_opcode. */
1215 base_opcode
= next_field (str
, ',', &str
, last
);
1217 /* Find extension_opcode. */
1218 extension_opcode
= next_field (str
, ',', &str
, last
);
1220 /* Find opcode_length. */
1221 opcode_length
= next_field (str
, ',', &str
, last
);
1223 /* Find cpu_flags. */
1224 cpu_flags
= next_field (str
, ',', &str
, last
);
1226 /* Find opcode_modifier. */
1227 opcode_modifier
= next_field (str
, ',', &str
, last
);
1229 /* Remove the first {. */
1230 str
= remove_leading_whitespaces (str
);
1233 str
= remove_leading_whitespaces (str
+ 1);
1237 /* There are at least "X}". */
1241 /* Remove trailing white spaces and }. */
1245 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1254 /* Find operand_types. */
1255 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1259 operand_types
[i
] = NULL
;
1263 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1264 if (*operand_types
[i
] == '0')
1267 operand_types
[i
] = NULL
;
1272 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1273 name
, operands
, base_opcode
, extension_opcode
,
1276 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1278 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1280 fprintf (table
, " { ");
1282 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1284 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1287 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1293 fprintf (table
, ",\n ");
1295 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1298 fprintf (table
, " } },\n");
1301 struct opcode_hash_entry
1303 struct opcode_hash_entry
*next
;
1309 /* Calculate the hash value of an opcode hash entry P. */
1312 opcode_hash_hash (const void *p
)
1314 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1315 return htab_hash_string (entry
->name
);
1318 /* Compare a string Q against an opcode hash entry P. */
1321 opcode_hash_eq (const void *p
, const void *q
)
1323 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1324 const char *name
= (const char *) q
;
1325 return strcmp (name
, entry
->name
) == 0;
1329 process_i386_opcodes (FILE *table
)
1334 char *str
, *p
, *last
, *name
;
1335 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1336 htab_t opcode_hash_table
;
1337 struct opcode_hash_entry
**opcode_array
;
1338 unsigned int opcode_array_size
= 1024;
1339 int lineno
= 0, marker
= 0;
1341 filename
= "i386-opc.tbl";
1345 opcode_array
= (struct opcode_hash_entry
**)
1346 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1348 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1349 opcode_hash_eq
, NULL
,
1352 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1353 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1355 /* Put everything on opcode array. */
1358 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1363 p
= remove_leading_whitespaces (buf
);
1365 /* Skip comments. */
1366 str
= strstr (p
, "//");
1370 /* Remove trailing white spaces. */
1371 remove_trailing_whitespaces (p
);
1376 if (!strcmp("### MARKER ###", buf
))
1380 /* Since we ignore all included files (we only care about their
1381 #define-s here), we don't need to monitor filenames. The final
1382 line number directive is going to refer to the main source file
1387 p
= remove_leading_whitespaces (p
+ 1);
1388 if (!strncmp(p
, "line", 4))
1390 ln
= strtoul (p
, &end
, 10);
1391 if (ln
> 1 && ln
< INT_MAX
1392 && *remove_leading_whitespaces (end
) == '"')
1395 /* Ignore comments. */
1405 last
= p
+ strlen (p
);
1408 name
= next_field (p
, ',', &str
, last
);
1410 /* Get the slot in hash table. */
1411 hash_slot
= (struct opcode_hash_entry
**)
1412 htab_find_slot_with_hash (opcode_hash_table
, name
,
1413 htab_hash_string (name
),
1416 if (*hash_slot
== NULL
)
1418 /* It is the new one. Put it on opcode array. */
1419 if (i
>= opcode_array_size
)
1421 /* Grow the opcode array when needed. */
1422 opcode_array_size
+= 1024;
1423 opcode_array
= (struct opcode_hash_entry
**)
1424 xrealloc (opcode_array
,
1425 sizeof (*opcode_array
) * opcode_array_size
);
1428 opcode_array
[i
] = (struct opcode_hash_entry
*)
1429 xmalloc (sizeof (struct opcode_hash_entry
));
1430 opcode_array
[i
]->next
= NULL
;
1431 opcode_array
[i
]->name
= xstrdup (name
);
1432 opcode_array
[i
]->opcode
= xstrdup (str
);
1433 opcode_array
[i
]->lineno
= lineno
;
1434 *hash_slot
= opcode_array
[i
];
1439 /* Append it to the existing one. */
1441 while ((*entry
) != NULL
)
1442 entry
= &(*entry
)->next
;
1443 *entry
= (struct opcode_hash_entry
*)
1444 xmalloc (sizeof (struct opcode_hash_entry
));
1445 (*entry
)->next
= NULL
;
1446 (*entry
)->name
= (*hash_slot
)->name
;
1447 (*entry
)->opcode
= xstrdup (str
);
1448 (*entry
)->lineno
= lineno
;
1452 /* Process opcode array. */
1453 for (j
= 0; j
< i
; j
++)
1455 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1459 lineno
= next
->lineno
;
1460 last
= str
+ strlen (str
);
1461 output_i386_opcode (table
, name
, str
, last
, lineno
);
1467 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1469 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1471 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1473 fprintf (table
, " { ");
1474 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1475 fprintf (table
, " } }\n");
1477 fprintf (table
, "};\n");
1481 process_i386_registers (FILE *table
)
1485 char *str
, *p
, *last
;
1486 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1487 char *dw2_32_num
, *dw2_64_num
;
1490 filename
= "i386-reg.tbl";
1491 fp
= fopen (filename
, "r");
1493 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1496 fprintf (table
, "\n/* i386 register table. */\n\n");
1497 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1501 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1506 p
= remove_leading_whitespaces (buf
);
1508 /* Skip comments. */
1509 str
= strstr (p
, "//");
1513 /* Remove trailing white spaces. */
1514 remove_trailing_whitespaces (p
);
1519 fprintf (table
, "%s\n", p
);
1527 last
= p
+ strlen (p
);
1529 /* Find reg_name. */
1530 reg_name
= next_field (p
, ',', &str
, last
);
1532 /* Find reg_type. */
1533 reg_type
= next_field (str
, ',', &str
, last
);
1535 /* Find reg_flags. */
1536 reg_flags
= next_field (str
, ',', &str
, last
);
1539 reg_num
= next_field (str
, ',', &str
, last
);
1541 fprintf (table
, " { \"%s\",\n ", reg_name
);
1543 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1546 /* Find 32-bit Dwarf2 register number. */
1547 dw2_32_num
= next_field (str
, ',', &str
, last
);
1549 /* Find 64-bit Dwarf2 register number. */
1550 dw2_64_num
= next_field (str
, ',', &str
, last
);
1552 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1553 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1558 fprintf (table
, "};\n");
1560 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1564 process_i386_initializers (void)
1567 FILE *fp
= fopen ("i386-init.h", "w");
1571 fail (_("can't create i386-init.h, errno = %s\n"),
1574 process_copyright (fp
);
1576 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1578 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1579 init
= xstrdup (cpu_flag_init
[i
].init
);
1580 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1584 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1586 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1587 init
= xstrdup (operand_type_init
[i
].init
);
1588 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1596 /* Program options. */
1597 #define OPTION_SRCDIR 200
1599 struct option long_options
[] =
1601 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1602 {"debug", no_argument
, NULL
, 'd'},
1603 {"version", no_argument
, NULL
, 'V'},
1604 {"help", no_argument
, NULL
, 'h'},
1605 {0, no_argument
, NULL
, 0}
1609 print_version (void)
1611 printf ("%s: version 1.0\n", program_name
);
1616 usage (FILE * stream
, int status
)
1618 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1624 main (int argc
, char **argv
)
1626 extern int chdir (char *);
1627 char *srcdir
= NULL
;
1629 unsigned int i
, cpumax
;
1632 program_name
= *argv
;
1633 xmalloc_set_program_name (program_name
);
1635 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1660 if (chdir (srcdir
) != 0)
1661 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1662 srcdir
, xstrerror (errno
));
1664 /* cpu_flags isn't sorted by position. */
1666 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1667 if (cpu_flags
[i
].position
> cpumax
)
1668 cpumax
= cpu_flags
[i
].position
;
1670 /* Check the unused bitfield in i386_cpu_flags. */
1672 if ((cpumax
- 1) != CpuMax
)
1673 fail (_("CpuMax != %d!\n"), cpumax
);
1675 if (cpumax
!= CpuMax
)
1676 fail (_("CpuMax != %d!\n"), cpumax
);
1678 c
= CpuNumOfBits
- CpuMax
- 1;
1680 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1683 /* Check the unused bitfield in i386_operand_type. */
1685 c
= OTNumOfBits
- OTMax
- 1;
1687 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1690 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1693 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1694 sizeof (opcode_modifiers
[0]), compare
);
1696 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1697 sizeof (operand_types
[0]), compare
);
1699 table
= fopen ("i386-tbl.h", "w");
1701 fail (_("can't create i386-tbl.h, errno = %s\n"),
1704 process_copyright (table
);
1706 process_i386_opcodes (table
);
1707 process_i386_registers (table
);
1708 process_i386_initializers ();