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|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 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG" },
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
),
554 BITFIELD (CpuClflushOpt
),
555 BITFIELD (CpuXSAVES
),
556 BITFIELD (CpuXSAVEC
),
557 BITFIELD (CpuPREFETCHWT1
),
563 BITFIELD (CpuAVX512IFMA
),
564 BITFIELD (CpuAVX512VBMI
),
565 BITFIELD (CpuAVX512_4FMAPS
),
566 BITFIELD (CpuAVX512_4VNNIW
),
567 BITFIELD (CpuAVX512_VPOPCNTDQ
),
568 BITFIELD (CpuAVX512_VBMI2
),
569 BITFIELD (CpuAVX512_VNNI
),
570 BITFIELD (CpuAVX512_BITALG
),
571 BITFIELD (CpuMWAITX
),
572 BITFIELD (CpuCLZERO
),
575 BITFIELD (CpuPTWRITE
),
580 BITFIELD (CpuVPCLMULQDQ
),
581 BITFIELD (CpuWBNOINVD
),
582 BITFIELD (CpuPCONFIG
),
583 BITFIELD (CpuWAITPKG
),
584 BITFIELD (CpuCLDEMOTE
),
585 BITFIELD (CpuMOVDIRI
),
586 BITFIELD (CpuMOVDIR64B
),
588 BITFIELD (CpuUnused
),
592 static bitfield opcode_modifiers
[] =
598 BITFIELD (ShortForm
),
600 BITFIELD (JumpDword
),
602 BITFIELD (JumpInterSegment
),
608 BITFIELD (CheckRegSize
),
609 BITFIELD (IgnoreSize
),
610 BITFIELD (DefaultSize
),
619 BITFIELD (BNDPrefixOk
),
620 BITFIELD (NoTrackPrefixOk
),
621 BITFIELD (IsLockable
),
622 BITFIELD (RegKludge
),
623 BITFIELD (Implicit1stXmm0
),
624 BITFIELD (RepPrefixOk
),
625 BITFIELD (HLEPrefixOk
),
628 BITFIELD (AddrPrefixOpReg
),
637 BITFIELD (VexOpcode
),
638 BITFIELD (VexSources
),
644 BITFIELD (Broadcast
),
645 BITFIELD (StaticRounding
),
647 BITFIELD (Disp8MemShift
),
648 BITFIELD (NoDefMask
),
649 BITFIELD (ImplicitQuadGroup
),
651 BITFIELD (ATTMnemonic
),
652 BITFIELD (ATTSyntax
),
653 BITFIELD (IntelSyntax
),
658 static bitfield operand_types
[] =
671 BITFIELD (BaseIndex
),
677 BITFIELD (InOutPortReg
),
678 BITFIELD (ShiftCount
),
685 BITFIELD (JumpAbsolute
),
697 BITFIELD (Unspecified
),
706 static const char *filename
;
707 static i386_cpu_flags active_cpu_flags
;
708 static int active_isstring
;
711 compare (const void *x
, const void *y
)
713 const bitfield
*xp
= (const bitfield
*) x
;
714 const bitfield
*yp
= (const bitfield
*) y
;
715 return xp
->position
- yp
->position
;
719 fail (const char *message
, ...)
723 va_start (args
, message
);
724 fprintf (stderr
, _("%s: error: "), program_name
);
725 vfprintf (stderr
, message
, args
);
731 process_copyright (FILE *fp
)
733 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
734 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
736 This file is part of the GNU opcodes library.\n\
738 This library is free software; you can redistribute it and/or modify\n\
739 it under the terms of the GNU General Public License as published by\n\
740 the Free Software Foundation; either version 3, or (at your option)\n\
741 any later version.\n\
743 It is distributed in the hope that it will be useful, but WITHOUT\n\
744 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
745 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
746 License for more details.\n\
748 You should have received a copy of the GNU General Public License\n\
749 along with this program; if not, write to the Free Software\n\
750 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
751 MA 02110-1301, USA. */\n");
754 /* Remove leading white spaces. */
757 remove_leading_whitespaces (char *str
)
759 while (ISSPACE (*str
))
764 /* Remove trailing white spaces. */
767 remove_trailing_whitespaces (char *str
)
769 size_t last
= strlen (str
);
777 if (ISSPACE (str
[last
]))
785 /* Find next field separated by SEP and terminate it. Return a
786 pointer to the one after it. */
789 next_field (char *str
, char sep
, char **next
, char *last
)
793 p
= remove_leading_whitespaces (str
);
794 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
797 remove_trailing_whitespaces (p
);
807 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
810 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
813 char *str
, *next
, *last
;
816 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
817 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
819 /* Turn on selective bits. */
820 char *init
= xstrdup (cpu_flag_init
[i
].init
);
821 last
= init
+ strlen (init
);
822 for (next
= init
; next
&& next
< last
; )
824 str
= next_field (next
, '|', &next
, last
);
826 set_bitfield (str
, array
, 1, size
, lineno
);
832 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
833 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
835 /* Turn on selective bits. */
836 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
837 last
= init
+ strlen (init
);
838 for (next
= init
; next
&& next
< last
; )
840 str
= next_field (next
, '|', &next
, last
);
842 set_bitfield (str
, array
, 1, size
, lineno
);
852 set_bitfield (char *f
, bitfield
*array
, int value
,
853 unsigned int size
, int lineno
)
857 if (strcmp (f
, "CpuFP") == 0)
859 set_bitfield("Cpu387", array
, value
, size
, lineno
);
860 set_bitfield("Cpu287", array
, value
, size
, lineno
);
863 else if (strcmp (f
, "Mmword") == 0)
865 else if (strcmp (f
, "Oword") == 0)
868 for (i
= 0; i
< size
; i
++)
869 if (strcasecmp (array
[i
].name
, f
) == 0)
871 array
[i
].value
= value
;
877 const char *v
= strchr (f
, '=');
884 for (i
= 0; i
< size
; i
++)
885 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
887 value
= strtol (v
+ 1, &end
, 0);
890 array
[i
].value
= value
;
898 /* Handle shorthands. */
899 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
903 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
905 fail (_("unknown bitfield: %s\n"), f
);
909 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
910 int macro
, const char *comma
, const char *indent
)
914 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
916 fprintf (table
, "%s{ { ", indent
);
918 for (i
= 0; i
< size
- 1; i
++)
920 if (((i
+ 1) % 20) != 0)
921 fprintf (table
, "%d, ", flags
[i
].value
);
923 fprintf (table
, "%d,", flags
[i
].value
);
924 if (((i
+ 1) % 20) == 0)
926 /* We need \\ for macro. */
928 fprintf (table
, " \\\n %s", indent
);
930 fprintf (table
, "\n %s", indent
);
933 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
936 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
940 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
941 const char *comma
, const char *indent
,
944 char *str
, *next
, *last
;
946 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
948 /* Copy the default cpu flags. */
949 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
951 if (strcasecmp (flag
, "unknown") == 0)
953 /* We turn on everything except for cpu64 in case of
954 CPU_UNKNOWN_FLAGS. */
955 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
956 if (flags
[i
].position
!= Cpu64
)
959 else if (flag
[0] == '~')
961 last
= flag
+ strlen (flag
);
968 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
975 /* First we turn on everything except for cpu64. */
976 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
977 if (flags
[i
].position
!= Cpu64
)
980 /* Turn off selective bits. */
981 for (; next
&& next
< last
; )
983 str
= next_field (next
, '|', &next
, last
);
985 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
988 else if (strcmp (flag
, "0"))
990 /* Turn on selective bits. */
991 last
= flag
+ strlen (flag
);
992 for (next
= flag
; next
&& next
< last
; )
994 str
= next_field (next
, '|', &next
, last
);
996 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1000 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1005 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1009 fprintf (table
, " { ");
1011 for (i
= 0; i
< size
- 1; i
++)
1013 if (((i
+ 1) % 20) != 0)
1014 fprintf (table
, "%d, ", modifier
[i
].value
);
1016 fprintf (table
, "%d,", modifier
[i
].value
);
1017 if (((i
+ 1) % 20) == 0)
1018 fprintf (table
, "\n ");
1021 fprintf (table
, "%d },\n", modifier
[i
].value
);
1025 adjust_broadcast_modifier (char **opnd
)
1027 char *str
, *next
, *last
, *op
;
1028 int bcst_type
= INT_MAX
;
1030 /* Skip the immediate operand. */
1032 if (strcasecmp(op
, "Imm8") == 0)
1036 last
= op
+ strlen (op
);
1037 for (next
= op
; next
&& next
< last
; )
1039 str
= next_field (next
, '|', &next
, last
);
1042 if (strcasecmp(str
, "Byte") == 0)
1044 /* The smalest broadcast type, no need to check
1046 bcst_type
= BYTE_BROADCAST
;
1049 else if (strcasecmp(str
, "Word") == 0)
1051 if (bcst_type
> WORD_BROADCAST
)
1052 bcst_type
= WORD_BROADCAST
;
1054 else if (strcasecmp(str
, "Dword") == 0)
1056 if (bcst_type
> DWORD_BROADCAST
)
1057 bcst_type
= DWORD_BROADCAST
;
1059 else if (strcasecmp(str
, "Qword") == 0)
1061 if (bcst_type
> QWORD_BROADCAST
)
1062 bcst_type
= QWORD_BROADCAST
;
1068 if (bcst_type
== INT_MAX
)
1069 fail (_("unknown broadcast operand: %s\n"), op
);
1075 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1077 char *str
, *next
, *last
;
1078 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1080 active_isstring
= 0;
1082 /* Copy the default opcode modifier. */
1083 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1085 if (strcmp (mod
, "0"))
1087 last
= mod
+ strlen (mod
);
1088 for (next
= mod
; next
&& next
< last
; )
1090 str
= next_field (next
, '|', &next
, last
);
1094 if (strcasecmp(str
, "Broadcast") == 0)
1095 val
= adjust_broadcast_modifier (opnd
);
1096 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1098 if (strcasecmp(str
, "IsString") == 0)
1099 active_isstring
= 1;
1103 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1113 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1114 enum stage stage
, const char *indent
)
1118 fprintf (table
, "{ { ");
1120 for (i
= 0; i
< size
- 1; i
++)
1122 if (((i
+ 1) % 20) != 0)
1123 fprintf (table
, "%d, ", types
[i
].value
);
1125 fprintf (table
, "%d,", types
[i
].value
);
1126 if (((i
+ 1) % 20) == 0)
1128 /* We need \\ for macro. */
1129 if (stage
== stage_macros
)
1130 fprintf (table
, " \\\n%s", indent
);
1132 fprintf (table
, "\n%s", indent
);
1136 fprintf (table
, "%d } }", types
[i
].value
);
1140 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1141 const char *indent
, int lineno
)
1143 char *str
, *next
, *last
;
1144 bitfield types
[ARRAY_SIZE (operand_types
)];
1146 /* Copy the default operand type. */
1147 memcpy (types
, operand_types
, sizeof (types
));
1149 if (strcmp (op
, "0"))
1153 last
= op
+ strlen (op
);
1154 for (next
= op
; next
&& next
< last
; )
1156 str
= next_field (next
, '|', &next
, last
);
1159 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1160 if (strcasecmp(str
, "BaseIndex") == 0)
1165 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1167 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1168 if (!active_cpu_flags
.bitfield
.cpu64
1169 && !active_cpu_flags
.bitfield
.cpumpx
)
1170 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1171 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1172 if (!active_cpu_flags
.bitfield
.cpuno64
)
1173 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1176 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1181 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1182 char *last
, int lineno
)
1185 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1186 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1188 /* Find number of operands. */
1189 operands
= next_field (str
, ',', &str
, last
);
1191 /* Find base_opcode. */
1192 base_opcode
= next_field (str
, ',', &str
, last
);
1194 /* Find extension_opcode. */
1195 extension_opcode
= next_field (str
, ',', &str
, last
);
1197 /* Find opcode_length. */
1198 opcode_length
= next_field (str
, ',', &str
, last
);
1200 /* Find cpu_flags. */
1201 cpu_flags
= next_field (str
, ',', &str
, last
);
1203 /* Find opcode_modifier. */
1204 opcode_modifier
= next_field (str
, ',', &str
, last
);
1206 /* Remove the first {. */
1207 str
= remove_leading_whitespaces (str
);
1210 str
= remove_leading_whitespaces (str
+ 1);
1214 /* There are at least "X}". */
1218 /* Remove trailing white spaces and }. */
1222 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1231 /* Find operand_types. */
1232 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1236 operand_types
[i
] = NULL
;
1240 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1241 if (*operand_types
[i
] == '0')
1244 operand_types
[i
] = NULL
;
1249 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1250 name
, operands
, base_opcode
, extension_opcode
,
1253 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1255 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1257 fprintf (table
, " { ");
1259 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1261 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1264 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1270 fprintf (table
, ",\n ");
1272 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1275 fprintf (table
, " } },\n");
1278 struct opcode_hash_entry
1280 struct opcode_hash_entry
*next
;
1286 /* Calculate the hash value of an opcode hash entry P. */
1289 opcode_hash_hash (const void *p
)
1291 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1292 return htab_hash_string (entry
->name
);
1295 /* Compare a string Q against an opcode hash entry P. */
1298 opcode_hash_eq (const void *p
, const void *q
)
1300 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1301 const char *name
= (const char *) q
;
1302 return strcmp (name
, entry
->name
) == 0;
1306 process_i386_opcodes (FILE *table
)
1311 char *str
, *p
, *last
, *name
;
1312 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1313 htab_t opcode_hash_table
;
1314 struct opcode_hash_entry
**opcode_array
;
1315 unsigned int opcode_array_size
= 1024;
1316 int lineno
= 0, marker
= 0;
1318 filename
= "i386-opc.tbl";
1322 opcode_array
= (struct opcode_hash_entry
**)
1323 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1325 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1326 opcode_hash_eq
, NULL
,
1329 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1330 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1332 /* Put everything on opcode array. */
1335 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1340 p
= remove_leading_whitespaces (buf
);
1342 /* Skip comments. */
1343 str
= strstr (p
, "//");
1347 /* Remove trailing white spaces. */
1348 remove_trailing_whitespaces (p
);
1353 if (!strcmp("### MARKER ###", buf
))
1357 /* Since we ignore all included files (we only care about their
1358 #define-s here), we don't need to monitor filenames. The final
1359 line number directive is going to refer to the main source file
1364 p
= remove_leading_whitespaces (p
+ 1);
1365 if (!strncmp(p
, "line", 4))
1367 ln
= strtoul (p
, &end
, 10);
1368 if (ln
> 1 && ln
< INT_MAX
1369 && *remove_leading_whitespaces (end
) == '"')
1372 /* Ignore comments. */
1382 last
= p
+ strlen (p
);
1385 name
= next_field (p
, ',', &str
, last
);
1387 /* Get the slot in hash table. */
1388 hash_slot
= (struct opcode_hash_entry
**)
1389 htab_find_slot_with_hash (opcode_hash_table
, name
,
1390 htab_hash_string (name
),
1393 if (*hash_slot
== NULL
)
1395 /* It is the new one. Put it on opcode array. */
1396 if (i
>= opcode_array_size
)
1398 /* Grow the opcode array when needed. */
1399 opcode_array_size
+= 1024;
1400 opcode_array
= (struct opcode_hash_entry
**)
1401 xrealloc (opcode_array
,
1402 sizeof (*opcode_array
) * opcode_array_size
);
1405 opcode_array
[i
] = (struct opcode_hash_entry
*)
1406 xmalloc (sizeof (struct opcode_hash_entry
));
1407 opcode_array
[i
]->next
= NULL
;
1408 opcode_array
[i
]->name
= xstrdup (name
);
1409 opcode_array
[i
]->opcode
= xstrdup (str
);
1410 opcode_array
[i
]->lineno
= lineno
;
1411 *hash_slot
= opcode_array
[i
];
1416 /* Append it to the existing one. */
1418 while ((*entry
) != NULL
)
1419 entry
= &(*entry
)->next
;
1420 *entry
= (struct opcode_hash_entry
*)
1421 xmalloc (sizeof (struct opcode_hash_entry
));
1422 (*entry
)->next
= NULL
;
1423 (*entry
)->name
= (*hash_slot
)->name
;
1424 (*entry
)->opcode
= xstrdup (str
);
1425 (*entry
)->lineno
= lineno
;
1429 /* Process opcode array. */
1430 for (j
= 0; j
< i
; j
++)
1432 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1436 lineno
= next
->lineno
;
1437 last
= str
+ strlen (str
);
1438 output_i386_opcode (table
, name
, str
, last
, lineno
);
1444 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1446 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1448 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1450 fprintf (table
, " { ");
1451 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1452 fprintf (table
, " } }\n");
1454 fprintf (table
, "};\n");
1458 process_i386_registers (FILE *table
)
1462 char *str
, *p
, *last
;
1463 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1464 char *dw2_32_num
, *dw2_64_num
;
1467 filename
= "i386-reg.tbl";
1468 fp
= fopen (filename
, "r");
1470 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1473 fprintf (table
, "\n/* i386 register table. */\n\n");
1474 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1478 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1483 p
= remove_leading_whitespaces (buf
);
1485 /* Skip comments. */
1486 str
= strstr (p
, "//");
1490 /* Remove trailing white spaces. */
1491 remove_trailing_whitespaces (p
);
1496 fprintf (table
, "%s\n", p
);
1504 last
= p
+ strlen (p
);
1506 /* Find reg_name. */
1507 reg_name
= next_field (p
, ',', &str
, last
);
1509 /* Find reg_type. */
1510 reg_type
= next_field (str
, ',', &str
, last
);
1512 /* Find reg_flags. */
1513 reg_flags
= next_field (str
, ',', &str
, last
);
1516 reg_num
= next_field (str
, ',', &str
, last
);
1518 fprintf (table
, " { \"%s\",\n ", reg_name
);
1520 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1523 /* Find 32-bit Dwarf2 register number. */
1524 dw2_32_num
= next_field (str
, ',', &str
, last
);
1526 /* Find 64-bit Dwarf2 register number. */
1527 dw2_64_num
= next_field (str
, ',', &str
, last
);
1529 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1530 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1535 fprintf (table
, "};\n");
1537 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1541 process_i386_initializers (void)
1544 FILE *fp
= fopen ("i386-init.h", "w");
1548 fail (_("can't create i386-init.h, errno = %s\n"),
1551 process_copyright (fp
);
1553 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1555 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1556 init
= xstrdup (cpu_flag_init
[i
].init
);
1557 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1561 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1563 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1564 init
= xstrdup (operand_type_init
[i
].init
);
1565 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1573 /* Program options. */
1574 #define OPTION_SRCDIR 200
1576 struct option long_options
[] =
1578 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1579 {"debug", no_argument
, NULL
, 'd'},
1580 {"version", no_argument
, NULL
, 'V'},
1581 {"help", no_argument
, NULL
, 'h'},
1582 {0, no_argument
, NULL
, 0}
1586 print_version (void)
1588 printf ("%s: version 1.0\n", program_name
);
1593 usage (FILE * stream
, int status
)
1595 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1601 main (int argc
, char **argv
)
1603 extern int chdir (char *);
1604 char *srcdir
= NULL
;
1606 unsigned int i
, cpumax
;
1609 program_name
= *argv
;
1610 xmalloc_set_program_name (program_name
);
1612 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1637 if (chdir (srcdir
) != 0)
1638 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1639 srcdir
, xstrerror (errno
));
1641 /* cpu_flags isn't sorted by position. */
1643 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1644 if (cpu_flags
[i
].position
> cpumax
)
1645 cpumax
= cpu_flags
[i
].position
;
1647 /* Check the unused bitfield in i386_cpu_flags. */
1649 if ((cpumax
- 1) != CpuMax
)
1650 fail (_("CpuMax != %d!\n"), cpumax
);
1652 if (cpumax
!= CpuMax
)
1653 fail (_("CpuMax != %d!\n"), cpumax
);
1655 c
= CpuNumOfBits
- CpuMax
- 1;
1657 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1660 /* Check the unused bitfield in i386_operand_type. */
1662 c
= OTNumOfBits
- OTMax
- 1;
1664 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1667 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1670 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1671 sizeof (opcode_modifiers
[0]), compare
);
1673 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1674 sizeof (operand_types
[0]), compare
);
1676 table
= fopen ("i386-tbl.h", "w");
1678 fail (_("can't create i386-tbl.h, errno = %s\n"),
1681 process_copyright (table
);
1683 process_i386_opcodes (table
);
1684 process_i386_registers (table
);
1685 process_i386_initializers ();