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" },
220 { "CPU_AVX512_4FMAPS_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
227 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
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_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|CpuAVX512_4FMAPS|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",
306 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
307 "CpuAVX512_4FMAPS" },
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
),
509 BITFIELD (CpuAVX512IFMA
),
510 BITFIELD (CpuAVX512VBMI
),
511 BITFIELD (CpuAVX512_4FMAPS
),
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
),
587 BITFIELD (ImplicitQuadGroup
),
589 BITFIELD (ATTMnemonic
),
590 BITFIELD (ATTSyntax
),
591 BITFIELD (IntelSyntax
),
596 static bitfield operand_types
[] =
615 BITFIELD (BaseIndex
),
621 BITFIELD (InOutPortReg
),
622 BITFIELD (ShiftCount
),
630 BITFIELD (JumpAbsolute
),
643 BITFIELD (Unspecified
),
647 BITFIELD (Vec_Disp8
),
653 static const char *filename
;
656 compare (const void *x
, const void *y
)
658 const bitfield
*xp
= (const bitfield
*) x
;
659 const bitfield
*yp
= (const bitfield
*) y
;
660 return xp
->position
- yp
->position
;
664 fail (const char *message
, ...)
668 va_start (args
, message
);
669 fprintf (stderr
, _("%s: Error: "), program_name
);
670 vfprintf (stderr
, message
, args
);
676 process_copyright (FILE *fp
)
678 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
679 /* Copyright (C) 2007-2016 Free Software Foundation, Inc.\n\
681 This file is part of the GNU opcodes library.\n\
683 This library is free software; you can redistribute it and/or modify\n\
684 it under the terms of the GNU General Public License as published by\n\
685 the Free Software Foundation; either version 3, or (at your option)\n\
686 any later version.\n\
688 It is distributed in the hope that it will be useful, but WITHOUT\n\
689 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
690 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
691 License for more details.\n\
693 You should have received a copy of the GNU General Public License\n\
694 along with this program; if not, write to the Free Software\n\
695 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
696 MA 02110-1301, USA. */\n");
699 /* Remove leading white spaces. */
702 remove_leading_whitespaces (char *str
)
704 while (ISSPACE (*str
))
709 /* Remove trailing white spaces. */
712 remove_trailing_whitespaces (char *str
)
714 size_t last
= strlen (str
);
722 if (ISSPACE (str
[last
]))
730 /* Find next field separated by SEP and terminate it. Return a
731 pointer to the one after it. */
734 next_field (char *str
, char sep
, char **next
, char *last
)
738 p
= remove_leading_whitespaces (str
);
739 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
742 remove_trailing_whitespaces (p
);
752 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
755 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
,
756 int value
, unsigned int size
,
759 char *str
, *next
, *last
;
762 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
763 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
765 /* Turn on selective bits. */
766 char *init
= xstrdup (cpu_flag_init
[i
].init
);
767 last
= init
+ strlen (init
);
768 for (next
= init
; next
&& next
< last
; )
770 str
= next_field (next
, '|', &next
, last
);
772 set_bitfield (str
, array
, 1, size
, lineno
);
782 set_bitfield (char *f
, bitfield
*array
, int value
,
783 unsigned int size
, int lineno
)
787 if (strcmp (f
, "CpuFP") == 0)
789 set_bitfield("Cpu387", array
, value
, size
, lineno
);
790 set_bitfield("Cpu287", array
, value
, size
, lineno
);
793 else if (strcmp (f
, "Mmword") == 0)
795 else if (strcmp (f
, "Oword") == 0)
798 for (i
= 0; i
< size
; i
++)
799 if (strcasecmp (array
[i
].name
, f
) == 0)
801 array
[i
].value
= value
;
807 const char *v
= strchr (f
, '=');
814 for (i
= 0; i
< size
; i
++)
815 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
817 value
= strtol (v
+ 1, &end
, 0);
820 array
[i
].value
= value
;
828 /* Handle CPU_XXX_FLAGS. */
829 if (!set_bitfield_from_cpu_flag_init (f
, array
, value
, size
, lineno
))
833 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
835 fail (_("Unknown bitfield: %s\n"), f
);
839 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
840 int macro
, const char *comma
, const char *indent
)
844 fprintf (table
, "%s{ { ", indent
);
846 for (i
= 0; i
< size
- 1; i
++)
848 if (((i
+ 1) % 20) != 0)
849 fprintf (table
, "%d, ", flags
[i
].value
);
851 fprintf (table
, "%d,", flags
[i
].value
);
852 if (((i
+ 1) % 20) == 0)
854 /* We need \\ for macro. */
856 fprintf (table
, " \\\n %s", indent
);
858 fprintf (table
, "\n %s", indent
);
862 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
866 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
867 const char *comma
, const char *indent
,
870 char *str
, *next
, *last
;
872 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
874 /* Copy the default cpu flags. */
875 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
877 if (strcasecmp (flag
, "unknown") == 0)
879 /* We turn on everything except for cpu64 in case of
880 CPU_UNKNOWN_FLAGS. */
881 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
882 if (flags
[i
].position
!= Cpu64
)
885 else if (flag
[0] == '~')
887 last
= flag
+ strlen (flag
);
894 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
901 /* First we turn on everything except for cpu64. */
902 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
903 if (flags
[i
].position
!= Cpu64
)
906 /* Turn off selective bits. */
907 for (; next
&& next
< last
; )
909 str
= next_field (next
, '|', &next
, last
);
911 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
914 else if (strcmp (flag
, "0"))
916 /* Turn on selective bits. */
917 last
= flag
+ strlen (flag
);
918 for (next
= flag
; next
&& next
< last
; )
920 str
= next_field (next
, '|', &next
, last
);
922 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
926 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
931 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
935 fprintf (table
, " { ");
937 for (i
= 0; i
< size
- 1; i
++)
939 if (((i
+ 1) % 20) != 0)
940 fprintf (table
, "%d, ", modifier
[i
].value
);
942 fprintf (table
, "%d,", modifier
[i
].value
);
943 if (((i
+ 1) % 20) == 0)
944 fprintf (table
, "\n ");
947 fprintf (table
, "%d },\n", modifier
[i
].value
);
951 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
953 char *str
, *next
, *last
;
954 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
956 /* Copy the default opcode modifier. */
957 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
959 if (strcmp (mod
, "0"))
961 last
= mod
+ strlen (mod
);
962 for (next
= mod
; next
&& next
< last
; )
964 str
= next_field (next
, '|', &next
, last
);
966 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
970 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
974 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
975 int macro
, const char *indent
)
979 fprintf (table
, "{ { ");
981 for (i
= 0; i
< size
- 1; i
++)
983 if (((i
+ 1) % 20) != 0)
984 fprintf (table
, "%d, ", types
[i
].value
);
986 fprintf (table
, "%d,", types
[i
].value
);
987 if (((i
+ 1) % 20) == 0)
989 /* We need \\ for macro. */
991 fprintf (table
, " \\\n%s", indent
);
993 fprintf (table
, "\n%s", indent
);
997 fprintf (table
, "%d } }", types
[i
].value
);
1001 process_i386_operand_type (FILE *table
, char *op
, int macro
,
1002 const char *indent
, int lineno
)
1004 char *str
, *next
, *last
;
1005 bitfield types
[ARRAY_SIZE (operand_types
)];
1007 /* Copy the default operand type. */
1008 memcpy (types
, operand_types
, sizeof (types
));
1010 if (strcmp (op
, "0"))
1012 last
= op
+ strlen (op
);
1013 for (next
= op
; next
&& next
< last
; )
1015 str
= next_field (next
, '|', &next
, last
);
1017 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1020 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
1025 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1026 char *last
, int lineno
)
1029 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1030 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1032 /* Find number of operands. */
1033 operands
= next_field (str
, ',', &str
, last
);
1035 /* Find base_opcode. */
1036 base_opcode
= next_field (str
, ',', &str
, last
);
1038 /* Find extension_opcode. */
1039 extension_opcode
= next_field (str
, ',', &str
, last
);
1041 /* Find opcode_length. */
1042 opcode_length
= next_field (str
, ',', &str
, last
);
1044 /* Find cpu_flags. */
1045 cpu_flags
= next_field (str
, ',', &str
, last
);
1047 /* Find opcode_modifier. */
1048 opcode_modifier
= next_field (str
, ',', &str
, last
);
1050 /* Remove the first {. */
1051 str
= remove_leading_whitespaces (str
);
1054 str
= remove_leading_whitespaces (str
+ 1);
1058 /* There are at least "X}". */
1062 /* Remove trailing white spaces and }. */
1066 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1075 /* Find operand_types. */
1076 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1080 operand_types
[i
] = NULL
;
1084 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1085 if (*operand_types
[i
] == '0')
1088 operand_types
[i
] = NULL
;
1093 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1094 name
, operands
, base_opcode
, extension_opcode
,
1097 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1099 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1101 fprintf (table
, " { ");
1103 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1105 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1108 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1113 fprintf (table
, ",\n ");
1115 process_i386_operand_type (table
, operand_types
[i
], 0,
1118 fprintf (table
, " } },\n");
1121 struct opcode_hash_entry
1123 struct opcode_hash_entry
*next
;
1129 /* Calculate the hash value of an opcode hash entry P. */
1132 opcode_hash_hash (const void *p
)
1134 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1135 return htab_hash_string (entry
->name
);
1138 /* Compare a string Q against an opcode hash entry P. */
1141 opcode_hash_eq (const void *p
, const void *q
)
1143 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1144 const char *name
= (const char *) q
;
1145 return strcmp (name
, entry
->name
) == 0;
1149 process_i386_opcodes (FILE *table
)
1154 char *str
, *p
, *last
, *name
;
1155 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1156 htab_t opcode_hash_table
;
1157 struct opcode_hash_entry
**opcode_array
;
1158 unsigned int opcode_array_size
= 1024;
1161 filename
= "i386-opc.tbl";
1162 fp
= fopen (filename
, "r");
1165 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1169 opcode_array
= (struct opcode_hash_entry
**)
1170 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1172 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1173 opcode_hash_eq
, NULL
,
1176 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1177 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1179 /* Put everything on opcode array. */
1182 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1187 p
= remove_leading_whitespaces (buf
);
1189 /* Skip comments. */
1190 str
= strstr (p
, "//");
1194 /* Remove trailing white spaces. */
1195 remove_trailing_whitespaces (p
);
1200 /* Ignore comments. */
1208 last
= p
+ strlen (p
);
1211 name
= next_field (p
, ',', &str
, last
);
1213 /* Get the slot in hash table. */
1214 hash_slot
= (struct opcode_hash_entry
**)
1215 htab_find_slot_with_hash (opcode_hash_table
, name
,
1216 htab_hash_string (name
),
1219 if (*hash_slot
== NULL
)
1221 /* It is the new one. Put it on opcode array. */
1222 if (i
>= opcode_array_size
)
1224 /* Grow the opcode array when needed. */
1225 opcode_array_size
+= 1024;
1226 opcode_array
= (struct opcode_hash_entry
**)
1227 xrealloc (opcode_array
,
1228 sizeof (*opcode_array
) * opcode_array_size
);
1231 opcode_array
[i
] = (struct opcode_hash_entry
*)
1232 xmalloc (sizeof (struct opcode_hash_entry
));
1233 opcode_array
[i
]->next
= NULL
;
1234 opcode_array
[i
]->name
= xstrdup (name
);
1235 opcode_array
[i
]->opcode
= xstrdup (str
);
1236 opcode_array
[i
]->lineno
= lineno
;
1237 *hash_slot
= opcode_array
[i
];
1242 /* Append it to the existing one. */
1244 while ((*entry
) != NULL
)
1245 entry
= &(*entry
)->next
;
1246 *entry
= (struct opcode_hash_entry
*)
1247 xmalloc (sizeof (struct opcode_hash_entry
));
1248 (*entry
)->next
= NULL
;
1249 (*entry
)->name
= (*hash_slot
)->name
;
1250 (*entry
)->opcode
= xstrdup (str
);
1251 (*entry
)->lineno
= lineno
;
1255 /* Process opcode array. */
1256 for (j
= 0; j
< i
; j
++)
1258 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1262 lineno
= next
->lineno
;
1263 last
= str
+ strlen (str
);
1264 output_i386_opcode (table
, name
, str
, last
, lineno
);
1270 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1272 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1274 process_i386_opcode_modifier (table
, "0", -1);
1276 fprintf (table
, " { ");
1277 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1278 fprintf (table
, " } }\n");
1280 fprintf (table
, "};\n");
1284 process_i386_registers (FILE *table
)
1288 char *str
, *p
, *last
;
1289 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1290 char *dw2_32_num
, *dw2_64_num
;
1293 filename
= "i386-reg.tbl";
1294 fp
= fopen (filename
, "r");
1296 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1299 fprintf (table
, "\n/* i386 register table. */\n\n");
1300 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1304 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1309 p
= remove_leading_whitespaces (buf
);
1311 /* Skip comments. */
1312 str
= strstr (p
, "//");
1316 /* Remove trailing white spaces. */
1317 remove_trailing_whitespaces (p
);
1322 fprintf (table
, "%s\n", p
);
1330 last
= p
+ strlen (p
);
1332 /* Find reg_name. */
1333 reg_name
= next_field (p
, ',', &str
, last
);
1335 /* Find reg_type. */
1336 reg_type
= next_field (str
, ',', &str
, last
);
1338 /* Find reg_flags. */
1339 reg_flags
= next_field (str
, ',', &str
, last
);
1342 reg_num
= next_field (str
, ',', &str
, last
);
1344 fprintf (table
, " { \"%s\",\n ", reg_name
);
1346 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1348 /* Find 32-bit Dwarf2 register number. */
1349 dw2_32_num
= next_field (str
, ',', &str
, last
);
1351 /* Find 64-bit Dwarf2 register number. */
1352 dw2_64_num
= next_field (str
, ',', &str
, last
);
1354 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1355 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1360 fprintf (table
, "};\n");
1362 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1366 process_i386_initializers (void)
1369 FILE *fp
= fopen ("i386-init.h", "w");
1373 fail (_("can't create i386-init.h, errno = %s\n"),
1376 process_copyright (fp
);
1378 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1380 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1381 init
= xstrdup (cpu_flag_init
[i
].init
);
1382 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1386 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1388 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1389 init
= xstrdup (operand_type_init
[i
].init
);
1390 process_i386_operand_type (fp
, init
, 1, " ", -1);
1398 /* Program options. */
1399 #define OPTION_SRCDIR 200
1401 struct option long_options
[] =
1403 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1404 {"debug", no_argument
, NULL
, 'd'},
1405 {"version", no_argument
, NULL
, 'V'},
1406 {"help", no_argument
, NULL
, 'h'},
1407 {0, no_argument
, NULL
, 0}
1411 print_version (void)
1413 printf ("%s: version 1.0\n", program_name
);
1418 usage (FILE * stream
, int status
)
1420 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1426 main (int argc
, char **argv
)
1428 extern int chdir (char *);
1429 char *srcdir
= NULL
;
1431 unsigned int i
, cpumax
;
1434 program_name
= *argv
;
1435 xmalloc_set_program_name (program_name
);
1437 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1462 if (chdir (srcdir
) != 0)
1463 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1464 srcdir
, xstrerror (errno
));
1466 /* cpu_flags isn't sorted by position. */
1468 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1469 if (cpu_flags
[i
].position
> cpumax
)
1470 cpumax
= cpu_flags
[i
].position
;
1472 /* Check the unused bitfield in i386_cpu_flags. */
1474 if ((cpumax
- 1) != CpuMax
)
1475 fail (_("CpuMax != %d!\n"), cpumax
);
1477 if (cpumax
!= CpuMax
)
1478 fail (_("CpuMax != %d!\n"), cpumax
);
1480 c
= CpuNumOfBits
- CpuMax
- 1;
1482 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1485 /* Check the unused bitfield in i386_operand_type. */
1487 c
= OTNumOfBits
- OTMax
- 1;
1489 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1492 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1495 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1496 sizeof (opcode_modifiers
[0]), compare
);
1498 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1499 sizeof (operand_types
[0]), compare
);
1501 table
= fopen ("i386-tbl.h", "w");
1503 fail (_("can't create i386-tbl.h, errno = %s\n"),
1506 process_copyright (table
);
1508 process_i386_opcodes (table
);
1509 process_i386_registers (table
);
1510 process_i386_initializers ();