1 /* Copyright (C) 2007-2017 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",
278 { "CPU_VPCLMULQDQ_FLAGS",
280 { "CPU_ANY_X87_FLAGS",
281 "CPU_ANY_287_FLAGS|Cpu8087" },
282 { "CPU_ANY_287_FLAGS",
283 "CPU_ANY_387_FLAGS|Cpu287" },
284 { "CPU_ANY_387_FLAGS",
285 "CPU_ANY_687_FLAGS|Cpu387" },
286 { "CPU_ANY_687_FLAGS",
287 "Cpu687|CpuFISTTP" },
288 { "CPU_ANY_MMX_FLAGS",
289 "CPU_3DNOWA_FLAGS" },
290 { "CPU_ANY_SSE_FLAGS",
291 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
292 { "CPU_ANY_SSE2_FLAGS",
293 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
294 { "CPU_ANY_SSE3_FLAGS",
295 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
296 { "CPU_ANY_SSSE3_FLAGS",
297 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
298 { "CPU_ANY_SSE4_1_FLAGS",
299 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
300 { "CPU_ANY_SSE4_2_FLAGS",
302 { "CPU_ANY_AVX_FLAGS",
303 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
304 { "CPU_ANY_AVX2_FLAGS",
306 { "CPU_ANY_AVX512F_FLAGS",
307 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512F" },
308 { "CPU_ANY_AVX512CD_FLAGS",
310 { "CPU_ANY_AVX512ER_FLAGS",
312 { "CPU_ANY_AVX512PF_FLAGS",
314 { "CPU_ANY_AVX512DQ_FLAGS",
316 { "CPU_ANY_AVX512BW_FLAGS",
318 { "CPU_ANY_AVX512VL_FLAGS",
320 { "CPU_ANY_AVX512IFMA_FLAGS",
322 { "CPU_ANY_AVX512VBMI_FLAGS",
324 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
325 "CpuAVX512_4FMAPS" },
326 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
327 "CpuAVX512_4VNNIW" },
328 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
329 "CpuAVX512_VPOPCNTDQ" },
330 { "CPU_ANY_AVX512_VBMI2_FLAGS",
332 { "CPU_ANY_AVX512_VNNI_FLAGS",
334 { "CPU_ANY_AVX512_BITALG_FLAGS",
335 "CpuAVX512_BITALG" },
338 static initializer operand_type_init
[] =
340 { "OPERAND_TYPE_NONE",
342 { "OPERAND_TYPE_REG8",
344 { "OPERAND_TYPE_REG16",
346 { "OPERAND_TYPE_REG32",
348 { "OPERAND_TYPE_REG64",
350 { "OPERAND_TYPE_IMM1",
352 { "OPERAND_TYPE_IMM8",
354 { "OPERAND_TYPE_IMM8S",
356 { "OPERAND_TYPE_IMM16",
358 { "OPERAND_TYPE_IMM32",
360 { "OPERAND_TYPE_IMM32S",
362 { "OPERAND_TYPE_IMM64",
364 { "OPERAND_TYPE_BASEINDEX",
366 { "OPERAND_TYPE_DISP8",
368 { "OPERAND_TYPE_DISP16",
370 { "OPERAND_TYPE_DISP32",
372 { "OPERAND_TYPE_DISP32S",
374 { "OPERAND_TYPE_DISP64",
376 { "OPERAND_TYPE_INOUTPORTREG",
378 { "OPERAND_TYPE_SHIFTCOUNT",
380 { "OPERAND_TYPE_CONTROL",
382 { "OPERAND_TYPE_TEST",
384 { "OPERAND_TYPE_DEBUG",
386 { "OPERAND_TYPE_FLOATREG",
388 { "OPERAND_TYPE_FLOATACC",
390 { "OPERAND_TYPE_SREG2",
392 { "OPERAND_TYPE_SREG3",
394 { "OPERAND_TYPE_ACC",
396 { "OPERAND_TYPE_JUMPABSOLUTE",
398 { "OPERAND_TYPE_REGMMX",
400 { "OPERAND_TYPE_REGXMM",
402 { "OPERAND_TYPE_REGYMM",
404 { "OPERAND_TYPE_REGZMM",
406 { "OPERAND_TYPE_REGMASK",
408 { "OPERAND_TYPE_ESSEG",
410 { "OPERAND_TYPE_ACC32",
412 { "OPERAND_TYPE_ACC64",
414 { "OPERAND_TYPE_INOUTPORTREG",
416 { "OPERAND_TYPE_REG16_INOUTPORTREG",
417 "Reg16|InOutPortReg" },
418 { "OPERAND_TYPE_DISP16_32",
420 { "OPERAND_TYPE_ANYDISP",
421 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
422 { "OPERAND_TYPE_IMM16_32",
424 { "OPERAND_TYPE_IMM16_32S",
426 { "OPERAND_TYPE_IMM16_32_32S",
427 "Imm16|Imm32|Imm32S" },
428 { "OPERAND_TYPE_IMM32_64",
430 { "OPERAND_TYPE_IMM32_32S_DISP32",
431 "Imm32|Imm32S|Disp32" },
432 { "OPERAND_TYPE_IMM64_DISP64",
434 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
435 "Imm32|Imm32S|Imm64|Disp32" },
436 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
437 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
438 { "OPERAND_TYPE_VEC_IMM4",
440 { "OPERAND_TYPE_REGBND",
442 { "OPERAND_TYPE_VEC_DISP8",
446 typedef struct bitfield
453 #define BITFIELD(n) { n, 0, #n }
455 static bitfield cpu_flags
[] =
463 BITFIELD (CpuClflush
),
465 BITFIELD (CpuSYSCALL
),
470 BITFIELD (CpuFISTTP
),
476 BITFIELD (CpuSSE4_1
),
477 BITFIELD (CpuSSE4_2
),
480 BITFIELD (CpuAVX512F
),
481 BITFIELD (CpuAVX512CD
),
482 BITFIELD (CpuAVX512ER
),
483 BITFIELD (CpuAVX512PF
),
484 BITFIELD (CpuAVX512VL
),
485 BITFIELD (CpuAVX512DQ
),
486 BITFIELD (CpuAVX512BW
),
492 BITFIELD (Cpu3dnowA
),
493 BITFIELD (CpuPadLock
),
499 BITFIELD (CpuXsaveopt
),
501 BITFIELD (CpuPCLMUL
),
512 BITFIELD (CpuRdtscp
),
513 BITFIELD (CpuFSGSBase
),
520 BITFIELD (CpuINVPCID
),
521 BITFIELD (CpuVMFUNC
),
522 BITFIELD (CpuRDSEED
),
524 BITFIELD (CpuPRFCHW
),
528 BITFIELD (CpuClflushOpt
),
529 BITFIELD (CpuXSAVES
),
530 BITFIELD (CpuXSAVEC
),
531 BITFIELD (CpuPREFETCHWT1
),
537 BITFIELD (CpuAVX512IFMA
),
538 BITFIELD (CpuAVX512VBMI
),
539 BITFIELD (CpuAVX512_4FMAPS
),
540 BITFIELD (CpuAVX512_4VNNIW
),
541 BITFIELD (CpuAVX512_VPOPCNTDQ
),
542 BITFIELD (CpuAVX512_VBMI2
),
543 BITFIELD (CpuAVX512_VNNI
),
544 BITFIELD (CpuAVX512_BITALG
),
545 BITFIELD (CpuMWAITX
),
546 BITFIELD (CpuCLZERO
),
549 BITFIELD (CpuPTWRITE
),
553 BITFIELD (CpuVPCLMULQDQ
),
554 BITFIELD (CpuRegMMX
),
555 BITFIELD (CpuRegXMM
),
556 BITFIELD (CpuRegYMM
),
557 BITFIELD (CpuRegZMM
),
558 BITFIELD (CpuRegMask
),
560 BITFIELD (CpuUnused
),
564 static bitfield opcode_modifiers
[] =
570 BITFIELD (ShortForm
),
572 BITFIELD (JumpDword
),
574 BITFIELD (JumpInterSegment
),
581 BITFIELD (CheckRegSize
),
582 BITFIELD (IgnoreSize
),
583 BITFIELD (DefaultSize
),
592 BITFIELD (BNDPrefixOk
),
593 BITFIELD (NoTrackPrefixOk
),
594 BITFIELD (IsLockable
),
595 BITFIELD (RegKludge
),
596 BITFIELD (FirstXmm0
),
597 BITFIELD (Implicit1stXmm0
),
598 BITFIELD (RepPrefixOk
),
599 BITFIELD (HLEPrefixOk
),
602 BITFIELD (AddrPrefixOp0
),
611 BITFIELD (VexOpcode
),
612 BITFIELD (VexSources
),
613 BITFIELD (VexImmExt
),
620 BITFIELD (Broadcast
),
621 BITFIELD (StaticRounding
),
623 BITFIELD (Disp8MemShift
),
624 BITFIELD (NoDefMask
),
625 BITFIELD (ImplicitQuadGroup
),
627 BITFIELD (ATTMnemonic
),
628 BITFIELD (ATTSyntax
),
629 BITFIELD (IntelSyntax
),
634 static bitfield operand_types
[] =
653 BITFIELD (BaseIndex
),
659 BITFIELD (InOutPortReg
),
660 BITFIELD (ShiftCount
),
668 BITFIELD (JumpAbsolute
),
681 BITFIELD (Unspecified
),
685 BITFIELD (Vec_Disp8
),
691 static const char *filename
;
694 compare (const void *x
, const void *y
)
696 const bitfield
*xp
= (const bitfield
*) x
;
697 const bitfield
*yp
= (const bitfield
*) y
;
698 return xp
->position
- yp
->position
;
702 fail (const char *message
, ...)
706 va_start (args
, message
);
707 fprintf (stderr
, _("%s: Error: "), program_name
);
708 vfprintf (stderr
, message
, args
);
714 process_copyright (FILE *fp
)
716 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
717 /* Copyright (C) 2007-2017 Free Software Foundation, Inc.\n\
719 This file is part of the GNU opcodes library.\n\
721 This library is free software; you can redistribute it and/or modify\n\
722 it under the terms of the GNU General Public License as published by\n\
723 the Free Software Foundation; either version 3, or (at your option)\n\
724 any later version.\n\
726 It is distributed in the hope that it will be useful, but WITHOUT\n\
727 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
728 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
729 License for more details.\n\
731 You should have received a copy of the GNU General Public License\n\
732 along with this program; if not, write to the Free Software\n\
733 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
734 MA 02110-1301, USA. */\n");
737 /* Remove leading white spaces. */
740 remove_leading_whitespaces (char *str
)
742 while (ISSPACE (*str
))
747 /* Remove trailing white spaces. */
750 remove_trailing_whitespaces (char *str
)
752 size_t last
= strlen (str
);
760 if (ISSPACE (str
[last
]))
768 /* Find next field separated by SEP and terminate it. Return a
769 pointer to the one after it. */
772 next_field (char *str
, char sep
, char **next
, char *last
)
776 p
= remove_leading_whitespaces (str
);
777 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
780 remove_trailing_whitespaces (p
);
790 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
793 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
,
794 int value
, unsigned int size
,
797 char *str
, *next
, *last
;
800 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
801 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
803 /* Turn on selective bits. */
804 char *init
= xstrdup (cpu_flag_init
[i
].init
);
805 last
= init
+ strlen (init
);
806 for (next
= init
; next
&& next
< last
; )
808 str
= next_field (next
, '|', &next
, last
);
810 set_bitfield (str
, array
, 1, size
, lineno
);
820 set_bitfield (char *f
, bitfield
*array
, int value
,
821 unsigned int size
, int lineno
)
825 if (strcmp (f
, "CpuFP") == 0)
827 set_bitfield("Cpu387", array
, value
, size
, lineno
);
828 set_bitfield("Cpu287", array
, value
, size
, lineno
);
831 else if (strcmp (f
, "Mmword") == 0)
833 else if (strcmp (f
, "Oword") == 0)
836 for (i
= 0; i
< size
; i
++)
837 if (strcasecmp (array
[i
].name
, f
) == 0)
839 array
[i
].value
= value
;
845 const char *v
= strchr (f
, '=');
852 for (i
= 0; i
< size
; i
++)
853 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
855 value
= strtol (v
+ 1, &end
, 0);
858 array
[i
].value
= value
;
866 /* Handle CPU_XXX_FLAGS. */
867 if (!set_bitfield_from_cpu_flag_init (f
, array
, value
, size
, lineno
))
871 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
873 fail (_("Unknown bitfield: %s\n"), f
);
877 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
878 int macro
, const char *comma
, const char *indent
)
882 fprintf (table
, "%s{ { ", indent
);
884 for (i
= 0; i
< size
- 1; i
++)
886 if (((i
+ 1) % 20) != 0)
887 fprintf (table
, "%d, ", flags
[i
].value
);
889 fprintf (table
, "%d,", flags
[i
].value
);
890 if (((i
+ 1) % 20) == 0)
892 /* We need \\ for macro. */
894 fprintf (table
, " \\\n %s", indent
);
896 fprintf (table
, "\n %s", indent
);
900 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
904 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
905 const char *comma
, const char *indent
,
908 char *str
, *next
, *last
;
910 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
912 /* Copy the default cpu flags. */
913 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
915 if (strcasecmp (flag
, "unknown") == 0)
917 /* We turn on everything except for cpu64 in case of
918 CPU_UNKNOWN_FLAGS. */
919 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
920 if (flags
[i
].position
!= Cpu64
)
923 else if (flag
[0] == '~')
925 last
= flag
+ strlen (flag
);
932 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
939 /* First we turn on everything except for cpu64. */
940 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
941 if (flags
[i
].position
!= Cpu64
)
944 /* Turn off selective bits. */
945 for (; next
&& next
< last
; )
947 str
= next_field (next
, '|', &next
, last
);
949 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
952 else if (strcmp (flag
, "0"))
954 /* Turn on selective bits. */
955 last
= flag
+ strlen (flag
);
956 for (next
= flag
; next
&& next
< last
; )
958 str
= next_field (next
, '|', &next
, last
);
960 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
964 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
969 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
973 fprintf (table
, " { ");
975 for (i
= 0; i
< size
- 1; i
++)
977 if (((i
+ 1) % 20) != 0)
978 fprintf (table
, "%d, ", modifier
[i
].value
);
980 fprintf (table
, "%d,", modifier
[i
].value
);
981 if (((i
+ 1) % 20) == 0)
982 fprintf (table
, "\n ");
985 fprintf (table
, "%d },\n", modifier
[i
].value
);
989 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
991 char *str
, *next
, *last
;
992 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
994 /* Copy the default opcode modifier. */
995 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
997 if (strcmp (mod
, "0"))
999 last
= mod
+ strlen (mod
);
1000 for (next
= mod
; next
&& next
< last
; )
1002 str
= next_field (next
, '|', &next
, last
);
1004 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
1008 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1012 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1013 int macro
, const char *indent
)
1017 fprintf (table
, "{ { ");
1019 for (i
= 0; i
< size
- 1; i
++)
1021 if (((i
+ 1) % 20) != 0)
1022 fprintf (table
, "%d, ", types
[i
].value
);
1024 fprintf (table
, "%d,", types
[i
].value
);
1025 if (((i
+ 1) % 20) == 0)
1027 /* We need \\ for macro. */
1029 fprintf (table
, " \\\n%s", indent
);
1031 fprintf (table
, "\n%s", indent
);
1035 fprintf (table
, "%d } }", types
[i
].value
);
1039 process_i386_operand_type (FILE *table
, char *op
, int macro
,
1040 const char *indent
, int lineno
)
1042 char *str
, *next
, *last
;
1043 bitfield types
[ARRAY_SIZE (operand_types
)];
1045 /* Copy the default operand type. */
1046 memcpy (types
, operand_types
, sizeof (types
));
1048 if (strcmp (op
, "0"))
1050 last
= op
+ strlen (op
);
1051 for (next
= op
; next
&& next
< last
; )
1053 str
= next_field (next
, '|', &next
, last
);
1055 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1058 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
1063 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1064 char *last
, int lineno
)
1067 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1068 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1070 /* Find number of operands. */
1071 operands
= next_field (str
, ',', &str
, last
);
1073 /* Find base_opcode. */
1074 base_opcode
= next_field (str
, ',', &str
, last
);
1076 /* Find extension_opcode. */
1077 extension_opcode
= next_field (str
, ',', &str
, last
);
1079 /* Find opcode_length. */
1080 opcode_length
= next_field (str
, ',', &str
, last
);
1082 /* Find cpu_flags. */
1083 cpu_flags
= next_field (str
, ',', &str
, last
);
1085 /* Find opcode_modifier. */
1086 opcode_modifier
= next_field (str
, ',', &str
, last
);
1088 /* Remove the first {. */
1089 str
= remove_leading_whitespaces (str
);
1092 str
= remove_leading_whitespaces (str
+ 1);
1096 /* There are at least "X}". */
1100 /* Remove trailing white spaces and }. */
1104 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1113 /* Find operand_types. */
1114 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1118 operand_types
[i
] = NULL
;
1122 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1123 if (*operand_types
[i
] == '0')
1126 operand_types
[i
] = NULL
;
1131 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1132 name
, operands
, base_opcode
, extension_opcode
,
1135 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1137 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1139 fprintf (table
, " { ");
1141 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1143 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1146 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1151 fprintf (table
, ",\n ");
1153 process_i386_operand_type (table
, operand_types
[i
], 0,
1156 fprintf (table
, " } },\n");
1159 struct opcode_hash_entry
1161 struct opcode_hash_entry
*next
;
1167 /* Calculate the hash value of an opcode hash entry P. */
1170 opcode_hash_hash (const void *p
)
1172 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1173 return htab_hash_string (entry
->name
);
1176 /* Compare a string Q against an opcode hash entry P. */
1179 opcode_hash_eq (const void *p
, const void *q
)
1181 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1182 const char *name
= (const char *) q
;
1183 return strcmp (name
, entry
->name
) == 0;
1187 process_i386_opcodes (FILE *table
)
1192 char *str
, *p
, *last
, *name
;
1193 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1194 htab_t opcode_hash_table
;
1195 struct opcode_hash_entry
**opcode_array
;
1196 unsigned int opcode_array_size
= 1024;
1199 filename
= "i386-opc.tbl";
1200 fp
= fopen (filename
, "r");
1203 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1207 opcode_array
= (struct opcode_hash_entry
**)
1208 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1210 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1211 opcode_hash_eq
, NULL
,
1214 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1215 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1217 /* Put everything on opcode array. */
1220 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1225 p
= remove_leading_whitespaces (buf
);
1227 /* Skip comments. */
1228 str
= strstr (p
, "//");
1232 /* Remove trailing white spaces. */
1233 remove_trailing_whitespaces (p
);
1238 /* Ignore comments. */
1246 last
= p
+ strlen (p
);
1249 name
= next_field (p
, ',', &str
, last
);
1251 /* Get the slot in hash table. */
1252 hash_slot
= (struct opcode_hash_entry
**)
1253 htab_find_slot_with_hash (opcode_hash_table
, name
,
1254 htab_hash_string (name
),
1257 if (*hash_slot
== NULL
)
1259 /* It is the new one. Put it on opcode array. */
1260 if (i
>= opcode_array_size
)
1262 /* Grow the opcode array when needed. */
1263 opcode_array_size
+= 1024;
1264 opcode_array
= (struct opcode_hash_entry
**)
1265 xrealloc (opcode_array
,
1266 sizeof (*opcode_array
) * opcode_array_size
);
1269 opcode_array
[i
] = (struct opcode_hash_entry
*)
1270 xmalloc (sizeof (struct opcode_hash_entry
));
1271 opcode_array
[i
]->next
= NULL
;
1272 opcode_array
[i
]->name
= xstrdup (name
);
1273 opcode_array
[i
]->opcode
= xstrdup (str
);
1274 opcode_array
[i
]->lineno
= lineno
;
1275 *hash_slot
= opcode_array
[i
];
1280 /* Append it to the existing one. */
1282 while ((*entry
) != NULL
)
1283 entry
= &(*entry
)->next
;
1284 *entry
= (struct opcode_hash_entry
*)
1285 xmalloc (sizeof (struct opcode_hash_entry
));
1286 (*entry
)->next
= NULL
;
1287 (*entry
)->name
= (*hash_slot
)->name
;
1288 (*entry
)->opcode
= xstrdup (str
);
1289 (*entry
)->lineno
= lineno
;
1293 /* Process opcode array. */
1294 for (j
= 0; j
< i
; j
++)
1296 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1300 lineno
= next
->lineno
;
1301 last
= str
+ strlen (str
);
1302 output_i386_opcode (table
, name
, str
, last
, lineno
);
1308 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1310 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1312 process_i386_opcode_modifier (table
, "0", -1);
1314 fprintf (table
, " { ");
1315 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1316 fprintf (table
, " } }\n");
1318 fprintf (table
, "};\n");
1322 process_i386_registers (FILE *table
)
1326 char *str
, *p
, *last
;
1327 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1328 char *dw2_32_num
, *dw2_64_num
;
1331 filename
= "i386-reg.tbl";
1332 fp
= fopen (filename
, "r");
1334 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1337 fprintf (table
, "\n/* i386 register table. */\n\n");
1338 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1342 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1347 p
= remove_leading_whitespaces (buf
);
1349 /* Skip comments. */
1350 str
= strstr (p
, "//");
1354 /* Remove trailing white spaces. */
1355 remove_trailing_whitespaces (p
);
1360 fprintf (table
, "%s\n", p
);
1368 last
= p
+ strlen (p
);
1370 /* Find reg_name. */
1371 reg_name
= next_field (p
, ',', &str
, last
);
1373 /* Find reg_type. */
1374 reg_type
= next_field (str
, ',', &str
, last
);
1376 /* Find reg_flags. */
1377 reg_flags
= next_field (str
, ',', &str
, last
);
1380 reg_num
= next_field (str
, ',', &str
, last
);
1382 fprintf (table
, " { \"%s\",\n ", reg_name
);
1384 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1386 /* Find 32-bit Dwarf2 register number. */
1387 dw2_32_num
= next_field (str
, ',', &str
, last
);
1389 /* Find 64-bit Dwarf2 register number. */
1390 dw2_64_num
= next_field (str
, ',', &str
, last
);
1392 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1393 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1398 fprintf (table
, "};\n");
1400 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1404 process_i386_initializers (void)
1407 FILE *fp
= fopen ("i386-init.h", "w");
1411 fail (_("can't create i386-init.h, errno = %s\n"),
1414 process_copyright (fp
);
1416 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1418 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1419 init
= xstrdup (cpu_flag_init
[i
].init
);
1420 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1424 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1426 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1427 init
= xstrdup (operand_type_init
[i
].init
);
1428 process_i386_operand_type (fp
, init
, 1, " ", -1);
1436 /* Program options. */
1437 #define OPTION_SRCDIR 200
1439 struct option long_options
[] =
1441 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1442 {"debug", no_argument
, NULL
, 'd'},
1443 {"version", no_argument
, NULL
, 'V'},
1444 {"help", no_argument
, NULL
, 'h'},
1445 {0, no_argument
, NULL
, 0}
1449 print_version (void)
1451 printf ("%s: version 1.0\n", program_name
);
1456 usage (FILE * stream
, int status
)
1458 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1464 main (int argc
, char **argv
)
1466 extern int chdir (char *);
1467 char *srcdir
= NULL
;
1469 unsigned int i
, cpumax
;
1472 program_name
= *argv
;
1473 xmalloc_set_program_name (program_name
);
1475 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1500 if (chdir (srcdir
) != 0)
1501 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1502 srcdir
, xstrerror (errno
));
1504 /* cpu_flags isn't sorted by position. */
1506 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1507 if (cpu_flags
[i
].position
> cpumax
)
1508 cpumax
= cpu_flags
[i
].position
;
1510 /* Check the unused bitfield in i386_cpu_flags. */
1512 if ((cpumax
- 1) != CpuMax
)
1513 fail (_("CpuMax != %d!\n"), cpumax
);
1515 if (cpumax
!= CpuMax
)
1516 fail (_("CpuMax != %d!\n"), cpumax
);
1518 c
= CpuNumOfBits
- CpuMax
- 1;
1520 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1523 /* Check the unused bitfield in i386_operand_type. */
1525 c
= OTNumOfBits
- OTMax
- 1;
1527 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1530 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1533 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1534 sizeof (opcode_modifiers
[0]), compare
);
1536 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1537 sizeof (operand_types
[0]), compare
);
1539 table
= fopen ("i386-tbl.h", "w");
1541 fail (_("can't create i386-tbl.h, errno = %s\n"),
1544 process_copyright (table
);
1546 process_i386_opcodes (table
);
1547 process_i386_registers (table
);
1548 process_i386_initializers ();