1 /* Copyright (C) 2007-2018 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" },
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" },
114 { "CPU_CLFLUSH_FLAGS",
118 { "CPU_SYSCALL_FLAGS",
125 "CPU_SSE_FLAGS|CpuSSE2" },
127 "CPU_SSE2_FLAGS|CpuSSE3" },
129 "CPU_SSE3_FLAGS|CpuSSSE3" },
130 { "CPU_SSE4_1_FLAGS",
131 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
132 { "CPU_SSE4_2_FLAGS",
133 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
140 { "CPU_XSAVEOPT_FLAGS",
141 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
143 "CPU_SSE2_FLAGS|CpuAES" },
144 { "CPU_PCLMUL_FLAGS",
145 "CPU_SSE2_FLAGS|CpuPCLMUL" },
147 "CPU_AVX_FLAGS|CpuFMA" },
149 "CPU_AVX_FLAGS|CpuFMA4" },
151 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
153 "CPU_XSAVE_FLAGS|CpuLWP" },
162 { "CPU_RDTSCP_FLAGS",
166 { "CPU_FSGSBASE_FLAGS",
171 "CPU_AVX_FLAGS|CpuF16C" },
180 { "CPU_INVPCID_FLAGS",
182 { "CPU_VMFUNC_FLAGS",
185 "CPU_MMX_FLAGS|Cpu3dnow" },
186 { "CPU_3DNOWA_FLAGS",
187 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
188 { "CPU_PADLOCK_FLAGS",
193 "CPU_SSE3_FLAGS|CpuSSE4a" },
197 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
199 "CPU_AVX_FLAGS|CpuAVX2" },
200 { "CPU_AVX512F_FLAGS",
201 "CPU_AVX2_FLAGS|CpuVREX|CpuAVX512F" },
202 { "CPU_AVX512CD_FLAGS",
203 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
204 { "CPU_AVX512ER_FLAGS",
205 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
206 { "CPU_AVX512PF_FLAGS",
207 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
208 { "CPU_AVX512DQ_FLAGS",
209 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
210 { "CPU_AVX512BW_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
212 { "CPU_AVX512VL_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
214 { "CPU_AVX512IFMA_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
216 { "CPU_AVX512VBMI_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
218 { "CPU_AVX512_4FMAPS_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
220 { "CPU_AVX512_4VNNIW_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
222 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
224 { "CPU_AVX512_VBMI2_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
226 { "CPU_AVX512_VNNI_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
228 { "CPU_AVX512_BITALG_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
235 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
238 { "CPU_RDSEED_FLAGS",
240 { "CPU_PRFCHW_FLAGS",
245 "CPU_XSAVE_FLAGS|CpuMPX" },
247 "CPU_SSE2_FLAGS|CpuSHA" },
248 { "CPU_CLFLUSHOPT_FLAGS",
250 { "CPU_XSAVES_FLAGS",
251 "CPU_XSAVE_FLAGS|CpuXSAVES" },
252 { "CPU_XSAVEC_FLAGS",
253 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
254 { "CPU_PREFETCHWT1_FLAGS",
260 { "CPU_CLZERO_FLAGS",
262 { "CPU_MWAITX_FLAGS",
265 "CPU_XSAVE_FLAGS|CpuOSPKE" },
268 { "CPU_PTWRITE_FLAGS",
278 { "CPU_VPCLMULQDQ_FLAGS",
280 { "CPU_WBNOINVD_FLAGS",
282 { "CPU_PCONFIG_FLAGS",
284 { "CPU_WAITPKG_FLAGS",
286 { "CPU_CLDEMOTE_FLAGS",
288 { "CPU_MOVDIRI_FLAGS",
290 { "CPU_MOVDIR64B_FLAGS",
292 { "CPU_ANY_X87_FLAGS",
293 "CPU_ANY_287_FLAGS|Cpu8087" },
294 { "CPU_ANY_287_FLAGS",
295 "CPU_ANY_387_FLAGS|Cpu287" },
296 { "CPU_ANY_387_FLAGS",
297 "CPU_ANY_687_FLAGS|Cpu387" },
298 { "CPU_ANY_687_FLAGS",
299 "Cpu687|CpuFISTTP" },
300 { "CPU_ANY_MMX_FLAGS",
301 "CPU_3DNOWA_FLAGS" },
302 { "CPU_ANY_SSE_FLAGS",
303 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
304 { "CPU_ANY_SSE2_FLAGS",
305 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
306 { "CPU_ANY_SSE3_FLAGS",
307 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
308 { "CPU_ANY_SSSE3_FLAGS",
309 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
310 { "CPU_ANY_SSE4_1_FLAGS",
311 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
312 { "CPU_ANY_SSE4_2_FLAGS",
314 { "CPU_ANY_AVX_FLAGS",
315 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
316 { "CPU_ANY_AVX2_FLAGS",
318 { "CPU_ANY_AVX512F_FLAGS",
319 "CpuVREX|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512F" },
320 { "CPU_ANY_AVX512CD_FLAGS",
322 { "CPU_ANY_AVX512ER_FLAGS",
324 { "CPU_ANY_AVX512PF_FLAGS",
326 { "CPU_ANY_AVX512DQ_FLAGS",
328 { "CPU_ANY_AVX512BW_FLAGS",
330 { "CPU_ANY_AVX512VL_FLAGS",
332 { "CPU_ANY_AVX512IFMA_FLAGS",
334 { "CPU_ANY_AVX512VBMI_FLAGS",
336 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
337 "CpuAVX512_4FMAPS" },
338 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
339 "CpuAVX512_4VNNIW" },
340 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
341 "CpuAVX512_VPOPCNTDQ" },
342 { "CPU_ANY_IBT_FLAGS",
344 { "CPU_ANY_SHSTK_FLAGS",
346 { "CPU_ANY_AVX512_VBMI2_FLAGS",
348 { "CPU_ANY_AVX512_VNNI_FLAGS",
350 { "CPU_ANY_AVX512_BITALG_FLAGS",
351 "CpuAVX512_BITALG" },
352 { "CPU_ANY_MOVDIRI_FLAGS",
354 { "CPU_ANY_MOVDIR64B_FLAGS",
358 static const initializer operand_type_shorthands
[] =
360 { "Reg8", "Reg|Byte" },
361 { "Reg16", "Reg|Word" },
362 { "Reg32", "Reg|Dword" },
363 { "Reg64", "Reg|Qword" },
364 { "FloatAcc", "Acc|Tbyte" },
365 { "FloatReg", "Reg|Tbyte" },
366 { "RegXMM", "RegSIMD|Xmmword" },
367 { "RegYMM", "RegSIMD|Ymmword" },
368 { "RegZMM", "RegSIMD|Zmmword" },
371 static initializer operand_type_init
[] =
373 { "OPERAND_TYPE_NONE",
375 { "OPERAND_TYPE_REG8",
377 { "OPERAND_TYPE_REG16",
379 { "OPERAND_TYPE_REG32",
381 { "OPERAND_TYPE_REG64",
383 { "OPERAND_TYPE_IMM1",
385 { "OPERAND_TYPE_IMM8",
387 { "OPERAND_TYPE_IMM8S",
389 { "OPERAND_TYPE_IMM16",
391 { "OPERAND_TYPE_IMM32",
393 { "OPERAND_TYPE_IMM32S",
395 { "OPERAND_TYPE_IMM64",
397 { "OPERAND_TYPE_BASEINDEX",
399 { "OPERAND_TYPE_DISP8",
401 { "OPERAND_TYPE_DISP16",
403 { "OPERAND_TYPE_DISP32",
405 { "OPERAND_TYPE_DISP32S",
407 { "OPERAND_TYPE_DISP64",
409 { "OPERAND_TYPE_INOUTPORTREG",
411 { "OPERAND_TYPE_SHIFTCOUNT",
413 { "OPERAND_TYPE_CONTROL",
415 { "OPERAND_TYPE_TEST",
417 { "OPERAND_TYPE_DEBUG",
419 { "OPERAND_TYPE_FLOATREG",
421 { "OPERAND_TYPE_FLOATACC",
423 { "OPERAND_TYPE_SREG2",
425 { "OPERAND_TYPE_SREG3",
427 { "OPERAND_TYPE_ACC",
429 { "OPERAND_TYPE_JUMPABSOLUTE",
431 { "OPERAND_TYPE_REGMMX",
433 { "OPERAND_TYPE_REGXMM",
435 { "OPERAND_TYPE_REGYMM",
437 { "OPERAND_TYPE_REGZMM",
439 { "OPERAND_TYPE_REGMASK",
441 { "OPERAND_TYPE_ESSEG",
443 { "OPERAND_TYPE_ACC32",
445 { "OPERAND_TYPE_ACC64",
447 { "OPERAND_TYPE_DISP16_32",
449 { "OPERAND_TYPE_ANYDISP",
450 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
451 { "OPERAND_TYPE_IMM16_32",
453 { "OPERAND_TYPE_IMM16_32S",
455 { "OPERAND_TYPE_IMM16_32_32S",
456 "Imm16|Imm32|Imm32S" },
457 { "OPERAND_TYPE_IMM32_64",
459 { "OPERAND_TYPE_IMM32_32S_DISP32",
460 "Imm32|Imm32S|Disp32" },
461 { "OPERAND_TYPE_IMM64_DISP64",
463 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
464 "Imm32|Imm32S|Imm64|Disp32" },
465 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
466 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
467 { "OPERAND_TYPE_VEC_IMM4",
469 { "OPERAND_TYPE_REGBND",
473 typedef struct bitfield
480 #define BITFIELD(n) { n, 0, #n }
482 static bitfield cpu_flags
[] =
490 BITFIELD (CpuClflush
),
492 BITFIELD (CpuSYSCALL
),
497 BITFIELD (CpuFISTTP
),
503 BITFIELD (CpuSSE4_1
),
504 BITFIELD (CpuSSE4_2
),
507 BITFIELD (CpuAVX512F
),
508 BITFIELD (CpuAVX512CD
),
509 BITFIELD (CpuAVX512ER
),
510 BITFIELD (CpuAVX512PF
),
511 BITFIELD (CpuAVX512VL
),
512 BITFIELD (CpuAVX512DQ
),
513 BITFIELD (CpuAVX512BW
),
519 BITFIELD (Cpu3dnowA
),
520 BITFIELD (CpuPadLock
),
526 BITFIELD (CpuXsaveopt
),
528 BITFIELD (CpuPCLMUL
),
539 BITFIELD (CpuRdtscp
),
540 BITFIELD (CpuFSGSBase
),
547 BITFIELD (CpuINVPCID
),
548 BITFIELD (CpuVMFUNC
),
549 BITFIELD (CpuRDSEED
),
551 BITFIELD (CpuPRFCHW
),
555 BITFIELD (CpuClflushOpt
),
556 BITFIELD (CpuXSAVES
),
557 BITFIELD (CpuXSAVEC
),
558 BITFIELD (CpuPREFETCHWT1
),
564 BITFIELD (CpuAVX512IFMA
),
565 BITFIELD (CpuAVX512VBMI
),
566 BITFIELD (CpuAVX512_4FMAPS
),
567 BITFIELD (CpuAVX512_4VNNIW
),
568 BITFIELD (CpuAVX512_VPOPCNTDQ
),
569 BITFIELD (CpuAVX512_VBMI2
),
570 BITFIELD (CpuAVX512_VNNI
),
571 BITFIELD (CpuAVX512_BITALG
),
572 BITFIELD (CpuMWAITX
),
573 BITFIELD (CpuCLZERO
),
576 BITFIELD (CpuPTWRITE
),
581 BITFIELD (CpuVPCLMULQDQ
),
582 BITFIELD (CpuWBNOINVD
),
583 BITFIELD (CpuPCONFIG
),
584 BITFIELD (CpuWAITPKG
),
585 BITFIELD (CpuCLDEMOTE
),
586 BITFIELD (CpuMOVDIRI
),
587 BITFIELD (CpuMOVDIR64B
),
589 BITFIELD (CpuUnused
),
593 static bitfield opcode_modifiers
[] =
599 BITFIELD (ShortForm
),
601 BITFIELD (JumpDword
),
603 BITFIELD (JumpInterSegment
),
609 BITFIELD (CheckRegSize
),
610 BITFIELD (IgnoreSize
),
611 BITFIELD (DefaultSize
),
620 BITFIELD (BNDPrefixOk
),
621 BITFIELD (NoTrackPrefixOk
),
622 BITFIELD (IsLockable
),
623 BITFIELD (RegKludge
),
624 BITFIELD (Implicit1stXmm0
),
625 BITFIELD (RepPrefixOk
),
626 BITFIELD (HLEPrefixOk
),
629 BITFIELD (AddrPrefixOpReg
),
638 BITFIELD (VexOpcode
),
639 BITFIELD (VexSources
),
645 BITFIELD (Broadcast
),
646 BITFIELD (StaticRounding
),
648 BITFIELD (Disp8MemShift
),
649 BITFIELD (NoDefMask
),
650 BITFIELD (ImplicitQuadGroup
),
652 BITFIELD (ATTMnemonic
),
653 BITFIELD (ATTSyntax
),
654 BITFIELD (IntelSyntax
),
659 static bitfield operand_types
[] =
672 BITFIELD (BaseIndex
),
678 BITFIELD (InOutPortReg
),
679 BITFIELD (ShiftCount
),
686 BITFIELD (JumpAbsolute
),
699 BITFIELD (Unspecified
),
708 static const char *filename
;
709 static i386_cpu_flags active_cpu_flags
;
710 static int active_isstring
;
713 compare (const void *x
, const void *y
)
715 const bitfield
*xp
= (const bitfield
*) x
;
716 const bitfield
*yp
= (const bitfield
*) y
;
717 return xp
->position
- yp
->position
;
721 fail (const char *message
, ...)
725 va_start (args
, message
);
726 fprintf (stderr
, _("%s: error: "), program_name
);
727 vfprintf (stderr
, message
, args
);
733 process_copyright (FILE *fp
)
735 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
736 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
738 This file is part of the GNU opcodes library.\n\
740 This library is free software; you can redistribute it and/or modify\n\
741 it under the terms of the GNU General Public License as published by\n\
742 the Free Software Foundation; either version 3, or (at your option)\n\
743 any later version.\n\
745 It is distributed in the hope that it will be useful, but WITHOUT\n\
746 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
747 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
748 License for more details.\n\
750 You should have received a copy of the GNU General Public License\n\
751 along with this program; if not, write to the Free Software\n\
752 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
753 MA 02110-1301, USA. */\n");
756 /* Remove leading white spaces. */
759 remove_leading_whitespaces (char *str
)
761 while (ISSPACE (*str
))
766 /* Remove trailing white spaces. */
769 remove_trailing_whitespaces (char *str
)
771 size_t last
= strlen (str
);
779 if (ISSPACE (str
[last
]))
787 /* Find next field separated by SEP and terminate it. Return a
788 pointer to the one after it. */
791 next_field (char *str
, char sep
, char **next
, char *last
)
795 p
= remove_leading_whitespaces (str
);
796 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
799 remove_trailing_whitespaces (p
);
809 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
812 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
815 char *str
, *next
, *last
;
818 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
819 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
821 /* Turn on selective bits. */
822 char *init
= xstrdup (cpu_flag_init
[i
].init
);
823 last
= init
+ strlen (init
);
824 for (next
= init
; next
&& next
< last
; )
826 str
= next_field (next
, '|', &next
, last
);
828 set_bitfield (str
, array
, 1, size
, lineno
);
834 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
835 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
837 /* Turn on selective bits. */
838 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
839 last
= init
+ strlen (init
);
840 for (next
= init
; next
&& next
< last
; )
842 str
= next_field (next
, '|', &next
, last
);
844 set_bitfield (str
, array
, 1, size
, lineno
);
854 set_bitfield (char *f
, bitfield
*array
, int value
,
855 unsigned int size
, int lineno
)
859 if (strcmp (f
, "CpuFP") == 0)
861 set_bitfield("Cpu387", array
, value
, size
, lineno
);
862 set_bitfield("Cpu287", array
, value
, size
, lineno
);
865 else if (strcmp (f
, "Mmword") == 0)
867 else if (strcmp (f
, "Oword") == 0)
870 for (i
= 0; i
< size
; i
++)
871 if (strcasecmp (array
[i
].name
, f
) == 0)
873 array
[i
].value
= value
;
879 const char *v
= strchr (f
, '=');
886 for (i
= 0; i
< size
; i
++)
887 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
889 value
= strtol (v
+ 1, &end
, 0);
892 array
[i
].value
= value
;
900 /* Handle shorthands. */
901 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
905 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
907 fail (_("unknown bitfield: %s\n"), f
);
911 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
912 int macro
, const char *comma
, const char *indent
)
916 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
918 fprintf (table
, "%s{ { ", indent
);
920 for (i
= 0; i
< size
- 1; i
++)
922 if (((i
+ 1) % 20) != 0)
923 fprintf (table
, "%d, ", flags
[i
].value
);
925 fprintf (table
, "%d,", flags
[i
].value
);
926 if (((i
+ 1) % 20) == 0)
928 /* We need \\ for macro. */
930 fprintf (table
, " \\\n %s", indent
);
932 fprintf (table
, "\n %s", indent
);
935 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
938 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
942 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
943 const char *comma
, const char *indent
,
946 char *str
, *next
, *last
;
948 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
950 /* Copy the default cpu flags. */
951 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
953 if (strcasecmp (flag
, "unknown") == 0)
955 /* We turn on everything except for cpu64 in case of
956 CPU_UNKNOWN_FLAGS. */
957 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
958 if (flags
[i
].position
!= Cpu64
)
961 else if (flag
[0] == '~')
963 last
= flag
+ strlen (flag
);
970 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
977 /* First we turn on everything except for cpu64. */
978 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
979 if (flags
[i
].position
!= Cpu64
)
982 /* Turn off selective bits. */
983 for (; next
&& next
< last
; )
985 str
= next_field (next
, '|', &next
, last
);
987 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
990 else if (strcmp (flag
, "0"))
992 /* Turn on selective bits. */
993 last
= flag
+ strlen (flag
);
994 for (next
= flag
; next
&& next
< last
; )
996 str
= next_field (next
, '|', &next
, last
);
998 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1002 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1007 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1011 fprintf (table
, " { ");
1013 for (i
= 0; i
< size
- 1; i
++)
1015 if (((i
+ 1) % 20) != 0)
1016 fprintf (table
, "%d, ", modifier
[i
].value
);
1018 fprintf (table
, "%d,", modifier
[i
].value
);
1019 if (((i
+ 1) % 20) == 0)
1020 fprintf (table
, "\n ");
1023 fprintf (table
, "%d },\n", modifier
[i
].value
);
1027 adjust_broadcast_modifier (char **opnd
)
1029 char *str
, *next
, *last
, *op
;
1030 int bcst_type
= INT_MAX
;
1032 /* Skip the immediate operand. */
1034 if (strcasecmp(op
, "Imm8") == 0)
1038 last
= op
+ strlen (op
);
1039 for (next
= op
; next
&& next
< last
; )
1041 str
= next_field (next
, '|', &next
, last
);
1044 if (strcasecmp(str
, "Byte") == 0)
1046 /* The smalest broadcast type, no need to check
1048 bcst_type
= BYTE_BROADCAST
;
1051 else if (strcasecmp(str
, "Word") == 0)
1053 if (bcst_type
> WORD_BROADCAST
)
1054 bcst_type
= WORD_BROADCAST
;
1056 else if (strcasecmp(str
, "Dword") == 0)
1058 if (bcst_type
> DWORD_BROADCAST
)
1059 bcst_type
= DWORD_BROADCAST
;
1061 else if (strcasecmp(str
, "Qword") == 0)
1063 if (bcst_type
> QWORD_BROADCAST
)
1064 bcst_type
= QWORD_BROADCAST
;
1070 if (bcst_type
== INT_MAX
)
1071 fail (_("unknown broadcast operand: %s\n"), op
);
1077 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1079 char *str
, *next
, *last
;
1080 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1082 active_isstring
= 0;
1084 /* Copy the default opcode modifier. */
1085 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1087 if (strcmp (mod
, "0"))
1089 last
= mod
+ strlen (mod
);
1090 for (next
= mod
; next
&& next
< last
; )
1092 str
= next_field (next
, '|', &next
, last
);
1096 if (strcasecmp(str
, "Broadcast") == 0)
1097 val
= adjust_broadcast_modifier (opnd
);
1098 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1100 if (strcasecmp(str
, "IsString") == 0)
1101 active_isstring
= 1;
1105 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1115 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1116 enum stage stage
, const char *indent
)
1120 fprintf (table
, "{ { ");
1122 for (i
= 0; i
< size
- 1; i
++)
1124 if (((i
+ 1) % 20) != 0)
1125 fprintf (table
, "%d, ", types
[i
].value
);
1127 fprintf (table
, "%d,", types
[i
].value
);
1128 if (((i
+ 1) % 20) == 0)
1130 /* We need \\ for macro. */
1131 if (stage
== stage_macros
)
1132 fprintf (table
, " \\\n%s", indent
);
1134 fprintf (table
, "\n%s", indent
);
1138 fprintf (table
, "%d } }", types
[i
].value
);
1142 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1143 const char *indent
, int lineno
)
1145 char *str
, *next
, *last
;
1146 bitfield types
[ARRAY_SIZE (operand_types
)];
1148 /* Copy the default operand type. */
1149 memcpy (types
, operand_types
, sizeof (types
));
1151 if (strcmp (op
, "0"))
1155 last
= op
+ strlen (op
);
1156 for (next
= op
; next
&& next
< last
; )
1158 str
= next_field (next
, '|', &next
, last
);
1161 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1162 if (strcasecmp(str
, "BaseIndex") == 0)
1167 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1169 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1170 if (!active_cpu_flags
.bitfield
.cpu64
1171 && !active_cpu_flags
.bitfield
.cpumpx
)
1172 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1173 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1174 if (!active_cpu_flags
.bitfield
.cpuno64
)
1175 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1178 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1183 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1184 char *last
, int lineno
)
1187 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1188 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1190 /* Find number of operands. */
1191 operands
= next_field (str
, ',', &str
, last
);
1193 /* Find base_opcode. */
1194 base_opcode
= next_field (str
, ',', &str
, last
);
1196 /* Find extension_opcode. */
1197 extension_opcode
= next_field (str
, ',', &str
, last
);
1199 /* Find opcode_length. */
1200 opcode_length
= next_field (str
, ',', &str
, last
);
1202 /* Find cpu_flags. */
1203 cpu_flags
= next_field (str
, ',', &str
, last
);
1205 /* Find opcode_modifier. */
1206 opcode_modifier
= next_field (str
, ',', &str
, last
);
1208 /* Remove the first {. */
1209 str
= remove_leading_whitespaces (str
);
1212 str
= remove_leading_whitespaces (str
+ 1);
1216 /* There are at least "X}". */
1220 /* Remove trailing white spaces and }. */
1224 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1233 /* Find operand_types. */
1234 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1238 operand_types
[i
] = NULL
;
1242 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1243 if (*operand_types
[i
] == '0')
1246 operand_types
[i
] = NULL
;
1251 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1252 name
, operands
, base_opcode
, extension_opcode
,
1255 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1257 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1259 fprintf (table
, " { ");
1261 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1263 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1266 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1272 fprintf (table
, ",\n ");
1274 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1277 fprintf (table
, " } },\n");
1280 struct opcode_hash_entry
1282 struct opcode_hash_entry
*next
;
1288 /* Calculate the hash value of an opcode hash entry P. */
1291 opcode_hash_hash (const void *p
)
1293 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1294 return htab_hash_string (entry
->name
);
1297 /* Compare a string Q against an opcode hash entry P. */
1300 opcode_hash_eq (const void *p
, const void *q
)
1302 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1303 const char *name
= (const char *) q
;
1304 return strcmp (name
, entry
->name
) == 0;
1308 process_i386_opcodes (FILE *table
)
1313 char *str
, *p
, *last
, *name
;
1314 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1315 htab_t opcode_hash_table
;
1316 struct opcode_hash_entry
**opcode_array
;
1317 unsigned int opcode_array_size
= 1024;
1318 int lineno
= 0, marker
= 0;
1320 filename
= "i386-opc.tbl";
1324 opcode_array
= (struct opcode_hash_entry
**)
1325 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1327 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1328 opcode_hash_eq
, NULL
,
1331 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1332 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1334 /* Put everything on opcode array. */
1337 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1342 p
= remove_leading_whitespaces (buf
);
1344 /* Skip comments. */
1345 str
= strstr (p
, "//");
1349 /* Remove trailing white spaces. */
1350 remove_trailing_whitespaces (p
);
1355 if (!strcmp("### MARKER ###", buf
))
1359 /* Since we ignore all included files (we only care about their
1360 #define-s here), we don't need to monitor filenames. The final
1361 line number directive is going to refer to the main source file
1366 p
= remove_leading_whitespaces (p
+ 1);
1367 if (!strncmp(p
, "line", 4))
1369 ln
= strtoul (p
, &end
, 10);
1370 if (ln
> 1 && ln
< INT_MAX
1371 && *remove_leading_whitespaces (end
) == '"')
1374 /* Ignore comments. */
1384 last
= p
+ strlen (p
);
1387 name
= next_field (p
, ',', &str
, last
);
1389 /* Get the slot in hash table. */
1390 hash_slot
= (struct opcode_hash_entry
**)
1391 htab_find_slot_with_hash (opcode_hash_table
, name
,
1392 htab_hash_string (name
),
1395 if (*hash_slot
== NULL
)
1397 /* It is the new one. Put it on opcode array. */
1398 if (i
>= opcode_array_size
)
1400 /* Grow the opcode array when needed. */
1401 opcode_array_size
+= 1024;
1402 opcode_array
= (struct opcode_hash_entry
**)
1403 xrealloc (opcode_array
,
1404 sizeof (*opcode_array
) * opcode_array_size
);
1407 opcode_array
[i
] = (struct opcode_hash_entry
*)
1408 xmalloc (sizeof (struct opcode_hash_entry
));
1409 opcode_array
[i
]->next
= NULL
;
1410 opcode_array
[i
]->name
= xstrdup (name
);
1411 opcode_array
[i
]->opcode
= xstrdup (str
);
1412 opcode_array
[i
]->lineno
= lineno
;
1413 *hash_slot
= opcode_array
[i
];
1418 /* Append it to the existing one. */
1420 while ((*entry
) != NULL
)
1421 entry
= &(*entry
)->next
;
1422 *entry
= (struct opcode_hash_entry
*)
1423 xmalloc (sizeof (struct opcode_hash_entry
));
1424 (*entry
)->next
= NULL
;
1425 (*entry
)->name
= (*hash_slot
)->name
;
1426 (*entry
)->opcode
= xstrdup (str
);
1427 (*entry
)->lineno
= lineno
;
1431 /* Process opcode array. */
1432 for (j
= 0; j
< i
; j
++)
1434 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1438 lineno
= next
->lineno
;
1439 last
= str
+ strlen (str
);
1440 output_i386_opcode (table
, name
, str
, last
, lineno
);
1446 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1448 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1450 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1452 fprintf (table
, " { ");
1453 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1454 fprintf (table
, " } }\n");
1456 fprintf (table
, "};\n");
1460 process_i386_registers (FILE *table
)
1464 char *str
, *p
, *last
;
1465 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1466 char *dw2_32_num
, *dw2_64_num
;
1469 filename
= "i386-reg.tbl";
1470 fp
= fopen (filename
, "r");
1472 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1475 fprintf (table
, "\n/* i386 register table. */\n\n");
1476 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1480 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1485 p
= remove_leading_whitespaces (buf
);
1487 /* Skip comments. */
1488 str
= strstr (p
, "//");
1492 /* Remove trailing white spaces. */
1493 remove_trailing_whitespaces (p
);
1498 fprintf (table
, "%s\n", p
);
1506 last
= p
+ strlen (p
);
1508 /* Find reg_name. */
1509 reg_name
= next_field (p
, ',', &str
, last
);
1511 /* Find reg_type. */
1512 reg_type
= next_field (str
, ',', &str
, last
);
1514 /* Find reg_flags. */
1515 reg_flags
= next_field (str
, ',', &str
, last
);
1518 reg_num
= next_field (str
, ',', &str
, last
);
1520 fprintf (table
, " { \"%s\",\n ", reg_name
);
1522 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1525 /* Find 32-bit Dwarf2 register number. */
1526 dw2_32_num
= next_field (str
, ',', &str
, last
);
1528 /* Find 64-bit Dwarf2 register number. */
1529 dw2_64_num
= next_field (str
, ',', &str
, last
);
1531 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1532 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1537 fprintf (table
, "};\n");
1539 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1543 process_i386_initializers (void)
1546 FILE *fp
= fopen ("i386-init.h", "w");
1550 fail (_("can't create i386-init.h, errno = %s\n"),
1553 process_copyright (fp
);
1555 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1557 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1558 init
= xstrdup (cpu_flag_init
[i
].init
);
1559 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1563 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1565 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1566 init
= xstrdup (operand_type_init
[i
].init
);
1567 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1575 /* Program options. */
1576 #define OPTION_SRCDIR 200
1578 struct option long_options
[] =
1580 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1581 {"debug", no_argument
, NULL
, 'd'},
1582 {"version", no_argument
, NULL
, 'V'},
1583 {"help", no_argument
, NULL
, 'h'},
1584 {0, no_argument
, NULL
, 0}
1588 print_version (void)
1590 printf ("%s: version 1.0\n", program_name
);
1595 usage (FILE * stream
, int status
)
1597 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1603 main (int argc
, char **argv
)
1605 extern int chdir (char *);
1606 char *srcdir
= NULL
;
1608 unsigned int i
, cpumax
;
1611 program_name
= *argv
;
1612 xmalloc_set_program_name (program_name
);
1614 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1639 if (chdir (srcdir
) != 0)
1640 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1641 srcdir
, xstrerror (errno
));
1643 /* cpu_flags isn't sorted by position. */
1645 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1646 if (cpu_flags
[i
].position
> cpumax
)
1647 cpumax
= cpu_flags
[i
].position
;
1649 /* Check the unused bitfield in i386_cpu_flags. */
1651 if ((cpumax
- 1) != CpuMax
)
1652 fail (_("CpuMax != %d!\n"), cpumax
);
1654 if (cpumax
!= CpuMax
)
1655 fail (_("CpuMax != %d!\n"), cpumax
);
1657 c
= CpuNumOfBits
- CpuMax
- 1;
1659 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1662 /* Check the unused bitfield in i386_operand_type. */
1664 c
= OTNumOfBits
- OTMax
- 1;
1666 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1669 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1672 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1673 sizeof (opcode_modifiers
[0]), compare
);
1675 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1676 sizeof (operand_types
[0]), compare
);
1678 table
= fopen ("i386-tbl.h", "w");
1680 fail (_("can't create i386-tbl.h, errno = %s\n"),
1683 process_copyright (table
);
1685 process_i386_opcodes (table
);
1686 process_i386_registers (table
);
1687 process_i386_initializers ();