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_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|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 (CpuWAITPKG
),
579 BITFIELD (CpuCLDEMOTE
),
581 BITFIELD (CpuUnused
),
585 static bitfield opcode_modifiers
[] =
591 BITFIELD (ShortForm
),
593 BITFIELD (JumpDword
),
595 BITFIELD (JumpInterSegment
),
601 BITFIELD (CheckRegSize
),
602 BITFIELD (IgnoreSize
),
603 BITFIELD (DefaultSize
),
612 BITFIELD (BNDPrefixOk
),
613 BITFIELD (NoTrackPrefixOk
),
614 BITFIELD (IsLockable
),
615 BITFIELD (RegKludge
),
616 BITFIELD (Implicit1stXmm0
),
617 BITFIELD (RepPrefixOk
),
618 BITFIELD (HLEPrefixOk
),
621 BITFIELD (AddrPrefixOp0
),
630 BITFIELD (VexOpcode
),
631 BITFIELD (VexSources
),
637 BITFIELD (Broadcast
),
638 BITFIELD (StaticRounding
),
640 BITFIELD (Disp8MemShift
),
641 BITFIELD (NoDefMask
),
642 BITFIELD (ImplicitQuadGroup
),
644 BITFIELD (ATTMnemonic
),
645 BITFIELD (ATTSyntax
),
646 BITFIELD (IntelSyntax
),
651 static bitfield operand_types
[] =
664 BITFIELD (BaseIndex
),
670 BITFIELD (InOutPortReg
),
671 BITFIELD (ShiftCount
),
678 BITFIELD (JumpAbsolute
),
691 BITFIELD (Unspecified
),
700 static const char *filename
;
701 static i386_cpu_flags active_cpu_flags
;
702 static int active_isstring
;
705 compare (const void *x
, const void *y
)
707 const bitfield
*xp
= (const bitfield
*) x
;
708 const bitfield
*yp
= (const bitfield
*) y
;
709 return xp
->position
- yp
->position
;
713 fail (const char *message
, ...)
717 va_start (args
, message
);
718 fprintf (stderr
, _("%s: error: "), program_name
);
719 vfprintf (stderr
, message
, args
);
725 process_copyright (FILE *fp
)
727 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
728 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
730 This file is part of the GNU opcodes library.\n\
732 This library is free software; you can redistribute it and/or modify\n\
733 it under the terms of the GNU General Public License as published by\n\
734 the Free Software Foundation; either version 3, or (at your option)\n\
735 any later version.\n\
737 It is distributed in the hope that it will be useful, but WITHOUT\n\
738 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
739 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
740 License for more details.\n\
742 You should have received a copy of the GNU General Public License\n\
743 along with this program; if not, write to the Free Software\n\
744 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
745 MA 02110-1301, USA. */\n");
748 /* Remove leading white spaces. */
751 remove_leading_whitespaces (char *str
)
753 while (ISSPACE (*str
))
758 /* Remove trailing white spaces. */
761 remove_trailing_whitespaces (char *str
)
763 size_t last
= strlen (str
);
771 if (ISSPACE (str
[last
]))
779 /* Find next field separated by SEP and terminate it. Return a
780 pointer to the one after it. */
783 next_field (char *str
, char sep
, char **next
, char *last
)
787 p
= remove_leading_whitespaces (str
);
788 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
791 remove_trailing_whitespaces (p
);
801 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
804 set_bitfield_from_shorthand (char *f
, bitfield
*array
, unsigned int size
,
807 char *str
, *next
, *last
;
810 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
811 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
813 /* Turn on selective bits. */
814 char *init
= xstrdup (cpu_flag_init
[i
].init
);
815 last
= init
+ strlen (init
);
816 for (next
= init
; next
&& next
< last
; )
818 str
= next_field (next
, '|', &next
, last
);
820 set_bitfield (str
, array
, 1, size
, lineno
);
826 for (i
= 0; i
< ARRAY_SIZE (operand_type_shorthands
); i
++)
827 if (strcmp (operand_type_shorthands
[i
].name
, f
) == 0)
829 /* Turn on selective bits. */
830 char *init
= xstrdup (operand_type_shorthands
[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
);
846 set_bitfield (char *f
, bitfield
*array
, int value
,
847 unsigned int size
, int lineno
)
851 if (strcmp (f
, "CpuFP") == 0)
853 set_bitfield("Cpu387", array
, value
, size
, lineno
);
854 set_bitfield("Cpu287", array
, value
, size
, lineno
);
857 else if (strcmp (f
, "Mmword") == 0)
859 else if (strcmp (f
, "Oword") == 0)
862 for (i
= 0; i
< size
; i
++)
863 if (strcasecmp (array
[i
].name
, f
) == 0)
865 array
[i
].value
= value
;
871 const char *v
= strchr (f
, '=');
878 for (i
= 0; i
< size
; i
++)
879 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
881 value
= strtol (v
+ 1, &end
, 0);
884 array
[i
].value
= value
;
892 /* Handle shorthands. */
893 if (value
== 1 && !set_bitfield_from_shorthand (f
, array
, size
, lineno
))
897 fail (_("%s: %d: unknown bitfield: %s\n"), filename
, lineno
, f
);
899 fail (_("unknown bitfield: %s\n"), f
);
903 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
904 int macro
, const char *comma
, const char *indent
)
908 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
910 fprintf (table
, "%s{ { ", indent
);
912 for (i
= 0; i
< size
- 1; i
++)
914 if (((i
+ 1) % 20) != 0)
915 fprintf (table
, "%d, ", flags
[i
].value
);
917 fprintf (table
, "%d,", flags
[i
].value
);
918 if (((i
+ 1) % 20) == 0)
920 /* We need \\ for macro. */
922 fprintf (table
, " \\\n %s", indent
);
924 fprintf (table
, "\n %s", indent
);
927 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
930 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
934 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
935 const char *comma
, const char *indent
,
938 char *str
, *next
, *last
;
940 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
942 /* Copy the default cpu flags. */
943 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
945 if (strcasecmp (flag
, "unknown") == 0)
947 /* We turn on everything except for cpu64 in case of
948 CPU_UNKNOWN_FLAGS. */
949 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
950 if (flags
[i
].position
!= Cpu64
)
953 else if (flag
[0] == '~')
955 last
= flag
+ strlen (flag
);
962 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename
,
969 /* First we turn on everything except for cpu64. */
970 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
971 if (flags
[i
].position
!= Cpu64
)
974 /* Turn off selective bits. */
975 for (; next
&& next
< last
; )
977 str
= next_field (next
, '|', &next
, last
);
979 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
982 else if (strcmp (flag
, "0"))
984 /* Turn on selective bits. */
985 last
= flag
+ strlen (flag
);
986 for (next
= flag
; next
&& next
< last
; )
988 str
= next_field (next
, '|', &next
, last
);
990 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
994 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
999 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1003 fprintf (table
, " { ");
1005 for (i
= 0; i
< size
- 1; i
++)
1007 if (((i
+ 1) % 20) != 0)
1008 fprintf (table
, "%d, ", modifier
[i
].value
);
1010 fprintf (table
, "%d,", modifier
[i
].value
);
1011 if (((i
+ 1) % 20) == 0)
1012 fprintf (table
, "\n ");
1015 fprintf (table
, "%d },\n", modifier
[i
].value
);
1019 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
1021 char *str
, *next
, *last
;
1022 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1024 active_isstring
= 0;
1026 /* Copy the default opcode modifier. */
1027 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1029 if (strcmp (mod
, "0"))
1031 last
= mod
+ strlen (mod
);
1032 for (next
= mod
; next
&& next
< last
; )
1034 str
= next_field (next
, '|', &next
, last
);
1037 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
1039 if (strcasecmp(str
, "IsString") == 0)
1040 active_isstring
= 1;
1044 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1054 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1055 enum stage stage
, const char *indent
)
1059 fprintf (table
, "{ { ");
1061 for (i
= 0; i
< size
- 1; i
++)
1063 if (((i
+ 1) % 20) != 0)
1064 fprintf (table
, "%d, ", types
[i
].value
);
1066 fprintf (table
, "%d,", types
[i
].value
);
1067 if (((i
+ 1) % 20) == 0)
1069 /* We need \\ for macro. */
1070 if (stage
== stage_macros
)
1071 fprintf (table
, " \\\n%s", indent
);
1073 fprintf (table
, "\n%s", indent
);
1077 fprintf (table
, "%d } }", types
[i
].value
);
1081 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1082 const char *indent
, int lineno
)
1084 char *str
, *next
, *last
;
1085 bitfield types
[ARRAY_SIZE (operand_types
)];
1087 /* Copy the default operand type. */
1088 memcpy (types
, operand_types
, sizeof (types
));
1090 if (strcmp (op
, "0"))
1094 last
= op
+ strlen (op
);
1095 for (next
= op
; next
&& next
< last
; )
1097 str
= next_field (next
, '|', &next
, last
);
1100 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1101 if (strcasecmp(str
, "BaseIndex") == 0)
1106 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1108 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1109 if (!active_cpu_flags
.bitfield
.cpu64
1110 && !active_cpu_flags
.bitfield
.cpumpx
)
1111 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1112 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1113 if (!active_cpu_flags
.bitfield
.cpuno64
)
1114 set_bitfield("Disp32S", types
, 1, ARRAY_SIZE (types
), lineno
);
1117 output_operand_type (table
, types
, ARRAY_SIZE (types
), stage
,
1122 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1123 char *last
, int lineno
)
1126 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1127 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1129 /* Find number of operands. */
1130 operands
= next_field (str
, ',', &str
, last
);
1132 /* Find base_opcode. */
1133 base_opcode
= next_field (str
, ',', &str
, last
);
1135 /* Find extension_opcode. */
1136 extension_opcode
= next_field (str
, ',', &str
, last
);
1138 /* Find opcode_length. */
1139 opcode_length
= next_field (str
, ',', &str
, last
);
1141 /* Find cpu_flags. */
1142 cpu_flags
= next_field (str
, ',', &str
, last
);
1144 /* Find opcode_modifier. */
1145 opcode_modifier
= next_field (str
, ',', &str
, last
);
1147 /* Remove the first {. */
1148 str
= remove_leading_whitespaces (str
);
1151 str
= remove_leading_whitespaces (str
+ 1);
1155 /* There are at least "X}". */
1159 /* Remove trailing white spaces and }. */
1163 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1172 /* Find operand_types. */
1173 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1177 operand_types
[i
] = NULL
;
1181 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1182 if (*operand_types
[i
] == '0')
1185 operand_types
[i
] = NULL
;
1190 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1191 name
, operands
, base_opcode
, extension_opcode
,
1194 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1196 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1198 fprintf (table
, " { ");
1200 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1202 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1205 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1211 fprintf (table
, ",\n ");
1213 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1216 fprintf (table
, " } },\n");
1219 struct opcode_hash_entry
1221 struct opcode_hash_entry
*next
;
1227 /* Calculate the hash value of an opcode hash entry P. */
1230 opcode_hash_hash (const void *p
)
1232 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1233 return htab_hash_string (entry
->name
);
1236 /* Compare a string Q against an opcode hash entry P. */
1239 opcode_hash_eq (const void *p
, const void *q
)
1241 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1242 const char *name
= (const char *) q
;
1243 return strcmp (name
, entry
->name
) == 0;
1247 process_i386_opcodes (FILE *table
)
1252 char *str
, *p
, *last
, *name
;
1253 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1254 htab_t opcode_hash_table
;
1255 struct opcode_hash_entry
**opcode_array
;
1256 unsigned int opcode_array_size
= 1024;
1259 filename
= "i386-opc.tbl";
1260 fp
= fopen (filename
, "r");
1263 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1267 opcode_array
= (struct opcode_hash_entry
**)
1268 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1270 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1271 opcode_hash_eq
, NULL
,
1274 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1275 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1277 /* Put everything on opcode array. */
1280 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1285 p
= remove_leading_whitespaces (buf
);
1287 /* Skip comments. */
1288 str
= strstr (p
, "//");
1292 /* Remove trailing white spaces. */
1293 remove_trailing_whitespaces (p
);
1298 /* Ignore comments. */
1306 last
= p
+ strlen (p
);
1309 name
= next_field (p
, ',', &str
, last
);
1311 /* Get the slot in hash table. */
1312 hash_slot
= (struct opcode_hash_entry
**)
1313 htab_find_slot_with_hash (opcode_hash_table
, name
,
1314 htab_hash_string (name
),
1317 if (*hash_slot
== NULL
)
1319 /* It is the new one. Put it on opcode array. */
1320 if (i
>= opcode_array_size
)
1322 /* Grow the opcode array when needed. */
1323 opcode_array_size
+= 1024;
1324 opcode_array
= (struct opcode_hash_entry
**)
1325 xrealloc (opcode_array
,
1326 sizeof (*opcode_array
) * opcode_array_size
);
1329 opcode_array
[i
] = (struct opcode_hash_entry
*)
1330 xmalloc (sizeof (struct opcode_hash_entry
));
1331 opcode_array
[i
]->next
= NULL
;
1332 opcode_array
[i
]->name
= xstrdup (name
);
1333 opcode_array
[i
]->opcode
= xstrdup (str
);
1334 opcode_array
[i
]->lineno
= lineno
;
1335 *hash_slot
= opcode_array
[i
];
1340 /* Append it to the existing one. */
1342 while ((*entry
) != NULL
)
1343 entry
= &(*entry
)->next
;
1344 *entry
= (struct opcode_hash_entry
*)
1345 xmalloc (sizeof (struct opcode_hash_entry
));
1346 (*entry
)->next
= NULL
;
1347 (*entry
)->name
= (*hash_slot
)->name
;
1348 (*entry
)->opcode
= xstrdup (str
);
1349 (*entry
)->lineno
= lineno
;
1353 /* Process opcode array. */
1354 for (j
= 0; j
< i
; j
++)
1356 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1360 lineno
= next
->lineno
;
1361 last
= str
+ strlen (str
);
1362 output_i386_opcode (table
, name
, str
, last
, lineno
);
1368 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1370 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1372 process_i386_opcode_modifier (table
, "0", -1);
1374 fprintf (table
, " { ");
1375 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ", -1);
1376 fprintf (table
, " } }\n");
1378 fprintf (table
, "};\n");
1382 process_i386_registers (FILE *table
)
1386 char *str
, *p
, *last
;
1387 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1388 char *dw2_32_num
, *dw2_64_num
;
1391 filename
= "i386-reg.tbl";
1392 fp
= fopen (filename
, "r");
1394 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1397 fprintf (table
, "\n/* i386 register table. */\n\n");
1398 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1402 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1407 p
= remove_leading_whitespaces (buf
);
1409 /* Skip comments. */
1410 str
= strstr (p
, "//");
1414 /* Remove trailing white spaces. */
1415 remove_trailing_whitespaces (p
);
1420 fprintf (table
, "%s\n", p
);
1428 last
= p
+ strlen (p
);
1430 /* Find reg_name. */
1431 reg_name
= next_field (p
, ',', &str
, last
);
1433 /* Find reg_type. */
1434 reg_type
= next_field (str
, ',', &str
, last
);
1436 /* Find reg_flags. */
1437 reg_flags
= next_field (str
, ',', &str
, last
);
1440 reg_num
= next_field (str
, ',', &str
, last
);
1442 fprintf (table
, " { \"%s\",\n ", reg_name
);
1444 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
1447 /* Find 32-bit Dwarf2 register number. */
1448 dw2_32_num
= next_field (str
, ',', &str
, last
);
1450 /* Find 64-bit Dwarf2 register number. */
1451 dw2_64_num
= next_field (str
, ',', &str
, last
);
1453 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1454 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1459 fprintf (table
, "};\n");
1461 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1465 process_i386_initializers (void)
1468 FILE *fp
= fopen ("i386-init.h", "w");
1472 fail (_("can't create i386-init.h, errno = %s\n"),
1475 process_copyright (fp
);
1477 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1479 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1480 init
= xstrdup (cpu_flag_init
[i
].init
);
1481 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1485 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1487 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1488 init
= xstrdup (operand_type_init
[i
].init
);
1489 process_i386_operand_type (fp
, init
, stage_macros
, " ", -1);
1497 /* Program options. */
1498 #define OPTION_SRCDIR 200
1500 struct option long_options
[] =
1502 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1503 {"debug", no_argument
, NULL
, 'd'},
1504 {"version", no_argument
, NULL
, 'V'},
1505 {"help", no_argument
, NULL
, 'h'},
1506 {0, no_argument
, NULL
, 0}
1510 print_version (void)
1512 printf ("%s: version 1.0\n", program_name
);
1517 usage (FILE * stream
, int status
)
1519 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1525 main (int argc
, char **argv
)
1527 extern int chdir (char *);
1528 char *srcdir
= NULL
;
1530 unsigned int i
, cpumax
;
1533 program_name
= *argv
;
1534 xmalloc_set_program_name (program_name
);
1536 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1561 if (chdir (srcdir
) != 0)
1562 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1563 srcdir
, xstrerror (errno
));
1565 /* cpu_flags isn't sorted by position. */
1567 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1568 if (cpu_flags
[i
].position
> cpumax
)
1569 cpumax
= cpu_flags
[i
].position
;
1571 /* Check the unused bitfield in i386_cpu_flags. */
1573 if ((cpumax
- 1) != CpuMax
)
1574 fail (_("CpuMax != %d!\n"), cpumax
);
1576 if (cpumax
!= CpuMax
)
1577 fail (_("CpuMax != %d!\n"), cpumax
);
1579 c
= CpuNumOfBits
- CpuMax
- 1;
1581 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1584 /* Check the unused bitfield in i386_operand_type. */
1586 c
= OTNumOfBits
- OTMax
- 1;
1588 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1591 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1594 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1595 sizeof (opcode_modifiers
[0]), compare
);
1597 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1598 sizeof (operand_types
[0]), compare
);
1600 table
= fopen ("i386-tbl.h", "w");
1602 fail (_("can't create i386-tbl.h, errno = %s\n"),
1605 process_copyright (table
);
1607 process_i386_opcodes (table
);
1608 process_i386_registers (table
);
1609 process_i386_initializers ();