1 /* Copyright (C) 2007-2016 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" },
225 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
226 { "CPU_IAMCU_COMPAT_FLAGS",
227 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuNo64|CpuNop" },
230 { "CPU_RDSEED_FLAGS",
232 { "CPU_PRFCHW_FLAGS",
239 "CPU_SSE2_FLAGS|CpuSHA" },
240 { "CPU_CLFLUSHOPT_FLAGS",
242 { "CPU_XSAVES_FLAGS",
243 "CPU_XSAVE_FLAGS|CpuXSAVES" },
244 { "CPU_XSAVEC_FLAGS",
245 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
246 { "CPU_PREFETCHWT1_FLAGS",
252 { "CPU_PCOMMIT_FLAGS",
254 { "CPU_CLZERO_FLAGS",
256 { "CPU_MWAITX_FLAGS",
262 { "CPU_PTWRITE_FLAGS",
264 { "CPU_ANY_X87_FLAGS",
265 "CPU_ANY_287_FLAGS|Cpu8087" },
266 { "CPU_ANY_287_FLAGS",
267 "CPU_ANY_387_FLAGS|Cpu287" },
268 { "CPU_ANY_387_FLAGS",
269 "CPU_ANY_687_FLAGS|Cpu387" },
270 { "CPU_ANY_687_FLAGS",
271 "Cpu687|CpuFISTTP" },
272 { "CPU_ANY_MMX_FLAGS",
273 "CPU_3DNOWA_FLAGS" },
274 { "CPU_ANY_SSE_FLAGS",
275 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
276 { "CPU_ANY_SSE2_FLAGS",
277 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
278 { "CPU_ANY_SSE3_FLAGS",
279 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
280 { "CPU_ANY_SSSE3_FLAGS",
281 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
282 { "CPU_ANY_SSE4_1_FLAGS",
283 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
284 { "CPU_ANY_SSE4_2_FLAGS",
286 { "CPU_ANY_AVX_FLAGS",
287 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
288 { "CPU_ANY_AVX2_FLAGS",
290 { "CPU_ANY_AVX512F_FLAGS",
291 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512F" },
292 { "CPU_ANY_AVX512CD_FLAGS",
294 { "CPU_ANY_AVX512ER_FLAGS",
296 { "CPU_ANY_AVX512PF_FLAGS",
298 { "CPU_ANY_AVX512DQ_FLAGS",
300 { "CPU_ANY_AVX512BW_FLAGS",
302 { "CPU_ANY_AVX512VL_FLAGS",
304 { "CPU_ANY_AVX512IFMA_FLAGS",
306 { "CPU_ANY_AVX512VBMI_FLAGS",
310 static initializer operand_type_init
[] =
312 { "OPERAND_TYPE_NONE",
314 { "OPERAND_TYPE_REG8",
316 { "OPERAND_TYPE_REG16",
318 { "OPERAND_TYPE_REG32",
320 { "OPERAND_TYPE_REG64",
322 { "OPERAND_TYPE_IMM1",
324 { "OPERAND_TYPE_IMM8",
326 { "OPERAND_TYPE_IMM8S",
328 { "OPERAND_TYPE_IMM16",
330 { "OPERAND_TYPE_IMM32",
332 { "OPERAND_TYPE_IMM32S",
334 { "OPERAND_TYPE_IMM64",
336 { "OPERAND_TYPE_BASEINDEX",
338 { "OPERAND_TYPE_DISP8",
340 { "OPERAND_TYPE_DISP16",
342 { "OPERAND_TYPE_DISP32",
344 { "OPERAND_TYPE_DISP32S",
346 { "OPERAND_TYPE_DISP64",
348 { "OPERAND_TYPE_INOUTPORTREG",
350 { "OPERAND_TYPE_SHIFTCOUNT",
352 { "OPERAND_TYPE_CONTROL",
354 { "OPERAND_TYPE_TEST",
356 { "OPERAND_TYPE_DEBUG",
358 { "OPERAND_TYPE_FLOATREG",
360 { "OPERAND_TYPE_FLOATACC",
362 { "OPERAND_TYPE_SREG2",
364 { "OPERAND_TYPE_SREG3",
366 { "OPERAND_TYPE_ACC",
368 { "OPERAND_TYPE_JUMPABSOLUTE",
370 { "OPERAND_TYPE_REGMMX",
372 { "OPERAND_TYPE_REGXMM",
374 { "OPERAND_TYPE_REGYMM",
376 { "OPERAND_TYPE_REGZMM",
378 { "OPERAND_TYPE_REGMASK",
380 { "OPERAND_TYPE_ESSEG",
382 { "OPERAND_TYPE_ACC32",
384 { "OPERAND_TYPE_ACC64",
386 { "OPERAND_TYPE_INOUTPORTREG",
388 { "OPERAND_TYPE_REG16_INOUTPORTREG",
389 "Reg16|InOutPortReg" },
390 { "OPERAND_TYPE_DISP16_32",
392 { "OPERAND_TYPE_ANYDISP",
393 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
394 { "OPERAND_TYPE_IMM16_32",
396 { "OPERAND_TYPE_IMM16_32S",
398 { "OPERAND_TYPE_IMM16_32_32S",
399 "Imm16|Imm32|Imm32S" },
400 { "OPERAND_TYPE_IMM32_64",
402 { "OPERAND_TYPE_IMM32_32S_DISP32",
403 "Imm32|Imm32S|Disp32" },
404 { "OPERAND_TYPE_IMM64_DISP64",
406 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
407 "Imm32|Imm32S|Imm64|Disp32" },
408 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
409 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
410 { "OPERAND_TYPE_VEC_IMM4",
412 { "OPERAND_TYPE_REGBND",
414 { "OPERAND_TYPE_VEC_DISP8",
418 typedef struct bitfield
425 #define BITFIELD(n) { n, 0, #n }
427 static bitfield cpu_flags
[] =
435 BITFIELD (CpuClflush
),
437 BITFIELD (CpuSYSCALL
),
442 BITFIELD (CpuFISTTP
),
448 BITFIELD (CpuSSE4_1
),
449 BITFIELD (CpuSSE4_2
),
452 BITFIELD (CpuAVX512F
),
453 BITFIELD (CpuAVX512CD
),
454 BITFIELD (CpuAVX512ER
),
455 BITFIELD (CpuAVX512PF
),
456 BITFIELD (CpuAVX512VL
),
457 BITFIELD (CpuAVX512DQ
),
458 BITFIELD (CpuAVX512BW
),
464 BITFIELD (Cpu3dnowA
),
465 BITFIELD (CpuPadLock
),
471 BITFIELD (CpuXsaveopt
),
473 BITFIELD (CpuPCLMUL
),
484 BITFIELD (CpuRdtscp
),
485 BITFIELD (CpuFSGSBase
),
492 BITFIELD (CpuINVPCID
),
493 BITFIELD (CpuVMFUNC
),
494 BITFIELD (CpuRDSEED
),
496 BITFIELD (CpuPRFCHW
),
500 BITFIELD (CpuClflushOpt
),
501 BITFIELD (CpuXSAVES
),
502 BITFIELD (CpuXSAVEC
),
503 BITFIELD (CpuPREFETCHWT1
),
506 BITFIELD (CpuPCOMMIT
),
510 BITFIELD (CpuAVX512IFMA
),
511 BITFIELD (CpuAVX512VBMI
),
512 BITFIELD (CpuMWAITX
),
513 BITFIELD (CpuCLZERO
),
516 BITFIELD (CpuPTWRITE
),
517 BITFIELD (CpuRegMMX
),
518 BITFIELD (CpuRegXMM
),
519 BITFIELD (CpuRegYMM
),
520 BITFIELD (CpuRegZMM
),
521 BITFIELD (CpuRegMask
),
523 BITFIELD (CpuUnused
),
527 static bitfield opcode_modifiers
[] =
533 BITFIELD (ShortForm
),
535 BITFIELD (JumpDword
),
537 BITFIELD (JumpInterSegment
),
544 BITFIELD (CheckRegSize
),
545 BITFIELD (IgnoreSize
),
546 BITFIELD (DefaultSize
),
555 BITFIELD (BNDPrefixOk
),
556 BITFIELD (IsLockable
),
557 BITFIELD (RegKludge
),
558 BITFIELD (FirstXmm0
),
559 BITFIELD (Implicit1stXmm0
),
560 BITFIELD (RepPrefixOk
),
561 BITFIELD (HLEPrefixOk
),
564 BITFIELD (AddrPrefixOp0
),
573 BITFIELD (VexOpcode
),
574 BITFIELD (VexSources
),
575 BITFIELD (VexImmExt
),
582 BITFIELD (Broadcast
),
583 BITFIELD (StaticRounding
),
585 BITFIELD (Disp8MemShift
),
586 BITFIELD (NoDefMask
),
588 BITFIELD (ATTMnemonic
),
589 BITFIELD (ATTSyntax
),
590 BITFIELD (IntelSyntax
),
595 static bitfield operand_types
[] =
614 BITFIELD (BaseIndex
),
620 BITFIELD (InOutPortReg
),
621 BITFIELD (ShiftCount
),
629 BITFIELD (JumpAbsolute
),
642 BITFIELD (Unspecified
),
646 BITFIELD (Vec_Disp8
),
652 static const char *filename
;
655 compare (const void *x
, const void *y
)
657 const bitfield
*xp
= (const bitfield
*) x
;
658 const bitfield
*yp
= (const bitfield
*) y
;
659 return xp
->position
- yp
->position
;
663 fail (const char *message
, ...)
667 va_start (args
, message
);
668 fprintf (stderr
, _("%s: Error: "), program_name
);
669 vfprintf (stderr
, message
, args
);
675 process_copyright (FILE *fp
)
677 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
678 /* Copyright (C) 2007-2016 Free Software Foundation, Inc.\n\
680 This file is part of the GNU opcodes library.\n\
682 This library is free software; you can redistribute it and/or modify\n\
683 it under the terms of the GNU General Public License as published by\n\
684 the Free Software Foundation; either version 3, or (at your option)\n\
685 any later version.\n\
687 It is distributed in the hope that it will be useful, but WITHOUT\n\
688 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
689 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
690 License for more details.\n\
692 You should have received a copy of the GNU General Public License\n\
693 along with this program; if not, write to the Free Software\n\
694 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
695 MA 02110-1301, USA. */\n");
698 /* Remove leading white spaces. */
701 remove_leading_whitespaces (char *str
)
703 while (ISSPACE (*str
))
708 /* Remove trailing white spaces. */
711 remove_trailing_whitespaces (char *str
)
713 size_t last
= strlen (str
);
721 if (ISSPACE (str
[last
]))
729 /* Find next field separated by SEP and terminate it. Return a
730 pointer to the one after it. */
733 next_field (char *str
, char sep
, char **next
, char *last
)
737 p
= remove_leading_whitespaces (str
);
738 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
741 remove_trailing_whitespaces (p
);
751 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
754 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
,
755 int value
, unsigned int size
,
758 char *str
, *next
, *last
;
761 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
762 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
764 /* Turn on selective bits. */
765 char *init
= xstrdup (cpu_flag_init
[i
].init
);
766 last
= init
+ strlen (init
);
767 for (next
= init
; next
&& next
< last
; )
769 str
= next_field (next
, '|', &next
, last
);
771 set_bitfield (str
, array
, 1, size
, lineno
);
781 set_bitfield (char *f
, bitfield
*array
, int value
,
782 unsigned int size
, int lineno
)
786 if (strcmp (f
, "CpuFP") == 0)
788 set_bitfield("Cpu387", array
, value
, size
, lineno
);
789 set_bitfield("Cpu287", array
, value
, size
, lineno
);
792 else if (strcmp (f
, "Mmword") == 0)
794 else if (strcmp (f
, "Oword") == 0)
797 for (i
= 0; i
< size
; i
++)
798 if (strcasecmp (array
[i
].name
, f
) == 0)
800 array
[i
].value
= value
;
806 const char *v
= strchr (f
, '=');
813 for (i
= 0; i
< size
; i
++)
814 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
816 value
= strtol (v
+ 1, &end
, 0);
819 array
[i
].value
= value
;
827 /* Handle CPU_XXX_FLAGS. */
828 if (!set_bitfield_from_cpu_flag_init (f
, array
, value
, size
, lineno
))
832 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
834 fail (_("Unknown bitfield: %s\n"), f
);
838 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
839 int macro
, const char *comma
, const char *indent
)
843 fprintf (table
, "%s{ { ", indent
);
845 for (i
= 0; i
< size
- 1; i
++)
847 if (((i
+ 1) % 20) != 0)
848 fprintf (table
, "%d, ", flags
[i
].value
);
850 fprintf (table
, "%d,", flags
[i
].value
);
851 if (((i
+ 1) % 20) == 0)
853 /* We need \\ for macro. */
855 fprintf (table
, " \\\n %s", indent
);
857 fprintf (table
, "\n %s", indent
);
861 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
865 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
866 const char *comma
, const char *indent
,
869 char *str
, *next
, *last
;
871 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
873 /* Copy the default cpu flags. */
874 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
876 if (strcasecmp (flag
, "unknown") == 0)
878 /* We turn on everything except for cpu64 in case of
879 CPU_UNKNOWN_FLAGS. */
880 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
881 if (flags
[i
].position
!= Cpu64
)
884 else if (flag
[0] == '~')
886 last
= flag
+ strlen (flag
);
893 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
900 /* First we turn on everything except for cpu64. */
901 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
902 if (flags
[i
].position
!= Cpu64
)
905 /* Turn off selective bits. */
906 for (; next
&& next
< last
; )
908 str
= next_field (next
, '|', &next
, last
);
910 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
913 else if (strcmp (flag
, "0"))
915 /* Turn on selective bits. */
916 last
= flag
+ strlen (flag
);
917 for (next
= flag
; next
&& next
< last
; )
919 str
= next_field (next
, '|', &next
, last
);
921 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
925 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
930 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
934 fprintf (table
, " { ");
936 for (i
= 0; i
< size
- 1; i
++)
938 if (((i
+ 1) % 20) != 0)
939 fprintf (table
, "%d, ", modifier
[i
].value
);
941 fprintf (table
, "%d,", modifier
[i
].value
);
942 if (((i
+ 1) % 20) == 0)
943 fprintf (table
, "\n ");
946 fprintf (table
, "%d },\n", modifier
[i
].value
);
950 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
952 char *str
, *next
, *last
;
953 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
955 /* Copy the default opcode modifier. */
956 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
958 if (strcmp (mod
, "0"))
960 last
= mod
+ strlen (mod
);
961 for (next
= mod
; next
&& next
< last
; )
963 str
= next_field (next
, '|', &next
, last
);
965 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
969 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
973 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
974 int macro
, const char *indent
)
978 fprintf (table
, "{ { ");
980 for (i
= 0; i
< size
- 1; i
++)
982 if (((i
+ 1) % 20) != 0)
983 fprintf (table
, "%d, ", types
[i
].value
);
985 fprintf (table
, "%d,", types
[i
].value
);
986 if (((i
+ 1) % 20) == 0)
988 /* We need \\ for macro. */
990 fprintf (table
, " \\\n%s", indent
);
992 fprintf (table
, "\n%s", indent
);
996 fprintf (table
, "%d } }", types
[i
].value
);
1000 process_i386_operand_type (FILE *table
, char *op
, int macro
,
1001 const char *indent
, int lineno
)
1003 char *str
, *next
, *last
;
1004 bitfield types
[ARRAY_SIZE (operand_types
)];
1006 /* Copy the default operand type. */
1007 memcpy (types
, operand_types
, sizeof (types
));
1009 if (strcmp (op
, "0"))
1011 last
= op
+ strlen (op
);
1012 for (next
= op
; next
&& next
< last
; )
1014 str
= next_field (next
, '|', &next
, last
);
1016 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1019 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
1024 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1025 char *last
, int lineno
)
1028 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1029 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1031 /* Find number of operands. */
1032 operands
= next_field (str
, ',', &str
, last
);
1034 /* Find base_opcode. */
1035 base_opcode
= next_field (str
, ',', &str
, last
);
1037 /* Find extension_opcode. */
1038 extension_opcode
= next_field (str
, ',', &str
, last
);
1040 /* Find opcode_length. */
1041 opcode_length
= next_field (str
, ',', &str
, last
);
1043 /* Find cpu_flags. */
1044 cpu_flags
= next_field (str
, ',', &str
, last
);
1046 /* Find opcode_modifier. */
1047 opcode_modifier
= next_field (str
, ',', &str
, last
);
1049 /* Remove the first {. */
1050 str
= remove_leading_whitespaces (str
);
1053 str
= remove_leading_whitespaces (str
+ 1);
1057 /* There are at least "X}". */
1061 /* Remove trailing white spaces and }. */
1065 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1074 /* Find operand_types. */
1075 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1079 operand_types
[i
] = NULL
;
1083 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1084 if (*operand_types
[i
] == '0')
1087 operand_types
[i
] = NULL
;
1092 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1093 name
, operands
, base_opcode
, extension_opcode
,
1096 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1098 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1100 fprintf (table
, " { ");
1102 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1104 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1107 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1112 fprintf (table
, ",\n ");
1114 process_i386_operand_type (table
, operand_types
[i
], 0,
1117 fprintf (table
, " } },\n");
1120 struct opcode_hash_entry
1122 struct opcode_hash_entry
*next
;
1128 /* Calculate the hash value of an opcode hash entry P. */
1131 opcode_hash_hash (const void *p
)
1133 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1134 return htab_hash_string (entry
->name
);
1137 /* Compare a string Q against an opcode hash entry P. */
1140 opcode_hash_eq (const void *p
, const void *q
)
1142 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1143 const char *name
= (const char *) q
;
1144 return strcmp (name
, entry
->name
) == 0;
1148 process_i386_opcodes (FILE *table
)
1153 char *str
, *p
, *last
, *name
;
1154 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1155 htab_t opcode_hash_table
;
1156 struct opcode_hash_entry
**opcode_array
;
1157 unsigned int opcode_array_size
= 1024;
1160 filename
= "i386-opc.tbl";
1161 fp
= fopen (filename
, "r");
1164 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1168 opcode_array
= (struct opcode_hash_entry
**)
1169 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1171 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1172 opcode_hash_eq
, NULL
,
1175 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1176 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1178 /* Put everything on opcode array. */
1181 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1186 p
= remove_leading_whitespaces (buf
);
1188 /* Skip comments. */
1189 str
= strstr (p
, "//");
1193 /* Remove trailing white spaces. */
1194 remove_trailing_whitespaces (p
);
1199 /* Ignore comments. */
1207 last
= p
+ strlen (p
);
1210 name
= next_field (p
, ',', &str
, last
);
1212 /* Get the slot in hash table. */
1213 hash_slot
= (struct opcode_hash_entry
**)
1214 htab_find_slot_with_hash (opcode_hash_table
, name
,
1215 htab_hash_string (name
),
1218 if (*hash_slot
== NULL
)
1220 /* It is the new one. Put it on opcode array. */
1221 if (i
>= opcode_array_size
)
1223 /* Grow the opcode array when needed. */
1224 opcode_array_size
+= 1024;
1225 opcode_array
= (struct opcode_hash_entry
**)
1226 xrealloc (opcode_array
,
1227 sizeof (*opcode_array
) * opcode_array_size
);
1230 opcode_array
[i
] = (struct opcode_hash_entry
*)
1231 xmalloc (sizeof (struct opcode_hash_entry
));
1232 opcode_array
[i
]->next
= NULL
;
1233 opcode_array
[i
]->name
= xstrdup (name
);
1234 opcode_array
[i
]->opcode
= xstrdup (str
);
1235 opcode_array
[i
]->lineno
= lineno
;
1236 *hash_slot
= opcode_array
[i
];
1241 /* Append it to the existing one. */
1243 while ((*entry
) != NULL
)
1244 entry
= &(*entry
)->next
;
1245 *entry
= (struct opcode_hash_entry
*)
1246 xmalloc (sizeof (struct opcode_hash_entry
));
1247 (*entry
)->next
= NULL
;
1248 (*entry
)->name
= (*hash_slot
)->name
;
1249 (*entry
)->opcode
= xstrdup (str
);
1250 (*entry
)->lineno
= lineno
;
1254 /* Process opcode array. */
1255 for (j
= 0; j
< i
; j
++)
1257 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1261 lineno
= next
->lineno
;
1262 last
= str
+ strlen (str
);
1263 output_i386_opcode (table
, name
, str
, last
, lineno
);
1269 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1271 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1273 process_i386_opcode_modifier (table
, "0", -1);
1275 fprintf (table
, " { ");
1276 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1277 fprintf (table
, " } }\n");
1279 fprintf (table
, "};\n");
1283 process_i386_registers (FILE *table
)
1287 char *str
, *p
, *last
;
1288 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1289 char *dw2_32_num
, *dw2_64_num
;
1292 filename
= "i386-reg.tbl";
1293 fp
= fopen (filename
, "r");
1295 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1298 fprintf (table
, "\n/* i386 register table. */\n\n");
1299 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1303 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1308 p
= remove_leading_whitespaces (buf
);
1310 /* Skip comments. */
1311 str
= strstr (p
, "//");
1315 /* Remove trailing white spaces. */
1316 remove_trailing_whitespaces (p
);
1321 fprintf (table
, "%s\n", p
);
1329 last
= p
+ strlen (p
);
1331 /* Find reg_name. */
1332 reg_name
= next_field (p
, ',', &str
, last
);
1334 /* Find reg_type. */
1335 reg_type
= next_field (str
, ',', &str
, last
);
1337 /* Find reg_flags. */
1338 reg_flags
= next_field (str
, ',', &str
, last
);
1341 reg_num
= next_field (str
, ',', &str
, last
);
1343 fprintf (table
, " { \"%s\",\n ", reg_name
);
1345 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1347 /* Find 32-bit Dwarf2 register number. */
1348 dw2_32_num
= next_field (str
, ',', &str
, last
);
1350 /* Find 64-bit Dwarf2 register number. */
1351 dw2_64_num
= next_field (str
, ',', &str
, last
);
1353 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1354 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1359 fprintf (table
, "};\n");
1361 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1365 process_i386_initializers (void)
1368 FILE *fp
= fopen ("i386-init.h", "w");
1372 fail (_("can't create i386-init.h, errno = %s\n"),
1375 process_copyright (fp
);
1377 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1379 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1380 init
= xstrdup (cpu_flag_init
[i
].init
);
1381 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1385 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1387 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1388 init
= xstrdup (operand_type_init
[i
].init
);
1389 process_i386_operand_type (fp
, init
, 1, " ", -1);
1397 /* Program options. */
1398 #define OPTION_SRCDIR 200
1400 struct option long_options
[] =
1402 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1403 {"debug", no_argument
, NULL
, 'd'},
1404 {"version", no_argument
, NULL
, 'V'},
1405 {"help", no_argument
, NULL
, 'h'},
1406 {0, no_argument
, NULL
, 0}
1410 print_version (void)
1412 printf ("%s: version 1.0\n", program_name
);
1417 usage (FILE * stream
, int status
)
1419 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1425 main (int argc
, char **argv
)
1427 extern int chdir (char *);
1428 char *srcdir
= NULL
;
1430 unsigned int i
, cpumax
;
1433 program_name
= *argv
;
1434 xmalloc_set_program_name (program_name
);
1436 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1461 if (chdir (srcdir
) != 0)
1462 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1463 srcdir
, xstrerror (errno
));
1465 /* cpu_flags isn't sorted by position. */
1467 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1468 if (cpu_flags
[i
].position
> cpumax
)
1469 cpumax
= cpu_flags
[i
].position
;
1471 /* Check the unused bitfield in i386_cpu_flags. */
1473 if ((cpumax
- 1) != CpuMax
)
1474 fail (_("CpuMax != %d!\n"), cpumax
);
1476 if (cpumax
!= CpuMax
)
1477 fail (_("CpuMax != %d!\n"), cpumax
);
1479 c
= CpuNumOfBits
- CpuMax
- 1;
1481 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1484 /* Check the unused bitfield in i386_operand_type. */
1486 c
= OTNumOfBits
- OTMax
- 1;
1488 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1491 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1494 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1495 sizeof (opcode_modifiers
[0]), compare
);
1497 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1498 sizeof (operand_types
[0]), compare
);
1500 table
= fopen ("i386-tbl.h", "w");
1502 fail (_("can't create i386-tbl.h, errno = %s\n"),
1505 process_copyright (table
);
1507 process_i386_opcodes (table
);
1508 process_i386_registers (table
);
1509 process_i386_initializers ();