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|CPU_387_FLAGS|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_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuFMA4|CpuXOP|CpuLWP|CpuSVME|CpuXsave|CpuAES|CpuAVX|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_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_BTVER1_FLAGS",
101 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
102 { "CPU_BTVER2_FLAGS",
103 "CPU_BTVER1_FLAGS|CPU_SSE4_2_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW" },
107 "CPU_8087_FLAGS|Cpu287" },
109 "CPU_287_FLAGS|Cpu387" },
111 "CPU_387_FLAGS|Cpu687" },
112 { "CPU_CLFLUSH_FLAGS",
116 { "CPU_SYSCALL_FLAGS",
119 "CpuRegMMX|CpuMMX" },
121 "CpuRegXMM|CpuSSE" },
123 "CPU_SSE_FLAGS|CpuSSE2" },
125 "CPU_SSE2_FLAGS|CpuSSE3" },
127 "CPU_SSE3_FLAGS|CpuSSSE3" },
128 { "CPU_SSE4_1_FLAGS",
129 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
130 { "CPU_SSE4_2_FLAGS",
131 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
138 { "CPU_XSAVEOPT_FLAGS",
139 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
141 "CPU_SSE2_FLAGS|CpuAES" },
142 { "CPU_PCLMUL_FLAGS",
143 "CPU_SSE2_FLAGS|CpuPCLMUL" },
145 "CPU_AVX_FLAGS|CpuFMA" },
147 "CPU_AVX_FLAGS|CpuFMA4" },
149 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
160 { "CPU_RDTSCP_FLAGS",
164 { "CPU_FSGSBASE_FLAGS",
169 "CPU_AVX_FLAGS|CpuF16C" },
178 { "CPU_INVPCID_FLAGS",
180 { "CPU_VMFUNC_FLAGS",
183 "CPU_MMX_FLAGS|Cpu3dnow" },
184 { "CPU_3DNOWA_FLAGS",
185 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
186 { "CPU_PADLOCK_FLAGS",
191 "CPU_SSE3_FLAGS|CpuSSE4a" },
195 "CPU_SSE4_2_FLAGS|CpuRegYMM|CpuAVX" },
197 "CPU_AVX_FLAGS|CpuAVX2" },
198 /* Don't use CPU_AVX2_FLAGS on CPU_AVX512F_FLAGS since AVX512F doesn't
199 support YMM registers. */
200 { "CPU_AVX512F_FLAGS",
201 "CpuVREX|CPU_SSE4_2_FLAGS|CpuRegZMM|CpuRegMask|CpuAVX|CpuAVX2|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 /* Use CPU_AVX2_FLAGS on CPU_AVX512VL_FLAGS since AVX512VL supports YMM
215 "CPU_AVX512F_FLAGS|CPU_AVX2_FLAGS|CpuAVX512VL" },
216 { "CPU_AVX512IFMA_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
218 { "CPU_AVX512VBMI_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
220 { "CPU_AVX512_4FMAPS_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
222 { "CPU_AVX512_4VNNIW_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
224 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
226 { "CPU_AVX512_VBMI2_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
228 { "CPU_AVX512_VNNI_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
230 { "CPU_AVX512_BITALG_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
237 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
240 { "CPU_RDSEED_FLAGS",
242 { "CPU_PRFCHW_FLAGS",
249 "CPU_SSE2_FLAGS|CpuSHA" },
250 { "CPU_CLFLUSHOPT_FLAGS",
252 { "CPU_XSAVES_FLAGS",
253 "CPU_XSAVE_FLAGS|CpuXSAVES" },
254 { "CPU_XSAVEC_FLAGS",
255 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
256 { "CPU_PREFETCHWT1_FLAGS",
262 { "CPU_CLZERO_FLAGS",
264 { "CPU_MWAITX_FLAGS",
270 { "CPU_PTWRITE_FLAGS",
280 { "CPU_VPCLMULQDQ_FLAGS",
282 { "CPU_WBNOINVD_FLAGS",
284 { "CPU_PCONFIG_FLAGS",
286 { "CPU_WAITPKG_FLAGS",
288 { "CPU_ANY_X87_FLAGS",
289 "CPU_ANY_287_FLAGS|Cpu8087" },
290 { "CPU_ANY_287_FLAGS",
291 "CPU_ANY_387_FLAGS|Cpu287" },
292 { "CPU_ANY_387_FLAGS",
293 "CPU_ANY_687_FLAGS|Cpu387" },
294 { "CPU_ANY_687_FLAGS",
295 "Cpu687|CpuFISTTP" },
296 { "CPU_ANY_MMX_FLAGS",
297 "CPU_3DNOWA_FLAGS" },
298 { "CPU_ANY_SSE_FLAGS",
299 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
300 { "CPU_ANY_SSE2_FLAGS",
301 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
302 { "CPU_ANY_SSE3_FLAGS",
303 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
304 { "CPU_ANY_SSSE3_FLAGS",
305 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
306 { "CPU_ANY_SSE4_1_FLAGS",
307 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
308 { "CPU_ANY_SSE4_2_FLAGS",
310 { "CPU_ANY_AVX_FLAGS",
311 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
312 { "CPU_ANY_AVX2_FLAGS",
314 { "CPU_ANY_AVX512F_FLAGS",
315 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512F" },
316 { "CPU_ANY_AVX512CD_FLAGS",
318 { "CPU_ANY_AVX512ER_FLAGS",
320 { "CPU_ANY_AVX512PF_FLAGS",
322 { "CPU_ANY_AVX512DQ_FLAGS",
324 { "CPU_ANY_AVX512BW_FLAGS",
326 { "CPU_ANY_AVX512VL_FLAGS",
328 { "CPU_ANY_AVX512IFMA_FLAGS",
330 { "CPU_ANY_AVX512VBMI_FLAGS",
332 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
333 "CpuAVX512_4FMAPS" },
334 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
335 "CpuAVX512_4VNNIW" },
336 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
337 "CpuAVX512_VPOPCNTDQ" },
338 { "CPU_ANY_IBT_FLAGS",
340 { "CPU_ANY_SHSTK_FLAGS",
342 { "CPU_ANY_AVX512_VBMI2_FLAGS",
344 { "CPU_ANY_AVX512_VNNI_FLAGS",
346 { "CPU_ANY_AVX512_BITALG_FLAGS",
347 "CpuAVX512_BITALG" },
350 static const initializer operand_type_shorthands
[] =
352 { "Reg8", "Reg|Byte" },
353 { "Reg16", "Reg|Word" },
354 { "Reg32", "Reg|Dword" },
355 { "Reg64", "Reg|Qword" },
356 { "FloatAcc", "Acc|Tbyte" },
357 { "FloatReg", "Reg|Tbyte" },
358 { "RegXMM", "RegSIMD|Xmmword" },
359 { "RegYMM", "RegSIMD|Ymmword" },
360 { "RegZMM", "RegSIMD|Zmmword" },
363 static initializer operand_type_init
[] =
365 { "OPERAND_TYPE_NONE",
367 { "OPERAND_TYPE_REG8",
369 { "OPERAND_TYPE_REG16",
371 { "OPERAND_TYPE_REG32",
373 { "OPERAND_TYPE_REG64",
375 { "OPERAND_TYPE_IMM1",
377 { "OPERAND_TYPE_IMM8",
379 { "OPERAND_TYPE_IMM8S",
381 { "OPERAND_TYPE_IMM16",
383 { "OPERAND_TYPE_IMM32",
385 { "OPERAND_TYPE_IMM32S",
387 { "OPERAND_TYPE_IMM64",
389 { "OPERAND_TYPE_BASEINDEX",
391 { "OPERAND_TYPE_DISP8",
393 { "OPERAND_TYPE_DISP16",
395 { "OPERAND_TYPE_DISP32",
397 { "OPERAND_TYPE_DISP32S",
399 { "OPERAND_TYPE_DISP64",
401 { "OPERAND_TYPE_INOUTPORTREG",
403 { "OPERAND_TYPE_SHIFTCOUNT",
405 { "OPERAND_TYPE_CONTROL",
407 { "OPERAND_TYPE_TEST",
409 { "OPERAND_TYPE_DEBUG",
411 { "OPERAND_TYPE_FLOATREG",
413 { "OPERAND_TYPE_FLOATACC",
415 { "OPERAND_TYPE_SREG2",
417 { "OPERAND_TYPE_SREG3",
419 { "OPERAND_TYPE_ACC",
421 { "OPERAND_TYPE_JUMPABSOLUTE",
423 { "OPERAND_TYPE_REGMMX",
425 { "OPERAND_TYPE_REGXMM",
427 { "OPERAND_TYPE_REGYMM",
429 { "OPERAND_TYPE_REGZMM",
431 { "OPERAND_TYPE_REGMASK",
433 { "OPERAND_TYPE_ESSEG",
435 { "OPERAND_TYPE_ACC32",
437 { "OPERAND_TYPE_ACC64",
439 { "OPERAND_TYPE_INOUTPORTREG",
441 { "OPERAND_TYPE_REG16_INOUTPORTREG",
442 "Reg16|InOutPortReg" },
443 { "OPERAND_TYPE_DISP16_32",
445 { "OPERAND_TYPE_ANYDISP",
446 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
447 { "OPERAND_TYPE_IMM16_32",
449 { "OPERAND_TYPE_IMM16_32S",
451 { "OPERAND_TYPE_IMM16_32_32S",
452 "Imm16|Imm32|Imm32S" },
453 { "OPERAND_TYPE_IMM32_64",
455 { "OPERAND_TYPE_IMM32_32S_DISP32",
456 "Imm32|Imm32S|Disp32" },
457 { "OPERAND_TYPE_IMM64_DISP64",
459 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
460 "Imm32|Imm32S|Imm64|Disp32" },
461 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
462 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
463 { "OPERAND_TYPE_VEC_IMM4",
465 { "OPERAND_TYPE_REGBND",
469 typedef struct bitfield
476 #define BITFIELD(n) { n, 0, #n }
478 static bitfield cpu_flags
[] =
486 BITFIELD (CpuClflush
),
488 BITFIELD (CpuSYSCALL
),
493 BITFIELD (CpuFISTTP
),
499 BITFIELD (CpuSSE4_1
),
500 BITFIELD (CpuSSE4_2
),
503 BITFIELD (CpuAVX512F
),
504 BITFIELD (CpuAVX512CD
),
505 BITFIELD (CpuAVX512ER
),
506 BITFIELD (CpuAVX512PF
),
507 BITFIELD (CpuAVX512VL
),
508 BITFIELD (CpuAVX512DQ
),
509 BITFIELD (CpuAVX512BW
),
515 BITFIELD (Cpu3dnowA
),
516 BITFIELD (CpuPadLock
),
522 BITFIELD (CpuXsaveopt
),
524 BITFIELD (CpuPCLMUL
),
535 BITFIELD (CpuRdtscp
),
536 BITFIELD (CpuFSGSBase
),
543 BITFIELD (CpuINVPCID
),
544 BITFIELD (CpuVMFUNC
),
545 BITFIELD (CpuRDSEED
),
547 BITFIELD (CpuPRFCHW
),
551 BITFIELD (CpuClflushOpt
),
552 BITFIELD (CpuXSAVES
),
553 BITFIELD (CpuXSAVEC
),
554 BITFIELD (CpuPREFETCHWT1
),
560 BITFIELD (CpuAVX512IFMA
),
561 BITFIELD (CpuAVX512VBMI
),
562 BITFIELD (CpuAVX512_4FMAPS
),
563 BITFIELD (CpuAVX512_4VNNIW
),
564 BITFIELD (CpuAVX512_VPOPCNTDQ
),
565 BITFIELD (CpuAVX512_VBMI2
),
566 BITFIELD (CpuAVX512_VNNI
),
567 BITFIELD (CpuAVX512_BITALG
),
568 BITFIELD (CpuMWAITX
),
569 BITFIELD (CpuCLZERO
),
572 BITFIELD (CpuPTWRITE
),
577 BITFIELD (CpuVPCLMULQDQ
),
578 BITFIELD (CpuWBNOINVD
),
579 BITFIELD (CpuPCONFIG
),
580 BITFIELD (CpuWAITPKG
),
581 BITFIELD (CpuRegMMX
),
582 BITFIELD (CpuRegXMM
),
583 BITFIELD (CpuRegYMM
),
584 BITFIELD (CpuRegZMM
),
585 BITFIELD (CpuRegMask
),
587 BITFIELD (CpuUnused
),
591 static bitfield opcode_modifiers
[] =
597 BITFIELD (ShortForm
),
599 BITFIELD (JumpDword
),
601 BITFIELD (JumpInterSegment
),
607 BITFIELD (CheckRegSize
),
608 BITFIELD (IgnoreSize
),
609 BITFIELD (DefaultSize
),
618 BITFIELD (BNDPrefixOk
),
619 BITFIELD (NoTrackPrefixOk
),
620 BITFIELD (IsLockable
),
621 BITFIELD (RegKludge
),
622 BITFIELD (Implicit1stXmm0
),
623 BITFIELD (RepPrefixOk
),
624 BITFIELD (HLEPrefixOk
),
627 BITFIELD (AddrPrefixOp0
),
636 BITFIELD (VexOpcode
),
637 BITFIELD (VexSources
),
638 BITFIELD (VexImmExt
),
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
),
698 BITFIELD (Unspecified
),
707 static const char *filename
;
708 static i386_cpu_flags active_cpu_flags
;
709 static int active_isstring
;
712 compare (const void *x
, const void *y
)
714 const bitfield
*xp
= (const bitfield
*) x
;
715 const bitfield
*yp
= (const bitfield
*) y
;
716 return xp
->position
- yp
->position
;
720 fail (const char *message
, ...)
724 va_start (args
, message
);
725 fprintf (stderr
, _("%s: error: "), program_name
);
726 vfprintf (stderr
, message
, args
);
732 process_copyright (FILE *fp
)
734 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
735 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
737 This file is part of the GNU opcodes library.\n\
739 This library is free software; you can redistribute it and/or modify\n\
740 it under the terms of the GNU General Public License as published by\n\
741 the Free Software Foundation; either version 3, or (at your option)\n\
742 any later version.\n\
744 It is distributed in the hope that it will be useful, but WITHOUT\n\
745 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
746 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
747 License for more details.\n\
749 You should have received a copy of the GNU General Public License\n\
750 along with this program; if not, write to the Free Software\n\
751 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
752 MA 02110-1301, USA. */\n");
755 /* Remove leading white spaces. */
758 remove_leading_whitespaces (char *str
)
760 while (ISSPACE (*str
))
765 /* Remove trailing white spaces. */
768 remove_trailing_whitespaces (char *str
)
770 size_t last
= strlen (str
);
778 if (ISSPACE (str
[last
]))
786 /* Find next field separated by SEP and terminate it. Return a
787 pointer to the one after it. */
790 next_field (char *str
, char sep
, char **next
, char *last
)
794 p
= remove_leading_whitespaces (str
);
795 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
798 remove_trailing_whitespaces (p
);
808 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
811 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
814 char *str
, *next
, *last
;
817 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
818 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
820 /* Turn on selective bits. */
821 char *init
= xstrdup (cpu_flag_init
[i
].init
);
822 last
= init
+ strlen (init
);
823 for (next
= init
; next
&& next
< last
; )
825 str
= next_field (next
, '|', &next
, last
);
827 set_bitfield (str
, array
, 1, size
, lineno
);
833 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
834 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
836 /* Turn on selective bits. */
837 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
838 last
= init
+ strlen (init
);
839 for (next
= init
; next
&& next
< last
; )
841 str
= next_field (next
, '|', &next
, last
);
843 set_bitfield (str
, array
, 1, size
, lineno
);
853 set_bitfield (char *f
, bitfield
*array
, int value
,
854 unsigned int size
, int lineno
)
858 if (strcmp (f
, "CpuFP") == 0)
860 set_bitfield("Cpu387", array
, value
, size
, lineno
);
861 set_bitfield("Cpu287", array
, value
, size
, lineno
);
864 else if (strcmp (f
, "Mmword") == 0)
866 else if (strcmp (f
, "Oword") == 0)
869 for (i
= 0; i
< size
; i
++)
870 if (strcasecmp (array
[i
].name
, f
) == 0)
872 array
[i
].value
= value
;
878 const char *v
= strchr (f
, '=');
885 for (i
= 0; i
< size
; i
++)
886 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
888 value
= strtol (v
+ 1, &end
, 0);
891 array
[i
].value
= value
;
899 /* Handle shorthands. */
900 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
904 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
906 fail (_("unknown bitfield: %s\n"), f
);
910 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
911 int macro
, const char *comma
, const char *indent
)
915 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
917 fprintf (table
, "%s{ { ", indent
);
919 for (i
= 0; i
< size
- 1; i
++)
921 if (((i
+ 1) % 20) != 0)
922 fprintf (table
, "%d, ", flags
[i
].value
);
924 fprintf (table
, "%d,", flags
[i
].value
);
925 if (((i
+ 1) % 20) == 0)
927 /* We need \\ for macro. */
929 fprintf (table
, " \\\n %s", indent
);
931 fprintf (table
, "\n %s", indent
);
934 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
937 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
941 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
942 const char *comma
, const char *indent
,
945 char *str
, *next
, *last
;
947 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
949 /* Copy the default cpu flags. */
950 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
952 if (strcasecmp (flag
, "unknown") == 0)
954 /* We turn on everything except for cpu64 in case of
955 CPU_UNKNOWN_FLAGS. */
956 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
957 if (flags
[i
].position
!= Cpu64
)
960 else if (flag
[0] == '~')
962 last
= flag
+ strlen (flag
);
969 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
976 /* First we turn on everything except for cpu64. */
977 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
978 if (flags
[i
].position
!= Cpu64
)
981 /* Turn off selective bits. */
982 for (; next
&& next
< last
; )
984 str
= next_field (next
, '|', &next
, last
);
986 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
989 else if (strcmp (flag
, "0"))
991 /* Turn on selective bits. */
992 last
= flag
+ strlen (flag
);
993 for (next
= flag
; next
&& next
< last
; )
995 str
= next_field (next
, '|', &next
, last
);
997 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1001 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1006 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1010 fprintf (table
, " { ");
1012 for (i
= 0; i
< size
- 1; i
++)
1014 if (((i
+ 1) % 20) != 0)
1015 fprintf (table
, "%d, ", modifier
[i
].value
);
1017 fprintf (table
, "%d,", modifier
[i
].value
);
1018 if (((i
+ 1) % 20) == 0)
1019 fprintf (table
, "\n ");
1022 fprintf (table
, "%d },\n", modifier
[i
].value
);
1026 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
1028 char *str
, *next
, *last
;
1029 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1031 active_isstring
= 0;
1033 /* Copy the default opcode modifier. */
1034 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1036 if (strcmp (mod
, "0"))
1038 last
= mod
+ strlen (mod
);
1039 for (next
= mod
; next
&& next
< last
; )
1041 str
= next_field (next
, '|', &next
, last
);
1044 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
1046 if (strcasecmp(str
, "IsString") == 0)
1047 active_isstring
= 1;
1051 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1061 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1062 enum stage stage
, const char *indent
)
1066 fprintf (table
, "{ { ");
1068 for (i
= 0; i
< size
- 1; i
++)
1070 if (((i
+ 1) % 20) != 0)
1071 fprintf (table
, "%d, ", types
[i
].value
);
1073 fprintf (table
, "%d,", types
[i
].value
);
1074 if (((i
+ 1) % 20) == 0)
1076 /* We need \\ for macro. */
1077 if (stage
== stage_macros
)
1078 fprintf (table
, " \\\n%s", indent
);
1080 fprintf (table
, "\n%s", indent
);
1084 fprintf (table
, "%d } }", types
[i
].value
);
1088 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1089 const char *indent
, int lineno
)
1091 char *str
, *next
, *last
;
1092 bitfield types
[ARRAY_SIZE (operand_types
)];
1094 /* Copy the default operand type. */
1095 memcpy (types
, operand_types
, sizeof (types
));
1097 if (strcmp (op
, "0"))
1101 last
= op
+ strlen (op
);
1102 for (next
= op
; next
&& next
< last
; )
1104 str
= next_field (next
, '|', &next
, last
);
1107 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1108 if (strcasecmp(str
, "BaseIndex") == 0)
1113 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1115 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1116 if (!active_cpu_flags
.bitfield
.cpu64
1117 && !active_cpu_flags
.bitfield
.cpumpx
)
1118 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1119 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1120 if (!active_cpu_flags
.bitfield
.cpuno64
)
1121 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1124 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1129 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1130 char *last
, int lineno
)
1133 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1134 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1136 /* Find number of operands. */
1137 operands
= next_field (str
, ',', &str
, last
);
1139 /* Find base_opcode. */
1140 base_opcode
= next_field (str
, ',', &str
, last
);
1142 /* Find extension_opcode. */
1143 extension_opcode
= next_field (str
, ',', &str
, last
);
1145 /* Find opcode_length. */
1146 opcode_length
= next_field (str
, ',', &str
, last
);
1148 /* Find cpu_flags. */
1149 cpu_flags
= next_field (str
, ',', &str
, last
);
1151 /* Find opcode_modifier. */
1152 opcode_modifier
= next_field (str
, ',', &str
, last
);
1154 /* Remove the first {. */
1155 str
= remove_leading_whitespaces (str
);
1158 str
= remove_leading_whitespaces (str
+ 1);
1162 /* There are at least "X}". */
1166 /* Remove trailing white spaces and }. */
1170 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1179 /* Find operand_types. */
1180 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1184 operand_types
[i
] = NULL
;
1188 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1189 if (*operand_types
[i
] == '0')
1192 operand_types
[i
] = NULL
;
1197 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1198 name
, operands
, base_opcode
, extension_opcode
,
1201 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1203 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1205 fprintf (table
, " { ");
1207 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1209 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1212 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1218 fprintf (table
, ",\n ");
1220 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1223 fprintf (table
, " } },\n");
1226 struct opcode_hash_entry
1228 struct opcode_hash_entry
*next
;
1234 /* Calculate the hash value of an opcode hash entry P. */
1237 opcode_hash_hash (const void *p
)
1239 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1240 return htab_hash_string (entry
->name
);
1243 /* Compare a string Q against an opcode hash entry P. */
1246 opcode_hash_eq (const void *p
, const void *q
)
1248 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1249 const char *name
= (const char *) q
;
1250 return strcmp (name
, entry
->name
) == 0;
1254 process_i386_opcodes (FILE *table
)
1259 char *str
, *p
, *last
, *name
;
1260 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1261 htab_t opcode_hash_table
;
1262 struct opcode_hash_entry
**opcode_array
;
1263 unsigned int opcode_array_size
= 1024;
1266 filename
= "i386-opc.tbl";
1267 fp
= fopen (filename
, "r");
1270 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1274 opcode_array
= (struct opcode_hash_entry
**)
1275 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1277 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1278 opcode_hash_eq
, NULL
,
1281 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1282 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1284 /* Put everything on opcode array. */
1287 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1292 p
= remove_leading_whitespaces (buf
);
1294 /* Skip comments. */
1295 str
= strstr (p
, "//");
1299 /* Remove trailing white spaces. */
1300 remove_trailing_whitespaces (p
);
1305 /* Ignore comments. */
1313 last
= p
+ strlen (p
);
1316 name
= next_field (p
, ',', &str
, last
);
1318 /* Get the slot in hash table. */
1319 hash_slot
= (struct opcode_hash_entry
**)
1320 htab_find_slot_with_hash (opcode_hash_table
, name
,
1321 htab_hash_string (name
),
1324 if (*hash_slot
== NULL
)
1326 /* It is the new one. Put it on opcode array. */
1327 if (i
>= opcode_array_size
)
1329 /* Grow the opcode array when needed. */
1330 opcode_array_size
+= 1024;
1331 opcode_array
= (struct opcode_hash_entry
**)
1332 xrealloc (opcode_array
,
1333 sizeof (*opcode_array
) * opcode_array_size
);
1336 opcode_array
[i
] = (struct opcode_hash_entry
*)
1337 xmalloc (sizeof (struct opcode_hash_entry
));
1338 opcode_array
[i
]->next
= NULL
;
1339 opcode_array
[i
]->name
= xstrdup (name
);
1340 opcode_array
[i
]->opcode
= xstrdup (str
);
1341 opcode_array
[i
]->lineno
= lineno
;
1342 *hash_slot
= opcode_array
[i
];
1347 /* Append it to the existing one. */
1349 while ((*entry
) != NULL
)
1350 entry
= &(*entry
)->next
;
1351 *entry
= (struct opcode_hash_entry
*)
1352 xmalloc (sizeof (struct opcode_hash_entry
));
1353 (*entry
)->next
= NULL
;
1354 (*entry
)->name
= (*hash_slot
)->name
;
1355 (*entry
)->opcode
= xstrdup (str
);
1356 (*entry
)->lineno
= lineno
;
1360 /* Process opcode array. */
1361 for (j
= 0; j
< i
; j
++)
1363 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1367 lineno
= next
->lineno
;
1368 last
= str
+ strlen (str
);
1369 output_i386_opcode (table
, name
, str
, last
, lineno
);
1375 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1377 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1379 process_i386_opcode_modifier (table
, "0", -1);
1381 fprintf (table
, " { ");
1382 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1383 fprintf (table
, " } }\n");
1385 fprintf (table
, "};\n");
1389 process_i386_registers (FILE *table
)
1393 char *str
, *p
, *last
;
1394 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1395 char *dw2_32_num
, *dw2_64_num
;
1398 filename
= "i386-reg.tbl";
1399 fp
= fopen (filename
, "r");
1401 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1404 fprintf (table
, "\n/* i386 register table. */\n\n");
1405 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1409 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1414 p
= remove_leading_whitespaces (buf
);
1416 /* Skip comments. */
1417 str
= strstr (p
, "//");
1421 /* Remove trailing white spaces. */
1422 remove_trailing_whitespaces (p
);
1427 fprintf (table
, "%s\n", p
);
1435 last
= p
+ strlen (p
);
1437 /* Find reg_name. */
1438 reg_name
= next_field (p
, ',', &str
, last
);
1440 /* Find reg_type. */
1441 reg_type
= next_field (str
, ',', &str
, last
);
1443 /* Find reg_flags. */
1444 reg_flags
= next_field (str
, ',', &str
, last
);
1447 reg_num
= next_field (str
, ',', &str
, last
);
1449 fprintf (table
, " { \"%s\",\n ", reg_name
);
1451 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1454 /* Find 32-bit Dwarf2 register number. */
1455 dw2_32_num
= next_field (str
, ',', &str
, last
);
1457 /* Find 64-bit Dwarf2 register number. */
1458 dw2_64_num
= next_field (str
, ',', &str
, last
);
1460 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1461 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1466 fprintf (table
, "};\n");
1468 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1472 process_i386_initializers (void)
1475 FILE *fp
= fopen ("i386-init.h", "w");
1479 fail (_("can't create i386-init.h, errno = %s\n"),
1482 process_copyright (fp
);
1484 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1486 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1487 init
= xstrdup (cpu_flag_init
[i
].init
);
1488 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1492 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1494 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1495 init
= xstrdup (operand_type_init
[i
].init
);
1496 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1504 /* Program options. */
1505 #define OPTION_SRCDIR 200
1507 struct option long_options
[] =
1509 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1510 {"debug", no_argument
, NULL
, 'd'},
1511 {"version", no_argument
, NULL
, 'V'},
1512 {"help", no_argument
, NULL
, 'h'},
1513 {0, no_argument
, NULL
, 0}
1517 print_version (void)
1519 printf ("%s: version 1.0\n", program_name
);
1524 usage (FILE * stream
, int status
)
1526 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1532 main (int argc
, char **argv
)
1534 extern int chdir (char *);
1535 char *srcdir
= NULL
;
1537 unsigned int i
, cpumax
;
1540 program_name
= *argv
;
1541 xmalloc_set_program_name (program_name
);
1543 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1568 if (chdir (srcdir
) != 0)
1569 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1570 srcdir
, xstrerror (errno
));
1572 /* cpu_flags isn't sorted by position. */
1574 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1575 if (cpu_flags
[i
].position
> cpumax
)
1576 cpumax
= cpu_flags
[i
].position
;
1578 /* Check the unused bitfield in i386_cpu_flags. */
1580 if ((cpumax
- 1) != CpuMax
)
1581 fail (_("CpuMax != %d!\n"), cpumax
);
1583 if (cpumax
!= CpuMax
)
1584 fail (_("CpuMax != %d!\n"), cpumax
);
1586 c
= CpuNumOfBits
- CpuMax
- 1;
1588 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1591 /* Check the unused bitfield in i386_operand_type. */
1593 c
= OTNumOfBits
- OTMax
- 1;
1595 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1598 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1601 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1602 sizeof (opcode_modifiers
[0]), compare
);
1604 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1605 sizeof (operand_types
[0]), compare
);
1607 table
= fopen ("i386-tbl.h", "w");
1609 fail (_("can't create i386-tbl.h, errno = %s\n"),
1612 process_copyright (table
);
1614 process_i386_opcodes (table
);
1615 process_i386_registers (table
);
1616 process_i386_initializers ();