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
),
642 BITFIELD (Broadcast
),
643 BITFIELD (StaticRounding
),
645 BITFIELD (Disp8MemShift
),
646 BITFIELD (NoDefMask
),
647 BITFIELD (ImplicitQuadGroup
),
649 BITFIELD (ATTMnemonic
),
650 BITFIELD (ATTSyntax
),
651 BITFIELD (IntelSyntax
),
656 static bitfield operand_types
[] =
669 BITFIELD (BaseIndex
),
675 BITFIELD (InOutPortReg
),
676 BITFIELD (ShiftCount
),
683 BITFIELD (JumpAbsolute
),
696 BITFIELD (Unspecified
),
705 static const char *filename
;
706 static i386_cpu_flags active_cpu_flags
;
707 static int active_isstring
;
710 compare (const void *x
, const void *y
)
712 const bitfield
*xp
= (const bitfield
*) x
;
713 const bitfield
*yp
= (const bitfield
*) y
;
714 return xp
->position
- yp
->position
;
718 fail (const char *message
, ...)
722 va_start (args
, message
);
723 fprintf (stderr
, _("%s: error: "), program_name
);
724 vfprintf (stderr
, message
, args
);
730 process_copyright (FILE *fp
)
732 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
733 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
735 This file is part of the GNU opcodes library.\n\
737 This library is free software; you can redistribute it and/or modify\n\
738 it under the terms of the GNU General Public License as published by\n\
739 the Free Software Foundation; either version 3, or (at your option)\n\
740 any later version.\n\
742 It is distributed in the hope that it will be useful, but WITHOUT\n\
743 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
744 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
745 License for more details.\n\
747 You should have received a copy of the GNU General Public License\n\
748 along with this program; if not, write to the Free Software\n\
749 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
750 MA 02110-1301, USA. */\n");
753 /* Remove leading white spaces. */
756 remove_leading_whitespaces (char *str
)
758 while (ISSPACE (*str
))
763 /* Remove trailing white spaces. */
766 remove_trailing_whitespaces (char *str
)
768 size_t last
= strlen (str
);
776 if (ISSPACE (str
[last
]))
784 /* Find next field separated by SEP and terminate it. Return a
785 pointer to the one after it. */
788 next_field (char *str
, char sep
, char **next
, char *last
)
792 p
= remove_leading_whitespaces (str
);
793 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
796 remove_trailing_whitespaces (p
);
806 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
809 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
812 char *str
, *next
, *last
;
815 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
816 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
818 /* Turn on selective bits. */
819 char *init
= xstrdup (cpu_flag_init
[i
].init
);
820 last
= init
+ strlen (init
);
821 for (next
= init
; next
&& next
< last
; )
823 str
= next_field (next
, '|', &next
, last
);
825 set_bitfield (str
, array
, 1, size
, lineno
);
831 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
832 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
834 /* Turn on selective bits. */
835 char *init
= xstrdup (operand_type_shorthands
[i
].init
);
836 last
= init
+ strlen (init
);
837 for (next
= init
; next
&& next
< last
; )
839 str
= next_field (next
, '|', &next
, last
);
841 set_bitfield (str
, array
, 1, size
, lineno
);
851 set_bitfield (char *f
, bitfield
*array
, int value
,
852 unsigned int size
, int lineno
)
856 if (strcmp (f
, "CpuFP") == 0)
858 set_bitfield("Cpu387", array
, value
, size
, lineno
);
859 set_bitfield("Cpu287", array
, value
, size
, lineno
);
862 else if (strcmp (f
, "Mmword") == 0)
864 else if (strcmp (f
, "Oword") == 0)
867 for (i
= 0; i
< size
; i
++)
868 if (strcasecmp (array
[i
].name
, f
) == 0)
870 array
[i
].value
= value
;
876 const char *v
= strchr (f
, '=');
883 for (i
= 0; i
< size
; i
++)
884 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
886 value
= strtol (v
+ 1, &end
, 0);
889 array
[i
].value
= value
;
897 /* Handle shorthands. */
898 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
902 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
904 fail (_("unknown bitfield: %s\n"), f
);
908 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
909 int macro
, const char *comma
, const char *indent
)
913 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
915 fprintf (table
, "%s{ { ", indent
);
917 for (i
= 0; i
< size
- 1; i
++)
919 if (((i
+ 1) % 20) != 0)
920 fprintf (table
, "%d, ", flags
[i
].value
);
922 fprintf (table
, "%d,", flags
[i
].value
);
923 if (((i
+ 1) % 20) == 0)
925 /* We need \\ for macro. */
927 fprintf (table
, " \\\n %s", indent
);
929 fprintf (table
, "\n %s", indent
);
932 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
935 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
939 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
940 const char *comma
, const char *indent
,
943 char *str
, *next
, *last
;
945 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
947 /* Copy the default cpu flags. */
948 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
950 if (strcasecmp (flag
, "unknown") == 0)
952 /* We turn on everything except for cpu64 in case of
953 CPU_UNKNOWN_FLAGS. */
954 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
955 if (flags
[i
].position
!= Cpu64
)
958 else if (flag
[0] == '~')
960 last
= flag
+ strlen (flag
);
967 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
974 /* First we turn on everything except for cpu64. */
975 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
976 if (flags
[i
].position
!= Cpu64
)
979 /* Turn off selective bits. */
980 for (; next
&& next
< last
; )
982 str
= next_field (next
, '|', &next
, last
);
984 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
987 else if (strcmp (flag
, "0"))
989 /* Turn on selective bits. */
990 last
= flag
+ strlen (flag
);
991 for (next
= flag
; next
&& next
< last
; )
993 str
= next_field (next
, '|', &next
, last
);
995 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
999 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
1004 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1008 fprintf (table
, " { ");
1010 for (i
= 0; i
< size
- 1; i
++)
1012 if (((i
+ 1) % 20) != 0)
1013 fprintf (table
, "%d, ", modifier
[i
].value
);
1015 fprintf (table
, "%d,", modifier
[i
].value
);
1016 if (((i
+ 1) % 20) == 0)
1017 fprintf (table
, "\n ");
1020 fprintf (table
, "%d },\n", modifier
[i
].value
);
1024 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
1026 char *str
, *next
, *last
;
1027 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1029 active_isstring
= 0;
1031 /* Copy the default opcode modifier. */
1032 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1034 if (strcmp (mod
, "0"))
1036 last
= mod
+ strlen (mod
);
1037 for (next
= mod
; next
&& next
< last
; )
1039 str
= next_field (next
, '|', &next
, last
);
1042 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
1044 if (strcasecmp(str
, "IsString") == 0)
1045 active_isstring
= 1;
1049 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1059 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1060 enum stage stage
, const char *indent
)
1064 fprintf (table
, "{ { ");
1066 for (i
= 0; i
< size
- 1; i
++)
1068 if (((i
+ 1) % 20) != 0)
1069 fprintf (table
, "%d, ", types
[i
].value
);
1071 fprintf (table
, "%d,", types
[i
].value
);
1072 if (((i
+ 1) % 20) == 0)
1074 /* We need \\ for macro. */
1075 if (stage
== stage_macros
)
1076 fprintf (table
, " \\\n%s", indent
);
1078 fprintf (table
, "\n%s", indent
);
1082 fprintf (table
, "%d } }", types
[i
].value
);
1086 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1087 const char *indent
, int lineno
)
1089 char *str
, *next
, *last
;
1090 bitfield types
[ARRAY_SIZE (operand_types
)];
1092 /* Copy the default operand type. */
1093 memcpy (types
, operand_types
, sizeof (types
));
1095 if (strcmp (op
, "0"))
1099 last
= op
+ strlen (op
);
1100 for (next
= op
; next
&& next
< last
; )
1102 str
= next_field (next
, '|', &next
, last
);
1105 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1106 if (strcasecmp(str
, "BaseIndex") == 0)
1111 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1113 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1114 if (!active_cpu_flags
.bitfield
.cpu64
1115 && !active_cpu_flags
.bitfield
.cpumpx
)
1116 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1117 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1118 if (!active_cpu_flags
.bitfield
.cpuno64
)
1119 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1122 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1127 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1128 char *last
, int lineno
)
1131 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1132 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1134 /* Find number of operands. */
1135 operands
= next_field (str
, ',', &str
, last
);
1137 /* Find base_opcode. */
1138 base_opcode
= next_field (str
, ',', &str
, last
);
1140 /* Find extension_opcode. */
1141 extension_opcode
= next_field (str
, ',', &str
, last
);
1143 /* Find opcode_length. */
1144 opcode_length
= next_field (str
, ',', &str
, last
);
1146 /* Find cpu_flags. */
1147 cpu_flags
= next_field (str
, ',', &str
, last
);
1149 /* Find opcode_modifier. */
1150 opcode_modifier
= next_field (str
, ',', &str
, last
);
1152 /* Remove the first {. */
1153 str
= remove_leading_whitespaces (str
);
1156 str
= remove_leading_whitespaces (str
+ 1);
1160 /* There are at least "X}". */
1164 /* Remove trailing white spaces and }. */
1168 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1177 /* Find operand_types. */
1178 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1182 operand_types
[i
] = NULL
;
1186 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1187 if (*operand_types
[i
] == '0')
1190 operand_types
[i
] = NULL
;
1195 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1196 name
, operands
, base_opcode
, extension_opcode
,
1199 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1201 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1203 fprintf (table
, " { ");
1205 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1207 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1210 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1216 fprintf (table
, ",\n ");
1218 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1221 fprintf (table
, " } },\n");
1224 struct opcode_hash_entry
1226 struct opcode_hash_entry
*next
;
1232 /* Calculate the hash value of an opcode hash entry P. */
1235 opcode_hash_hash (const void *p
)
1237 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1238 return htab_hash_string (entry
->name
);
1241 /* Compare a string Q against an opcode hash entry P. */
1244 opcode_hash_eq (const void *p
, const void *q
)
1246 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1247 const char *name
= (const char *) q
;
1248 return strcmp (name
, entry
->name
) == 0;
1252 process_i386_opcodes (FILE *table
)
1257 char *str
, *p
, *last
, *name
;
1258 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1259 htab_t opcode_hash_table
;
1260 struct opcode_hash_entry
**opcode_array
;
1261 unsigned int opcode_array_size
= 1024;
1264 filename
= "i386-opc.tbl";
1265 fp
= fopen (filename
, "r");
1268 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1272 opcode_array
= (struct opcode_hash_entry
**)
1273 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1275 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1276 opcode_hash_eq
, NULL
,
1279 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1280 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1282 /* Put everything on opcode array. */
1285 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1290 p
= remove_leading_whitespaces (buf
);
1292 /* Skip comments. */
1293 str
= strstr (p
, "//");
1297 /* Remove trailing white spaces. */
1298 remove_trailing_whitespaces (p
);
1303 /* Ignore comments. */
1311 last
= p
+ strlen (p
);
1314 name
= next_field (p
, ',', &str
, last
);
1316 /* Get the slot in hash table. */
1317 hash_slot
= (struct opcode_hash_entry
**)
1318 htab_find_slot_with_hash (opcode_hash_table
, name
,
1319 htab_hash_string (name
),
1322 if (*hash_slot
== NULL
)
1324 /* It is the new one. Put it on opcode array. */
1325 if (i
>= opcode_array_size
)
1327 /* Grow the opcode array when needed. */
1328 opcode_array_size
+= 1024;
1329 opcode_array
= (struct opcode_hash_entry
**)
1330 xrealloc (opcode_array
,
1331 sizeof (*opcode_array
) * opcode_array_size
);
1334 opcode_array
[i
] = (struct opcode_hash_entry
*)
1335 xmalloc (sizeof (struct opcode_hash_entry
));
1336 opcode_array
[i
]->next
= NULL
;
1337 opcode_array
[i
]->name
= xstrdup (name
);
1338 opcode_array
[i
]->opcode
= xstrdup (str
);
1339 opcode_array
[i
]->lineno
= lineno
;
1340 *hash_slot
= opcode_array
[i
];
1345 /* Append it to the existing one. */
1347 while ((*entry
) != NULL
)
1348 entry
= &(*entry
)->next
;
1349 *entry
= (struct opcode_hash_entry
*)
1350 xmalloc (sizeof (struct opcode_hash_entry
));
1351 (*entry
)->next
= NULL
;
1352 (*entry
)->name
= (*hash_slot
)->name
;
1353 (*entry
)->opcode
= xstrdup (str
);
1354 (*entry
)->lineno
= lineno
;
1358 /* Process opcode array. */
1359 for (j
= 0; j
< i
; j
++)
1361 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1365 lineno
= next
->lineno
;
1366 last
= str
+ strlen (str
);
1367 output_i386_opcode (table
, name
, str
, last
, lineno
);
1373 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1375 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1377 process_i386_opcode_modifier (table
, "0", -1);
1379 fprintf (table
, " { ");
1380 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1381 fprintf (table
, " } }\n");
1383 fprintf (table
, "};\n");
1387 process_i386_registers (FILE *table
)
1391 char *str
, *p
, *last
;
1392 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1393 char *dw2_32_num
, *dw2_64_num
;
1396 filename
= "i386-reg.tbl";
1397 fp
= fopen (filename
, "r");
1399 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1402 fprintf (table
, "\n/* i386 register table. */\n\n");
1403 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1407 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1412 p
= remove_leading_whitespaces (buf
);
1414 /* Skip comments. */
1415 str
= strstr (p
, "//");
1419 /* Remove trailing white spaces. */
1420 remove_trailing_whitespaces (p
);
1425 fprintf (table
, "%s\n", p
);
1433 last
= p
+ strlen (p
);
1435 /* Find reg_name. */
1436 reg_name
= next_field (p
, ',', &str
, last
);
1438 /* Find reg_type. */
1439 reg_type
= next_field (str
, ',', &str
, last
);
1441 /* Find reg_flags. */
1442 reg_flags
= next_field (str
, ',', &str
, last
);
1445 reg_num
= next_field (str
, ',', &str
, last
);
1447 fprintf (table
, " { \"%s\",\n ", reg_name
);
1449 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1452 /* Find 32-bit Dwarf2 register number. */
1453 dw2_32_num
= next_field (str
, ',', &str
, last
);
1455 /* Find 64-bit Dwarf2 register number. */
1456 dw2_64_num
= next_field (str
, ',', &str
, last
);
1458 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1459 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1464 fprintf (table
, "};\n");
1466 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1470 process_i386_initializers (void)
1473 FILE *fp
= fopen ("i386-init.h", "w");
1477 fail (_("can't create i386-init.h, errno = %s\n"),
1480 process_copyright (fp
);
1482 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1484 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1485 init
= xstrdup (cpu_flag_init
[i
].init
);
1486 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1490 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1492 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1493 init
= xstrdup (operand_type_init
[i
].init
);
1494 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1502 /* Program options. */
1503 #define OPTION_SRCDIR 200
1505 struct option long_options
[] =
1507 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1508 {"debug", no_argument
, NULL
, 'd'},
1509 {"version", no_argument
, NULL
, 'V'},
1510 {"help", no_argument
, NULL
, 'h'},
1511 {0, no_argument
, NULL
, 0}
1515 print_version (void)
1517 printf ("%s: version 1.0\n", program_name
);
1522 usage (FILE * stream
, int status
)
1524 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1530 main (int argc
, char **argv
)
1532 extern int chdir (char *);
1533 char *srcdir
= NULL
;
1535 unsigned int i
, cpumax
;
1538 program_name
= *argv
;
1539 xmalloc_set_program_name (program_name
);
1541 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1566 if (chdir (srcdir
) != 0)
1567 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1568 srcdir
, xstrerror (errno
));
1570 /* cpu_flags isn't sorted by position. */
1572 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1573 if (cpu_flags
[i
].position
> cpumax
)
1574 cpumax
= cpu_flags
[i
].position
;
1576 /* Check the unused bitfield in i386_cpu_flags. */
1578 if ((cpumax
- 1) != CpuMax
)
1579 fail (_("CpuMax != %d!\n"), cpumax
);
1581 if (cpumax
!= CpuMax
)
1582 fail (_("CpuMax != %d!\n"), cpumax
);
1584 c
= CpuNumOfBits
- CpuMax
- 1;
1586 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1589 /* Check the unused bitfield in i386_operand_type. */
1591 c
= OTNumOfBits
- OTMax
- 1;
1593 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1596 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1599 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1600 sizeof (opcode_modifiers
[0]), compare
);
1602 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1603 sizeof (operand_types
[0]), compare
);
1605 table
= fopen ("i386-tbl.h", "w");
1607 fail (_("can't create i386-tbl.h, errno = %s\n"),
1610 process_copyright (table
);
1612 process_i386_opcodes (table
);
1613 process_i386_registers (table
);
1614 process_i386_initializers ();