1 /* Copyright (C) 2007-2019 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 /* Build-time checks are preferrable over runtime ones. Use this construct
34 in preference where possible. */
35 #define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
37 static const char *program_name
= NULL
;
40 typedef struct initializer
46 static initializer cpu_flag_init
[] =
48 { "CPU_UNKNOWN_FLAGS",
49 "~(CpuL1OM|CpuK1OM)" },
50 { "CPU_GENERIC32_FLAGS",
51 "Cpu186|Cpu286|Cpu386" },
52 { "CPU_GENERIC64_FLAGS",
53 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
59 "CPU_I186_FLAGS|Cpu286" },
61 "CPU_I286_FLAGS|Cpu386" },
63 "CPU_I386_FLAGS|Cpu486" },
65 "CPU_I486_FLAGS|Cpu387|Cpu586" },
67 "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" },
68 { "CPU_PENTIUMPRO_FLAGS",
69 "CPU_I686_FLAGS|CpuNop" },
71 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
73 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
75 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
77 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
79 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
81 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
83 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
87 "CPU_K6_FLAGS|Cpu3dnow" },
89 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
91 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
92 { "CPU_AMDFAM10_FLAGS",
93 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
95 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
97 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
99 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
100 { "CPU_BDVER4_FLAGS",
101 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
102 { "CPU_ZNVER1_FLAGS",
103 "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" },
104 { "CPU_ZNVER2_FLAGS",
105 "CPU_ZNVER1_FLAGS|CpuRDPID|CpuWBNOINVD|CpuCLWB" },
106 { "CPU_BTVER1_FLAGS",
107 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
108 { "CPU_BTVER2_FLAGS",
109 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
117 "CPU_387_FLAGS|Cpu687" },
122 { "CPU_CLFLUSH_FLAGS",
126 { "CPU_SYSCALL_FLAGS",
133 "CPU_SSE_FLAGS|CpuSSE2" },
135 "CPU_SSE2_FLAGS|CpuSSE3" },
137 "CPU_SSE3_FLAGS|CpuSSSE3" },
138 { "CPU_SSE4_1_FLAGS",
139 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
140 { "CPU_SSE4_2_FLAGS",
141 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
148 { "CPU_XSAVEOPT_FLAGS",
149 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
151 "CPU_SSE2_FLAGS|CpuAES" },
152 { "CPU_PCLMUL_FLAGS",
153 "CPU_SSE2_FLAGS|CpuPCLMUL" },
155 "CPU_AVX_FLAGS|CpuFMA" },
157 "CPU_AVX_FLAGS|CpuFMA4" },
159 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
161 "CPU_XSAVE_FLAGS|CpuLWP" },
170 { "CPU_RDTSCP_FLAGS",
174 { "CPU_FSGSBASE_FLAGS",
179 "CPU_AVX_FLAGS|CpuF16C" },
188 { "CPU_INVPCID_FLAGS",
190 { "CPU_VMFUNC_FLAGS",
193 "CPU_MMX_FLAGS|Cpu3dnow" },
194 { "CPU_3DNOWA_FLAGS",
195 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
196 { "CPU_PADLOCK_FLAGS",
201 "CPU_SSE3_FLAGS|CpuSSE4a" },
205 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
207 "CPU_AVX_FLAGS|CpuAVX2" },
208 { "CPU_AVX512F_FLAGS",
209 "CPU_AVX2_FLAGS|CpuAVX512F" },
210 { "CPU_AVX512CD_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
212 { "CPU_AVX512ER_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
214 { "CPU_AVX512PF_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
216 { "CPU_AVX512DQ_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
218 { "CPU_AVX512BW_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
220 { "CPU_AVX512VL_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
222 { "CPU_AVX512IFMA_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
224 { "CPU_AVX512VBMI_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
226 { "CPU_AVX512_4FMAPS_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
228 { "CPU_AVX512_4VNNIW_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
230 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
232 { "CPU_AVX512_VBMI2_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
234 { "CPU_AVX512_VNNI_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
236 { "CPU_AVX512_BITALG_FLAGS",
237 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
238 { "CPU_AVX512_BF16_FLAGS",
239 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
245 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
248 { "CPU_RDSEED_FLAGS",
250 { "CPU_PRFCHW_FLAGS",
255 "CPU_XSAVE_FLAGS|CpuMPX" },
257 "CPU_SSE2_FLAGS|CpuSHA" },
258 { "CPU_CLFLUSHOPT_FLAGS",
260 { "CPU_XSAVES_FLAGS",
261 "CPU_XSAVE_FLAGS|CpuXSAVES" },
262 { "CPU_XSAVEC_FLAGS",
263 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
264 { "CPU_PREFETCHWT1_FLAGS",
270 { "CPU_CLZERO_FLAGS",
272 { "CPU_MWAITX_FLAGS",
275 "CPU_XSAVE_FLAGS|CpuOSPKE" },
278 { "CPU_PTWRITE_FLAGS",
288 { "CPU_VPCLMULQDQ_FLAGS",
290 { "CPU_WBNOINVD_FLAGS",
292 { "CPU_PCONFIG_FLAGS",
294 { "CPU_WAITPKG_FLAGS",
296 { "CPU_CLDEMOTE_FLAGS",
298 { "CPU_MOVDIRI_FLAGS",
300 { "CPU_MOVDIR64B_FLAGS",
302 { "CPU_ENQCMD_FLAGS",
304 { "CPU_AVX512_VP2INTERSECT_FLAGS",
305 "CpuAVX512_VP2INTERSECT" },
306 { "CPU_ANY_X87_FLAGS",
307 "CPU_ANY_287_FLAGS|Cpu8087" },
308 { "CPU_ANY_287_FLAGS",
309 "CPU_ANY_387_FLAGS|Cpu287" },
310 { "CPU_ANY_387_FLAGS",
311 "CPU_ANY_687_FLAGS|Cpu387" },
312 { "CPU_ANY_687_FLAGS",
313 "Cpu687|CpuFISTTP" },
314 { "CPU_ANY_CMOV_FLAGS",
316 { "CPU_ANY_FXSR_FLAGS",
318 { "CPU_ANY_MMX_FLAGS",
319 "CPU_3DNOWA_FLAGS" },
320 { "CPU_ANY_SSE_FLAGS",
321 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
322 { "CPU_ANY_SSE2_FLAGS",
323 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
324 { "CPU_ANY_SSE3_FLAGS",
325 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
326 { "CPU_ANY_SSSE3_FLAGS",
327 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
328 { "CPU_ANY_SSE4_1_FLAGS",
329 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
330 { "CPU_ANY_SSE4_2_FLAGS",
332 { "CPU_ANY_AVX_FLAGS",
333 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
334 { "CPU_ANY_AVX2_FLAGS",
335 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
336 { "CPU_ANY_AVX512F_FLAGS",
337 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
338 { "CPU_ANY_AVX512CD_FLAGS",
340 { "CPU_ANY_AVX512ER_FLAGS",
342 { "CPU_ANY_AVX512PF_FLAGS",
344 { "CPU_ANY_AVX512DQ_FLAGS",
346 { "CPU_ANY_AVX512BW_FLAGS",
348 { "CPU_ANY_AVX512VL_FLAGS",
350 { "CPU_ANY_AVX512IFMA_FLAGS",
352 { "CPU_ANY_AVX512VBMI_FLAGS",
354 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
355 "CpuAVX512_4FMAPS" },
356 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
357 "CpuAVX512_4VNNIW" },
358 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
359 "CpuAVX512_VPOPCNTDQ" },
360 { "CPU_ANY_IBT_FLAGS",
362 { "CPU_ANY_SHSTK_FLAGS",
364 { "CPU_ANY_AVX512_VBMI2_FLAGS",
366 { "CPU_ANY_AVX512_VNNI_FLAGS",
368 { "CPU_ANY_AVX512_BITALG_FLAGS",
369 "CpuAVX512_BITALG" },
370 { "CPU_ANY_AVX512_BF16_FLAGS",
372 { "CPU_ANY_MOVDIRI_FLAGS",
374 { "CPU_ANY_MOVDIR64B_FLAGS",
376 { "CPU_ANY_ENQCMD_FLAGS",
378 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
379 "CpuAVX512_VP2INTERSECT" },
382 static const initializer operand_type_shorthands
[] =
384 { "Reg8", "Reg|Byte" },
385 { "Reg16", "Reg|Word" },
386 { "Reg32", "Reg|Dword" },
387 { "Reg64", "Reg|Qword" },
388 { "FloatAcc", "Acc|Tbyte" },
389 { "FloatReg", "Reg|Tbyte" },
390 { "RegXMM", "RegSIMD|Xmmword" },
391 { "RegYMM", "RegSIMD|Ymmword" },
392 { "RegZMM", "RegSIMD|Zmmword" },
395 static initializer operand_type_init
[] =
397 { "OPERAND_TYPE_NONE",
399 { "OPERAND_TYPE_REG8",
401 { "OPERAND_TYPE_REG16",
403 { "OPERAND_TYPE_REG32",
405 { "OPERAND_TYPE_REG64",
407 { "OPERAND_TYPE_IMM1",
409 { "OPERAND_TYPE_IMM8",
411 { "OPERAND_TYPE_IMM8S",
413 { "OPERAND_TYPE_IMM16",
415 { "OPERAND_TYPE_IMM32",
417 { "OPERAND_TYPE_IMM32S",
419 { "OPERAND_TYPE_IMM64",
421 { "OPERAND_TYPE_BASEINDEX",
423 { "OPERAND_TYPE_DISP8",
425 { "OPERAND_TYPE_DISP16",
427 { "OPERAND_TYPE_DISP32",
429 { "OPERAND_TYPE_DISP32S",
431 { "OPERAND_TYPE_DISP64",
433 { "OPERAND_TYPE_INOUTPORTREG",
435 { "OPERAND_TYPE_SHIFTCOUNT",
437 { "OPERAND_TYPE_CONTROL",
439 { "OPERAND_TYPE_TEST",
441 { "OPERAND_TYPE_DEBUG",
443 { "OPERAND_TYPE_FLOATREG",
445 { "OPERAND_TYPE_FLOATACC",
447 { "OPERAND_TYPE_SREG",
449 { "OPERAND_TYPE_JUMPABSOLUTE",
451 { "OPERAND_TYPE_REGMMX",
453 { "OPERAND_TYPE_REGXMM",
455 { "OPERAND_TYPE_REGYMM",
457 { "OPERAND_TYPE_REGZMM",
459 { "OPERAND_TYPE_REGMASK",
461 { "OPERAND_TYPE_ESSEG",
463 { "OPERAND_TYPE_ACC8",
465 { "OPERAND_TYPE_ACC16",
467 { "OPERAND_TYPE_ACC32",
469 { "OPERAND_TYPE_ACC64",
471 { "OPERAND_TYPE_DISP16_32",
473 { "OPERAND_TYPE_ANYDISP",
474 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
475 { "OPERAND_TYPE_IMM16_32",
477 { "OPERAND_TYPE_IMM16_32S",
479 { "OPERAND_TYPE_IMM16_32_32S",
480 "Imm16|Imm32|Imm32S" },
481 { "OPERAND_TYPE_IMM32_64",
483 { "OPERAND_TYPE_IMM32_32S_DISP32",
484 "Imm32|Imm32S|Disp32" },
485 { "OPERAND_TYPE_IMM64_DISP64",
487 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
488 "Imm32|Imm32S|Imm64|Disp32" },
489 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
490 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
491 { "OPERAND_TYPE_REGBND",
495 typedef struct bitfield
502 #define BITFIELD(n) { n, 0, #n }
504 static bitfield cpu_flags
[] =
514 BITFIELD (CpuClflush
),
516 BITFIELD (CpuSYSCALL
),
521 BITFIELD (CpuFISTTP
),
527 BITFIELD (CpuSSE4_1
),
528 BITFIELD (CpuSSE4_2
),
531 BITFIELD (CpuAVX512F
),
532 BITFIELD (CpuAVX512CD
),
533 BITFIELD (CpuAVX512ER
),
534 BITFIELD (CpuAVX512PF
),
535 BITFIELD (CpuAVX512VL
),
536 BITFIELD (CpuAVX512DQ
),
537 BITFIELD (CpuAVX512BW
),
543 BITFIELD (Cpu3dnowA
),
544 BITFIELD (CpuPadLock
),
550 BITFIELD (CpuXsaveopt
),
552 BITFIELD (CpuPCLMUL
),
563 BITFIELD (CpuRdtscp
),
564 BITFIELD (CpuFSGSBase
),
571 BITFIELD (CpuINVPCID
),
572 BITFIELD (CpuVMFUNC
),
573 BITFIELD (CpuRDSEED
),
575 BITFIELD (CpuPRFCHW
),
578 BITFIELD (CpuClflushOpt
),
579 BITFIELD (CpuXSAVES
),
580 BITFIELD (CpuXSAVEC
),
581 BITFIELD (CpuPREFETCHWT1
),
587 BITFIELD (CpuAVX512IFMA
),
588 BITFIELD (CpuAVX512VBMI
),
589 BITFIELD (CpuAVX512_4FMAPS
),
590 BITFIELD (CpuAVX512_4VNNIW
),
591 BITFIELD (CpuAVX512_VPOPCNTDQ
),
592 BITFIELD (CpuAVX512_VBMI2
),
593 BITFIELD (CpuAVX512_VNNI
),
594 BITFIELD (CpuAVX512_BITALG
),
595 BITFIELD (CpuAVX512_BF16
),
596 BITFIELD (CpuAVX512_VP2INTERSECT
),
597 BITFIELD (CpuMWAITX
),
598 BITFIELD (CpuCLZERO
),
601 BITFIELD (CpuPTWRITE
),
606 BITFIELD (CpuVPCLMULQDQ
),
607 BITFIELD (CpuWBNOINVD
),
608 BITFIELD (CpuPCONFIG
),
609 BITFIELD (CpuWAITPKG
),
610 BITFIELD (CpuCLDEMOTE
),
611 BITFIELD (CpuMOVDIRI
),
612 BITFIELD (CpuMOVDIR64B
),
613 BITFIELD (CpuENQCMD
),
615 BITFIELD (CpuUnused
),
619 static bitfield opcode_modifiers
[] =
625 BITFIELD (ShortForm
),
627 BITFIELD (JumpDword
),
629 BITFIELD (JumpInterSegment
),
633 BITFIELD (CheckRegSize
),
634 BITFIELD (IgnoreSize
),
635 BITFIELD (DefaultSize
),
645 BITFIELD (BNDPrefixOk
),
646 BITFIELD (NoTrackPrefixOk
),
647 BITFIELD (IsLockable
),
648 BITFIELD (RegKludge
),
649 BITFIELD (Implicit1stXmm0
),
650 BITFIELD (RepPrefixOk
),
651 BITFIELD (HLEPrefixOk
),
654 BITFIELD (AddrPrefixOpReg
),
663 BITFIELD (VexOpcode
),
664 BITFIELD (VexSources
),
670 BITFIELD (Broadcast
),
671 BITFIELD (StaticRounding
),
673 BITFIELD (Disp8MemShift
),
674 BITFIELD (NoDefMask
),
675 BITFIELD (ImplicitQuadGroup
),
677 BITFIELD (ATTMnemonic
),
678 BITFIELD (ATTSyntax
),
679 BITFIELD (IntelSyntax
),
684 static bitfield operand_types
[] =
697 BITFIELD (BaseIndex
),
703 BITFIELD (InOutPortReg
),
704 BITFIELD (ShiftCount
),
710 BITFIELD (JumpAbsolute
),
721 BITFIELD (Unspecified
),
729 static const char *filename
;
730 static i386_cpu_flags active_cpu_flags
;
731 static int active_isstring
;
734 compare (const void *x
, const void *y
)
736 const bitfield
*xp
= (const bitfield
*) x
;
737 const bitfield
*yp
= (const bitfield
*) y
;
738 return xp
->position
- yp
->position
;
742 fail (const char *message
, ...)
746 va_start (args
, message
);
747 fprintf (stderr
, _("%s: error: "), program_name
);
748 vfprintf (stderr
, message
, args
);
754 process_copyright (FILE *fp
)
756 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
757 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
759 This file is part of the GNU opcodes library.\n\
761 This library is free software; you can redistribute it and/or modify\n\
762 it under the terms of the GNU General Public License as published by\n\
763 the Free Software Foundation; either version 3, or (at your option)\n\
764 any later version.\n\
766 It is distributed in the hope that it will be useful, but WITHOUT\n\
767 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
768 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
769 License for more details.\n\
771 You should have received a copy of the GNU General Public License\n\
772 along with this program; if not, write to the Free Software\n\
773 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
774 MA 02110-1301, USA. */\n");
777 /* Remove leading white spaces. */
780 remove_leading_whitespaces (char *str
)
782 while (ISSPACE (*str
))
787 /* Remove trailing white spaces. */
790 remove_trailing_whitespaces (char *str
)
792 size_t last
= strlen (str
);
800 if (ISSPACE (str
[last
]))
808 /* Find next field separated by SEP and terminate it. Return a
809 pointer to the one after it. */
812 next_field (char *str
, char sep
, char **next
, char *last
)
816 p
= remove_leading_whitespaces (str
);
817 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
820 remove_trailing_whitespaces (p
);
830 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
833 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
836 char *str
, *next
, *last
;
839 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
840 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
842 /* Turn on selective bits. */
843 char *init
= xstrdup (cpu_flag_init
[i
].init
);
844 last
= init
+ strlen (init
);
845 for (next
= init
; next
&& next
< last
; )
847 str
= next_field (next
, '|', &next
, last
);
849 set_bitfield (str
, array
, 1, size
, lineno
);
855 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
856 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
858 /* Turn on selective bits. */
859 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
860 last
= init
+ strlen (init
);
861 for (next
= init
; next
&& next
< last
; )
863 str
= next_field (next
, '|', &next
, last
);
865 set_bitfield (str
, array
, 1, size
, lineno
);
875 set_bitfield (char *f
, bitfield
*array
, int value
,
876 unsigned int size
, int lineno
)
880 if (strcmp (f
, "CpuFP") == 0)
882 set_bitfield("Cpu387", array
, value
, size
, lineno
);
883 set_bitfield("Cpu287", array
, value
, size
, lineno
);
886 else if (strcmp (f
, "Mmword") == 0)
888 else if (strcmp (f
, "Oword") == 0)
891 for (i
= 0; i
< size
; i
++)
892 if (strcasecmp (array
[i
].name
, f
) == 0)
894 array
[i
].value
= value
;
900 const char *v
= strchr (f
, '=');
907 for (i
= 0; i
< size
; i
++)
908 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
910 value
= strtol (v
+ 1, &end
, 0);
913 array
[i
].value
= value
;
921 /* Handle shorthands. */
922 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
926 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
928 fail (_("unknown bitfield: %s\n"), f
);
932 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
933 int macro
, const char *comma
, const char *indent
)
937 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
939 fprintf (table
, "%s{ { ", indent
);
941 for (i
= 0; i
< size
- 1; i
++)
943 if (((i
+ 1) % 20) != 0)
944 fprintf (table
, "%d, ", flags
[i
].value
);
946 fprintf (table
, "%d,", flags
[i
].value
);
947 if (((i
+ 1) % 20) == 0)
949 /* We need \\ for macro. */
951 fprintf (table
, " \\\n %s", indent
);
953 fprintf (table
, "\n %s", indent
);
956 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
959 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
963 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
964 const char *comma
, const char *indent
,
967 char *str
, *next
, *last
;
969 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
971 /* Copy the default cpu flags. */
972 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
974 if (strcasecmp (flag
, "unknown") == 0)
976 /* We turn on everything except for cpu64 in case of
977 CPU_UNKNOWN_FLAGS. */
978 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
979 if (flags
[i
].position
!= Cpu64
)
982 else if (flag
[0] == '~')
984 last
= flag
+ strlen (flag
);
991 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
998 /* First we turn on everything except for cpu64. */
999 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
1000 if (flags
[i
].position
!= Cpu64
)
1003 /* Turn off selective bits. */
1004 for (; next
&& next
< last
; )
1006 str
= next_field (next
, '|', &next
, last
);
1008 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
1011 else if (strcmp (flag
, "0"))
1013 /* Turn on selective bits. */
1014 last
= flag
+ strlen (flag
);
1015 for (next
= flag
; next
&& next
< last
; )
1017 str
= next_field (next
, '|', &next
, last
);
1019 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1023 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1028 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1032 fprintf (table
, " { ");
1034 for (i
= 0; i
< size
- 1; i
++)
1036 if (((i
+ 1) % 20) != 0)
1037 fprintf (table
, "%d, ", modifier
[i
].value
);
1039 fprintf (table
, "%d,", modifier
[i
].value
);
1040 if (((i
+ 1) % 20) == 0)
1041 fprintf (table
, "\n ");
1044 fprintf (table
, "%d },\n", modifier
[i
].value
);
1048 adjust_broadcast_modifier (char **opnd
)
1050 char *str
, *next
, *last
, *op
;
1051 int bcst_type
= INT_MAX
;
1053 /* Skip the immediate operand. */
1055 if (strcasecmp(op
, "Imm8") == 0)
1059 last
= op
+ strlen (op
);
1060 for (next
= op
; next
&& next
< last
; )
1062 str
= next_field (next
, '|', &next
, last
);
1065 if (strcasecmp(str
, "Byte") == 0)
1067 /* The smalest broadcast type, no need to check
1069 bcst_type
= BYTE_BROADCAST
;
1072 else if (strcasecmp(str
, "Word") == 0)
1074 if (bcst_type
> WORD_BROADCAST
)
1075 bcst_type
= WORD_BROADCAST
;
1077 else if (strcasecmp(str
, "Dword") == 0)
1079 if (bcst_type
> DWORD_BROADCAST
)
1080 bcst_type
= DWORD_BROADCAST
;
1082 else if (strcasecmp(str
, "Qword") == 0)
1084 if (bcst_type
> QWORD_BROADCAST
)
1085 bcst_type
= QWORD_BROADCAST
;
1091 if (bcst_type
== INT_MAX
)
1092 fail (_("unknown broadcast operand: %s\n"), op
);
1098 process_i386_opcode_modifier (FILE *table
, char *mod
, char **opnd
, int lineno
)
1100 char *str
, *next
, *last
;
1101 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1103 active_isstring
= 0;
1105 /* Copy the default opcode modifier. */
1106 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1108 if (strcmp (mod
, "0"))
1110 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1112 last
= mod
+ strlen (mod
);
1113 for (next
= mod
; next
&& next
< last
; )
1115 str
= next_field (next
, '|', &next
, last
);
1119 if (strcasecmp(str
, "Broadcast") == 0)
1120 val
= adjust_broadcast_modifier (opnd
);
1121 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1123 if (strcasecmp(str
, "IsString") == 0)
1124 active_isstring
= 1;
1126 if (strcasecmp(str
, "W") == 0)
1129 if (strcasecmp(str
, "No_bSuf") == 0)
1131 if (strcasecmp(str
, "No_wSuf") == 0)
1133 if (strcasecmp(str
, "No_lSuf") == 0)
1135 if (strcasecmp(str
, "No_qSuf") == 0)
1140 if (have_w
&& !bwlq_suf
)
1141 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1142 if (have_w
&& !(bwlq_suf
& 1))
1143 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1145 if (have_w
&& !(bwlq_suf
& ~1))
1147 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1150 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1160 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1161 enum stage stage
, const char *indent
)
1165 fprintf (table
, "{ { ");
1167 for (i
= 0; i
< size
- 1; i
++)
1169 if (((i
+ 1) % 20) != 0)
1170 fprintf (table
, "%d, ", types
[i
].value
);
1172 fprintf (table
, "%d,", types
[i
].value
);
1173 if (((i
+ 1) % 20) == 0)
1175 /* We need \\ for macro. */
1176 if (stage
== stage_macros
)
1177 fprintf (table
, " \\\n%s", indent
);
1179 fprintf (table
, "\n%s", indent
);
1183 fprintf (table
, "%d } }", types
[i
].value
);
1187 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1188 const char *indent
, int lineno
)
1190 char *str
, *next
, *last
;
1191 bitfield types
[ARRAY_SIZE (operand_types
)];
1193 /* Copy the default operand type. */
1194 memcpy (types
, operand_types
, sizeof (types
));
1196 if (strcmp (op
, "0"))
1200 last
= op
+ strlen (op
);
1201 for (next
= op
; next
&& next
< last
; )
1203 str
= next_field (next
, '|', &next
, last
);
1206 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1207 if (strcasecmp(str
, "BaseIndex") == 0)
1212 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1214 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1215 if (!active_cpu_flags
.bitfield
.cpu64
1216 && !active_cpu_flags
.bitfield
.cpumpx
)
1217 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1218 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1219 if (!active_cpu_flags
.bitfield
.cpuno64
)
1220 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1223 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1228 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1229 char *last
, int lineno
)
1232 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1233 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1235 /* Find number of operands. */
1236 operands
= next_field (str
, ',', &str
, last
);
1238 /* Find base_opcode. */
1239 base_opcode
= next_field (str
, ',', &str
, last
);
1241 /* Find extension_opcode. */
1242 extension_opcode
= next_field (str
, ',', &str
, last
);
1244 /* Find opcode_length. */
1245 opcode_length
= next_field (str
, ',', &str
, last
);
1247 /* Find cpu_flags. */
1248 cpu_flags
= next_field (str
, ',', &str
, last
);
1250 /* Find opcode_modifier. */
1251 opcode_modifier
= next_field (str
, ',', &str
, last
);
1253 /* Remove the first {. */
1254 str
= remove_leading_whitespaces (str
);
1257 str
= remove_leading_whitespaces (str
+ 1);
1261 /* There are at least "X}". */
1265 /* Remove trailing white spaces and }. */
1269 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1278 /* Find operand_types. */
1279 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1283 operand_types
[i
] = NULL
;
1287 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1288 if (*operand_types
[i
] == '0')
1291 operand_types
[i
] = NULL
;
1296 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1297 name
, base_opcode
, extension_opcode
, opcode_length
, operands
);
1299 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1301 process_i386_opcode_modifier (table
, opcode_modifier
, operand_types
, lineno
);
1303 fprintf (table
, " { ");
1305 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1307 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1310 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1316 fprintf (table
, ",\n ");
1318 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1321 fprintf (table
, " } },\n");
1324 struct opcode_hash_entry
1326 struct opcode_hash_entry
*next
;
1332 /* Calculate the hash value of an opcode hash entry P. */
1335 opcode_hash_hash (const void *p
)
1337 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1338 return htab_hash_string (entry
->name
);
1341 /* Compare a string Q against an opcode hash entry P. */
1344 opcode_hash_eq (const void *p
, const void *q
)
1346 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1347 const char *name
= (const char *) q
;
1348 return strcmp (name
, entry
->name
) == 0;
1352 process_i386_opcodes (FILE *table
)
1357 char *str
, *p
, *last
, *name
;
1358 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1359 htab_t opcode_hash_table
;
1360 struct opcode_hash_entry
**opcode_array
;
1361 unsigned int opcode_array_size
= 1024;
1362 int lineno
= 0, marker
= 0;
1364 filename
= "i386-opc.tbl";
1368 opcode_array
= (struct opcode_hash_entry
**)
1369 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1371 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1372 opcode_hash_eq
, NULL
,
1375 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1376 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1378 /* Put everything on opcode array. */
1381 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1386 p
= remove_leading_whitespaces (buf
);
1388 /* Skip comments. */
1389 str
= strstr (p
, "//");
1393 /* Remove trailing white spaces. */
1394 remove_trailing_whitespaces (p
);
1399 if (!strcmp("### MARKER ###", buf
))
1403 /* Since we ignore all included files (we only care about their
1404 #define-s here), we don't need to monitor filenames. The final
1405 line number directive is going to refer to the main source file
1410 p
= remove_leading_whitespaces (p
+ 1);
1411 if (!strncmp(p
, "line", 4))
1413 ln
= strtoul (p
, &end
, 10);
1414 if (ln
> 1 && ln
< INT_MAX
1415 && *remove_leading_whitespaces (end
) == '"')
1418 /* Ignore comments. */
1428 last
= p
+ strlen (p
);
1431 name
= next_field (p
, ',', &str
, last
);
1433 /* Get the slot in hash table. */
1434 hash_slot
= (struct opcode_hash_entry
**)
1435 htab_find_slot_with_hash (opcode_hash_table
, name
,
1436 htab_hash_string (name
),
1439 if (*hash_slot
== NULL
)
1441 /* It is the new one. Put it on opcode array. */
1442 if (i
>= opcode_array_size
)
1444 /* Grow the opcode array when needed. */
1445 opcode_array_size
+= 1024;
1446 opcode_array
= (struct opcode_hash_entry
**)
1447 xrealloc (opcode_array
,
1448 sizeof (*opcode_array
) * opcode_array_size
);
1451 opcode_array
[i
] = (struct opcode_hash_entry
*)
1452 xmalloc (sizeof (struct opcode_hash_entry
));
1453 opcode_array
[i
]->next
= NULL
;
1454 opcode_array
[i
]->name
= xstrdup (name
);
1455 opcode_array
[i
]->opcode
= xstrdup (str
);
1456 opcode_array
[i
]->lineno
= lineno
;
1457 *hash_slot
= opcode_array
[i
];
1462 /* Append it to the existing one. */
1464 while ((*entry
) != NULL
)
1465 entry
= &(*entry
)->next
;
1466 *entry
= (struct opcode_hash_entry
*)
1467 xmalloc (sizeof (struct opcode_hash_entry
));
1468 (*entry
)->next
= NULL
;
1469 (*entry
)->name
= (*hash_slot
)->name
;
1470 (*entry
)->opcode
= xstrdup (str
);
1471 (*entry
)->lineno
= lineno
;
1475 /* Process opcode array. */
1476 for (j
= 0; j
< i
; j
++)
1478 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1482 lineno
= next
->lineno
;
1483 last
= str
+ strlen (str
);
1484 output_i386_opcode (table
, name
, str
, last
, lineno
);
1490 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1492 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1494 process_i386_opcode_modifier (table
, "0", NULL
, -1);
1496 fprintf (table
, " { ");
1497 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1498 fprintf (table
, " } }\n");
1500 fprintf (table
, "};\n");
1504 process_i386_registers (FILE *table
)
1508 char *str
, *p
, *last
;
1509 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1510 char *dw2_32_num
, *dw2_64_num
;
1513 filename
= "i386-reg.tbl";
1514 fp
= fopen (filename
, "r");
1516 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1519 fprintf (table
, "\n/* i386 register table. */\n\n");
1520 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1524 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1529 p
= remove_leading_whitespaces (buf
);
1531 /* Skip comments. */
1532 str
= strstr (p
, "//");
1536 /* Remove trailing white spaces. */
1537 remove_trailing_whitespaces (p
);
1542 fprintf (table
, "%s\n", p
);
1550 last
= p
+ strlen (p
);
1552 /* Find reg_name. */
1553 reg_name
= next_field (p
, ',', &str
, last
);
1555 /* Find reg_type. */
1556 reg_type
= next_field (str
, ',', &str
, last
);
1558 /* Find reg_flags. */
1559 reg_flags
= next_field (str
, ',', &str
, last
);
1562 reg_num
= next_field (str
, ',', &str
, last
);
1564 fprintf (table
, " { \"%s\",\n ", reg_name
);
1566 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1569 /* Find 32-bit Dwarf2 register number. */
1570 dw2_32_num
= next_field (str
, ',', &str
, last
);
1572 /* Find 64-bit Dwarf2 register number. */
1573 dw2_64_num
= next_field (str
, ',', &str
, last
);
1575 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1576 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1581 fprintf (table
, "};\n");
1583 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1587 process_i386_initializers (void)
1590 FILE *fp
= fopen ("i386-init.h", "w");
1594 fail (_("can't create i386-init.h, errno = %s\n"),
1597 process_copyright (fp
);
1599 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1601 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1602 init
= xstrdup (cpu_flag_init
[i
].init
);
1603 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1607 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1609 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1610 init
= xstrdup (operand_type_init
[i
].init
);
1611 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1619 /* Program options. */
1620 #define OPTION_SRCDIR 200
1622 struct option long_options
[] =
1624 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1625 {"debug", no_argument
, NULL
, 'd'},
1626 {"version", no_argument
, NULL
, 'V'},
1627 {"help", no_argument
, NULL
, 'h'},
1628 {0, no_argument
, NULL
, 0}
1632 print_version (void)
1634 printf ("%s: version 1.0\n", program_name
);
1639 usage (FILE * stream
, int status
)
1641 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1647 main (int argc
, char **argv
)
1649 extern int chdir (char *);
1650 char *srcdir
= NULL
;
1652 unsigned int i
, cpumax
;
1655 program_name
= *argv
;
1656 xmalloc_set_program_name (program_name
);
1658 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1683 if (chdir (srcdir
) != 0)
1684 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1685 srcdir
, xstrerror (errno
));
1687 /* cpu_flags isn't sorted by position. */
1689 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1690 if (cpu_flags
[i
].position
> cpumax
)
1691 cpumax
= cpu_flags
[i
].position
;
1693 /* Check the unused bitfield in i386_cpu_flags. */
1695 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
1697 if ((cpumax
- 1) != CpuMax
)
1698 fail (_("CpuMax != %d!\n"), cpumax
);
1700 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
1702 if (cpumax
!= CpuMax
)
1703 fail (_("CpuMax != %d!\n"), cpumax
);
1705 c
= CpuNumOfBits
- CpuMax
- 1;
1707 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1710 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
1712 /* Check the unused bitfield in i386_operand_type. */
1714 static_assert (ARRAY_SIZE (operand_types
) == OTNum
+ 1);
1716 static_assert (ARRAY_SIZE (operand_types
) == OTNum
);
1718 c
= OTNumOfBits
- OTMax
- 1;
1720 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1723 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1726 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1727 sizeof (opcode_modifiers
[0]), compare
);
1729 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1730 sizeof (operand_types
[0]), compare
);
1732 table
= fopen ("i386-tbl.h", "w");
1734 fail (_("can't create i386-tbl.h, errno = %s\n"),
1737 process_copyright (table
);
1739 process_i386_opcodes (table
);
1740 process_i386_registers (table
);
1741 process_i386_initializers ();