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_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" },
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_CLDEMOTE_FLAGS",
290 { "CPU_ANY_X87_FLAGS",
291 "CPU_ANY_287_FLAGS|Cpu8087" },
292 { "CPU_ANY_287_FLAGS",
293 "CPU_ANY_387_FLAGS|Cpu287" },
294 { "CPU_ANY_387_FLAGS",
295 "CPU_ANY_687_FLAGS|Cpu387" },
296 { "CPU_ANY_687_FLAGS",
297 "Cpu687|CpuFISTTP" },
298 { "CPU_ANY_MMX_FLAGS",
299 "CPU_3DNOWA_FLAGS" },
300 { "CPU_ANY_SSE_FLAGS",
301 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
302 { "CPU_ANY_SSE2_FLAGS",
303 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
304 { "CPU_ANY_SSE3_FLAGS",
305 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
306 { "CPU_ANY_SSSE3_FLAGS",
307 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
308 { "CPU_ANY_SSE4_1_FLAGS",
309 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
310 { "CPU_ANY_SSE4_2_FLAGS",
312 { "CPU_ANY_AVX_FLAGS",
313 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
314 { "CPU_ANY_AVX2_FLAGS",
316 { "CPU_ANY_AVX512F_FLAGS",
317 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512F" },
318 { "CPU_ANY_AVX512CD_FLAGS",
320 { "CPU_ANY_AVX512ER_FLAGS",
322 { "CPU_ANY_AVX512PF_FLAGS",
324 { "CPU_ANY_AVX512DQ_FLAGS",
326 { "CPU_ANY_AVX512BW_FLAGS",
328 { "CPU_ANY_AVX512VL_FLAGS",
330 { "CPU_ANY_AVX512IFMA_FLAGS",
332 { "CPU_ANY_AVX512VBMI_FLAGS",
334 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
335 "CpuAVX512_4FMAPS" },
336 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
337 "CpuAVX512_4VNNIW" },
338 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
339 "CpuAVX512_VPOPCNTDQ" },
340 { "CPU_ANY_IBT_FLAGS",
342 { "CPU_ANY_SHSTK_FLAGS",
344 { "CPU_ANY_AVX512_VBMI2_FLAGS",
346 { "CPU_ANY_AVX512_VNNI_FLAGS",
348 { "CPU_ANY_AVX512_BITALG_FLAGS",
349 "CpuAVX512_BITALG" },
352 static const initializer operand_type_shorthands
[] =
354 { "Reg8", "Reg|Byte" },
355 { "Reg16", "Reg|Word" },
356 { "Reg32", "Reg|Dword" },
357 { "Reg64", "Reg|Qword" },
358 { "FloatAcc", "Acc|Tbyte" },
359 { "FloatReg", "Reg|Tbyte" },
360 { "RegXMM", "RegSIMD|Xmmword" },
361 { "RegYMM", "RegSIMD|Ymmword" },
362 { "RegZMM", "RegSIMD|Zmmword" },
365 static initializer operand_type_init
[] =
367 { "OPERAND_TYPE_NONE",
369 { "OPERAND_TYPE_REG8",
371 { "OPERAND_TYPE_REG16",
373 { "OPERAND_TYPE_REG32",
375 { "OPERAND_TYPE_REG64",
377 { "OPERAND_TYPE_IMM1",
379 { "OPERAND_TYPE_IMM8",
381 { "OPERAND_TYPE_IMM8S",
383 { "OPERAND_TYPE_IMM16",
385 { "OPERAND_TYPE_IMM32",
387 { "OPERAND_TYPE_IMM32S",
389 { "OPERAND_TYPE_IMM64",
391 { "OPERAND_TYPE_BASEINDEX",
393 { "OPERAND_TYPE_DISP8",
395 { "OPERAND_TYPE_DISP16",
397 { "OPERAND_TYPE_DISP32",
399 { "OPERAND_TYPE_DISP32S",
401 { "OPERAND_TYPE_DISP64",
403 { "OPERAND_TYPE_INOUTPORTREG",
405 { "OPERAND_TYPE_SHIFTCOUNT",
407 { "OPERAND_TYPE_CONTROL",
409 { "OPERAND_TYPE_TEST",
411 { "OPERAND_TYPE_DEBUG",
413 { "OPERAND_TYPE_FLOATREG",
415 { "OPERAND_TYPE_FLOATACC",
417 { "OPERAND_TYPE_SREG2",
419 { "OPERAND_TYPE_SREG3",
421 { "OPERAND_TYPE_ACC",
423 { "OPERAND_TYPE_JUMPABSOLUTE",
425 { "OPERAND_TYPE_REGMMX",
427 { "OPERAND_TYPE_REGXMM",
429 { "OPERAND_TYPE_REGYMM",
431 { "OPERAND_TYPE_REGZMM",
433 { "OPERAND_TYPE_REGMASK",
435 { "OPERAND_TYPE_ESSEG",
437 { "OPERAND_TYPE_ACC32",
439 { "OPERAND_TYPE_ACC64",
441 { "OPERAND_TYPE_INOUTPORTREG",
443 { "OPERAND_TYPE_REG16_INOUTPORTREG",
444 "Reg16|InOutPortReg" },
445 { "OPERAND_TYPE_DISP16_32",
447 { "OPERAND_TYPE_ANYDISP",
448 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
449 { "OPERAND_TYPE_IMM16_32",
451 { "OPERAND_TYPE_IMM16_32S",
453 { "OPERAND_TYPE_IMM16_32_32S",
454 "Imm16|Imm32|Imm32S" },
455 { "OPERAND_TYPE_IMM32_64",
457 { "OPERAND_TYPE_IMM32_32S_DISP32",
458 "Imm32|Imm32S|Disp32" },
459 { "OPERAND_TYPE_IMM64_DISP64",
461 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
462 "Imm32|Imm32S|Imm64|Disp32" },
463 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
464 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
465 { "OPERAND_TYPE_VEC_IMM4",
467 { "OPERAND_TYPE_REGBND",
471 typedef struct bitfield
478 #define BITFIELD(n) { n, 0, #n }
480 static bitfield cpu_flags
[] =
488 BITFIELD (CpuClflush
),
490 BITFIELD (CpuSYSCALL
),
495 BITFIELD (CpuFISTTP
),
501 BITFIELD (CpuSSE4_1
),
502 BITFIELD (CpuSSE4_2
),
505 BITFIELD (CpuAVX512F
),
506 BITFIELD (CpuAVX512CD
),
507 BITFIELD (CpuAVX512ER
),
508 BITFIELD (CpuAVX512PF
),
509 BITFIELD (CpuAVX512VL
),
510 BITFIELD (CpuAVX512DQ
),
511 BITFIELD (CpuAVX512BW
),
517 BITFIELD (Cpu3dnowA
),
518 BITFIELD (CpuPadLock
),
524 BITFIELD (CpuXsaveopt
),
526 BITFIELD (CpuPCLMUL
),
537 BITFIELD (CpuRdtscp
),
538 BITFIELD (CpuFSGSBase
),
545 BITFIELD (CpuINVPCID
),
546 BITFIELD (CpuVMFUNC
),
547 BITFIELD (CpuRDSEED
),
549 BITFIELD (CpuPRFCHW
),
553 BITFIELD (CpuClflushOpt
),
554 BITFIELD (CpuXSAVES
),
555 BITFIELD (CpuXSAVEC
),
556 BITFIELD (CpuPREFETCHWT1
),
562 BITFIELD (CpuAVX512IFMA
),
563 BITFIELD (CpuAVX512VBMI
),
564 BITFIELD (CpuAVX512_4FMAPS
),
565 BITFIELD (CpuAVX512_4VNNIW
),
566 BITFIELD (CpuAVX512_VPOPCNTDQ
),
567 BITFIELD (CpuAVX512_VBMI2
),
568 BITFIELD (CpuAVX512_VNNI
),
569 BITFIELD (CpuAVX512_BITALG
),
570 BITFIELD (CpuMWAITX
),
571 BITFIELD (CpuCLZERO
),
574 BITFIELD (CpuPTWRITE
),
579 BITFIELD (CpuVPCLMULQDQ
),
580 BITFIELD (CpuWBNOINVD
),
581 BITFIELD (CpuPCONFIG
),
582 BITFIELD (CpuWAITPKG
),
583 BITFIELD (CpuCLDEMOTE
),
584 BITFIELD (CpuRegMMX
),
585 BITFIELD (CpuRegXMM
),
586 BITFIELD (CpuRegYMM
),
587 BITFIELD (CpuRegZMM
),
588 BITFIELD (CpuRegMask
),
590 BITFIELD (CpuUnused
),
594 static bitfield opcode_modifiers
[] =
600 BITFIELD (ShortForm
),
602 BITFIELD (JumpDword
),
604 BITFIELD (JumpInterSegment
),
610 BITFIELD (CheckRegSize
),
611 BITFIELD (IgnoreSize
),
612 BITFIELD (DefaultSize
),
621 BITFIELD (BNDPrefixOk
),
622 BITFIELD (NoTrackPrefixOk
),
623 BITFIELD (IsLockable
),
624 BITFIELD (RegKludge
),
625 BITFIELD (Implicit1stXmm0
),
626 BITFIELD (RepPrefixOk
),
627 BITFIELD (HLEPrefixOk
),
630 BITFIELD (AddrPrefixOp0
),
639 BITFIELD (VexOpcode
),
640 BITFIELD (VexSources
),
646 BITFIELD (Broadcast
),
647 BITFIELD (StaticRounding
),
649 BITFIELD (Disp8MemShift
),
650 BITFIELD (NoDefMask
),
651 BITFIELD (ImplicitQuadGroup
),
653 BITFIELD (ATTMnemonic
),
654 BITFIELD (ATTSyntax
),
655 BITFIELD (IntelSyntax
),
660 static bitfield operand_types
[] =
673 BITFIELD (BaseIndex
),
679 BITFIELD (InOutPortReg
),
680 BITFIELD (ShiftCount
),
687 BITFIELD (JumpAbsolute
),
700 BITFIELD (Unspecified
),
709 static const char *filename
;
710 static i386_cpu_flags active_cpu_flags
;
711 static int active_isstring
;
714 compare (const void *x
, const void *y
)
716 const bitfield
*xp
= (const bitfield
*) x
;
717 const bitfield
*yp
= (const bitfield
*) y
;
718 return xp
->position
- yp
->position
;
722 fail (const char *message
, ...)
726 va_start (args
, message
);
727 fprintf (stderr
, _("%s: error: "), program_name
);
728 vfprintf (stderr
, message
, args
);
734 process_copyright (FILE *fp
)
736 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
737 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
739 This file is part of the GNU opcodes library.\n\
741 This library is free software; you can redistribute it and/or modify\n\
742 it under the terms of the GNU General Public License as published by\n\
743 the Free Software Foundation; either version 3, or (at your option)\n\
744 any later version.\n\
746 It is distributed in the hope that it will be useful, but WITHOUT\n\
747 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
748 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
749 License for more details.\n\
751 You should have received a copy of the GNU General Public License\n\
752 along with this program; if not, write to the Free Software\n\
753 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
754 MA 02110-1301, USA. */\n");
757 /* Remove leading white spaces. */
760 remove_leading_whitespaces (char *str
)
762 while (ISSPACE (*str
))
767 /* Remove trailing white spaces. */
770 remove_trailing_whitespaces (char *str
)
772 size_t last
= strlen (str
);
780 if (ISSPACE (str
[last
]))
788 /* Find next field separated by SEP and terminate it. Return a
789 pointer to the one after it. */
792 next_field (char *str
, char sep
, char **next
, char *last
)
796 p
= remove_leading_whitespaces (str
);
797 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
800 remove_trailing_whitespaces (p
);
810 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
813 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
816 char *str
, *next
, *last
;
819 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
820 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
822 /* Turn on selective bits. */
823 char *init
= xstrdup (cpu_flag_init
[i
].init
);
824 last
= init
+ strlen (init
);
825 for (next
= init
; next
&& next
< last
; )
827 str
= next_field (next
, '|', &next
, last
);
829 set_bitfield (str
, array
, 1, size
, lineno
);
835 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
836 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
838 /* Turn on selective bits. */
839 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
840 last
= init
+ strlen (init
);
841 for (next
= init
; next
&& next
< last
; )
843 str
= next_field (next
, '|', &next
, last
);
845 set_bitfield (str
, array
, 1, size
, lineno
);
855 set_bitfield (char *f
, bitfield
*array
, int value
,
856 unsigned int size
, int lineno
)
860 if (strcmp (f
, "CpuFP") == 0)
862 set_bitfield("Cpu387", array
, value
, size
, lineno
);
863 set_bitfield("Cpu287", array
, value
, size
, lineno
);
866 else if (strcmp (f
, "Mmword") == 0)
868 else if (strcmp (f
, "Oword") == 0)
871 for (i
= 0; i
< size
; i
++)
872 if (strcasecmp (array
[i
].name
, f
) == 0)
874 array
[i
].value
= value
;
880 const char *v
= strchr (f
, '=');
887 for (i
= 0; i
< size
; i
++)
888 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
890 value
= strtol (v
+ 1, &end
, 0);
893 array
[i
].value
= value
;
901 /* Handle shorthands. */
902 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
906 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
908 fail (_("unknown bitfield: %s\n"), f
);
912 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
913 int macro
, const char *comma
, const char *indent
)
917 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
919 fprintf (table
, "%s{ { ", indent
);
921 for (i
= 0; i
< size
- 1; i
++)
923 if (((i
+ 1) % 20) != 0)
924 fprintf (table
, "%d, ", flags
[i
].value
);
926 fprintf (table
, "%d,", flags
[i
].value
);
927 if (((i
+ 1) % 20) == 0)
929 /* We need \\ for macro. */
931 fprintf (table
, " \\\n %s", indent
);
933 fprintf (table
, "\n %s", indent
);
936 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
939 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
943 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
944 const char *comma
, const char *indent
,
947 char *str
, *next
, *last
;
949 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
951 /* Copy the default cpu flags. */
952 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
954 if (strcasecmp (flag
, "unknown") == 0)
956 /* We turn on everything except for cpu64 in case of
957 CPU_UNKNOWN_FLAGS. */
958 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
959 if (flags
[i
].position
!= Cpu64
)
962 else if (flag
[0] == '~')
964 last
= flag
+ strlen (flag
);
971 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
978 /* First we turn on everything except for cpu64. */
979 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
980 if (flags
[i
].position
!= Cpu64
)
983 /* Turn off selective bits. */
984 for (; next
&& next
< last
; )
986 str
= next_field (next
, '|', &next
, last
);
988 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
991 else if (strcmp (flag
, "0"))
993 /* Turn on selective bits. */
994 last
= flag
+ strlen (flag
);
995 for (next
= flag
; next
&& next
< last
; )
997 str
= next_field (next
, '|', &next
, last
);
999 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1003 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1008 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1012 fprintf (table
, " { ");
1014 for (i
= 0; i
< size
- 1; i
++)
1016 if (((i
+ 1) % 20) != 0)
1017 fprintf (table
, "%d, ", modifier
[i
].value
);
1019 fprintf (table
, "%d,", modifier
[i
].value
);
1020 if (((i
+ 1) % 20) == 0)
1021 fprintf (table
, "\n ");
1024 fprintf (table
, "%d },\n", modifier
[i
].value
);
1028 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
1030 char *str
, *next
, *last
;
1031 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1033 active_isstring
= 0;
1035 /* Copy the default opcode modifier. */
1036 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1038 if (strcmp (mod
, "0"))
1040 last
= mod
+ strlen (mod
);
1041 for (next
= mod
; next
&& next
< last
; )
1043 str
= next_field (next
, '|', &next
, last
);
1046 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
1048 if (strcasecmp(str
, "IsString") == 0)
1049 active_isstring
= 1;
1053 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1063 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1064 enum stage stage
, const char *indent
)
1068 fprintf (table
, "{ { ");
1070 for (i
= 0; i
< size
- 1; i
++)
1072 if (((i
+ 1) % 20) != 0)
1073 fprintf (table
, "%d, ", types
[i
].value
);
1075 fprintf (table
, "%d,", types
[i
].value
);
1076 if (((i
+ 1) % 20) == 0)
1078 /* We need \\ for macro. */
1079 if (stage
== stage_macros
)
1080 fprintf (table
, " \\\n%s", indent
);
1082 fprintf (table
, "\n%s", indent
);
1086 fprintf (table
, "%d } }", types
[i
].value
);
1090 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1091 const char *indent
, int lineno
)
1093 char *str
, *next
, *last
;
1094 bitfield types
[ARRAY_SIZE (operand_types
)];
1096 /* Copy the default operand type. */
1097 memcpy (types
, operand_types
, sizeof (types
));
1099 if (strcmp (op
, "0"))
1103 last
= op
+ strlen (op
);
1104 for (next
= op
; next
&& next
< last
; )
1106 str
= next_field (next
, '|', &next
, last
);
1109 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1110 if (strcasecmp(str
, "BaseIndex") == 0)
1115 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1117 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1118 if (!active_cpu_flags
.bitfield
.cpu64
1119 && !active_cpu_flags
.bitfield
.cpumpx
)
1120 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1121 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1122 if (!active_cpu_flags
.bitfield
.cpuno64
)
1123 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1126 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1131 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1132 char *last
, int lineno
)
1135 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1136 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1138 /* Find number of operands. */
1139 operands
= next_field (str
, ',', &str
, last
);
1141 /* Find base_opcode. */
1142 base_opcode
= next_field (str
, ',', &str
, last
);
1144 /* Find extension_opcode. */
1145 extension_opcode
= next_field (str
, ',', &str
, last
);
1147 /* Find opcode_length. */
1148 opcode_length
= next_field (str
, ',', &str
, last
);
1150 /* Find cpu_flags. */
1151 cpu_flags
= next_field (str
, ',', &str
, last
);
1153 /* Find opcode_modifier. */
1154 opcode_modifier
= next_field (str
, ',', &str
, last
);
1156 /* Remove the first {. */
1157 str
= remove_leading_whitespaces (str
);
1160 str
= remove_leading_whitespaces (str
+ 1);
1164 /* There are at least "X}". */
1168 /* Remove trailing white spaces and }. */
1172 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1181 /* Find operand_types. */
1182 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1186 operand_types
[i
] = NULL
;
1190 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1191 if (*operand_types
[i
] == '0')
1194 operand_types
[i
] = NULL
;
1199 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1200 name
, operands
, base_opcode
, extension_opcode
,
1203 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1205 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1207 fprintf (table
, " { ");
1209 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1211 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1214 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1220 fprintf (table
, ",\n ");
1222 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1225 fprintf (table
, " } },\n");
1228 struct opcode_hash_entry
1230 struct opcode_hash_entry
*next
;
1236 /* Calculate the hash value of an opcode hash entry P. */
1239 opcode_hash_hash (const void *p
)
1241 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1242 return htab_hash_string (entry
->name
);
1245 /* Compare a string Q against an opcode hash entry P. */
1248 opcode_hash_eq (const void *p
, const void *q
)
1250 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1251 const char *name
= (const char *) q
;
1252 return strcmp (name
, entry
->name
) == 0;
1256 process_i386_opcodes (FILE *table
)
1261 char *str
, *p
, *last
, *name
;
1262 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1263 htab_t opcode_hash_table
;
1264 struct opcode_hash_entry
**opcode_array
;
1265 unsigned int opcode_array_size
= 1024;
1268 filename
= "i386-opc.tbl";
1269 fp
= fopen (filename
, "r");
1272 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1276 opcode_array
= (struct opcode_hash_entry
**)
1277 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1279 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1280 opcode_hash_eq
, NULL
,
1283 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1284 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1286 /* Put everything on opcode array. */
1289 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1294 p
= remove_leading_whitespaces (buf
);
1296 /* Skip comments. */
1297 str
= strstr (p
, "//");
1301 /* Remove trailing white spaces. */
1302 remove_trailing_whitespaces (p
);
1307 /* Ignore comments. */
1315 last
= p
+ strlen (p
);
1318 name
= next_field (p
, ',', &str
, last
);
1320 /* Get the slot in hash table. */
1321 hash_slot
= (struct opcode_hash_entry
**)
1322 htab_find_slot_with_hash (opcode_hash_table
, name
,
1323 htab_hash_string (name
),
1326 if (*hash_slot
== NULL
)
1328 /* It is the new one. Put it on opcode array. */
1329 if (i
>= opcode_array_size
)
1331 /* Grow the opcode array when needed. */
1332 opcode_array_size
+= 1024;
1333 opcode_array
= (struct opcode_hash_entry
**)
1334 xrealloc (opcode_array
,
1335 sizeof (*opcode_array
) * opcode_array_size
);
1338 opcode_array
[i
] = (struct opcode_hash_entry
*)
1339 xmalloc (sizeof (struct opcode_hash_entry
));
1340 opcode_array
[i
]->next
= NULL
;
1341 opcode_array
[i
]->name
= xstrdup (name
);
1342 opcode_array
[i
]->opcode
= xstrdup (str
);
1343 opcode_array
[i
]->lineno
= lineno
;
1344 *hash_slot
= opcode_array
[i
];
1349 /* Append it to the existing one. */
1351 while ((*entry
) != NULL
)
1352 entry
= &(*entry
)->next
;
1353 *entry
= (struct opcode_hash_entry
*)
1354 xmalloc (sizeof (struct opcode_hash_entry
));
1355 (*entry
)->next
= NULL
;
1356 (*entry
)->name
= (*hash_slot
)->name
;
1357 (*entry
)->opcode
= xstrdup (str
);
1358 (*entry
)->lineno
= lineno
;
1362 /* Process opcode array. */
1363 for (j
= 0; j
< i
; j
++)
1365 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1369 lineno
= next
->lineno
;
1370 last
= str
+ strlen (str
);
1371 output_i386_opcode (table
, name
, str
, last
, lineno
);
1377 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1379 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1381 process_i386_opcode_modifier (table
, "0", -1);
1383 fprintf (table
, " { ");
1384 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1385 fprintf (table
, " } }\n");
1387 fprintf (table
, "};\n");
1391 process_i386_registers (FILE *table
)
1395 char *str
, *p
, *last
;
1396 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1397 char *dw2_32_num
, *dw2_64_num
;
1400 filename
= "i386-reg.tbl";
1401 fp
= fopen (filename
, "r");
1403 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1406 fprintf (table
, "\n/* i386 register table. */\n\n");
1407 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1411 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1416 p
= remove_leading_whitespaces (buf
);
1418 /* Skip comments. */
1419 str
= strstr (p
, "//");
1423 /* Remove trailing white spaces. */
1424 remove_trailing_whitespaces (p
);
1429 fprintf (table
, "%s\n", p
);
1437 last
= p
+ strlen (p
);
1439 /* Find reg_name. */
1440 reg_name
= next_field (p
, ',', &str
, last
);
1442 /* Find reg_type. */
1443 reg_type
= next_field (str
, ',', &str
, last
);
1445 /* Find reg_flags. */
1446 reg_flags
= next_field (str
, ',', &str
, last
);
1449 reg_num
= next_field (str
, ',', &str
, last
);
1451 fprintf (table
, " { \"%s\",\n ", reg_name
);
1453 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1456 /* Find 32-bit Dwarf2 register number. */
1457 dw2_32_num
= next_field (str
, ',', &str
, last
);
1459 /* Find 64-bit Dwarf2 register number. */
1460 dw2_64_num
= next_field (str
, ',', &str
, last
);
1462 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1463 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1468 fprintf (table
, "};\n");
1470 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1474 process_i386_initializers (void)
1477 FILE *fp
= fopen ("i386-init.h", "w");
1481 fail (_("can't create i386-init.h, errno = %s\n"),
1484 process_copyright (fp
);
1486 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1488 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1489 init
= xstrdup (cpu_flag_init
[i
].init
);
1490 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1494 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1496 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1497 init
= xstrdup (operand_type_init
[i
].init
);
1498 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1506 /* Program options. */
1507 #define OPTION_SRCDIR 200
1509 struct option long_options
[] =
1511 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1512 {"debug", no_argument
, NULL
, 'd'},
1513 {"version", no_argument
, NULL
, 'V'},
1514 {"help", no_argument
, NULL
, 'h'},
1515 {0, no_argument
, NULL
, 0}
1519 print_version (void)
1521 printf ("%s: version 1.0\n", program_name
);
1526 usage (FILE * stream
, int status
)
1528 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1534 main (int argc
, char **argv
)
1536 extern int chdir (char *);
1537 char *srcdir
= NULL
;
1539 unsigned int i
, cpumax
;
1542 program_name
= *argv
;
1543 xmalloc_set_program_name (program_name
);
1545 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1570 if (chdir (srcdir
) != 0)
1571 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1572 srcdir
, xstrerror (errno
));
1574 /* cpu_flags isn't sorted by position. */
1576 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1577 if (cpu_flags
[i
].position
> cpumax
)
1578 cpumax
= cpu_flags
[i
].position
;
1580 /* Check the unused bitfield in i386_cpu_flags. */
1582 if ((cpumax
- 1) != CpuMax
)
1583 fail (_("CpuMax != %d!\n"), cpumax
);
1585 if (cpumax
!= CpuMax
)
1586 fail (_("CpuMax != %d!\n"), cpumax
);
1588 c
= CpuNumOfBits
- CpuMax
- 1;
1590 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1593 /* Check the unused bitfield in i386_operand_type. */
1595 c
= OTNumOfBits
- OTMax
- 1;
1597 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1600 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1603 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1604 sizeof (opcode_modifiers
[0]), compare
);
1606 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1607 sizeof (operand_types
[0]), compare
);
1609 table
= fopen ("i386-tbl.h", "w");
1611 fail (_("can't create i386-tbl.h, errno = %s\n"),
1614 process_copyright (table
);
1616 process_i386_opcodes (table
);
1617 process_i386_registers (table
);
1618 process_i386_initializers ();