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",
444 typedef struct bitfield
451 #define BITFIELD(n) { n, 0, #n }
453 static bitfield cpu_flags
[] =
461 BITFIELD (CpuClflush
),
463 BITFIELD (CpuSYSCALL
),
468 BITFIELD (CpuFISTTP
),
474 BITFIELD (CpuSSE4_1
),
475 BITFIELD (CpuSSE4_2
),
478 BITFIELD (CpuAVX512F
),
479 BITFIELD (CpuAVX512CD
),
480 BITFIELD (CpuAVX512ER
),
481 BITFIELD (CpuAVX512PF
),
482 BITFIELD (CpuAVX512VL
),
483 BITFIELD (CpuAVX512DQ
),
484 BITFIELD (CpuAVX512BW
),
490 BITFIELD (Cpu3dnowA
),
491 BITFIELD (CpuPadLock
),
497 BITFIELD (CpuXsaveopt
),
499 BITFIELD (CpuPCLMUL
),
510 BITFIELD (CpuRdtscp
),
511 BITFIELD (CpuFSGSBase
),
518 BITFIELD (CpuINVPCID
),
519 BITFIELD (CpuVMFUNC
),
520 BITFIELD (CpuRDSEED
),
522 BITFIELD (CpuPRFCHW
),
526 BITFIELD (CpuClflushOpt
),
527 BITFIELD (CpuXSAVES
),
528 BITFIELD (CpuXSAVEC
),
529 BITFIELD (CpuPREFETCHWT1
),
535 BITFIELD (CpuAVX512IFMA
),
536 BITFIELD (CpuAVX512VBMI
),
537 BITFIELD (CpuAVX512_4FMAPS
),
538 BITFIELD (CpuAVX512_4VNNIW
),
539 BITFIELD (CpuAVX512_VPOPCNTDQ
),
540 BITFIELD (CpuAVX512_VBMI2
),
541 BITFIELD (CpuAVX512_VNNI
),
542 BITFIELD (CpuAVX512_BITALG
),
543 BITFIELD (CpuMWAITX
),
544 BITFIELD (CpuCLZERO
),
547 BITFIELD (CpuPTWRITE
),
551 BITFIELD (CpuVPCLMULQDQ
),
552 BITFIELD (CpuRegMMX
),
553 BITFIELD (CpuRegXMM
),
554 BITFIELD (CpuRegYMM
),
555 BITFIELD (CpuRegZMM
),
556 BITFIELD (CpuRegMask
),
558 BITFIELD (CpuUnused
),
562 static bitfield opcode_modifiers
[] =
568 BITFIELD (ShortForm
),
570 BITFIELD (JumpDword
),
572 BITFIELD (JumpInterSegment
),
579 BITFIELD (CheckRegSize
),
580 BITFIELD (IgnoreSize
),
581 BITFIELD (DefaultSize
),
590 BITFIELD (BNDPrefixOk
),
591 BITFIELD (NoTrackPrefixOk
),
592 BITFIELD (IsLockable
),
593 BITFIELD (RegKludge
),
594 BITFIELD (FirstXmm0
),
595 BITFIELD (Implicit1stXmm0
),
596 BITFIELD (RepPrefixOk
),
597 BITFIELD (HLEPrefixOk
),
600 BITFIELD (AddrPrefixOp0
),
609 BITFIELD (VexOpcode
),
610 BITFIELD (VexSources
),
611 BITFIELD (VexImmExt
),
618 BITFIELD (Broadcast
),
619 BITFIELD (StaticRounding
),
621 BITFIELD (Disp8MemShift
),
622 BITFIELD (NoDefMask
),
623 BITFIELD (ImplicitQuadGroup
),
625 BITFIELD (ATTMnemonic
),
626 BITFIELD (ATTSyntax
),
627 BITFIELD (IntelSyntax
),
632 static bitfield operand_types
[] =
651 BITFIELD (BaseIndex
),
657 BITFIELD (InOutPortReg
),
658 BITFIELD (ShiftCount
),
666 BITFIELD (JumpAbsolute
),
679 BITFIELD (Unspecified
),
688 static const char *filename
;
691 compare (const void *x
, const void *y
)
693 const bitfield
*xp
= (const bitfield
*) x
;
694 const bitfield
*yp
= (const bitfield
*) y
;
695 return xp
->position
- yp
->position
;
699 fail (const char *message
, ...)
703 va_start (args
, message
);
704 fprintf (stderr
, _("%s: Error: "), program_name
);
705 vfprintf (stderr
, message
, args
);
711 process_copyright (FILE *fp
)
713 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
714 /* Copyright (C) 2007-2017 Free Software Foundation, Inc.\n\
716 This file is part of the GNU opcodes library.\n\
718 This library is free software; you can redistribute it and/or modify\n\
719 it under the terms of the GNU General Public License as published by\n\
720 the Free Software Foundation; either version 3, or (at your option)\n\
721 any later version.\n\
723 It is distributed in the hope that it will be useful, but WITHOUT\n\
724 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
725 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
726 License for more details.\n\
728 You should have received a copy of the GNU General Public License\n\
729 along with this program; if not, write to the Free Software\n\
730 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
731 MA 02110-1301, USA. */\n");
734 /* Remove leading white spaces. */
737 remove_leading_whitespaces (char *str
)
739 while (ISSPACE (*str
))
744 /* Remove trailing white spaces. */
747 remove_trailing_whitespaces (char *str
)
749 size_t last
= strlen (str
);
757 if (ISSPACE (str
[last
]))
765 /* Find next field separated by SEP and terminate it. Return a
766 pointer to the one after it. */
769 next_field (char *str
, char sep
, char **next
, char *last
)
773 p
= remove_leading_whitespaces (str
);
774 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
777 remove_trailing_whitespaces (p
);
787 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
790 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
,
791 int value
, unsigned int size
,
794 char *str
, *next
, *last
;
797 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
798 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
800 /* Turn on selective bits. */
801 char *init
= xstrdup (cpu_flag_init
[i
].init
);
802 last
= init
+ strlen (init
);
803 for (next
= init
; next
&& next
< last
; )
805 str
= next_field (next
, '|', &next
, last
);
807 set_bitfield (str
, array
, 1, size
, lineno
);
817 set_bitfield (char *f
, bitfield
*array
, int value
,
818 unsigned int size
, int lineno
)
822 if (strcmp (f
, "CpuFP") == 0)
824 set_bitfield("Cpu387", array
, value
, size
, lineno
);
825 set_bitfield("Cpu287", array
, value
, size
, lineno
);
828 else if (strcmp (f
, "Mmword") == 0)
830 else if (strcmp (f
, "Oword") == 0)
833 for (i
= 0; i
< size
; i
++)
834 if (strcasecmp (array
[i
].name
, f
) == 0)
836 array
[i
].value
= value
;
842 const char *v
= strchr (f
, '=');
849 for (i
= 0; i
< size
; i
++)
850 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
852 value
= strtol (v
+ 1, &end
, 0);
855 array
[i
].value
= value
;
863 /* Handle CPU_XXX_FLAGS. */
864 if (!set_bitfield_from_cpu_flag_init (f
, array
, value
, size
, lineno
))
868 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
870 fail (_("Unknown bitfield: %s\n"), f
);
874 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
875 int macro
, const char *comma
, const char *indent
)
879 fprintf (table
, "%s{ { ", indent
);
881 for (i
= 0; i
< size
- 1; i
++)
883 if (((i
+ 1) % 20) != 0)
884 fprintf (table
, "%d, ", flags
[i
].value
);
886 fprintf (table
, "%d,", flags
[i
].value
);
887 if (((i
+ 1) % 20) == 0)
889 /* We need \\ for macro. */
891 fprintf (table
, " \\\n %s", indent
);
893 fprintf (table
, "\n %s", indent
);
897 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
901 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
902 const char *comma
, const char *indent
,
905 char *str
, *next
, *last
;
907 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
909 /* Copy the default cpu flags. */
910 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
912 if (strcasecmp (flag
, "unknown") == 0)
914 /* We turn on everything except for cpu64 in case of
915 CPU_UNKNOWN_FLAGS. */
916 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
917 if (flags
[i
].position
!= Cpu64
)
920 else if (flag
[0] == '~')
922 last
= flag
+ strlen (flag
);
929 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
936 /* First we turn on everything except for cpu64. */
937 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
938 if (flags
[i
].position
!= Cpu64
)
941 /* Turn off selective bits. */
942 for (; next
&& next
< last
; )
944 str
= next_field (next
, '|', &next
, last
);
946 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
949 else if (strcmp (flag
, "0"))
951 /* Turn on selective bits. */
952 last
= flag
+ strlen (flag
);
953 for (next
= flag
; next
&& next
< last
; )
955 str
= next_field (next
, '|', &next
, last
);
957 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
961 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
966 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
970 fprintf (table
, " { ");
972 for (i
= 0; i
< size
- 1; i
++)
974 if (((i
+ 1) % 20) != 0)
975 fprintf (table
, "%d, ", modifier
[i
].value
);
977 fprintf (table
, "%d,", modifier
[i
].value
);
978 if (((i
+ 1) % 20) == 0)
979 fprintf (table
, "\n ");
982 fprintf (table
, "%d },\n", modifier
[i
].value
);
986 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
988 char *str
, *next
, *last
;
989 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
991 /* Copy the default opcode modifier. */
992 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
994 if (strcmp (mod
, "0"))
996 last
= mod
+ strlen (mod
);
997 for (next
= mod
; next
&& next
< last
; )
999 str
= next_field (next
, '|', &next
, last
);
1001 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
1005 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1009 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
1010 int macro
, const char *indent
)
1014 fprintf (table
, "{ { ");
1016 for (i
= 0; i
< size
- 1; i
++)
1018 if (((i
+ 1) % 20) != 0)
1019 fprintf (table
, "%d, ", types
[i
].value
);
1021 fprintf (table
, "%d,", types
[i
].value
);
1022 if (((i
+ 1) % 20) == 0)
1024 /* We need \\ for macro. */
1026 fprintf (table
, " \\\n%s", indent
);
1028 fprintf (table
, "\n%s", indent
);
1032 fprintf (table
, "%d } }", types
[i
].value
);
1036 process_i386_operand_type (FILE *table
, char *op
, int macro
,
1037 const char *indent
, int lineno
)
1039 char *str
, *next
, *last
;
1040 bitfield types
[ARRAY_SIZE (operand_types
)];
1042 /* Copy the default operand type. */
1043 memcpy (types
, operand_types
, sizeof (types
));
1045 if (strcmp (op
, "0"))
1047 last
= op
+ strlen (op
);
1048 for (next
= op
; next
&& next
< last
; )
1050 str
= next_field (next
, '|', &next
, last
);
1052 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1055 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
1060 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1061 char *last
, int lineno
)
1064 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1065 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1067 /* Find number of operands. */
1068 operands
= next_field (str
, ',', &str
, last
);
1070 /* Find base_opcode. */
1071 base_opcode
= next_field (str
, ',', &str
, last
);
1073 /* Find extension_opcode. */
1074 extension_opcode
= next_field (str
, ',', &str
, last
);
1076 /* Find opcode_length. */
1077 opcode_length
= next_field (str
, ',', &str
, last
);
1079 /* Find cpu_flags. */
1080 cpu_flags
= next_field (str
, ',', &str
, last
);
1082 /* Find opcode_modifier. */
1083 opcode_modifier
= next_field (str
, ',', &str
, last
);
1085 /* Remove the first {. */
1086 str
= remove_leading_whitespaces (str
);
1089 str
= remove_leading_whitespaces (str
+ 1);
1093 /* There are at least "X}". */
1097 /* Remove trailing white spaces and }. */
1101 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1110 /* Find operand_types. */
1111 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1115 operand_types
[i
] = NULL
;
1119 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1120 if (*operand_types
[i
] == '0')
1123 operand_types
[i
] = NULL
;
1128 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1129 name
, operands
, base_opcode
, extension_opcode
,
1132 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1134 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1136 fprintf (table
, " { ");
1138 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1140 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1143 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1148 fprintf (table
, ",\n ");
1150 process_i386_operand_type (table
, operand_types
[i
], 0,
1153 fprintf (table
, " } },\n");
1156 struct opcode_hash_entry
1158 struct opcode_hash_entry
*next
;
1164 /* Calculate the hash value of an opcode hash entry P. */
1167 opcode_hash_hash (const void *p
)
1169 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1170 return htab_hash_string (entry
->name
);
1173 /* Compare a string Q against an opcode hash entry P. */
1176 opcode_hash_eq (const void *p
, const void *q
)
1178 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1179 const char *name
= (const char *) q
;
1180 return strcmp (name
, entry
->name
) == 0;
1184 process_i386_opcodes (FILE *table
)
1189 char *str
, *p
, *last
, *name
;
1190 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1191 htab_t opcode_hash_table
;
1192 struct opcode_hash_entry
**opcode_array
;
1193 unsigned int opcode_array_size
= 1024;
1196 filename
= "i386-opc.tbl";
1197 fp
= fopen (filename
, "r");
1200 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1204 opcode_array
= (struct opcode_hash_entry
**)
1205 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1207 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1208 opcode_hash_eq
, NULL
,
1211 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1212 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1214 /* Put everything on opcode array. */
1217 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1222 p
= remove_leading_whitespaces (buf
);
1224 /* Skip comments. */
1225 str
= strstr (p
, "//");
1229 /* Remove trailing white spaces. */
1230 remove_trailing_whitespaces (p
);
1235 /* Ignore comments. */
1243 last
= p
+ strlen (p
);
1246 name
= next_field (p
, ',', &str
, last
);
1248 /* Get the slot in hash table. */
1249 hash_slot
= (struct opcode_hash_entry
**)
1250 htab_find_slot_with_hash (opcode_hash_table
, name
,
1251 htab_hash_string (name
),
1254 if (*hash_slot
== NULL
)
1256 /* It is the new one. Put it on opcode array. */
1257 if (i
>= opcode_array_size
)
1259 /* Grow the opcode array when needed. */
1260 opcode_array_size
+= 1024;
1261 opcode_array
= (struct opcode_hash_entry
**)
1262 xrealloc (opcode_array
,
1263 sizeof (*opcode_array
) * opcode_array_size
);
1266 opcode_array
[i
] = (struct opcode_hash_entry
*)
1267 xmalloc (sizeof (struct opcode_hash_entry
));
1268 opcode_array
[i
]->next
= NULL
;
1269 opcode_array
[i
]->name
= xstrdup (name
);
1270 opcode_array
[i
]->opcode
= xstrdup (str
);
1271 opcode_array
[i
]->lineno
= lineno
;
1272 *hash_slot
= opcode_array
[i
];
1277 /* Append it to the existing one. */
1279 while ((*entry
) != NULL
)
1280 entry
= &(*entry
)->next
;
1281 *entry
= (struct opcode_hash_entry
*)
1282 xmalloc (sizeof (struct opcode_hash_entry
));
1283 (*entry
)->next
= NULL
;
1284 (*entry
)->name
= (*hash_slot
)->name
;
1285 (*entry
)->opcode
= xstrdup (str
);
1286 (*entry
)->lineno
= lineno
;
1290 /* Process opcode array. */
1291 for (j
= 0; j
< i
; j
++)
1293 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1297 lineno
= next
->lineno
;
1298 last
= str
+ strlen (str
);
1299 output_i386_opcode (table
, name
, str
, last
, lineno
);
1305 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1307 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1309 process_i386_opcode_modifier (table
, "0", -1);
1311 fprintf (table
, " { ");
1312 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1313 fprintf (table
, " } }\n");
1315 fprintf (table
, "};\n");
1319 process_i386_registers (FILE *table
)
1323 char *str
, *p
, *last
;
1324 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1325 char *dw2_32_num
, *dw2_64_num
;
1328 filename
= "i386-reg.tbl";
1329 fp
= fopen (filename
, "r");
1331 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1334 fprintf (table
, "\n/* i386 register table. */\n\n");
1335 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1339 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1344 p
= remove_leading_whitespaces (buf
);
1346 /* Skip comments. */
1347 str
= strstr (p
, "//");
1351 /* Remove trailing white spaces. */
1352 remove_trailing_whitespaces (p
);
1357 fprintf (table
, "%s\n", p
);
1365 last
= p
+ strlen (p
);
1367 /* Find reg_name. */
1368 reg_name
= next_field (p
, ',', &str
, last
);
1370 /* Find reg_type. */
1371 reg_type
= next_field (str
, ',', &str
, last
);
1373 /* Find reg_flags. */
1374 reg_flags
= next_field (str
, ',', &str
, last
);
1377 reg_num
= next_field (str
, ',', &str
, last
);
1379 fprintf (table
, " { \"%s\",\n ", reg_name
);
1381 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1383 /* Find 32-bit Dwarf2 register number. */
1384 dw2_32_num
= next_field (str
, ',', &str
, last
);
1386 /* Find 64-bit Dwarf2 register number. */
1387 dw2_64_num
= next_field (str
, ',', &str
, last
);
1389 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1390 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1395 fprintf (table
, "};\n");
1397 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1401 process_i386_initializers (void)
1404 FILE *fp
= fopen ("i386-init.h", "w");
1408 fail (_("can't create i386-init.h, errno = %s\n"),
1411 process_copyright (fp
);
1413 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1415 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1416 init
= xstrdup (cpu_flag_init
[i
].init
);
1417 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1421 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1423 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1424 init
= xstrdup (operand_type_init
[i
].init
);
1425 process_i386_operand_type (fp
, init
, 1, " ", -1);
1433 /* Program options. */
1434 #define OPTION_SRCDIR 200
1436 struct option long_options
[] =
1438 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1439 {"debug", no_argument
, NULL
, 'd'},
1440 {"version", no_argument
, NULL
, 'V'},
1441 {"help", no_argument
, NULL
, 'h'},
1442 {0, no_argument
, NULL
, 0}
1446 print_version (void)
1448 printf ("%s: version 1.0\n", program_name
);
1453 usage (FILE * stream
, int status
)
1455 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1461 main (int argc
, char **argv
)
1463 extern int chdir (char *);
1464 char *srcdir
= NULL
;
1466 unsigned int i
, cpumax
;
1469 program_name
= *argv
;
1470 xmalloc_set_program_name (program_name
);
1472 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1497 if (chdir (srcdir
) != 0)
1498 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1499 srcdir
, xstrerror (errno
));
1501 /* cpu_flags isn't sorted by position. */
1503 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1504 if (cpu_flags
[i
].position
> cpumax
)
1505 cpumax
= cpu_flags
[i
].position
;
1507 /* Check the unused bitfield in i386_cpu_flags. */
1509 if ((cpumax
- 1) != CpuMax
)
1510 fail (_("CpuMax != %d!\n"), cpumax
);
1512 if (cpumax
!= CpuMax
)
1513 fail (_("CpuMax != %d!\n"), cpumax
);
1515 c
= CpuNumOfBits
- CpuMax
- 1;
1517 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1520 /* Check the unused bitfield in i386_operand_type. */
1522 c
= OTNumOfBits
- OTMax
- 1;
1524 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1527 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1530 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1531 sizeof (opcode_modifiers
[0]), compare
);
1533 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1534 sizeof (operand_types
[0]), compare
);
1536 table
= fopen ("i386-tbl.h", "w");
1538 fail (_("can't create i386-tbl.h, errno = %s\n"),
1541 process_copyright (table
);
1543 process_i386_opcodes (table
);
1544 process_i386_registers (table
);
1545 process_i386_initializers ();