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|CpuCMOV|CpuFXSR" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "CPU_I686_FLAGS|CpuNop" },
67 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
69 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
71 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
73 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
75 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
77 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
79 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
83 "CPU_K6_FLAGS|Cpu3dnow" },
85 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
87 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
91 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
95 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
97 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
99 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_ZNVER2_FLAGS",
101 "CPU_ZNVER1_FLAGS|CpuRDPID|CpuWBNOINVD|CpuCLWB" },
102 { "CPU_BTVER1_FLAGS",
103 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
104 { "CPU_BTVER2_FLAGS",
105 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
113 "CPU_387_FLAGS|Cpu687" },
118 { "CPU_CLFLUSH_FLAGS",
122 { "CPU_SYSCALL_FLAGS",
129 "CPU_SSE_FLAGS|CpuSSE2" },
131 "CPU_SSE2_FLAGS|CpuSSE3" },
133 "CPU_SSE3_FLAGS|CpuSSSE3" },
134 { "CPU_SSE4_1_FLAGS",
135 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
136 { "CPU_SSE4_2_FLAGS",
137 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
144 { "CPU_XSAVEOPT_FLAGS",
145 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
147 "CPU_SSE2_FLAGS|CpuAES" },
148 { "CPU_PCLMUL_FLAGS",
149 "CPU_SSE2_FLAGS|CpuPCLMUL" },
151 "CPU_AVX_FLAGS|CpuFMA" },
153 "CPU_AVX_FLAGS|CpuFMA4" },
155 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
157 "CPU_XSAVE_FLAGS|CpuLWP" },
166 { "CPU_RDTSCP_FLAGS",
170 { "CPU_FSGSBASE_FLAGS",
175 "CPU_AVX_FLAGS|CpuF16C" },
184 { "CPU_INVPCID_FLAGS",
186 { "CPU_VMFUNC_FLAGS",
189 "CPU_MMX_FLAGS|Cpu3dnow" },
190 { "CPU_3DNOWA_FLAGS",
191 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
192 { "CPU_PADLOCK_FLAGS",
197 "CPU_SSE3_FLAGS|CpuSSE4a" },
201 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
203 "CPU_AVX_FLAGS|CpuAVX2" },
204 { "CPU_AVX512F_FLAGS",
205 "CPU_AVX2_FLAGS|CpuAVX512F" },
206 { "CPU_AVX512CD_FLAGS",
207 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
208 { "CPU_AVX512ER_FLAGS",
209 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
210 { "CPU_AVX512PF_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
212 { "CPU_AVX512DQ_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
214 { "CPU_AVX512BW_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
216 { "CPU_AVX512VL_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
218 { "CPU_AVX512IFMA_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
220 { "CPU_AVX512VBMI_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
222 { "CPU_AVX512_4FMAPS_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
224 { "CPU_AVX512_4VNNIW_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
226 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
228 { "CPU_AVX512_VBMI2_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
230 { "CPU_AVX512_VNNI_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
232 { "CPU_AVX512_BITALG_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
239 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
242 { "CPU_RDSEED_FLAGS",
244 { "CPU_PRFCHW_FLAGS",
249 "CPU_XSAVE_FLAGS|CpuMPX" },
251 "CPU_SSE2_FLAGS|CpuSHA" },
252 { "CPU_CLFLUSHOPT_FLAGS",
254 { "CPU_XSAVES_FLAGS",
255 "CPU_XSAVE_FLAGS|CpuXSAVES" },
256 { "CPU_XSAVEC_FLAGS",
257 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
258 { "CPU_PREFETCHWT1_FLAGS",
264 { "CPU_CLZERO_FLAGS",
266 { "CPU_MWAITX_FLAGS",
269 "CPU_XSAVE_FLAGS|CpuOSPKE" },
272 { "CPU_PTWRITE_FLAGS",
282 { "CPU_VPCLMULQDQ_FLAGS",
284 { "CPU_WBNOINVD_FLAGS",
286 { "CPU_PCONFIG_FLAGS",
288 { "CPU_WAITPKG_FLAGS",
290 { "CPU_CLDEMOTE_FLAGS",
292 { "CPU_MOVDIRI_FLAGS",
294 { "CPU_MOVDIR64B_FLAGS",
296 { "CPU_ANY_X87_FLAGS",
297 "CPU_ANY_287_FLAGS|Cpu8087" },
298 { "CPU_ANY_287_FLAGS",
299 "CPU_ANY_387_FLAGS|Cpu287" },
300 { "CPU_ANY_387_FLAGS",
301 "CPU_ANY_687_FLAGS|Cpu387" },
302 { "CPU_ANY_687_FLAGS",
303 "Cpu687|CpuFISTTP" },
304 { "CPU_ANY_CMOV_FLAGS",
306 { "CPU_ANY_FXSR_FLAGS",
308 { "CPU_ANY_MMX_FLAGS",
309 "CPU_3DNOWA_FLAGS" },
310 { "CPU_ANY_SSE_FLAGS",
311 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
312 { "CPU_ANY_SSE2_FLAGS",
313 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
314 { "CPU_ANY_SSE3_FLAGS",
315 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
316 { "CPU_ANY_SSSE3_FLAGS",
317 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
318 { "CPU_ANY_SSE4_1_FLAGS",
319 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
320 { "CPU_ANY_SSE4_2_FLAGS",
322 { "CPU_ANY_AVX_FLAGS",
323 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
324 { "CPU_ANY_AVX2_FLAGS",
326 { "CPU_ANY_AVX512F_FLAGS",
327 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG" },
328 { "CPU_ANY_AVX512CD_FLAGS",
330 { "CPU_ANY_AVX512ER_FLAGS",
332 { "CPU_ANY_AVX512PF_FLAGS",
334 { "CPU_ANY_AVX512DQ_FLAGS",
336 { "CPU_ANY_AVX512BW_FLAGS",
338 { "CPU_ANY_AVX512VL_FLAGS",
340 { "CPU_ANY_AVX512IFMA_FLAGS",
342 { "CPU_ANY_AVX512VBMI_FLAGS",
344 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
345 "CpuAVX512_4FMAPS" },
346 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
347 "CpuAVX512_4VNNIW" },
348 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
349 "CpuAVX512_VPOPCNTDQ" },
350 { "CPU_ANY_IBT_FLAGS",
352 { "CPU_ANY_SHSTK_FLAGS",
354 { "CPU_ANY_AVX512_VBMI2_FLAGS",
356 { "CPU_ANY_AVX512_VNNI_FLAGS",
358 { "CPU_ANY_AVX512_BITALG_FLAGS",
359 "CpuAVX512_BITALG" },
360 { "CPU_ANY_MOVDIRI_FLAGS",
362 { "CPU_ANY_MOVDIR64B_FLAGS",
366 static const initializer operand_type_shorthands
[] =
368 { "Reg8", "Reg|Byte" },
369 { "Reg16", "Reg|Word" },
370 { "Reg32", "Reg|Dword" },
371 { "Reg64", "Reg|Qword" },
372 { "FloatAcc", "Acc|Tbyte" },
373 { "FloatReg", "Reg|Tbyte" },
374 { "RegXMM", "RegSIMD|Xmmword" },
375 { "RegYMM", "RegSIMD|Ymmword" },
376 { "RegZMM", "RegSIMD|Zmmword" },
379 static initializer operand_type_init
[] =
381 { "OPERAND_TYPE_NONE",
383 { "OPERAND_TYPE_REG8",
385 { "OPERAND_TYPE_REG16",
387 { "OPERAND_TYPE_REG32",
389 { "OPERAND_TYPE_REG64",
391 { "OPERAND_TYPE_IMM1",
393 { "OPERAND_TYPE_IMM8",
395 { "OPERAND_TYPE_IMM8S",
397 { "OPERAND_TYPE_IMM16",
399 { "OPERAND_TYPE_IMM32",
401 { "OPERAND_TYPE_IMM32S",
403 { "OPERAND_TYPE_IMM64",
405 { "OPERAND_TYPE_BASEINDEX",
407 { "OPERAND_TYPE_DISP8",
409 { "OPERAND_TYPE_DISP16",
411 { "OPERAND_TYPE_DISP32",
413 { "OPERAND_TYPE_DISP32S",
415 { "OPERAND_TYPE_DISP64",
417 { "OPERAND_TYPE_INOUTPORTREG",
419 { "OPERAND_TYPE_SHIFTCOUNT",
421 { "OPERAND_TYPE_CONTROL",
423 { "OPERAND_TYPE_TEST",
425 { "OPERAND_TYPE_DEBUG",
427 { "OPERAND_TYPE_FLOATREG",
429 { "OPERAND_TYPE_FLOATACC",
431 { "OPERAND_TYPE_SREG2",
433 { "OPERAND_TYPE_SREG3",
435 { "OPERAND_TYPE_ACC",
437 { "OPERAND_TYPE_JUMPABSOLUTE",
439 { "OPERAND_TYPE_REGMMX",
441 { "OPERAND_TYPE_REGXMM",
443 { "OPERAND_TYPE_REGYMM",
445 { "OPERAND_TYPE_REGZMM",
447 { "OPERAND_TYPE_REGMASK",
449 { "OPERAND_TYPE_ESSEG",
451 { "OPERAND_TYPE_ACC32",
453 { "OPERAND_TYPE_ACC64",
455 { "OPERAND_TYPE_DISP16_32",
457 { "OPERAND_TYPE_ANYDISP",
458 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
459 { "OPERAND_TYPE_IMM16_32",
461 { "OPERAND_TYPE_IMM16_32S",
463 { "OPERAND_TYPE_IMM16_32_32S",
464 "Imm16|Imm32|Imm32S" },
465 { "OPERAND_TYPE_IMM32_64",
467 { "OPERAND_TYPE_IMM32_32S_DISP32",
468 "Imm32|Imm32S|Disp32" },
469 { "OPERAND_TYPE_IMM64_DISP64",
471 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
472 "Imm32|Imm32S|Imm64|Disp32" },
473 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
474 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
475 { "OPERAND_TYPE_VEC_IMM4",
477 { "OPERAND_TYPE_REGBND",
481 typedef struct bitfield
488 #define BITFIELD(n) { n, 0, #n }
490 static bitfield cpu_flags
[] =
500 BITFIELD (CpuClflush
),
502 BITFIELD (CpuSYSCALL
),
507 BITFIELD (CpuFISTTP
),
513 BITFIELD (CpuSSE4_1
),
514 BITFIELD (CpuSSE4_2
),
517 BITFIELD (CpuAVX512F
),
518 BITFIELD (CpuAVX512CD
),
519 BITFIELD (CpuAVX512ER
),
520 BITFIELD (CpuAVX512PF
),
521 BITFIELD (CpuAVX512VL
),
522 BITFIELD (CpuAVX512DQ
),
523 BITFIELD (CpuAVX512BW
),
529 BITFIELD (Cpu3dnowA
),
530 BITFIELD (CpuPadLock
),
536 BITFIELD (CpuXsaveopt
),
538 BITFIELD (CpuPCLMUL
),
549 BITFIELD (CpuRdtscp
),
550 BITFIELD (CpuFSGSBase
),
557 BITFIELD (CpuINVPCID
),
558 BITFIELD (CpuVMFUNC
),
559 BITFIELD (CpuRDSEED
),
561 BITFIELD (CpuPRFCHW
),
564 BITFIELD (CpuClflushOpt
),
565 BITFIELD (CpuXSAVES
),
566 BITFIELD (CpuXSAVEC
),
567 BITFIELD (CpuPREFETCHWT1
),
573 BITFIELD (CpuAVX512IFMA
),
574 BITFIELD (CpuAVX512VBMI
),
575 BITFIELD (CpuAVX512_4FMAPS
),
576 BITFIELD (CpuAVX512_4VNNIW
),
577 BITFIELD (CpuAVX512_VPOPCNTDQ
),
578 BITFIELD (CpuAVX512_VBMI2
),
579 BITFIELD (CpuAVX512_VNNI
),
580 BITFIELD (CpuAVX512_BITALG
),
581 BITFIELD (CpuMWAITX
),
582 BITFIELD (CpuCLZERO
),
585 BITFIELD (CpuPTWRITE
),
590 BITFIELD (CpuVPCLMULQDQ
),
591 BITFIELD (CpuWBNOINVD
),
592 BITFIELD (CpuPCONFIG
),
593 BITFIELD (CpuWAITPKG
),
594 BITFIELD (CpuCLDEMOTE
),
595 BITFIELD (CpuMOVDIRI
),
596 BITFIELD (CpuMOVDIR64B
),
598 BITFIELD (CpuUnused
),
602 static bitfield opcode_modifiers
[] =
608 BITFIELD (ShortForm
),
610 BITFIELD (JumpDword
),
612 BITFIELD (JumpInterSegment
),
618 BITFIELD (CheckRegSize
),
619 BITFIELD (IgnoreSize
),
620 BITFIELD (DefaultSize
),
629 BITFIELD (BNDPrefixOk
),
630 BITFIELD (NoTrackPrefixOk
),
631 BITFIELD (IsLockable
),
632 BITFIELD (RegKludge
),
633 BITFIELD (Implicit1stXmm0
),
634 BITFIELD (RepPrefixOk
),
635 BITFIELD (HLEPrefixOk
),
638 BITFIELD (AddrPrefixOpReg
),
647 BITFIELD (VexOpcode
),
648 BITFIELD (VexSources
),
654 BITFIELD (Broadcast
),
655 BITFIELD (StaticRounding
),
657 BITFIELD (Disp8MemShift
),
658 BITFIELD (NoDefMask
),
659 BITFIELD (ImplicitQuadGroup
),
661 BITFIELD (ATTMnemonic
),
662 BITFIELD (ATTSyntax
),
663 BITFIELD (IntelSyntax
),
668 static bitfield operand_types
[] =
681 BITFIELD (BaseIndex
),
687 BITFIELD (InOutPortReg
),
688 BITFIELD (ShiftCount
),
695 BITFIELD (JumpAbsolute
),
707 BITFIELD (Unspecified
),
716 static const char *filename
;
717 static i386_cpu_flags active_cpu_flags
;
718 static int active_isstring
;
721 compare (const void *x
, const void *y
)
723 const bitfield
*xp
= (const bitfield
*) x
;
724 const bitfield
*yp
= (const bitfield
*) y
;
725 return xp
->position
- yp
->position
;
729 fail (const char *message
, ...)
733 va_start (args
, message
);
734 fprintf (stderr
, _("%s: error: "), program_name
);
735 vfprintf (stderr
, message
, args
);
741 process_copyright (FILE *fp
)
743 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
744 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
746 This file is part of the GNU opcodes library.\n\
748 This library is free software; you can redistribute it and/or modify\n\
749 it under the terms of the GNU General Public License as published by\n\
750 the Free Software Foundation; either version 3, or (at your option)\n\
751 any later version.\n\
753 It is distributed in the hope that it will be useful, but WITHOUT\n\
754 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
755 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
756 License for more details.\n\
758 You should have received a copy of the GNU General Public License\n\
759 along with this program; if not, write to the Free Software\n\
760 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
761 MA 02110-1301, USA. */\n");
764 /* Remove leading white spaces. */
767 remove_leading_whitespaces (char *str
)
769 while (ISSPACE (*str
))
774 /* Remove trailing white spaces. */
777 remove_trailing_whitespaces (char *str
)
779 size_t last
= strlen (str
);
787 if (ISSPACE (str
[last
]))
795 /* Find next field separated by SEP and terminate it. Return a
796 pointer to the one after it. */
799 next_field (char *str
, char sep
, char **next
, char *last
)
803 p
= remove_leading_whitespaces (str
);
804 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
807 remove_trailing_whitespaces (p
);
817 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
820 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
823 char *str
, *next
, *last
;
826 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
827 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
829 /* Turn on selective bits. */
830 char *init
= xstrdup (cpu_flag_init
[i
].init
);
831 last
= init
+ strlen (init
);
832 for (next
= init
; next
&& next
< last
; )
834 str
= next_field (next
, '|', &next
, last
);
836 set_bitfield (str
, array
, 1, size
, lineno
);
842 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
843 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
845 /* Turn on selective bits. */
846 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
847 last
= init
+ strlen (init
);
848 for (next
= init
; next
&& next
< last
; )
850 str
= next_field (next
, '|', &next
, last
);
852 set_bitfield (str
, array
, 1, size
, lineno
);
862 set_bitfield (char *f
, bitfield
*array
, int value
,
863 unsigned int size
, int lineno
)
867 if (strcmp (f
, "CpuFP") == 0)
869 set_bitfield("Cpu387", array
, value
, size
, lineno
);
870 set_bitfield("Cpu287", array
, value
, size
, lineno
);
873 else if (strcmp (f
, "Mmword") == 0)
875 else if (strcmp (f
, "Oword") == 0)
878 for (i
= 0; i
< size
; i
++)
879 if (strcasecmp (array
[i
].name
, f
) == 0)
881 array
[i
].value
= value
;
887 const char *v
= strchr (f
, '=');
894 for (i
= 0; i
< size
; i
++)
895 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
897 value
= strtol (v
+ 1, &end
, 0);
900 array
[i
].value
= value
;
908 /* Handle shorthands. */
909 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
913 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
915 fail (_("unknown bitfield: %s\n"), f
);
919 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
920 int macro
, const char *comma
, const char *indent
)
924 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
926 fprintf (table
, "%s{ { ", indent
);
928 for (i
= 0; i
< size
- 1; i
++)
930 if (((i
+ 1) % 20) != 0)
931 fprintf (table
, "%d, ", flags
[i
].value
);
933 fprintf (table
, "%d,", flags
[i
].value
);
934 if (((i
+ 1) % 20) == 0)
936 /* We need \\ for macro. */
938 fprintf (table
, " \\\n %s", indent
);
940 fprintf (table
, "\n %s", indent
);
943 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
946 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
950 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
951 const char *comma
, const char *indent
,
954 char *str
, *next
, *last
;
956 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
958 /* Copy the default cpu flags. */
959 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
961 if (strcasecmp (flag
, "unknown") == 0)
963 /* We turn on everything except for cpu64 in case of
964 CPU_UNKNOWN_FLAGS. */
965 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
966 if (flags
[i
].position
!= Cpu64
)
969 else if (flag
[0] == '~')
971 last
= flag
+ strlen (flag
);
978 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
985 /* First we turn on everything except for cpu64. */
986 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
987 if (flags
[i
].position
!= Cpu64
)
990 /* Turn off selective bits. */
991 for (; next
&& next
< last
; )
993 str
= next_field (next
, '|', &next
, last
);
995 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
998 else if (strcmp (flag
, "0"))
1000 /* Turn on selective bits. */
1001 last
= flag
+ strlen (flag
);
1002 for (next
= flag
; next
&& next
< last
; )
1004 str
= next_field (next
, '|', &next
, last
);
1006 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1010 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1015 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1019 fprintf (table
, " { ");
1021 for (i
= 0; i
< size
- 1; i
++)
1023 if (((i
+ 1) % 20) != 0)
1024 fprintf (table
, "%d, ", modifier
[i
].value
);
1026 fprintf (table
, "%d,", modifier
[i
].value
);
1027 if (((i
+ 1) % 20) == 0)
1028 fprintf (table
, "\n ");
1031 fprintf (table
, "%d },\n", modifier
[i
].value
);
1035 adjust_broadcast_modifier (char **opnd
)
1037 char *str
, *next
, *last
, *op
;
1038 int bcst_type
= INT_MAX
;
1040 /* Skip the immediate operand. */
1042 if (strcasecmp(op
, "Imm8") == 0)
1046 last
= op
+ strlen (op
);
1047 for (next
= op
; next
&& next
< last
; )
1049 str
= next_field (next
, '|', &next
, last
);
1052 if (strcasecmp(str
, "Byte") == 0)
1054 /* The smalest broadcast type, no need to check
1056 bcst_type
= BYTE_BROADCAST
;
1059 else if (strcasecmp(str
, "Word") == 0)
1061 if (bcst_type
> WORD_BROADCAST
)
1062 bcst_type
= WORD_BROADCAST
;
1064 else if (strcasecmp(str
, "Dword") == 0)
1066 if (bcst_type
> DWORD_BROADCAST
)
1067 bcst_type
= DWORD_BROADCAST
;
1069 else if (strcasecmp(str
, "Qword") == 0)
1071 if (bcst_type
> QWORD_BROADCAST
)
1072 bcst_type
= QWORD_BROADCAST
;
1078 if (bcst_type
== INT_MAX
)
1079 fail (_("unknown broadcast operand: %s\n"), op
);
1085 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1087 char *str
, *next
, *last
;
1088 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1090 active_isstring
= 0;
1092 /* Copy the default opcode modifier. */
1093 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1095 if (strcmp (mod
, "0"))
1097 last
= mod
+ strlen (mod
);
1098 for (next
= mod
; next
&& next
< last
; )
1100 str
= next_field (next
, '|', &next
, last
);
1104 if (strcasecmp(str
, "Broadcast") == 0)
1105 val
= adjust_broadcast_modifier (opnd
);
1106 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1108 if (strcasecmp(str
, "IsString") == 0)
1109 active_isstring
= 1;
1113 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1123 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1124 enum stage stage
, const char *indent
)
1128 fprintf (table
, "{ { ");
1130 for (i
= 0; i
< size
- 1; i
++)
1132 if (((i
+ 1) % 20) != 0)
1133 fprintf (table
, "%d, ", types
[i
].value
);
1135 fprintf (table
, "%d,", types
[i
].value
);
1136 if (((i
+ 1) % 20) == 0)
1138 /* We need \\ for macro. */
1139 if (stage
== stage_macros
)
1140 fprintf (table
, " \\\n%s", indent
);
1142 fprintf (table
, "\n%s", indent
);
1146 fprintf (table
, "%d } }", types
[i
].value
);
1150 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1151 const char *indent
, int lineno
)
1153 char *str
, *next
, *last
;
1154 bitfield types
[ARRAY_SIZE (operand_types
)];
1156 /* Copy the default operand type. */
1157 memcpy (types
, operand_types
, sizeof (types
));
1159 if (strcmp (op
, "0"))
1163 last
= op
+ strlen (op
);
1164 for (next
= op
; next
&& next
< last
; )
1166 str
= next_field (next
, '|', &next
, last
);
1169 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1170 if (strcasecmp(str
, "BaseIndex") == 0)
1175 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1177 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1178 if (!active_cpu_flags
.bitfield
.cpu64
1179 && !active_cpu_flags
.bitfield
.cpumpx
)
1180 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1181 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1182 if (!active_cpu_flags
.bitfield
.cpuno64
)
1183 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1186 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1191 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1192 char *last
, int lineno
)
1195 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1196 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1198 /* Find number of operands. */
1199 operands
= next_field (str
, ',', &str
, last
);
1201 /* Find base_opcode. */
1202 base_opcode
= next_field (str
, ',', &str
, last
);
1204 /* Find extension_opcode. */
1205 extension_opcode
= next_field (str
, ',', &str
, last
);
1207 /* Find opcode_length. */
1208 opcode_length
= next_field (str
, ',', &str
, last
);
1210 /* Find cpu_flags. */
1211 cpu_flags
= next_field (str
, ',', &str
, last
);
1213 /* Find opcode_modifier. */
1214 opcode_modifier
= next_field (str
, ',', &str
, last
);
1216 /* Remove the first {. */
1217 str
= remove_leading_whitespaces (str
);
1220 str
= remove_leading_whitespaces (str
+ 1);
1224 /* There are at least "X}". */
1228 /* Remove trailing white spaces and }. */
1232 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1241 /* Find operand_types. */
1242 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1246 operand_types
[i
] = NULL
;
1250 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1251 if (*operand_types
[i
] == '0')
1254 operand_types
[i
] = NULL
;
1259 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1260 name
, operands
, base_opcode
, extension_opcode
,
1263 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1265 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1267 fprintf (table
, " { ");
1269 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1271 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1274 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1280 fprintf (table
, ",\n ");
1282 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1285 fprintf (table
, " } },\n");
1288 struct opcode_hash_entry
1290 struct opcode_hash_entry
*next
;
1296 /* Calculate the hash value of an opcode hash entry P. */
1299 opcode_hash_hash (const void *p
)
1301 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1302 return htab_hash_string (entry
->name
);
1305 /* Compare a string Q against an opcode hash entry P. */
1308 opcode_hash_eq (const void *p
, const void *q
)
1310 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1311 const char *name
= (const char *) q
;
1312 return strcmp (name
, entry
->name
) == 0;
1316 process_i386_opcodes (FILE *table
)
1321 char *str
, *p
, *last
, *name
;
1322 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1323 htab_t opcode_hash_table
;
1324 struct opcode_hash_entry
**opcode_array
;
1325 unsigned int opcode_array_size
= 1024;
1326 int lineno
= 0, marker
= 0;
1328 filename
= "i386-opc.tbl";
1332 opcode_array
= (struct opcode_hash_entry
**)
1333 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1335 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1336 opcode_hash_eq
, NULL
,
1339 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1340 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1342 /* Put everything on opcode array. */
1345 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1350 p
= remove_leading_whitespaces (buf
);
1352 /* Skip comments. */
1353 str
= strstr (p
, "//");
1357 /* Remove trailing white spaces. */
1358 remove_trailing_whitespaces (p
);
1363 if (!strcmp("### MARKER ###", buf
))
1367 /* Since we ignore all included files (we only care about their
1368 #define-s here), we don't need to monitor filenames. The final
1369 line number directive is going to refer to the main source file
1374 p
= remove_leading_whitespaces (p
+ 1);
1375 if (!strncmp(p
, "line", 4))
1377 ln
= strtoul (p
, &end
, 10);
1378 if (ln
> 1 && ln
< INT_MAX
1379 && *remove_leading_whitespaces (end
) == '"')
1382 /* Ignore comments. */
1392 last
= p
+ strlen (p
);
1395 name
= next_field (p
, ',', &str
, last
);
1397 /* Get the slot in hash table. */
1398 hash_slot
= (struct opcode_hash_entry
**)
1399 htab_find_slot_with_hash (opcode_hash_table
, name
,
1400 htab_hash_string (name
),
1403 if (*hash_slot
== NULL
)
1405 /* It is the new one. Put it on opcode array. */
1406 if (i
>= opcode_array_size
)
1408 /* Grow the opcode array when needed. */
1409 opcode_array_size
+= 1024;
1410 opcode_array
= (struct opcode_hash_entry
**)
1411 xrealloc (opcode_array
,
1412 sizeof (*opcode_array
) * opcode_array_size
);
1415 opcode_array
[i
] = (struct opcode_hash_entry
*)
1416 xmalloc (sizeof (struct opcode_hash_entry
));
1417 opcode_array
[i
]->next
= NULL
;
1418 opcode_array
[i
]->name
= xstrdup (name
);
1419 opcode_array
[i
]->opcode
= xstrdup (str
);
1420 opcode_array
[i
]->lineno
= lineno
;
1421 *hash_slot
= opcode_array
[i
];
1426 /* Append it to the existing one. */
1428 while ((*entry
) != NULL
)
1429 entry
= &(*entry
)->next
;
1430 *entry
= (struct opcode_hash_entry
*)
1431 xmalloc (sizeof (struct opcode_hash_entry
));
1432 (*entry
)->next
= NULL
;
1433 (*entry
)->name
= (*hash_slot
)->name
;
1434 (*entry
)->opcode
= xstrdup (str
);
1435 (*entry
)->lineno
= lineno
;
1439 /* Process opcode array. */
1440 for (j
= 0; j
< i
; j
++)
1442 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1446 lineno
= next
->lineno
;
1447 last
= str
+ strlen (str
);
1448 output_i386_opcode (table
, name
, str
, last
, lineno
);
1454 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1456 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1458 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1460 fprintf (table
, " { ");
1461 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1462 fprintf (table
, " } }\n");
1464 fprintf (table
, "};\n");
1468 process_i386_registers (FILE *table
)
1472 char *str
, *p
, *last
;
1473 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1474 char *dw2_32_num
, *dw2_64_num
;
1477 filename
= "i386-reg.tbl";
1478 fp
= fopen (filename
, "r");
1480 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1483 fprintf (table
, "\n/* i386 register table. */\n\n");
1484 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1488 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1493 p
= remove_leading_whitespaces (buf
);
1495 /* Skip comments. */
1496 str
= strstr (p
, "//");
1500 /* Remove trailing white spaces. */
1501 remove_trailing_whitespaces (p
);
1506 fprintf (table
, "%s\n", p
);
1514 last
= p
+ strlen (p
);
1516 /* Find reg_name. */
1517 reg_name
= next_field (p
, ',', &str
, last
);
1519 /* Find reg_type. */
1520 reg_type
= next_field (str
, ',', &str
, last
);
1522 /* Find reg_flags. */
1523 reg_flags
= next_field (str
, ',', &str
, last
);
1526 reg_num
= next_field (str
, ',', &str
, last
);
1528 fprintf (table
, " { \"%s\",\n ", reg_name
);
1530 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1533 /* Find 32-bit Dwarf2 register number. */
1534 dw2_32_num
= next_field (str
, ',', &str
, last
);
1536 /* Find 64-bit Dwarf2 register number. */
1537 dw2_64_num
= next_field (str
, ',', &str
, last
);
1539 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1540 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1545 fprintf (table
, "};\n");
1547 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1551 process_i386_initializers (void)
1554 FILE *fp
= fopen ("i386-init.h", "w");
1558 fail (_("can't create i386-init.h, errno = %s\n"),
1561 process_copyright (fp
);
1563 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1565 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1566 init
= xstrdup (cpu_flag_init
[i
].init
);
1567 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1571 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1573 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1574 init
= xstrdup (operand_type_init
[i
].init
);
1575 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1583 /* Program options. */
1584 #define OPTION_SRCDIR 200
1586 struct option long_options
[] =
1588 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1589 {"debug", no_argument
, NULL
, 'd'},
1590 {"version", no_argument
, NULL
, 'V'},
1591 {"help", no_argument
, NULL
, 'h'},
1592 {0, no_argument
, NULL
, 0}
1596 print_version (void)
1598 printf ("%s: version 1.0\n", program_name
);
1603 usage (FILE * stream
, int status
)
1605 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1611 main (int argc
, char **argv
)
1613 extern int chdir (char *);
1614 char *srcdir
= NULL
;
1616 unsigned int i
, cpumax
;
1619 program_name
= *argv
;
1620 xmalloc_set_program_name (program_name
);
1622 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1647 if (chdir (srcdir
) != 0)
1648 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1649 srcdir
, xstrerror (errno
));
1651 /* cpu_flags isn't sorted by position. */
1653 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1654 if (cpu_flags
[i
].position
> cpumax
)
1655 cpumax
= cpu_flags
[i
].position
;
1657 /* Check the unused bitfield in i386_cpu_flags. */
1659 if ((cpumax
- 1) != CpuMax
)
1660 fail (_("CpuMax != %d!\n"), cpumax
);
1662 if (cpumax
!= CpuMax
)
1663 fail (_("CpuMax != %d!\n"), cpumax
);
1665 c
= CpuNumOfBits
- CpuMax
- 1;
1667 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1670 /* Check the unused bitfield in i386_operand_type. */
1672 c
= OTNumOfBits
- OTMax
- 1;
1674 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1677 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1680 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1681 sizeof (opcode_modifiers
[0]), compare
);
1683 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1684 sizeof (operand_types
[0]), compare
);
1686 table
= fopen ("i386-tbl.h", "w");
1688 fail (_("can't create i386-tbl.h, errno = %s\n"),
1691 process_copyright (table
);
1693 process_i386_opcodes (table
);
1694 process_i386_registers (table
);
1695 process_i386_initializers ();