1 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
24 #include "libiberty.h"
26 #include "safe-ctype.h"
31 #define _(String) gettext (String)
33 static const char *program_name
= NULL
;
36 typedef struct initializer
42 static initializer cpu_flag_init
[] =
44 { "CPU_UNKNOWN_FLAGS",
45 "~(CpuL1OM|CpuK1OM)" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
55 "CPU_I186_FLAGS|Cpu286" },
57 "CPU_I286_FLAGS|Cpu386" },
59 "CPU_I386_FLAGS|Cpu486" },
61 "CPU_I486_FLAGS|Cpu387|Cpu586" },
63 "CPU_I586_FLAGS|Cpu686|Cpu687" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "CPU_I686_FLAGS|CpuNop" },
67 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
69 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
71 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
73 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
75 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
77 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
79 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
83 "CPU_K6_FLAGS|Cpu3dnow" },
85 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
87 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
91 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
95 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
97 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
99 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_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_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
111 "CPU_387_FLAGS|Cpu687" },
112 { "CPU_CLFLUSH_FLAGS",
116 { "CPU_SYSCALL_FLAGS",
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" },
151 "CPU_XSAVE_FLAGS|CpuLWP" },
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|CPU_XSAVE_FLAGS|CpuAVX" },
197 "CPU_AVX_FLAGS|CpuAVX2" },
198 { "CPU_AVX512F_FLAGS",
199 "CPU_AVX2_FLAGS|CpuVREX|CpuAVX512F" },
200 { "CPU_AVX512CD_FLAGS",
201 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
202 { "CPU_AVX512ER_FLAGS",
203 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
204 { "CPU_AVX512PF_FLAGS",
205 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
206 { "CPU_AVX512DQ_FLAGS",
207 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
208 { "CPU_AVX512BW_FLAGS",
209 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
210 { "CPU_AVX512VL_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
212 { "CPU_AVX512IFMA_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
214 { "CPU_AVX512VBMI_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
216 { "CPU_AVX512_4FMAPS_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
218 { "CPU_AVX512_4VNNIW_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
220 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
222 { "CPU_AVX512_VBMI2_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
224 { "CPU_AVX512_VNNI_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
226 { "CPU_AVX512_BITALG_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
233 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
236 { "CPU_RDSEED_FLAGS",
238 { "CPU_PRFCHW_FLAGS",
243 "CPU_XSAVE_FLAGS|CpuMPX" },
245 "CPU_SSE2_FLAGS|CpuSHA" },
246 { "CPU_CLFLUSHOPT_FLAGS",
248 { "CPU_XSAVES_FLAGS",
249 "CPU_XSAVE_FLAGS|CpuXSAVES" },
250 { "CPU_XSAVEC_FLAGS",
251 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
252 { "CPU_PREFETCHWT1_FLAGS",
258 { "CPU_CLZERO_FLAGS",
260 { "CPU_MWAITX_FLAGS",
263 "CPU_XSAVE_FLAGS|CpuOSPKE" },
266 { "CPU_PTWRITE_FLAGS",
276 { "CPU_VPCLMULQDQ_FLAGS",
278 { "CPU_WBNOINVD_FLAGS",
280 { "CPU_PCONFIG_FLAGS",
282 { "CPU_WAITPKG_FLAGS",
284 { "CPU_CLDEMOTE_FLAGS",
286 { "CPU_MOVDIRI_FLAGS",
288 { "CPU_MOVDIR64B_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|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" },
350 { "CPU_ANY_MOVDIRI_FLAGS",
352 { "CPU_ANY_MOVDIR64B_FLAGS",
356 static const initializer operand_type_shorthands
[] =
358 { "Reg8", "Reg|Byte" },
359 { "Reg16", "Reg|Word" },
360 { "Reg32", "Reg|Dword" },
361 { "Reg64", "Reg|Qword" },
362 { "FloatAcc", "Acc|Tbyte" },
363 { "FloatReg", "Reg|Tbyte" },
364 { "RegXMM", "RegSIMD|Xmmword" },
365 { "RegYMM", "RegSIMD|Ymmword" },
366 { "RegZMM", "RegSIMD|Zmmword" },
369 static initializer operand_type_init
[] =
371 { "OPERAND_TYPE_NONE",
373 { "OPERAND_TYPE_REG8",
375 { "OPERAND_TYPE_REG16",
377 { "OPERAND_TYPE_REG32",
379 { "OPERAND_TYPE_REG64",
381 { "OPERAND_TYPE_IMM1",
383 { "OPERAND_TYPE_IMM8",
385 { "OPERAND_TYPE_IMM8S",
387 { "OPERAND_TYPE_IMM16",
389 { "OPERAND_TYPE_IMM32",
391 { "OPERAND_TYPE_IMM32S",
393 { "OPERAND_TYPE_IMM64",
395 { "OPERAND_TYPE_BASEINDEX",
397 { "OPERAND_TYPE_DISP8",
399 { "OPERAND_TYPE_DISP16",
401 { "OPERAND_TYPE_DISP32",
403 { "OPERAND_TYPE_DISP32S",
405 { "OPERAND_TYPE_DISP64",
407 { "OPERAND_TYPE_INOUTPORTREG",
409 { "OPERAND_TYPE_SHIFTCOUNT",
411 { "OPERAND_TYPE_CONTROL",
413 { "OPERAND_TYPE_TEST",
415 { "OPERAND_TYPE_DEBUG",
417 { "OPERAND_TYPE_FLOATREG",
419 { "OPERAND_TYPE_FLOATACC",
421 { "OPERAND_TYPE_SREG2",
423 { "OPERAND_TYPE_SREG3",
425 { "OPERAND_TYPE_ACC",
427 { "OPERAND_TYPE_JUMPABSOLUTE",
429 { "OPERAND_TYPE_REGMMX",
431 { "OPERAND_TYPE_REGXMM",
433 { "OPERAND_TYPE_REGYMM",
435 { "OPERAND_TYPE_REGZMM",
437 { "OPERAND_TYPE_REGMASK",
439 { "OPERAND_TYPE_ESSEG",
441 { "OPERAND_TYPE_ACC32",
443 { "OPERAND_TYPE_ACC64",
445 { "OPERAND_TYPE_INOUTPORTREG",
447 { "OPERAND_TYPE_REG16_INOUTPORTREG",
448 "Reg16|InOutPortReg" },
449 { "OPERAND_TYPE_DISP16_32",
451 { "OPERAND_TYPE_ANYDISP",
452 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
453 { "OPERAND_TYPE_IMM16_32",
455 { "OPERAND_TYPE_IMM16_32S",
457 { "OPERAND_TYPE_IMM16_32_32S",
458 "Imm16|Imm32|Imm32S" },
459 { "OPERAND_TYPE_IMM32_64",
461 { "OPERAND_TYPE_IMM32_32S_DISP32",
462 "Imm32|Imm32S|Disp32" },
463 { "OPERAND_TYPE_IMM64_DISP64",
465 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
466 "Imm32|Imm32S|Imm64|Disp32" },
467 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
468 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
469 { "OPERAND_TYPE_VEC_IMM4",
471 { "OPERAND_TYPE_REGBND",
475 typedef struct bitfield
482 #define BITFIELD(n) { n, 0, #n }
484 static bitfield cpu_flags
[] =
492 BITFIELD (CpuClflush
),
494 BITFIELD (CpuSYSCALL
),
499 BITFIELD (CpuFISTTP
),
505 BITFIELD (CpuSSE4_1
),
506 BITFIELD (CpuSSE4_2
),
509 BITFIELD (CpuAVX512F
),
510 BITFIELD (CpuAVX512CD
),
511 BITFIELD (CpuAVX512ER
),
512 BITFIELD (CpuAVX512PF
),
513 BITFIELD (CpuAVX512VL
),
514 BITFIELD (CpuAVX512DQ
),
515 BITFIELD (CpuAVX512BW
),
521 BITFIELD (Cpu3dnowA
),
522 BITFIELD (CpuPadLock
),
528 BITFIELD (CpuXsaveopt
),
530 BITFIELD (CpuPCLMUL
),
541 BITFIELD (CpuRdtscp
),
542 BITFIELD (CpuFSGSBase
),
549 BITFIELD (CpuINVPCID
),
550 BITFIELD (CpuVMFUNC
),
551 BITFIELD (CpuRDSEED
),
553 BITFIELD (CpuPRFCHW
),
557 BITFIELD (CpuClflushOpt
),
558 BITFIELD (CpuXSAVES
),
559 BITFIELD (CpuXSAVEC
),
560 BITFIELD (CpuPREFETCHWT1
),
566 BITFIELD (CpuAVX512IFMA
),
567 BITFIELD (CpuAVX512VBMI
),
568 BITFIELD (CpuAVX512_4FMAPS
),
569 BITFIELD (CpuAVX512_4VNNIW
),
570 BITFIELD (CpuAVX512_VPOPCNTDQ
),
571 BITFIELD (CpuAVX512_VBMI2
),
572 BITFIELD (CpuAVX512_VNNI
),
573 BITFIELD (CpuAVX512_BITALG
),
574 BITFIELD (CpuMWAITX
),
575 BITFIELD (CpuCLZERO
),
578 BITFIELD (CpuPTWRITE
),
583 BITFIELD (CpuVPCLMULQDQ
),
584 BITFIELD (CpuWBNOINVD
),
585 BITFIELD (CpuPCONFIG
),
586 BITFIELD (CpuWAITPKG
),
587 BITFIELD (CpuCLDEMOTE
),
588 BITFIELD (CpuMOVDIRI
),
589 BITFIELD (CpuMOVDIR64B
),
590 BITFIELD (CpuRegMMX
),
591 BITFIELD (CpuRegXMM
),
592 BITFIELD (CpuRegYMM
),
593 BITFIELD (CpuRegZMM
),
594 BITFIELD (CpuRegMask
),
596 BITFIELD (CpuUnused
),
600 static bitfield opcode_modifiers
[] =
606 BITFIELD (ShortForm
),
608 BITFIELD (JumpDword
),
610 BITFIELD (JumpInterSegment
),
616 BITFIELD (CheckRegSize
),
617 BITFIELD (IgnoreSize
),
618 BITFIELD (DefaultSize
),
627 BITFIELD (BNDPrefixOk
),
628 BITFIELD (NoTrackPrefixOk
),
629 BITFIELD (IsLockable
),
630 BITFIELD (RegKludge
),
631 BITFIELD (Implicit1stXmm0
),
632 BITFIELD (RepPrefixOk
),
633 BITFIELD (HLEPrefixOk
),
636 BITFIELD (AddrPrefixOp0
),
637 BITFIELD (AddrPrefixOpReg
),
646 BITFIELD (VexOpcode
),
647 BITFIELD (VexSources
),
653 BITFIELD (Broadcast
),
654 BITFIELD (StaticRounding
),
656 BITFIELD (Disp8MemShift
),
657 BITFIELD (NoDefMask
),
658 BITFIELD (ImplicitQuadGroup
),
660 BITFIELD (ATTMnemonic
),
661 BITFIELD (ATTSyntax
),
662 BITFIELD (IntelSyntax
),
667 static bitfield operand_types
[] =
680 BITFIELD (BaseIndex
),
686 BITFIELD (InOutPortReg
),
687 BITFIELD (ShiftCount
),
694 BITFIELD (JumpAbsolute
),
707 BITFIELD (Unspecified
),
716 static const char *filename
;
717 static i386_cpu_flags active_cpu_flags
;
718 static int active_isstring
;
721 compare (const void *x
, const void *y
)
723 const bitfield
*xp
= (const bitfield
*) x
;
724 const bitfield
*yp
= (const bitfield
*) y
;
725 return xp
->position
- yp
->position
;
729 fail (const char *message
, ...)
733 va_start (args
, message
);
734 fprintf (stderr
, _("%s: error: "), program_name
);
735 vfprintf (stderr
, message
, args
);
741 process_copyright (FILE *fp
)
743 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
744 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
746 This file is part of the GNU opcodes library.\n\
748 This library is free software; you can redistribute it and/or modify\n\
749 it under the terms of the GNU General Public License as published by\n\
750 the Free Software Foundation; either version 3, or (at your option)\n\
751 any later version.\n\
753 It is distributed in the hope that it will be useful, but WITHOUT\n\
754 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
755 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
756 License for more details.\n\
758 You should have received a copy of the GNU General Public License\n\
759 along with this program; if not, write to the Free Software\n\
760 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
761 MA 02110-1301, USA. */\n");
764 /* Remove leading white spaces. */
767 remove_leading_whitespaces (char *str
)
769 while (ISSPACE (*str
))
774 /* Remove trailing white spaces. */
777 remove_trailing_whitespaces (char *str
)
779 size_t last
= strlen (str
);
787 if (ISSPACE (str
[last
]))
795 /* Find next field separated by SEP and terminate it. Return a
796 pointer to the one after it. */
799 next_field (char *str
, char sep
, char **next
, char *last
)
803 p
= remove_leading_whitespaces (str
);
804 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
807 remove_trailing_whitespaces (p
);
817 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
820 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
823 char *str
, *next
, *last
;
826 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
827 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
829 /* Turn on selective bits. */
830 char *init
= xstrdup (cpu_flag_init
[i
].init
);
831 last
= init
+ strlen (init
);
832 for (next
= init
; next
&& next
< last
; )
834 str
= next_field (next
, '|', &next
, last
);
836 set_bitfield (str
, array
, 1, size
, lineno
);
842 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
843 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
845 /* Turn on selective bits. */
846 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
847 last
= init
+ strlen (init
);
848 for (next
= init
; next
&& next
< last
; )
850 str
= next_field (next
, '|', &next
, last
);
852 set_bitfield (str
, array
, 1, size
, lineno
);
862 set_bitfield (char *f
, bitfield
*array
, int value
,
863 unsigned int size
, int lineno
)
867 if (strcmp (f
, "CpuFP") == 0)
869 set_bitfield("Cpu387", array
, value
, size
, lineno
);
870 set_bitfield("Cpu287", array
, value
, size
, lineno
);
873 else if (strcmp (f
, "Mmword") == 0)
875 else if (strcmp (f
, "Oword") == 0)
878 for (i
= 0; i
< size
; i
++)
879 if (strcasecmp (array
[i
].name
, f
) == 0)
881 array
[i
].value
= value
;
887 const char *v
= strchr (f
, '=');
894 for (i
= 0; i
< size
; i
++)
895 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
897 value
= strtol (v
+ 1, &end
, 0);
900 array
[i
].value
= value
;
908 /* Handle shorthands. */
909 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
913 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
915 fail (_("unknown bitfield: %s\n"), f
);
919 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
920 int macro
, const char *comma
, const char *indent
)
924 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
926 fprintf (table
, "%s{ { ", indent
);
928 for (i
= 0; i
< size
- 1; i
++)
930 if (((i
+ 1) % 20) != 0)
931 fprintf (table
, "%d, ", flags
[i
].value
);
933 fprintf (table
, "%d,", flags
[i
].value
);
934 if (((i
+ 1) % 20) == 0)
936 /* We need \\ for macro. */
938 fprintf (table
, " \\\n %s", indent
);
940 fprintf (table
, "\n %s", indent
);
943 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
946 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
950 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
951 const char *comma
, const char *indent
,
954 char *str
, *next
, *last
;
956 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
958 /* Copy the default cpu flags. */
959 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
961 if (strcasecmp (flag
, "unknown") == 0)
963 /* We turn on everything except for cpu64 in case of
964 CPU_UNKNOWN_FLAGS. */
965 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
966 if (flags
[i
].position
!= Cpu64
)
969 else if (flag
[0] == '~')
971 last
= flag
+ strlen (flag
);
978 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
985 /* First we turn on everything except for cpu64. */
986 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
987 if (flags
[i
].position
!= Cpu64
)
990 /* Turn off selective bits. */
991 for (; next
&& next
< last
; )
993 str
= next_field (next
, '|', &next
, last
);
995 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
998 else if (strcmp (flag
, "0"))
1000 /* Turn on selective bits. */
1001 last
= flag
+ strlen (flag
);
1002 for (next
= flag
; next
&& next
< last
; )
1004 str
= next_field (next
, '|', &next
, last
);
1006 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
1010 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1015 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1019 fprintf (table
, " { ");
1021 for (i
= 0; i
< size
- 1; i
++)
1023 if (((i
+ 1) % 20) != 0)
1024 fprintf (table
, "%d, ", modifier
[i
].value
);
1026 fprintf (table
, "%d,", modifier
[i
].value
);
1027 if (((i
+ 1) % 20) == 0)
1028 fprintf (table
, "\n ");
1031 fprintf (table
, "%d },\n", modifier
[i
].value
);
1035 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
1037 char *str
, *next
, *last
;
1038 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1040 active_isstring
= 0;
1042 /* Copy the default opcode modifier. */
1043 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1045 if (strcmp (mod
, "0"))
1047 last
= mod
+ strlen (mod
);
1048 for (next
= mod
; next
&& next
< last
; )
1050 str
= next_field (next
, '|', &next
, last
);
1053 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
1055 if (strcasecmp(str
, "IsString") == 0)
1056 active_isstring
= 1;
1060 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1070 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1071 enum stage stage
, const char *indent
)
1075 fprintf (table
, "{ { ");
1077 for (i
= 0; i
< size
- 1; i
++)
1079 if (((i
+ 1) % 20) != 0)
1080 fprintf (table
, "%d, ", types
[i
].value
);
1082 fprintf (table
, "%d,", types
[i
].value
);
1083 if (((i
+ 1) % 20) == 0)
1085 /* We need \\ for macro. */
1086 if (stage
== stage_macros
)
1087 fprintf (table
, " \\\n%s", indent
);
1089 fprintf (table
, "\n%s", indent
);
1093 fprintf (table
, "%d } }", types
[i
].value
);
1097 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1098 const char *indent
, int lineno
)
1100 char *str
, *next
, *last
;
1101 bitfield types
[ARRAY_SIZE (operand_types
)];
1103 /* Copy the default operand type. */
1104 memcpy (types
, operand_types
, sizeof (types
));
1106 if (strcmp (op
, "0"))
1110 last
= op
+ strlen (op
);
1111 for (next
= op
; next
&& next
< last
; )
1113 str
= next_field (next
, '|', &next
, last
);
1116 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1117 if (strcasecmp(str
, "BaseIndex") == 0)
1122 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1124 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1125 if (!active_cpu_flags
.bitfield
.cpu64
1126 && !active_cpu_flags
.bitfield
.cpumpx
)
1127 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1128 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1129 if (!active_cpu_flags
.bitfield
.cpuno64
)
1130 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1133 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1138 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1139 char *last
, int lineno
)
1142 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1143 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1145 /* Find number of operands. */
1146 operands
= next_field (str
, ',', &str
, last
);
1148 /* Find base_opcode. */
1149 base_opcode
= next_field (str
, ',', &str
, last
);
1151 /* Find extension_opcode. */
1152 extension_opcode
= next_field (str
, ',', &str
, last
);
1154 /* Find opcode_length. */
1155 opcode_length
= next_field (str
, ',', &str
, last
);
1157 /* Find cpu_flags. */
1158 cpu_flags
= next_field (str
, ',', &str
, last
);
1160 /* Find opcode_modifier. */
1161 opcode_modifier
= next_field (str
, ',', &str
, last
);
1163 /* Remove the first {. */
1164 str
= remove_leading_whitespaces (str
);
1167 str
= remove_leading_whitespaces (str
+ 1);
1171 /* There are at least "X}". */
1175 /* Remove trailing white spaces and }. */
1179 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1188 /* Find operand_types. */
1189 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1193 operand_types
[i
] = NULL
;
1197 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1198 if (*operand_types
[i
] == '0')
1201 operand_types
[i
] = NULL
;
1206 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1207 name
, operands
, base_opcode
, extension_opcode
,
1210 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1212 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1214 fprintf (table
, " { ");
1216 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1218 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1221 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1227 fprintf (table
, ",\n ");
1229 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1232 fprintf (table
, " } },\n");
1235 struct opcode_hash_entry
1237 struct opcode_hash_entry
*next
;
1243 /* Calculate the hash value of an opcode hash entry P. */
1246 opcode_hash_hash (const void *p
)
1248 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1249 return htab_hash_string (entry
->name
);
1252 /* Compare a string Q against an opcode hash entry P. */
1255 opcode_hash_eq (const void *p
, const void *q
)
1257 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1258 const char *name
= (const char *) q
;
1259 return strcmp (name
, entry
->name
) == 0;
1263 process_i386_opcodes (FILE *table
)
1268 char *str
, *p
, *last
, *name
;
1269 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1270 htab_t opcode_hash_table
;
1271 struct opcode_hash_entry
**opcode_array
;
1272 unsigned int opcode_array_size
= 1024;
1275 filename
= "i386-opc.tbl";
1276 fp
= fopen (filename
, "r");
1279 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1283 opcode_array
= (struct opcode_hash_entry
**)
1284 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1286 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1287 opcode_hash_eq
, NULL
,
1290 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1291 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1293 /* Put everything on opcode array. */
1296 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1301 p
= remove_leading_whitespaces (buf
);
1303 /* Skip comments. */
1304 str
= strstr (p
, "//");
1308 /* Remove trailing white spaces. */
1309 remove_trailing_whitespaces (p
);
1314 /* Ignore comments. */
1322 last
= p
+ strlen (p
);
1325 name
= next_field (p
, ',', &str
, last
);
1327 /* Get the slot in hash table. */
1328 hash_slot
= (struct opcode_hash_entry
**)
1329 htab_find_slot_with_hash (opcode_hash_table
, name
,
1330 htab_hash_string (name
),
1333 if (*hash_slot
== NULL
)
1335 /* It is the new one. Put it on opcode array. */
1336 if (i
>= opcode_array_size
)
1338 /* Grow the opcode array when needed. */
1339 opcode_array_size
+= 1024;
1340 opcode_array
= (struct opcode_hash_entry
**)
1341 xrealloc (opcode_array
,
1342 sizeof (*opcode_array
) * opcode_array_size
);
1345 opcode_array
[i
] = (struct opcode_hash_entry
*)
1346 xmalloc (sizeof (struct opcode_hash_entry
));
1347 opcode_array
[i
]->next
= NULL
;
1348 opcode_array
[i
]->name
= xstrdup (name
);
1349 opcode_array
[i
]->opcode
= xstrdup (str
);
1350 opcode_array
[i
]->lineno
= lineno
;
1351 *hash_slot
= opcode_array
[i
];
1356 /* Append it to the existing one. */
1358 while ((*entry
) != NULL
)
1359 entry
= &(*entry
)->next
;
1360 *entry
= (struct opcode_hash_entry
*)
1361 xmalloc (sizeof (struct opcode_hash_entry
));
1362 (*entry
)->next
= NULL
;
1363 (*entry
)->name
= (*hash_slot
)->name
;
1364 (*entry
)->opcode
= xstrdup (str
);
1365 (*entry
)->lineno
= lineno
;
1369 /* Process opcode array. */
1370 for (j
= 0; j
< i
; j
++)
1372 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1376 lineno
= next
->lineno
;
1377 last
= str
+ strlen (str
);
1378 output_i386_opcode (table
, name
, str
, last
, lineno
);
1384 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1386 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1388 process_i386_opcode_modifier (table
, "0", -1);
1390 fprintf (table
, " { ");
1391 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1392 fprintf (table
, " } }\n");
1394 fprintf (table
, "};\n");
1398 process_i386_registers (FILE *table
)
1402 char *str
, *p
, *last
;
1403 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1404 char *dw2_32_num
, *dw2_64_num
;
1407 filename
= "i386-reg.tbl";
1408 fp
= fopen (filename
, "r");
1410 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1413 fprintf (table
, "\n/* i386 register table. */\n\n");
1414 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1418 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1423 p
= remove_leading_whitespaces (buf
);
1425 /* Skip comments. */
1426 str
= strstr (p
, "//");
1430 /* Remove trailing white spaces. */
1431 remove_trailing_whitespaces (p
);
1436 fprintf (table
, "%s\n", p
);
1444 last
= p
+ strlen (p
);
1446 /* Find reg_name. */
1447 reg_name
= next_field (p
, ',', &str
, last
);
1449 /* Find reg_type. */
1450 reg_type
= next_field (str
, ',', &str
, last
);
1452 /* Find reg_flags. */
1453 reg_flags
= next_field (str
, ',', &str
, last
);
1456 reg_num
= next_field (str
, ',', &str
, last
);
1458 fprintf (table
, " { \"%s\",\n ", reg_name
);
1460 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1463 /* Find 32-bit Dwarf2 register number. */
1464 dw2_32_num
= next_field (str
, ',', &str
, last
);
1466 /* Find 64-bit Dwarf2 register number. */
1467 dw2_64_num
= next_field (str
, ',', &str
, last
);
1469 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1470 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1475 fprintf (table
, "};\n");
1477 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1481 process_i386_initializers (void)
1484 FILE *fp
= fopen ("i386-init.h", "w");
1488 fail (_("can't create i386-init.h, errno = %s\n"),
1491 process_copyright (fp
);
1493 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1495 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1496 init
= xstrdup (cpu_flag_init
[i
].init
);
1497 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1501 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1503 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1504 init
= xstrdup (operand_type_init
[i
].init
);
1505 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1513 /* Program options. */
1514 #define OPTION_SRCDIR 200
1516 struct option long_options
[] =
1518 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1519 {"debug", no_argument
, NULL
, 'd'},
1520 {"version", no_argument
, NULL
, 'V'},
1521 {"help", no_argument
, NULL
, 'h'},
1522 {0, no_argument
, NULL
, 0}
1526 print_version (void)
1528 printf ("%s: version 1.0\n", program_name
);
1533 usage (FILE * stream
, int status
)
1535 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1541 main (int argc
, char **argv
)
1543 extern int chdir (char *);
1544 char *srcdir
= NULL
;
1546 unsigned int i
, cpumax
;
1549 program_name
= *argv
;
1550 xmalloc_set_program_name (program_name
);
1552 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1577 if (chdir (srcdir
) != 0)
1578 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1579 srcdir
, xstrerror (errno
));
1581 /* cpu_flags isn't sorted by position. */
1583 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1584 if (cpu_flags
[i
].position
> cpumax
)
1585 cpumax
= cpu_flags
[i
].position
;
1587 /* Check the unused bitfield in i386_cpu_flags. */
1589 if ((cpumax
- 1) != CpuMax
)
1590 fail (_("CpuMax != %d!\n"), cpumax
);
1592 if (cpumax
!= CpuMax
)
1593 fail (_("CpuMax != %d!\n"), cpumax
);
1595 c
= CpuNumOfBits
- CpuMax
- 1;
1597 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1600 /* Check the unused bitfield in i386_operand_type. */
1602 c
= OTNumOfBits
- OTMax
- 1;
1604 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1607 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1610 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1611 sizeof (opcode_modifiers
[0]), compare
);
1613 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1614 sizeof (operand_types
[0]), compare
);
1616 table
= fopen ("i386-tbl.h", "w");
1618 fail (_("can't create i386-tbl.h, errno = %s\n"),
1621 process_copyright (table
);
1623 process_i386_opcodes (table
);
1624 process_i386_registers (table
);
1625 process_i386_initializers ();