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 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
1029 char *str
, *next
, *last
;
1030 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1032 active_isstring
= 0;
1034 /* Copy the default opcode modifier. */
1035 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1037 if (strcmp (mod
, "0"))
1039 last
= mod
+ strlen (mod
);
1040 for (next
= mod
; next
&& next
< last
; )
1042 str
= next_field (next
, '|', &next
, last
);
1045 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
1047 if (strcasecmp(str
, "IsString") == 0)
1048 active_isstring
= 1;
1052 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1062 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1063 enum stage stage
, const char *indent
)
1067 fprintf (table
, "{ { ");
1069 for (i
= 0; i
< size
- 1; i
++)
1071 if (((i
+ 1) % 20) != 0)
1072 fprintf (table
, "%d, ", types
[i
].value
);
1074 fprintf (table
, "%d,", types
[i
].value
);
1075 if (((i
+ 1) % 20) == 0)
1077 /* We need \\ for macro. */
1078 if (stage
== stage_macros
)
1079 fprintf (table
, " \\\n%s", indent
);
1081 fprintf (table
, "\n%s", indent
);
1085 fprintf (table
, "%d } }", types
[i
].value
);
1089 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1090 const char *indent
, int lineno
)
1092 char *str
, *next
, *last
;
1093 bitfield types
[ARRAY_SIZE (operand_types
)];
1095 /* Copy the default operand type. */
1096 memcpy (types
, operand_types
, sizeof (types
));
1098 if (strcmp (op
, "0"))
1102 last
= op
+ strlen (op
);
1103 for (next
= op
; next
&& next
< last
; )
1105 str
= next_field (next
, '|', &next
, last
);
1108 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1109 if (strcasecmp(str
, "BaseIndex") == 0)
1114 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1116 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1117 if (!active_cpu_flags
.bitfield
.cpu64
1118 && !active_cpu_flags
.bitfield
.cpumpx
)
1119 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1120 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1121 if (!active_cpu_flags
.bitfield
.cpuno64
)
1122 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1125 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1130 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1131 char *last
, int lineno
)
1134 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1135 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1137 /* Find number of operands. */
1138 operands
= next_field (str
, ',', &str
, last
);
1140 /* Find base_opcode. */
1141 base_opcode
= next_field (str
, ',', &str
, last
);
1143 /* Find extension_opcode. */
1144 extension_opcode
= next_field (str
, ',', &str
, last
);
1146 /* Find opcode_length. */
1147 opcode_length
= next_field (str
, ',', &str
, last
);
1149 /* Find cpu_flags. */
1150 cpu_flags
= next_field (str
, ',', &str
, last
);
1152 /* Find opcode_modifier. */
1153 opcode_modifier
= next_field (str
, ',', &str
, last
);
1155 /* Remove the first {. */
1156 str
= remove_leading_whitespaces (str
);
1159 str
= remove_leading_whitespaces (str
+ 1);
1163 /* There are at least "X}". */
1167 /* Remove trailing white spaces and }. */
1171 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1180 /* Find operand_types. */
1181 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1185 operand_types
[i
] = NULL
;
1189 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1190 if (*operand_types
[i
] == '0')
1193 operand_types
[i
] = NULL
;
1198 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1199 name
, operands
, base_opcode
, extension_opcode
,
1202 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1204 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1206 fprintf (table
, " { ");
1208 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1210 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1213 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1219 fprintf (table
, ",\n ");
1221 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1224 fprintf (table
, " } },\n");
1227 struct opcode_hash_entry
1229 struct opcode_hash_entry
*next
;
1235 /* Calculate the hash value of an opcode hash entry P. */
1238 opcode_hash_hash (const void *p
)
1240 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1241 return htab_hash_string (entry
->name
);
1244 /* Compare a string Q against an opcode hash entry P. */
1247 opcode_hash_eq (const void *p
, const void *q
)
1249 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1250 const char *name
= (const char *) q
;
1251 return strcmp (name
, entry
->name
) == 0;
1255 process_i386_opcodes (FILE *table
)
1260 char *str
, *p
, *last
, *name
;
1261 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1262 htab_t opcode_hash_table
;
1263 struct opcode_hash_entry
**opcode_array
;
1264 unsigned int opcode_array_size
= 1024;
1267 filename
= "i386-opc.tbl";
1268 fp
= fopen (filename
, "r");
1271 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1275 opcode_array
= (struct opcode_hash_entry
**)
1276 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1278 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1279 opcode_hash_eq
, NULL
,
1282 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1283 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1285 /* Put everything on opcode array. */
1288 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1293 p
= remove_leading_whitespaces (buf
);
1295 /* Skip comments. */
1296 str
= strstr (p
, "//");
1300 /* Remove trailing white spaces. */
1301 remove_trailing_whitespaces (p
);
1306 /* Ignore comments. */
1314 last
= p
+ strlen (p
);
1317 name
= next_field (p
, ',', &str
, last
);
1319 /* Get the slot in hash table. */
1320 hash_slot
= (struct opcode_hash_entry
**)
1321 htab_find_slot_with_hash (opcode_hash_table
, name
,
1322 htab_hash_string (name
),
1325 if (*hash_slot
== NULL
)
1327 /* It is the new one. Put it on opcode array. */
1328 if (i
>= opcode_array_size
)
1330 /* Grow the opcode array when needed. */
1331 opcode_array_size
+= 1024;
1332 opcode_array
= (struct opcode_hash_entry
**)
1333 xrealloc (opcode_array
,
1334 sizeof (*opcode_array
) * opcode_array_size
);
1337 opcode_array
[i
] = (struct opcode_hash_entry
*)
1338 xmalloc (sizeof (struct opcode_hash_entry
));
1339 opcode_array
[i
]->next
= NULL
;
1340 opcode_array
[i
]->name
= xstrdup (name
);
1341 opcode_array
[i
]->opcode
= xstrdup (str
);
1342 opcode_array
[i
]->lineno
= lineno
;
1343 *hash_slot
= opcode_array
[i
];
1348 /* Append it to the existing one. */
1350 while ((*entry
) != NULL
)
1351 entry
= &(*entry
)->next
;
1352 *entry
= (struct opcode_hash_entry
*)
1353 xmalloc (sizeof (struct opcode_hash_entry
));
1354 (*entry
)->next
= NULL
;
1355 (*entry
)->name
= (*hash_slot
)->name
;
1356 (*entry
)->opcode
= xstrdup (str
);
1357 (*entry
)->lineno
= lineno
;
1361 /* Process opcode array. */
1362 for (j
= 0; j
< i
; j
++)
1364 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1368 lineno
= next
->lineno
;
1369 last
= str
+ strlen (str
);
1370 output_i386_opcode (table
, name
, str
, last
, lineno
);
1376 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1378 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1380 process_i386_opcode_modifier (table
, "0", -1);
1382 fprintf (table
, " { ");
1383 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1384 fprintf (table
, " } }\n");
1386 fprintf (table
, "};\n");
1390 process_i386_registers (FILE *table
)
1394 char *str
, *p
, *last
;
1395 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1396 char *dw2_32_num
, *dw2_64_num
;
1399 filename
= "i386-reg.tbl";
1400 fp
= fopen (filename
, "r");
1402 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1405 fprintf (table
, "\n/* i386 register table. */\n\n");
1406 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1410 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1415 p
= remove_leading_whitespaces (buf
);
1417 /* Skip comments. */
1418 str
= strstr (p
, "//");
1422 /* Remove trailing white spaces. */
1423 remove_trailing_whitespaces (p
);
1428 fprintf (table
, "%s\n", p
);
1436 last
= p
+ strlen (p
);
1438 /* Find reg_name. */
1439 reg_name
= next_field (p
, ',', &str
, last
);
1441 /* Find reg_type. */
1442 reg_type
= next_field (str
, ',', &str
, last
);
1444 /* Find reg_flags. */
1445 reg_flags
= next_field (str
, ',', &str
, last
);
1448 reg_num
= next_field (str
, ',', &str
, last
);
1450 fprintf (table
, " { \"%s\",\n ", reg_name
);
1452 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1455 /* Find 32-bit Dwarf2 register number. */
1456 dw2_32_num
= next_field (str
, ',', &str
, last
);
1458 /* Find 64-bit Dwarf2 register number. */
1459 dw2_64_num
= next_field (str
, ',', &str
, last
);
1461 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1462 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1467 fprintf (table
, "};\n");
1469 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1473 process_i386_initializers (void)
1476 FILE *fp
= fopen ("i386-init.h", "w");
1480 fail (_("can't create i386-init.h, errno = %s\n"),
1483 process_copyright (fp
);
1485 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1487 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1488 init
= xstrdup (cpu_flag_init
[i
].init
);
1489 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1493 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1495 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1496 init
= xstrdup (operand_type_init
[i
].init
);
1497 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1505 /* Program options. */
1506 #define OPTION_SRCDIR 200
1508 struct option long_options
[] =
1510 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1511 {"debug", no_argument
, NULL
, 'd'},
1512 {"version", no_argument
, NULL
, 'V'},
1513 {"help", no_argument
, NULL
, 'h'},
1514 {0, no_argument
, NULL
, 0}
1518 print_version (void)
1520 printf ("%s: version 1.0\n", program_name
);
1525 usage (FILE * stream
, int status
)
1527 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1533 main (int argc
, char **argv
)
1535 extern int chdir (char *);
1536 char *srcdir
= NULL
;
1538 unsigned int i
, cpumax
;
1541 program_name
= *argv
;
1542 xmalloc_set_program_name (program_name
);
1544 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1569 if (chdir (srcdir
) != 0)
1570 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1571 srcdir
, xstrerror (errno
));
1573 /* cpu_flags isn't sorted by position. */
1575 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1576 if (cpu_flags
[i
].position
> cpumax
)
1577 cpumax
= cpu_flags
[i
].position
;
1579 /* Check the unused bitfield in i386_cpu_flags. */
1581 if ((cpumax
- 1) != CpuMax
)
1582 fail (_("CpuMax != %d!\n"), cpumax
);
1584 if (cpumax
!= CpuMax
)
1585 fail (_("CpuMax != %d!\n"), cpumax
);
1587 c
= CpuNumOfBits
- CpuMax
- 1;
1589 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1592 /* Check the unused bitfield in i386_operand_type. */
1594 c
= OTNumOfBits
- OTMax
- 1;
1596 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1599 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1602 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1603 sizeof (opcode_modifiers
[0]), compare
);
1605 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1606 sizeof (operand_types
[0]), compare
);
1608 table
= fopen ("i386-tbl.h", "w");
1610 fail (_("can't create i386-tbl.h, errno = %s\n"),
1613 process_copyright (table
);
1615 process_i386_opcodes (table
);
1616 process_i386_registers (table
);
1617 process_i386_initializers ();