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" },
228 { "CPU_RDSEED_FLAGS",
230 { "CPU_PRFCHW_FLAGS",
237 "CPU_SSE2_FLAGS|CpuSHA" },
238 { "CPU_CLFLUSHOPT_FLAGS",
240 { "CPU_XSAVES_FLAGS",
241 "CPU_XSAVE_FLAGS|CpuXSAVES" },
242 { "CPU_XSAVEC_FLAGS",
243 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
244 { "CPU_PREFETCHWT1_FLAGS",
250 { "CPU_PCOMMIT_FLAGS",
252 { "CPU_CLZERO_FLAGS",
254 { "CPU_MWAITX_FLAGS",
260 { "CPU_PTWRITE_FLAGS",
262 { "CPU_ANY_X87_FLAGS",
263 "CPU_ANY_287_FLAGS|Cpu8087" },
264 { "CPU_ANY_287_FLAGS",
265 "CPU_ANY_387_FLAGS|Cpu287" },
266 { "CPU_ANY_387_FLAGS",
267 "CPU_ANY_687_FLAGS|Cpu387" },
268 { "CPU_ANY_687_FLAGS",
269 "Cpu687|CpuFISTTP" },
270 { "CPU_ANY_MMX_FLAGS",
271 "CPU_3DNOWA_FLAGS" },
272 { "CPU_ANY_SSE_FLAGS",
273 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
274 { "CPU_ANY_SSE2_FLAGS",
275 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
276 { "CPU_ANY_SSE3_FLAGS",
277 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
278 { "CPU_ANY_SSSE3_FLAGS",
279 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
280 { "CPU_ANY_SSE4_1_FLAGS",
281 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
282 { "CPU_ANY_SSE4_2_FLAGS",
284 { "CPU_ANY_AVX_FLAGS",
285 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
286 { "CPU_ANY_AVX2_FLAGS",
288 { "CPU_ANY_AVX512F_FLAGS",
289 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512F" },
290 { "CPU_ANY_AVX512CD_FLAGS",
292 { "CPU_ANY_AVX512ER_FLAGS",
294 { "CPU_ANY_AVX512PF_FLAGS",
296 { "CPU_ANY_AVX512DQ_FLAGS",
298 { "CPU_ANY_AVX512BW_FLAGS",
300 { "CPU_ANY_AVX512VL_FLAGS",
302 { "CPU_ANY_AVX512IFMA_FLAGS",
304 { "CPU_ANY_AVX512VBMI_FLAGS",
308 static initializer operand_type_init
[] =
310 { "OPERAND_TYPE_NONE",
312 { "OPERAND_TYPE_REG8",
314 { "OPERAND_TYPE_REG16",
316 { "OPERAND_TYPE_REG32",
318 { "OPERAND_TYPE_REG64",
320 { "OPERAND_TYPE_IMM1",
322 { "OPERAND_TYPE_IMM8",
324 { "OPERAND_TYPE_IMM8S",
326 { "OPERAND_TYPE_IMM16",
328 { "OPERAND_TYPE_IMM32",
330 { "OPERAND_TYPE_IMM32S",
332 { "OPERAND_TYPE_IMM64",
334 { "OPERAND_TYPE_BASEINDEX",
336 { "OPERAND_TYPE_DISP8",
338 { "OPERAND_TYPE_DISP16",
340 { "OPERAND_TYPE_DISP32",
342 { "OPERAND_TYPE_DISP32S",
344 { "OPERAND_TYPE_DISP64",
346 { "OPERAND_TYPE_INOUTPORTREG",
348 { "OPERAND_TYPE_SHIFTCOUNT",
350 { "OPERAND_TYPE_CONTROL",
352 { "OPERAND_TYPE_TEST",
354 { "OPERAND_TYPE_DEBUG",
356 { "OPERAND_TYPE_FLOATREG",
358 { "OPERAND_TYPE_FLOATACC",
360 { "OPERAND_TYPE_SREG2",
362 { "OPERAND_TYPE_SREG3",
364 { "OPERAND_TYPE_ACC",
366 { "OPERAND_TYPE_JUMPABSOLUTE",
368 { "OPERAND_TYPE_REGMMX",
370 { "OPERAND_TYPE_REGXMM",
372 { "OPERAND_TYPE_REGYMM",
374 { "OPERAND_TYPE_REGZMM",
376 { "OPERAND_TYPE_REGMASK",
378 { "OPERAND_TYPE_ESSEG",
380 { "OPERAND_TYPE_ACC32",
382 { "OPERAND_TYPE_ACC64",
384 { "OPERAND_TYPE_INOUTPORTREG",
386 { "OPERAND_TYPE_REG16_INOUTPORTREG",
387 "Reg16|InOutPortReg" },
388 { "OPERAND_TYPE_DISP16_32",
390 { "OPERAND_TYPE_ANYDISP",
391 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
392 { "OPERAND_TYPE_IMM16_32",
394 { "OPERAND_TYPE_IMM16_32S",
396 { "OPERAND_TYPE_IMM16_32_32S",
397 "Imm16|Imm32|Imm32S" },
398 { "OPERAND_TYPE_IMM32_64",
400 { "OPERAND_TYPE_IMM32_32S_DISP32",
401 "Imm32|Imm32S|Disp32" },
402 { "OPERAND_TYPE_IMM64_DISP64",
404 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
405 "Imm32|Imm32S|Imm64|Disp32" },
406 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
407 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
408 { "OPERAND_TYPE_VEC_IMM4",
410 { "OPERAND_TYPE_REGBND",
412 { "OPERAND_TYPE_VEC_DISP8",
416 typedef struct bitfield
423 #define BITFIELD(n) { n, 0, #n }
425 static bitfield cpu_flags
[] =
433 BITFIELD (CpuClflush
),
435 BITFIELD (CpuSYSCALL
),
440 BITFIELD (CpuFISTTP
),
446 BITFIELD (CpuSSE4_1
),
447 BITFIELD (CpuSSE4_2
),
450 BITFIELD (CpuAVX512F
),
451 BITFIELD (CpuAVX512CD
),
452 BITFIELD (CpuAVX512ER
),
453 BITFIELD (CpuAVX512PF
),
454 BITFIELD (CpuAVX512VL
),
455 BITFIELD (CpuAVX512DQ
),
456 BITFIELD (CpuAVX512BW
),
462 BITFIELD (Cpu3dnowA
),
463 BITFIELD (CpuPadLock
),
469 BITFIELD (CpuXsaveopt
),
471 BITFIELD (CpuPCLMUL
),
482 BITFIELD (CpuRdtscp
),
483 BITFIELD (CpuFSGSBase
),
490 BITFIELD (CpuINVPCID
),
491 BITFIELD (CpuVMFUNC
),
492 BITFIELD (CpuRDSEED
),
494 BITFIELD (CpuPRFCHW
),
498 BITFIELD (CpuClflushOpt
),
499 BITFIELD (CpuXSAVES
),
500 BITFIELD (CpuXSAVEC
),
501 BITFIELD (CpuPREFETCHWT1
),
504 BITFIELD (CpuPCOMMIT
),
508 BITFIELD (CpuAVX512IFMA
),
509 BITFIELD (CpuAVX512VBMI
),
510 BITFIELD (CpuMWAITX
),
511 BITFIELD (CpuCLZERO
),
514 BITFIELD (CpuPTWRITE
),
515 BITFIELD (CpuRegMMX
),
516 BITFIELD (CpuRegXMM
),
517 BITFIELD (CpuRegYMM
),
518 BITFIELD (CpuRegZMM
),
519 BITFIELD (CpuRegMask
),
521 BITFIELD (CpuUnused
),
525 static bitfield opcode_modifiers
[] =
531 BITFIELD (ShortForm
),
533 BITFIELD (JumpDword
),
535 BITFIELD (JumpInterSegment
),
542 BITFIELD (CheckRegSize
),
543 BITFIELD (IgnoreSize
),
544 BITFIELD (DefaultSize
),
553 BITFIELD (BNDPrefixOk
),
554 BITFIELD (IsLockable
),
555 BITFIELD (RegKludge
),
556 BITFIELD (FirstXmm0
),
557 BITFIELD (Implicit1stXmm0
),
558 BITFIELD (RepPrefixOk
),
559 BITFIELD (HLEPrefixOk
),
562 BITFIELD (AddrPrefixOp0
),
571 BITFIELD (VexOpcode
),
572 BITFIELD (VexSources
),
573 BITFIELD (VexImmExt
),
580 BITFIELD (Broadcast
),
581 BITFIELD (StaticRounding
),
583 BITFIELD (Disp8MemShift
),
584 BITFIELD (NoDefMask
),
586 BITFIELD (ATTMnemonic
),
587 BITFIELD (ATTSyntax
),
588 BITFIELD (IntelSyntax
),
593 static bitfield operand_types
[] =
612 BITFIELD (BaseIndex
),
618 BITFIELD (InOutPortReg
),
619 BITFIELD (ShiftCount
),
627 BITFIELD (JumpAbsolute
),
640 BITFIELD (Unspecified
),
644 BITFIELD (Vec_Disp8
),
650 static const char *filename
;
653 compare (const void *x
, const void *y
)
655 const bitfield
*xp
= (const bitfield
*) x
;
656 const bitfield
*yp
= (const bitfield
*) y
;
657 return xp
->position
- yp
->position
;
661 fail (const char *message
, ...)
665 va_start (args
, message
);
666 fprintf (stderr
, _("%s: Error: "), program_name
);
667 vfprintf (stderr
, message
, args
);
673 process_copyright (FILE *fp
)
675 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
676 /* Copyright (C) 2007-2016 Free Software Foundation, Inc.\n\
678 This file is part of the GNU opcodes library.\n\
680 This library is free software; you can redistribute it and/or modify\n\
681 it under the terms of the GNU General Public License as published by\n\
682 the Free Software Foundation; either version 3, or (at your option)\n\
683 any later version.\n\
685 It is distributed in the hope that it will be useful, but WITHOUT\n\
686 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
687 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
688 License for more details.\n\
690 You should have received a copy of the GNU General Public License\n\
691 along with this program; if not, write to the Free Software\n\
692 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
693 MA 02110-1301, USA. */\n");
696 /* Remove leading white spaces. */
699 remove_leading_whitespaces (char *str
)
701 while (ISSPACE (*str
))
706 /* Remove trailing white spaces. */
709 remove_trailing_whitespaces (char *str
)
711 size_t last
= strlen (str
);
719 if (ISSPACE (str
[last
]))
727 /* Find next field separated by SEP and terminate it. Return a
728 pointer to the one after it. */
731 next_field (char *str
, char sep
, char **next
, char *last
)
735 p
= remove_leading_whitespaces (str
);
736 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
739 remove_trailing_whitespaces (p
);
749 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
752 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
,
753 int value
, unsigned int size
,
756 char *str
, *next
, *last
;
759 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
760 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
762 /* Turn on selective bits. */
763 char *init
= xstrdup (cpu_flag_init
[i
].init
);
764 last
= init
+ strlen (init
);
765 for (next
= init
; next
&& next
< last
; )
767 str
= next_field (next
, '|', &next
, last
);
769 set_bitfield (str
, array
, 1, size
, lineno
);
779 set_bitfield (char *f
, bitfield
*array
, int value
,
780 unsigned int size
, int lineno
)
784 if (strcmp (f
, "CpuFP") == 0)
786 set_bitfield("Cpu387", array
, value
, size
, lineno
);
787 set_bitfield("Cpu287", array
, value
, size
, lineno
);
790 else if (strcmp (f
, "Mmword") == 0)
792 else if (strcmp (f
, "Oword") == 0)
795 for (i
= 0; i
< size
; i
++)
796 if (strcasecmp (array
[i
].name
, f
) == 0)
798 array
[i
].value
= value
;
804 const char *v
= strchr (f
, '=');
811 for (i
= 0; i
< size
; i
++)
812 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
814 value
= strtol (v
+ 1, &end
, 0);
817 array
[i
].value
= value
;
825 /* Handle CPU_XXX_FLAGS. */
826 if (!set_bitfield_from_cpu_flag_init (f
, array
, value
, size
, lineno
))
830 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
832 fail (_("Unknown bitfield: %s\n"), f
);
836 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
837 int macro
, const char *comma
, const char *indent
)
841 fprintf (table
, "%s{ { ", indent
);
843 for (i
= 0; i
< size
- 1; i
++)
845 if (((i
+ 1) % 20) != 0)
846 fprintf (table
, "%d, ", flags
[i
].value
);
848 fprintf (table
, "%d,", flags
[i
].value
);
849 if (((i
+ 1) % 20) == 0)
851 /* We need \\ for macro. */
853 fprintf (table
, " \\\n %s", indent
);
855 fprintf (table
, "\n %s", indent
);
859 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
863 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
864 const char *comma
, const char *indent
,
867 char *str
, *next
, *last
;
869 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
871 /* Copy the default cpu flags. */
872 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
874 if (strcasecmp (flag
, "unknown") == 0)
876 /* We turn on everything except for cpu64 in case of
877 CPU_UNKNOWN_FLAGS. */
878 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
879 if (flags
[i
].position
!= Cpu64
)
882 else if (flag
[0] == '~')
884 last
= flag
+ strlen (flag
);
891 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
898 /* First we turn on everything except for cpu64. */
899 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
900 if (flags
[i
].position
!= Cpu64
)
903 /* Turn off selective bits. */
904 for (; next
&& next
< last
; )
906 str
= next_field (next
, '|', &next
, last
);
908 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
911 else if (strcmp (flag
, "0"))
913 /* Turn on selective bits. */
914 last
= flag
+ strlen (flag
);
915 for (next
= flag
; next
&& next
< last
; )
917 str
= next_field (next
, '|', &next
, last
);
919 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
923 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
928 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
932 fprintf (table
, " { ");
934 for (i
= 0; i
< size
- 1; i
++)
936 if (((i
+ 1) % 20) != 0)
937 fprintf (table
, "%d, ", modifier
[i
].value
);
939 fprintf (table
, "%d,", modifier
[i
].value
);
940 if (((i
+ 1) % 20) == 0)
941 fprintf (table
, "\n ");
944 fprintf (table
, "%d },\n", modifier
[i
].value
);
948 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
950 char *str
, *next
, *last
;
951 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
953 /* Copy the default opcode modifier. */
954 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
956 if (strcmp (mod
, "0"))
958 last
= mod
+ strlen (mod
);
959 for (next
= mod
; next
&& next
< last
; )
961 str
= next_field (next
, '|', &next
, last
);
963 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
967 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
971 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
972 int macro
, const char *indent
)
976 fprintf (table
, "{ { ");
978 for (i
= 0; i
< size
- 1; i
++)
980 if (((i
+ 1) % 20) != 0)
981 fprintf (table
, "%d, ", types
[i
].value
);
983 fprintf (table
, "%d,", types
[i
].value
);
984 if (((i
+ 1) % 20) == 0)
986 /* We need \\ for macro. */
988 fprintf (table
, " \\\n%s", indent
);
990 fprintf (table
, "\n%s", indent
);
994 fprintf (table
, "%d } }", types
[i
].value
);
998 process_i386_operand_type (FILE *table
, char *op
, int macro
,
999 const char *indent
, int lineno
)
1001 char *str
, *next
, *last
;
1002 bitfield types
[ARRAY_SIZE (operand_types
)];
1004 /* Copy the default operand type. */
1005 memcpy (types
, operand_types
, sizeof (types
));
1007 if (strcmp (op
, "0"))
1009 last
= op
+ strlen (op
);
1010 for (next
= op
; next
&& next
< last
; )
1012 str
= next_field (next
, '|', &next
, last
);
1014 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1017 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
1022 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1023 char *last
, int lineno
)
1026 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1027 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1029 /* Find number of operands. */
1030 operands
= next_field (str
, ',', &str
, last
);
1032 /* Find base_opcode. */
1033 base_opcode
= next_field (str
, ',', &str
, last
);
1035 /* Find extension_opcode. */
1036 extension_opcode
= next_field (str
, ',', &str
, last
);
1038 /* Find opcode_length. */
1039 opcode_length
= next_field (str
, ',', &str
, last
);
1041 /* Find cpu_flags. */
1042 cpu_flags
= next_field (str
, ',', &str
, last
);
1044 /* Find opcode_modifier. */
1045 opcode_modifier
= next_field (str
, ',', &str
, last
);
1047 /* Remove the first {. */
1048 str
= remove_leading_whitespaces (str
);
1051 str
= remove_leading_whitespaces (str
+ 1);
1055 /* There are at least "X}". */
1059 /* Remove trailing white spaces and }. */
1063 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1072 /* Find operand_types. */
1073 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1077 operand_types
[i
] = NULL
;
1081 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1082 if (*operand_types
[i
] == '0')
1085 operand_types
[i
] = NULL
;
1090 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1091 name
, operands
, base_opcode
, extension_opcode
,
1094 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1096 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1098 fprintf (table
, " { ");
1100 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1102 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1105 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1110 fprintf (table
, ",\n ");
1112 process_i386_operand_type (table
, operand_types
[i
], 0,
1115 fprintf (table
, " } },\n");
1118 struct opcode_hash_entry
1120 struct opcode_hash_entry
*next
;
1126 /* Calculate the hash value of an opcode hash entry P. */
1129 opcode_hash_hash (const void *p
)
1131 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1132 return htab_hash_string (entry
->name
);
1135 /* Compare a string Q against an opcode hash entry P. */
1138 opcode_hash_eq (const void *p
, const void *q
)
1140 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1141 const char *name
= (const char *) q
;
1142 return strcmp (name
, entry
->name
) == 0;
1146 process_i386_opcodes (FILE *table
)
1151 char *str
, *p
, *last
, *name
;
1152 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1153 htab_t opcode_hash_table
;
1154 struct opcode_hash_entry
**opcode_array
;
1155 unsigned int opcode_array_size
= 1024;
1158 filename
= "i386-opc.tbl";
1159 fp
= fopen (filename
, "r");
1162 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1166 opcode_array
= (struct opcode_hash_entry
**)
1167 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1169 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1170 opcode_hash_eq
, NULL
,
1173 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1174 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1176 /* Put everything on opcode array. */
1179 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1184 p
= remove_leading_whitespaces (buf
);
1186 /* Skip comments. */
1187 str
= strstr (p
, "//");
1191 /* Remove trailing white spaces. */
1192 remove_trailing_whitespaces (p
);
1197 /* Ignore comments. */
1205 last
= p
+ strlen (p
);
1208 name
= next_field (p
, ',', &str
, last
);
1210 /* Get the slot in hash table. */
1211 hash_slot
= (struct opcode_hash_entry
**)
1212 htab_find_slot_with_hash (opcode_hash_table
, name
,
1213 htab_hash_string (name
),
1216 if (*hash_slot
== NULL
)
1218 /* It is the new one. Put it on opcode array. */
1219 if (i
>= opcode_array_size
)
1221 /* Grow the opcode array when needed. */
1222 opcode_array_size
+= 1024;
1223 opcode_array
= (struct opcode_hash_entry
**)
1224 xrealloc (opcode_array
,
1225 sizeof (*opcode_array
) * opcode_array_size
);
1228 opcode_array
[i
] = (struct opcode_hash_entry
*)
1229 xmalloc (sizeof (struct opcode_hash_entry
));
1230 opcode_array
[i
]->next
= NULL
;
1231 opcode_array
[i
]->name
= xstrdup (name
);
1232 opcode_array
[i
]->opcode
= xstrdup (str
);
1233 opcode_array
[i
]->lineno
= lineno
;
1234 *hash_slot
= opcode_array
[i
];
1239 /* Append it to the existing one. */
1241 while ((*entry
) != NULL
)
1242 entry
= &(*entry
)->next
;
1243 *entry
= (struct opcode_hash_entry
*)
1244 xmalloc (sizeof (struct opcode_hash_entry
));
1245 (*entry
)->next
= NULL
;
1246 (*entry
)->name
= (*hash_slot
)->name
;
1247 (*entry
)->opcode
= xstrdup (str
);
1248 (*entry
)->lineno
= lineno
;
1252 /* Process opcode array. */
1253 for (j
= 0; j
< i
; j
++)
1255 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1259 lineno
= next
->lineno
;
1260 last
= str
+ strlen (str
);
1261 output_i386_opcode (table
, name
, str
, last
, lineno
);
1267 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1269 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1271 process_i386_opcode_modifier (table
, "0", -1);
1273 fprintf (table
, " { ");
1274 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1275 fprintf (table
, " } }\n");
1277 fprintf (table
, "};\n");
1281 process_i386_registers (FILE *table
)
1285 char *str
, *p
, *last
;
1286 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1287 char *dw2_32_num
, *dw2_64_num
;
1290 filename
= "i386-reg.tbl";
1291 fp
= fopen (filename
, "r");
1293 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1296 fprintf (table
, "\n/* i386 register table. */\n\n");
1297 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1301 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1306 p
= remove_leading_whitespaces (buf
);
1308 /* Skip comments. */
1309 str
= strstr (p
, "//");
1313 /* Remove trailing white spaces. */
1314 remove_trailing_whitespaces (p
);
1319 fprintf (table
, "%s\n", p
);
1327 last
= p
+ strlen (p
);
1329 /* Find reg_name. */
1330 reg_name
= next_field (p
, ',', &str
, last
);
1332 /* Find reg_type. */
1333 reg_type
= next_field (str
, ',', &str
, last
);
1335 /* Find reg_flags. */
1336 reg_flags
= next_field (str
, ',', &str
, last
);
1339 reg_num
= next_field (str
, ',', &str
, last
);
1341 fprintf (table
, " { \"%s\",\n ", reg_name
);
1343 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1345 /* Find 32-bit Dwarf2 register number. */
1346 dw2_32_num
= next_field (str
, ',', &str
, last
);
1348 /* Find 64-bit Dwarf2 register number. */
1349 dw2_64_num
= next_field (str
, ',', &str
, last
);
1351 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1352 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1357 fprintf (table
, "};\n");
1359 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1363 process_i386_initializers (void)
1366 FILE *fp
= fopen ("i386-init.h", "w");
1370 fail (_("can't create i386-init.h, errno = %s\n"),
1373 process_copyright (fp
);
1375 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1377 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1378 init
= xstrdup (cpu_flag_init
[i
].init
);
1379 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1383 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1385 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1386 init
= xstrdup (operand_type_init
[i
].init
);
1387 process_i386_operand_type (fp
, init
, 1, " ", -1);
1395 /* Program options. */
1396 #define OPTION_SRCDIR 200
1398 struct option long_options
[] =
1400 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1401 {"debug", no_argument
, NULL
, 'd'},
1402 {"version", no_argument
, NULL
, 'V'},
1403 {"help", no_argument
, NULL
, 'h'},
1404 {0, no_argument
, NULL
, 0}
1408 print_version (void)
1410 printf ("%s: version 1.0\n", program_name
);
1415 usage (FILE * stream
, int status
)
1417 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1423 main (int argc
, char **argv
)
1425 extern int chdir (char *);
1426 char *srcdir
= NULL
;
1428 unsigned int i
, cpumax
;
1431 program_name
= *argv
;
1432 xmalloc_set_program_name (program_name
);
1434 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1459 if (chdir (srcdir
) != 0)
1460 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1461 srcdir
, xstrerror (errno
));
1463 /* cpu_flags isn't sorted by position. */
1465 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1466 if (cpu_flags
[i
].position
> cpumax
)
1467 cpumax
= cpu_flags
[i
].position
;
1469 /* Check the unused bitfield in i386_cpu_flags. */
1471 if ((cpumax
- 1) != CpuMax
)
1472 fail (_("CpuMax != %d!\n"), cpumax
);
1474 if (cpumax
!= CpuMax
)
1475 fail (_("CpuMax != %d!\n"), cpumax
);
1477 c
= CpuNumOfBits
- CpuMax
- 1;
1479 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1482 /* Check the unused bitfield in i386_operand_type. */
1484 c
= OTNumOfBits
- OTMax
- 1;
1486 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1489 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1492 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1493 sizeof (opcode_modifiers
[0]), compare
);
1495 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1496 sizeof (operand_types
[0]), compare
);
1498 table
= fopen ("i386-tbl.h", "w");
1500 fail (_("can't create i386-tbl.h, errno = %s\n"),
1503 process_copyright (table
);
1505 process_i386_opcodes (table
);
1506 process_i386_registers (table
);
1507 process_i386_initializers ();