1 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
24 #include "libiberty.h"
26 #include "safe-ctype.h"
31 #define _(String) gettext (String)
33 static const char *program_name
= NULL
;
36 typedef struct initializer
42 static initializer cpu_flag_init
[] =
44 { "CPU_UNKNOWN_FLAGS",
45 "~(CpuL1OM|CpuK1OM)" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
55 "CPU_I186_FLAGS|Cpu286" },
57 "CPU_I286_FLAGS|Cpu386" },
59 "CPU_I386_FLAGS|Cpu486" },
61 "CPU_I486_FLAGS|CPU_387_FLAGS|Cpu586" },
63 "CPU_I586_FLAGS|Cpu686|Cpu687" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "CPU_I686_FLAGS|CpuNop" },
67 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
69 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
71 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
73 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
75 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
77 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
79 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
83 "CPU_K6_FLAGS|Cpu3dnow" },
85 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
87 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
91 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuFMA4|CpuXOP|CpuLWP|CpuSVME|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
93 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
95 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
97 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
99 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_BTVER1_FLAGS",
101 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
102 { "CPU_BTVER2_FLAGS",
103 "CPU_BTVER1_FLAGS|CPU_SSE4_2_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW" },
107 "CPU_8087_FLAGS|Cpu287" },
109 "CPU_287_FLAGS|Cpu387" },
111 "CPU_387_FLAGS|Cpu687" },
112 { "CPU_CLFLUSH_FLAGS",
116 { "CPU_SYSCALL_FLAGS",
119 "CpuRegMMX|CpuMMX" },
121 "CpuRegXMM|CpuSSE" },
123 "CPU_SSE_FLAGS|CpuSSE2" },
125 "CPU_SSE2_FLAGS|CpuSSE3" },
127 "CPU_SSE3_FLAGS|CpuSSSE3" },
128 { "CPU_SSE4_1_FLAGS",
129 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
130 { "CPU_SSE4_2_FLAGS",
131 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
138 { "CPU_XSAVEOPT_FLAGS",
139 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
141 "CPU_SSE2_FLAGS|CpuAES" },
142 { "CPU_PCLMUL_FLAGS",
143 "CPU_SSE2_FLAGS|CpuPCLMUL" },
145 "CPU_AVX_FLAGS|CpuFMA" },
147 "CPU_AVX_FLAGS|CpuFMA4" },
149 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
160 { "CPU_RDTSCP_FLAGS",
164 { "CPU_FSGSBASE_FLAGS",
169 "CPU_AVX_FLAGS|CpuF16C" },
178 { "CPU_INVPCID_FLAGS",
180 { "CPU_VMFUNC_FLAGS",
183 "CPU_MMX_FLAGS|Cpu3dnow" },
184 { "CPU_3DNOWA_FLAGS",
185 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
186 { "CPU_PADLOCK_FLAGS",
191 "CPU_SSE3_FLAGS|CpuSSE4a" },
195 "CPU_SSE4_2_FLAGS|CpuRegYMM|CpuAVX" },
197 "CPU_AVX_FLAGS|CpuAVX2" },
198 /* Don't use CPU_AVX2_FLAGS on CPU_AVX512F_FLAGS since AVX512F doesn't
199 support YMM registers. */
200 { "CPU_AVX512F_FLAGS",
201 "CpuVREX|CPU_SSE4_2_FLAGS|CpuRegZMM|CpuRegMask|CpuAVX|CpuAVX2|CpuAVX512F" },
202 { "CPU_AVX512CD_FLAGS",
203 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
204 { "CPU_AVX512ER_FLAGS",
205 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
206 { "CPU_AVX512PF_FLAGS",
207 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
208 { "CPU_AVX512DQ_FLAGS",
209 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
210 { "CPU_AVX512BW_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
212 { "CPU_AVX512VL_FLAGS",
213 /* Use CPU_AVX2_FLAGS on CPU_AVX512VL_FLAGS since AVX512VL supports YMM
215 "CPU_AVX512F_FLAGS|CPU_AVX2_FLAGS|CpuAVX512VL" },
216 { "CPU_AVX512IFMA_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
218 { "CPU_AVX512VBMI_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
220 { "CPU_AVX512_4FMAPS_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
222 { "CPU_AVX512_4VNNIW_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
224 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
226 { "CPU_AVX512_VBMI2_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
228 { "CPU_AVX512_VNNI_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
230 { "CPU_AVX512_BITALG_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
237 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
240 { "CPU_RDSEED_FLAGS",
242 { "CPU_PRFCHW_FLAGS",
249 "CPU_SSE2_FLAGS|CpuSHA" },
250 { "CPU_CLFLUSHOPT_FLAGS",
252 { "CPU_XSAVES_FLAGS",
253 "CPU_XSAVE_FLAGS|CpuXSAVES" },
254 { "CPU_XSAVEC_FLAGS",
255 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
256 { "CPU_PREFETCHWT1_FLAGS",
262 { "CPU_CLZERO_FLAGS",
264 { "CPU_MWAITX_FLAGS",
270 { "CPU_PTWRITE_FLAGS",
280 { "CPU_VPCLMULQDQ_FLAGS",
282 { "CPU_WBNOINVD_FLAGS",
284 { "CPU_PCONFIG_FLAGS",
286 { "CPU_ANY_X87_FLAGS",
287 "CPU_ANY_287_FLAGS|Cpu8087" },
288 { "CPU_ANY_287_FLAGS",
289 "CPU_ANY_387_FLAGS|Cpu287" },
290 { "CPU_ANY_387_FLAGS",
291 "CPU_ANY_687_FLAGS|Cpu387" },
292 { "CPU_ANY_687_FLAGS",
293 "Cpu687|CpuFISTTP" },
294 { "CPU_ANY_MMX_FLAGS",
295 "CPU_3DNOWA_FLAGS" },
296 { "CPU_ANY_SSE_FLAGS",
297 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
298 { "CPU_ANY_SSE2_FLAGS",
299 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
300 { "CPU_ANY_SSE3_FLAGS",
301 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
302 { "CPU_ANY_SSSE3_FLAGS",
303 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
304 { "CPU_ANY_SSE4_1_FLAGS",
305 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
306 { "CPU_ANY_SSE4_2_FLAGS",
308 { "CPU_ANY_AVX_FLAGS",
309 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
310 { "CPU_ANY_AVX2_FLAGS",
312 { "CPU_ANY_AVX512F_FLAGS",
313 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512F" },
314 { "CPU_ANY_AVX512CD_FLAGS",
316 { "CPU_ANY_AVX512ER_FLAGS",
318 { "CPU_ANY_AVX512PF_FLAGS",
320 { "CPU_ANY_AVX512DQ_FLAGS",
322 { "CPU_ANY_AVX512BW_FLAGS",
324 { "CPU_ANY_AVX512VL_FLAGS",
326 { "CPU_ANY_AVX512IFMA_FLAGS",
328 { "CPU_ANY_AVX512VBMI_FLAGS",
330 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
331 "CpuAVX512_4FMAPS" },
332 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
333 "CpuAVX512_4VNNIW" },
334 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
335 "CpuAVX512_VPOPCNTDQ" },
336 { "CPU_ANY_IBT_FLAGS",
338 { "CPU_ANY_SHSTK_FLAGS",
340 { "CPU_ANY_AVX512_VBMI2_FLAGS",
342 { "CPU_ANY_AVX512_VNNI_FLAGS",
344 { "CPU_ANY_AVX512_BITALG_FLAGS",
345 "CpuAVX512_BITALG" },
348 static const initializer operand_type_shorthands
[] =
350 { "Reg8", "Reg|Byte" },
351 { "Reg16", "Reg|Word" },
352 { "Reg32", "Reg|Dword" },
353 { "Reg64", "Reg|Qword" },
354 { "FloatAcc", "Acc|Tbyte" },
355 { "FloatReg", "Reg|Tbyte" },
356 { "RegXMM", "RegSIMD|Xmmword" },
357 { "RegYMM", "RegSIMD|Ymmword" },
358 { "RegZMM", "RegSIMD|Zmmword" },
361 static initializer operand_type_init
[] =
363 { "OPERAND_TYPE_NONE",
365 { "OPERAND_TYPE_REG8",
367 { "OPERAND_TYPE_REG16",
369 { "OPERAND_TYPE_REG32",
371 { "OPERAND_TYPE_REG64",
373 { "OPERAND_TYPE_IMM1",
375 { "OPERAND_TYPE_IMM8",
377 { "OPERAND_TYPE_IMM8S",
379 { "OPERAND_TYPE_IMM16",
381 { "OPERAND_TYPE_IMM32",
383 { "OPERAND_TYPE_IMM32S",
385 { "OPERAND_TYPE_IMM64",
387 { "OPERAND_TYPE_BASEINDEX",
389 { "OPERAND_TYPE_DISP8",
391 { "OPERAND_TYPE_DISP16",
393 { "OPERAND_TYPE_DISP32",
395 { "OPERAND_TYPE_DISP32S",
397 { "OPERAND_TYPE_DISP64",
399 { "OPERAND_TYPE_INOUTPORTREG",
401 { "OPERAND_TYPE_SHIFTCOUNT",
403 { "OPERAND_TYPE_CONTROL",
405 { "OPERAND_TYPE_TEST",
407 { "OPERAND_TYPE_DEBUG",
409 { "OPERAND_TYPE_FLOATREG",
411 { "OPERAND_TYPE_FLOATACC",
413 { "OPERAND_TYPE_SREG2",
415 { "OPERAND_TYPE_SREG3",
417 { "OPERAND_TYPE_ACC",
419 { "OPERAND_TYPE_JUMPABSOLUTE",
421 { "OPERAND_TYPE_REGMMX",
423 { "OPERAND_TYPE_REGXMM",
425 { "OPERAND_TYPE_REGYMM",
427 { "OPERAND_TYPE_REGZMM",
429 { "OPERAND_TYPE_REGMASK",
431 { "OPERAND_TYPE_ESSEG",
433 { "OPERAND_TYPE_ACC32",
435 { "OPERAND_TYPE_ACC64",
437 { "OPERAND_TYPE_INOUTPORTREG",
439 { "OPERAND_TYPE_REG16_INOUTPORTREG",
440 "Reg16|InOutPortReg" },
441 { "OPERAND_TYPE_DISP16_32",
443 { "OPERAND_TYPE_ANYDISP",
444 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
445 { "OPERAND_TYPE_IMM16_32",
447 { "OPERAND_TYPE_IMM16_32S",
449 { "OPERAND_TYPE_IMM16_32_32S",
450 "Imm16|Imm32|Imm32S" },
451 { "OPERAND_TYPE_IMM32_64",
453 { "OPERAND_TYPE_IMM32_32S_DISP32",
454 "Imm32|Imm32S|Disp32" },
455 { "OPERAND_TYPE_IMM64_DISP64",
457 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
458 "Imm32|Imm32S|Imm64|Disp32" },
459 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
460 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
461 { "OPERAND_TYPE_VEC_IMM4",
463 { "OPERAND_TYPE_REGBND",
467 typedef struct bitfield
474 #define BITFIELD(n) { n, 0, #n }
476 static bitfield cpu_flags
[] =
484 BITFIELD (CpuClflush
),
486 BITFIELD (CpuSYSCALL
),
491 BITFIELD (CpuFISTTP
),
497 BITFIELD (CpuSSE4_1
),
498 BITFIELD (CpuSSE4_2
),
501 BITFIELD (CpuAVX512F
),
502 BITFIELD (CpuAVX512CD
),
503 BITFIELD (CpuAVX512ER
),
504 BITFIELD (CpuAVX512PF
),
505 BITFIELD (CpuAVX512VL
),
506 BITFIELD (CpuAVX512DQ
),
507 BITFIELD (CpuAVX512BW
),
513 BITFIELD (Cpu3dnowA
),
514 BITFIELD (CpuPadLock
),
520 BITFIELD (CpuXsaveopt
),
522 BITFIELD (CpuPCLMUL
),
533 BITFIELD (CpuRdtscp
),
534 BITFIELD (CpuFSGSBase
),
541 BITFIELD (CpuINVPCID
),
542 BITFIELD (CpuVMFUNC
),
543 BITFIELD (CpuRDSEED
),
545 BITFIELD (CpuPRFCHW
),
549 BITFIELD (CpuClflushOpt
),
550 BITFIELD (CpuXSAVES
),
551 BITFIELD (CpuXSAVEC
),
552 BITFIELD (CpuPREFETCHWT1
),
558 BITFIELD (CpuAVX512IFMA
),
559 BITFIELD (CpuAVX512VBMI
),
560 BITFIELD (CpuAVX512_4FMAPS
),
561 BITFIELD (CpuAVX512_4VNNIW
),
562 BITFIELD (CpuAVX512_VPOPCNTDQ
),
563 BITFIELD (CpuAVX512_VBMI2
),
564 BITFIELD (CpuAVX512_VNNI
),
565 BITFIELD (CpuAVX512_BITALG
),
566 BITFIELD (CpuMWAITX
),
567 BITFIELD (CpuCLZERO
),
570 BITFIELD (CpuPTWRITE
),
575 BITFIELD (CpuVPCLMULQDQ
),
576 BITFIELD (CpuWBNOINVD
),
577 BITFIELD (CpuPCONFIG
),
578 BITFIELD (CpuRegMMX
),
579 BITFIELD (CpuRegXMM
),
580 BITFIELD (CpuRegYMM
),
581 BITFIELD (CpuRegZMM
),
582 BITFIELD (CpuRegMask
),
584 BITFIELD (CpuUnused
),
588 static bitfield opcode_modifiers
[] =
594 BITFIELD (ShortForm
),
596 BITFIELD (JumpDword
),
598 BITFIELD (JumpInterSegment
),
604 BITFIELD (CheckRegSize
),
605 BITFIELD (IgnoreSize
),
606 BITFIELD (DefaultSize
),
615 BITFIELD (BNDPrefixOk
),
616 BITFIELD (NoTrackPrefixOk
),
617 BITFIELD (IsLockable
),
618 BITFIELD (RegKludge
),
619 BITFIELD (Implicit1stXmm0
),
620 BITFIELD (RepPrefixOk
),
621 BITFIELD (HLEPrefixOk
),
624 BITFIELD (AddrPrefixOp0
),
633 BITFIELD (VexOpcode
),
634 BITFIELD (VexSources
),
635 BITFIELD (VexImmExt
),
641 BITFIELD (Broadcast
),
642 BITFIELD (StaticRounding
),
644 BITFIELD (Disp8MemShift
),
645 BITFIELD (NoDefMask
),
646 BITFIELD (ImplicitQuadGroup
),
648 BITFIELD (ATTMnemonic
),
649 BITFIELD (ATTSyntax
),
650 BITFIELD (IntelSyntax
),
655 static bitfield operand_types
[] =
668 BITFIELD (BaseIndex
),
674 BITFIELD (InOutPortReg
),
675 BITFIELD (ShiftCount
),
682 BITFIELD (JumpAbsolute
),
695 BITFIELD (Unspecified
),
704 static const char *filename
;
705 static i386_cpu_flags active_cpu_flags
;
706 static int active_isstring
;
709 compare (const void *x
, const void *y
)
711 const bitfield
*xp
= (const bitfield
*) x
;
712 const bitfield
*yp
= (const bitfield
*) y
;
713 return xp
->position
- yp
->position
;
717 fail (const char *message
, ...)
721 va_start (args
, message
);
722 fprintf (stderr
, _("%s: error: "), program_name
);
723 vfprintf (stderr
, message
, args
);
729 process_copyright (FILE *fp
)
731 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
732 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
734 This file is part of the GNU opcodes library.\n\
736 This library is free software; you can redistribute it and/or modify\n\
737 it under the terms of the GNU General Public License as published by\n\
738 the Free Software Foundation; either version 3, or (at your option)\n\
739 any later version.\n\
741 It is distributed in the hope that it will be useful, but WITHOUT\n\
742 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
743 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
744 License for more details.\n\
746 You should have received a copy of the GNU General Public License\n\
747 along with this program; if not, write to the Free Software\n\
748 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
749 MA 02110-1301, USA. */\n");
752 /* Remove leading white spaces. */
755 remove_leading_whitespaces (char *str
)
757 while (ISSPACE (*str
))
762 /* Remove trailing white spaces. */
765 remove_trailing_whitespaces (char *str
)
767 size_t last
= strlen (str
);
775 if (ISSPACE (str
[last
]))
783 /* Find next field separated by SEP and terminate it. Return a
784 pointer to the one after it. */
787 next_field (char *str
, char sep
, char **next
, char *last
)
791 p
= remove_leading_whitespaces (str
);
792 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
795 remove_trailing_whitespaces (p
);
805 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
808 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
811 char *str
, *next
, *last
;
814 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
815 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
817 /* Turn on selective bits. */
818 char *init
= xstrdup (cpu_flag_init
[i
].init
);
819 last
= init
+ strlen (init
);
820 for (next
= init
; next
&& next
< last
; )
822 str
= next_field (next
, '|', &next
, last
);
824 set_bitfield (str
, array
, 1, size
, lineno
);
830 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
831 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
833 /* Turn on selective bits. */
834 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
835 last
= init
+ strlen (init
);
836 for (next
= init
; next
&& next
< last
; )
838 str
= next_field (next
, '|', &next
, last
);
840 set_bitfield (str
, array
, 1, size
, lineno
);
850 set_bitfield (char *f
, bitfield
*array
, int value
,
851 unsigned int size
, int lineno
)
855 if (strcmp (f
, "CpuFP") == 0)
857 set_bitfield("Cpu387", array
, value
, size
, lineno
);
858 set_bitfield("Cpu287", array
, value
, size
, lineno
);
861 else if (strcmp (f
, "Mmword") == 0)
863 else if (strcmp (f
, "Oword") == 0)
866 for (i
= 0; i
< size
; i
++)
867 if (strcasecmp (array
[i
].name
, f
) == 0)
869 array
[i
].value
= value
;
875 const char *v
= strchr (f
, '=');
882 for (i
= 0; i
< size
; i
++)
883 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
885 value
= strtol (v
+ 1, &end
, 0);
888 array
[i
].value
= value
;
896 /* Handle shorthands. */
897 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
901 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
903 fail (_("unknown bitfield: %s\n"), f
);
907 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
908 int macro
, const char *comma
, const char *indent
)
912 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
914 fprintf (table
, "%s{ { ", indent
);
916 for (i
= 0; i
< size
- 1; i
++)
918 if (((i
+ 1) % 20) != 0)
919 fprintf (table
, "%d, ", flags
[i
].value
);
921 fprintf (table
, "%d,", flags
[i
].value
);
922 if (((i
+ 1) % 20) == 0)
924 /* We need \\ for macro. */
926 fprintf (table
, " \\\n %s", indent
);
928 fprintf (table
, "\n %s", indent
);
931 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
934 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
938 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
939 const char *comma
, const char *indent
,
942 char *str
, *next
, *last
;
944 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
946 /* Copy the default cpu flags. */
947 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
949 if (strcasecmp (flag
, "unknown") == 0)
951 /* We turn on everything except for cpu64 in case of
952 CPU_UNKNOWN_FLAGS. */
953 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
954 if (flags
[i
].position
!= Cpu64
)
957 else if (flag
[0] == '~')
959 last
= flag
+ strlen (flag
);
966 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
973 /* First we turn on everything except for cpu64. */
974 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
975 if (flags
[i
].position
!= Cpu64
)
978 /* Turn off selective bits. */
979 for (; next
&& next
< last
; )
981 str
= next_field (next
, '|', &next
, last
);
983 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
986 else if (strcmp (flag
, "0"))
988 /* Turn on selective bits. */
989 last
= flag
+ strlen (flag
);
990 for (next
= flag
; next
&& next
< last
; )
992 str
= next_field (next
, '|', &next
, last
);
994 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
998 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1003 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1007 fprintf (table
, " { ");
1009 for (i
= 0; i
< size
- 1; i
++)
1011 if (((i
+ 1) % 20) != 0)
1012 fprintf (table
, "%d, ", modifier
[i
].value
);
1014 fprintf (table
, "%d,", modifier
[i
].value
);
1015 if (((i
+ 1) % 20) == 0)
1016 fprintf (table
, "\n ");
1019 fprintf (table
, "%d },\n", modifier
[i
].value
);
1023 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
1025 char *str
, *next
, *last
;
1026 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1028 active_isstring
= 0;
1030 /* Copy the default opcode modifier. */
1031 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1033 if (strcmp (mod
, "0"))
1035 last
= mod
+ strlen (mod
);
1036 for (next
= mod
; next
&& next
< last
; )
1038 str
= next_field (next
, '|', &next
, last
);
1041 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
1043 if (strcasecmp(str
, "IsString") == 0)
1044 active_isstring
= 1;
1048 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1058 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1059 enum stage stage
, const char *indent
)
1063 fprintf (table
, "{ { ");
1065 for (i
= 0; i
< size
- 1; i
++)
1067 if (((i
+ 1) % 20) != 0)
1068 fprintf (table
, "%d, ", types
[i
].value
);
1070 fprintf (table
, "%d,", types
[i
].value
);
1071 if (((i
+ 1) % 20) == 0)
1073 /* We need \\ for macro. */
1074 if (stage
== stage_macros
)
1075 fprintf (table
, " \\\n%s", indent
);
1077 fprintf (table
, "\n%s", indent
);
1081 fprintf (table
, "%d } }", types
[i
].value
);
1085 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1086 const char *indent
, int lineno
)
1088 char *str
, *next
, *last
;
1089 bitfield types
[ARRAY_SIZE (operand_types
)];
1091 /* Copy the default operand type. */
1092 memcpy (types
, operand_types
, sizeof (types
));
1094 if (strcmp (op
, "0"))
1098 last
= op
+ strlen (op
);
1099 for (next
= op
; next
&& next
< last
; )
1101 str
= next_field (next
, '|', &next
, last
);
1104 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1105 if (strcasecmp(str
, "BaseIndex") == 0)
1110 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1112 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1113 if (!active_cpu_flags
.bitfield
.cpu64
1114 && !active_cpu_flags
.bitfield
.cpumpx
)
1115 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1116 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1117 if (!active_cpu_flags
.bitfield
.cpuno64
)
1118 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1121 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1126 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1127 char *last
, int lineno
)
1130 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1131 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1133 /* Find number of operands. */
1134 operands
= next_field (str
, ',', &str
, last
);
1136 /* Find base_opcode. */
1137 base_opcode
= next_field (str
, ',', &str
, last
);
1139 /* Find extension_opcode. */
1140 extension_opcode
= next_field (str
, ',', &str
, last
);
1142 /* Find opcode_length. */
1143 opcode_length
= next_field (str
, ',', &str
, last
);
1145 /* Find cpu_flags. */
1146 cpu_flags
= next_field (str
, ',', &str
, last
);
1148 /* Find opcode_modifier. */
1149 opcode_modifier
= next_field (str
, ',', &str
, last
);
1151 /* Remove the first {. */
1152 str
= remove_leading_whitespaces (str
);
1155 str
= remove_leading_whitespaces (str
+ 1);
1159 /* There are at least "X}". */
1163 /* Remove trailing white spaces and }. */
1167 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1176 /* Find operand_types. */
1177 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1181 operand_types
[i
] = NULL
;
1185 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1186 if (*operand_types
[i
] == '0')
1189 operand_types
[i
] = NULL
;
1194 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1195 name
, operands
, base_opcode
, extension_opcode
,
1198 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1200 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1202 fprintf (table
, " { ");
1204 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1206 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1209 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1215 fprintf (table
, ",\n ");
1217 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1220 fprintf (table
, " } },\n");
1223 struct opcode_hash_entry
1225 struct opcode_hash_entry
*next
;
1231 /* Calculate the hash value of an opcode hash entry P. */
1234 opcode_hash_hash (const void *p
)
1236 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1237 return htab_hash_string (entry
->name
);
1240 /* Compare a string Q against an opcode hash entry P. */
1243 opcode_hash_eq (const void *p
, const void *q
)
1245 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1246 const char *name
= (const char *) q
;
1247 return strcmp (name
, entry
->name
) == 0;
1251 process_i386_opcodes (FILE *table
)
1256 char *str
, *p
, *last
, *name
;
1257 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1258 htab_t opcode_hash_table
;
1259 struct opcode_hash_entry
**opcode_array
;
1260 unsigned int opcode_array_size
= 1024;
1263 filename
= "i386-opc.tbl";
1264 fp
= fopen (filename
, "r");
1267 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1271 opcode_array
= (struct opcode_hash_entry
**)
1272 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1274 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1275 opcode_hash_eq
, NULL
,
1278 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1279 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1281 /* Put everything on opcode array. */
1284 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1289 p
= remove_leading_whitespaces (buf
);
1291 /* Skip comments. */
1292 str
= strstr (p
, "//");
1296 /* Remove trailing white spaces. */
1297 remove_trailing_whitespaces (p
);
1302 /* Ignore comments. */
1310 last
= p
+ strlen (p
);
1313 name
= next_field (p
, ',', &str
, last
);
1315 /* Get the slot in hash table. */
1316 hash_slot
= (struct opcode_hash_entry
**)
1317 htab_find_slot_with_hash (opcode_hash_table
, name
,
1318 htab_hash_string (name
),
1321 if (*hash_slot
== NULL
)
1323 /* It is the new one. Put it on opcode array. */
1324 if (i
>= opcode_array_size
)
1326 /* Grow the opcode array when needed. */
1327 opcode_array_size
+= 1024;
1328 opcode_array
= (struct opcode_hash_entry
**)
1329 xrealloc (opcode_array
,
1330 sizeof (*opcode_array
) * opcode_array_size
);
1333 opcode_array
[i
] = (struct opcode_hash_entry
*)
1334 xmalloc (sizeof (struct opcode_hash_entry
));
1335 opcode_array
[i
]->next
= NULL
;
1336 opcode_array
[i
]->name
= xstrdup (name
);
1337 opcode_array
[i
]->opcode
= xstrdup (str
);
1338 opcode_array
[i
]->lineno
= lineno
;
1339 *hash_slot
= opcode_array
[i
];
1344 /* Append it to the existing one. */
1346 while ((*entry
) != NULL
)
1347 entry
= &(*entry
)->next
;
1348 *entry
= (struct opcode_hash_entry
*)
1349 xmalloc (sizeof (struct opcode_hash_entry
));
1350 (*entry
)->next
= NULL
;
1351 (*entry
)->name
= (*hash_slot
)->name
;
1352 (*entry
)->opcode
= xstrdup (str
);
1353 (*entry
)->lineno
= lineno
;
1357 /* Process opcode array. */
1358 for (j
= 0; j
< i
; j
++)
1360 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1364 lineno
= next
->lineno
;
1365 last
= str
+ strlen (str
);
1366 output_i386_opcode (table
, name
, str
, last
, lineno
);
1372 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1374 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1376 process_i386_opcode_modifier (table
, "0", -1);
1378 fprintf (table
, " { ");
1379 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1380 fprintf (table
, " } }\n");
1382 fprintf (table
, "};\n");
1386 process_i386_registers (FILE *table
)
1390 char *str
, *p
, *last
;
1391 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1392 char *dw2_32_num
, *dw2_64_num
;
1395 filename
= "i386-reg.tbl";
1396 fp
= fopen (filename
, "r");
1398 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1401 fprintf (table
, "\n/* i386 register table. */\n\n");
1402 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1406 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1411 p
= remove_leading_whitespaces (buf
);
1413 /* Skip comments. */
1414 str
= strstr (p
, "//");
1418 /* Remove trailing white spaces. */
1419 remove_trailing_whitespaces (p
);
1424 fprintf (table
, "%s\n", p
);
1432 last
= p
+ strlen (p
);
1434 /* Find reg_name. */
1435 reg_name
= next_field (p
, ',', &str
, last
);
1437 /* Find reg_type. */
1438 reg_type
= next_field (str
, ',', &str
, last
);
1440 /* Find reg_flags. */
1441 reg_flags
= next_field (str
, ',', &str
, last
);
1444 reg_num
= next_field (str
, ',', &str
, last
);
1446 fprintf (table
, " { \"%s\",\n ", reg_name
);
1448 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1451 /* Find 32-bit Dwarf2 register number. */
1452 dw2_32_num
= next_field (str
, ',', &str
, last
);
1454 /* Find 64-bit Dwarf2 register number. */
1455 dw2_64_num
= next_field (str
, ',', &str
, last
);
1457 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1458 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1463 fprintf (table
, "};\n");
1465 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1469 process_i386_initializers (void)
1472 FILE *fp
= fopen ("i386-init.h", "w");
1476 fail (_("can't create i386-init.h, errno = %s\n"),
1479 process_copyright (fp
);
1481 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1483 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1484 init
= xstrdup (cpu_flag_init
[i
].init
);
1485 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1489 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1491 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1492 init
= xstrdup (operand_type_init
[i
].init
);
1493 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1501 /* Program options. */
1502 #define OPTION_SRCDIR 200
1504 struct option long_options
[] =
1506 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1507 {"debug", no_argument
, NULL
, 'd'},
1508 {"version", no_argument
, NULL
, 'V'},
1509 {"help", no_argument
, NULL
, 'h'},
1510 {0, no_argument
, NULL
, 0}
1514 print_version (void)
1516 printf ("%s: version 1.0\n", program_name
);
1521 usage (FILE * stream
, int status
)
1523 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1529 main (int argc
, char **argv
)
1531 extern int chdir (char *);
1532 char *srcdir
= NULL
;
1534 unsigned int i
, cpumax
;
1537 program_name
= *argv
;
1538 xmalloc_set_program_name (program_name
);
1540 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1565 if (chdir (srcdir
) != 0)
1566 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1567 srcdir
, xstrerror (errno
));
1569 /* cpu_flags isn't sorted by position. */
1571 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1572 if (cpu_flags
[i
].position
> cpumax
)
1573 cpumax
= cpu_flags
[i
].position
;
1575 /* Check the unused bitfield in i386_cpu_flags. */
1577 if ((cpumax
- 1) != CpuMax
)
1578 fail (_("CpuMax != %d!\n"), cpumax
);
1580 if (cpumax
!= CpuMax
)
1581 fail (_("CpuMax != %d!\n"), cpumax
);
1583 c
= CpuNumOfBits
- CpuMax
- 1;
1585 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1588 /* Check the unused bitfield in i386_operand_type. */
1590 c
= OTNumOfBits
- OTMax
- 1;
1592 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1595 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1598 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1599 sizeof (opcode_modifiers
[0]), compare
);
1601 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1602 sizeof (operand_types
[0]), compare
);
1604 table
= fopen ("i386-tbl.h", "w");
1606 fail (_("can't create i386-tbl.h, errno = %s\n"),
1609 process_copyright (table
);
1611 process_i386_opcodes (table
);
1612 process_i386_registers (table
);
1613 process_i386_initializers ();