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" },
233 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
236 { "CPU_RDSEED_FLAGS",
238 { "CPU_PRFCHW_FLAGS",
245 "CPU_SSE2_FLAGS|CpuSHA" },
246 { "CPU_CLFLUSHOPT_FLAGS",
248 { "CPU_XSAVES_FLAGS",
249 "CPU_XSAVE_FLAGS|CpuXSAVES" },
250 { "CPU_XSAVEC_FLAGS",
251 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
252 { "CPU_PREFETCHWT1_FLAGS",
258 { "CPU_CLZERO_FLAGS",
260 { "CPU_MWAITX_FLAGS",
266 { "CPU_PTWRITE_FLAGS",
270 { "CPU_ANY_X87_FLAGS",
271 "CPU_ANY_287_FLAGS|Cpu8087" },
272 { "CPU_ANY_287_FLAGS",
273 "CPU_ANY_387_FLAGS|Cpu287" },
274 { "CPU_ANY_387_FLAGS",
275 "CPU_ANY_687_FLAGS|Cpu387" },
276 { "CPU_ANY_687_FLAGS",
277 "Cpu687|CpuFISTTP" },
278 { "CPU_ANY_MMX_FLAGS",
279 "CPU_3DNOWA_FLAGS" },
280 { "CPU_ANY_SSE_FLAGS",
281 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
282 { "CPU_ANY_SSE2_FLAGS",
283 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
284 { "CPU_ANY_SSE3_FLAGS",
285 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
286 { "CPU_ANY_SSSE3_FLAGS",
287 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
288 { "CPU_ANY_SSE4_1_FLAGS",
289 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
290 { "CPU_ANY_SSE4_2_FLAGS",
292 { "CPU_ANY_AVX_FLAGS",
293 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
294 { "CPU_ANY_AVX2_FLAGS",
296 { "CPU_ANY_AVX512F_FLAGS",
297 "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512F" },
298 { "CPU_ANY_AVX512CD_FLAGS",
300 { "CPU_ANY_AVX512ER_FLAGS",
302 { "CPU_ANY_AVX512PF_FLAGS",
304 { "CPU_ANY_AVX512DQ_FLAGS",
306 { "CPU_ANY_AVX512BW_FLAGS",
308 { "CPU_ANY_AVX512VL_FLAGS",
310 { "CPU_ANY_AVX512IFMA_FLAGS",
312 { "CPU_ANY_AVX512VBMI_FLAGS",
314 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
315 "CpuAVX512_4FMAPS" },
316 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
317 "CpuAVX512_4VNNIW" },
318 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
319 "CpuAVX512_VPOPCNTDQ" },
320 { "CPU_ANY_AVX512_VBMI2_FLAGS",
324 static initializer operand_type_init
[] =
326 { "OPERAND_TYPE_NONE",
328 { "OPERAND_TYPE_REG8",
330 { "OPERAND_TYPE_REG16",
332 { "OPERAND_TYPE_REG32",
334 { "OPERAND_TYPE_REG64",
336 { "OPERAND_TYPE_IMM1",
338 { "OPERAND_TYPE_IMM8",
340 { "OPERAND_TYPE_IMM8S",
342 { "OPERAND_TYPE_IMM16",
344 { "OPERAND_TYPE_IMM32",
346 { "OPERAND_TYPE_IMM32S",
348 { "OPERAND_TYPE_IMM64",
350 { "OPERAND_TYPE_BASEINDEX",
352 { "OPERAND_TYPE_DISP8",
354 { "OPERAND_TYPE_DISP16",
356 { "OPERAND_TYPE_DISP32",
358 { "OPERAND_TYPE_DISP32S",
360 { "OPERAND_TYPE_DISP64",
362 { "OPERAND_TYPE_INOUTPORTREG",
364 { "OPERAND_TYPE_SHIFTCOUNT",
366 { "OPERAND_TYPE_CONTROL",
368 { "OPERAND_TYPE_TEST",
370 { "OPERAND_TYPE_DEBUG",
372 { "OPERAND_TYPE_FLOATREG",
374 { "OPERAND_TYPE_FLOATACC",
376 { "OPERAND_TYPE_SREG2",
378 { "OPERAND_TYPE_SREG3",
380 { "OPERAND_TYPE_ACC",
382 { "OPERAND_TYPE_JUMPABSOLUTE",
384 { "OPERAND_TYPE_REGMMX",
386 { "OPERAND_TYPE_REGXMM",
388 { "OPERAND_TYPE_REGYMM",
390 { "OPERAND_TYPE_REGZMM",
392 { "OPERAND_TYPE_REGMASK",
394 { "OPERAND_TYPE_ESSEG",
396 { "OPERAND_TYPE_ACC32",
398 { "OPERAND_TYPE_ACC64",
400 { "OPERAND_TYPE_INOUTPORTREG",
402 { "OPERAND_TYPE_REG16_INOUTPORTREG",
403 "Reg16|InOutPortReg" },
404 { "OPERAND_TYPE_DISP16_32",
406 { "OPERAND_TYPE_ANYDISP",
407 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
408 { "OPERAND_TYPE_IMM16_32",
410 { "OPERAND_TYPE_IMM16_32S",
412 { "OPERAND_TYPE_IMM16_32_32S",
413 "Imm16|Imm32|Imm32S" },
414 { "OPERAND_TYPE_IMM32_64",
416 { "OPERAND_TYPE_IMM32_32S_DISP32",
417 "Imm32|Imm32S|Disp32" },
418 { "OPERAND_TYPE_IMM64_DISP64",
420 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
421 "Imm32|Imm32S|Imm64|Disp32" },
422 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
423 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
424 { "OPERAND_TYPE_VEC_IMM4",
426 { "OPERAND_TYPE_REGBND",
428 { "OPERAND_TYPE_VEC_DISP8",
432 typedef struct bitfield
439 #define BITFIELD(n) { n, 0, #n }
441 static bitfield cpu_flags
[] =
449 BITFIELD (CpuClflush
),
451 BITFIELD (CpuSYSCALL
),
456 BITFIELD (CpuFISTTP
),
462 BITFIELD (CpuSSE4_1
),
463 BITFIELD (CpuSSE4_2
),
466 BITFIELD (CpuAVX512F
),
467 BITFIELD (CpuAVX512CD
),
468 BITFIELD (CpuAVX512ER
),
469 BITFIELD (CpuAVX512PF
),
470 BITFIELD (CpuAVX512VL
),
471 BITFIELD (CpuAVX512DQ
),
472 BITFIELD (CpuAVX512BW
),
478 BITFIELD (Cpu3dnowA
),
479 BITFIELD (CpuPadLock
),
485 BITFIELD (CpuXsaveopt
),
487 BITFIELD (CpuPCLMUL
),
498 BITFIELD (CpuRdtscp
),
499 BITFIELD (CpuFSGSBase
),
506 BITFIELD (CpuINVPCID
),
507 BITFIELD (CpuVMFUNC
),
508 BITFIELD (CpuRDSEED
),
510 BITFIELD (CpuPRFCHW
),
514 BITFIELD (CpuClflushOpt
),
515 BITFIELD (CpuXSAVES
),
516 BITFIELD (CpuXSAVEC
),
517 BITFIELD (CpuPREFETCHWT1
),
523 BITFIELD (CpuAVX512IFMA
),
524 BITFIELD (CpuAVX512VBMI
),
525 BITFIELD (CpuAVX512_4FMAPS
),
526 BITFIELD (CpuAVX512_4VNNIW
),
527 BITFIELD (CpuAVX512_VPOPCNTDQ
),
528 BITFIELD (CpuAVX512_VBMI2
),
529 BITFIELD (CpuMWAITX
),
530 BITFIELD (CpuCLZERO
),
533 BITFIELD (CpuPTWRITE
),
535 BITFIELD (CpuRegMMX
),
536 BITFIELD (CpuRegXMM
),
537 BITFIELD (CpuRegYMM
),
538 BITFIELD (CpuRegZMM
),
539 BITFIELD (CpuRegMask
),
541 BITFIELD (CpuUnused
),
545 static bitfield opcode_modifiers
[] =
551 BITFIELD (ShortForm
),
553 BITFIELD (JumpDword
),
555 BITFIELD (JumpInterSegment
),
562 BITFIELD (CheckRegSize
),
563 BITFIELD (IgnoreSize
),
564 BITFIELD (DefaultSize
),
573 BITFIELD (BNDPrefixOk
),
574 BITFIELD (NoTrackPrefixOk
),
575 BITFIELD (IsLockable
),
576 BITFIELD (RegKludge
),
577 BITFIELD (FirstXmm0
),
578 BITFIELD (Implicit1stXmm0
),
579 BITFIELD (RepPrefixOk
),
580 BITFIELD (HLEPrefixOk
),
583 BITFIELD (AddrPrefixOp0
),
592 BITFIELD (VexOpcode
),
593 BITFIELD (VexSources
),
594 BITFIELD (VexImmExt
),
601 BITFIELD (Broadcast
),
602 BITFIELD (StaticRounding
),
604 BITFIELD (Disp8MemShift
),
605 BITFIELD (NoDefMask
),
606 BITFIELD (ImplicitQuadGroup
),
608 BITFIELD (ATTMnemonic
),
609 BITFIELD (ATTSyntax
),
610 BITFIELD (IntelSyntax
),
615 static bitfield operand_types
[] =
634 BITFIELD (BaseIndex
),
640 BITFIELD (InOutPortReg
),
641 BITFIELD (ShiftCount
),
649 BITFIELD (JumpAbsolute
),
662 BITFIELD (Unspecified
),
666 BITFIELD (Vec_Disp8
),
672 static const char *filename
;
675 compare (const void *x
, const void *y
)
677 const bitfield
*xp
= (const bitfield
*) x
;
678 const bitfield
*yp
= (const bitfield
*) y
;
679 return xp
->position
- yp
->position
;
683 fail (const char *message
, ...)
687 va_start (args
, message
);
688 fprintf (stderr
, _("%s: Error: "), program_name
);
689 vfprintf (stderr
, message
, args
);
695 process_copyright (FILE *fp
)
697 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
698 /* Copyright (C) 2007-2017 Free Software Foundation, Inc.\n\
700 This file is part of the GNU opcodes library.\n\
702 This library is free software; you can redistribute it and/or modify\n\
703 it under the terms of the GNU General Public License as published by\n\
704 the Free Software Foundation; either version 3, or (at your option)\n\
705 any later version.\n\
707 It is distributed in the hope that it will be useful, but WITHOUT\n\
708 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
709 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
710 License for more details.\n\
712 You should have received a copy of the GNU General Public License\n\
713 along with this program; if not, write to the Free Software\n\
714 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
715 MA 02110-1301, USA. */\n");
718 /* Remove leading white spaces. */
721 remove_leading_whitespaces (char *str
)
723 while (ISSPACE (*str
))
728 /* Remove trailing white spaces. */
731 remove_trailing_whitespaces (char *str
)
733 size_t last
= strlen (str
);
741 if (ISSPACE (str
[last
]))
749 /* Find next field separated by SEP and terminate it. Return a
750 pointer to the one after it. */
753 next_field (char *str
, char sep
, char **next
, char *last
)
757 p
= remove_leading_whitespaces (str
);
758 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
761 remove_trailing_whitespaces (p
);
771 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
774 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
,
775 int value
, unsigned int size
,
778 char *str
, *next
, *last
;
781 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
782 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
784 /* Turn on selective bits. */
785 char *init
= xstrdup (cpu_flag_init
[i
].init
);
786 last
= init
+ strlen (init
);
787 for (next
= init
; next
&& next
< last
; )
789 str
= next_field (next
, '|', &next
, last
);
791 set_bitfield (str
, array
, 1, size
, lineno
);
801 set_bitfield (char *f
, bitfield
*array
, int value
,
802 unsigned int size
, int lineno
)
806 if (strcmp (f
, "CpuFP") == 0)
808 set_bitfield("Cpu387", array
, value
, size
, lineno
);
809 set_bitfield("Cpu287", array
, value
, size
, lineno
);
812 else if (strcmp (f
, "Mmword") == 0)
814 else if (strcmp (f
, "Oword") == 0)
817 for (i
= 0; i
< size
; i
++)
818 if (strcasecmp (array
[i
].name
, f
) == 0)
820 array
[i
].value
= value
;
826 const char *v
= strchr (f
, '=');
833 for (i
= 0; i
< size
; i
++)
834 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
836 value
= strtol (v
+ 1, &end
, 0);
839 array
[i
].value
= value
;
847 /* Handle CPU_XXX_FLAGS. */
848 if (!set_bitfield_from_cpu_flag_init (f
, array
, value
, size
, lineno
))
852 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
854 fail (_("Unknown bitfield: %s\n"), f
);
858 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
859 int macro
, const char *comma
, const char *indent
)
863 fprintf (table
, "%s{ { ", indent
);
865 for (i
= 0; i
< size
- 1; i
++)
867 if (((i
+ 1) % 20) != 0)
868 fprintf (table
, "%d, ", flags
[i
].value
);
870 fprintf (table
, "%d,", flags
[i
].value
);
871 if (((i
+ 1) % 20) == 0)
873 /* We need \\ for macro. */
875 fprintf (table
, " \\\n %s", indent
);
877 fprintf (table
, "\n %s", indent
);
881 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
885 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
886 const char *comma
, const char *indent
,
889 char *str
, *next
, *last
;
891 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
893 /* Copy the default cpu flags. */
894 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
896 if (strcasecmp (flag
, "unknown") == 0)
898 /* We turn on everything except for cpu64 in case of
899 CPU_UNKNOWN_FLAGS. */
900 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
901 if (flags
[i
].position
!= Cpu64
)
904 else if (flag
[0] == '~')
906 last
= flag
+ strlen (flag
);
913 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
920 /* First we turn on everything except for cpu64. */
921 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
922 if (flags
[i
].position
!= Cpu64
)
925 /* Turn off selective bits. */
926 for (; next
&& next
< last
; )
928 str
= next_field (next
, '|', &next
, last
);
930 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
933 else if (strcmp (flag
, "0"))
935 /* Turn on selective bits. */
936 last
= flag
+ strlen (flag
);
937 for (next
= flag
; next
&& next
< last
; )
939 str
= next_field (next
, '|', &next
, last
);
941 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
945 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
950 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
954 fprintf (table
, " { ");
956 for (i
= 0; i
< size
- 1; i
++)
958 if (((i
+ 1) % 20) != 0)
959 fprintf (table
, "%d, ", modifier
[i
].value
);
961 fprintf (table
, "%d,", modifier
[i
].value
);
962 if (((i
+ 1) % 20) == 0)
963 fprintf (table
, "\n ");
966 fprintf (table
, "%d },\n", modifier
[i
].value
);
970 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
972 char *str
, *next
, *last
;
973 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
975 /* Copy the default opcode modifier. */
976 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
978 if (strcmp (mod
, "0"))
980 last
= mod
+ strlen (mod
);
981 for (next
= mod
; next
&& next
< last
; )
983 str
= next_field (next
, '|', &next
, last
);
985 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
989 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
993 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
994 int macro
, const char *indent
)
998 fprintf (table
, "{ { ");
1000 for (i
= 0; i
< size
- 1; i
++)
1002 if (((i
+ 1) % 20) != 0)
1003 fprintf (table
, "%d, ", types
[i
].value
);
1005 fprintf (table
, "%d,", types
[i
].value
);
1006 if (((i
+ 1) % 20) == 0)
1008 /* We need \\ for macro. */
1010 fprintf (table
, " \\\n%s", indent
);
1012 fprintf (table
, "\n%s", indent
);
1016 fprintf (table
, "%d } }", types
[i
].value
);
1020 process_i386_operand_type (FILE *table
, char *op
, int macro
,
1021 const char *indent
, int lineno
)
1023 char *str
, *next
, *last
;
1024 bitfield types
[ARRAY_SIZE (operand_types
)];
1026 /* Copy the default operand type. */
1027 memcpy (types
, operand_types
, sizeof (types
));
1029 if (strcmp (op
, "0"))
1031 last
= op
+ strlen (op
);
1032 for (next
= op
; next
&& next
< last
; )
1034 str
= next_field (next
, '|', &next
, last
);
1036 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1039 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
1044 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1045 char *last
, int lineno
)
1048 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1049 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1051 /* Find number of operands. */
1052 operands
= next_field (str
, ',', &str
, last
);
1054 /* Find base_opcode. */
1055 base_opcode
= next_field (str
, ',', &str
, last
);
1057 /* Find extension_opcode. */
1058 extension_opcode
= next_field (str
, ',', &str
, last
);
1060 /* Find opcode_length. */
1061 opcode_length
= next_field (str
, ',', &str
, last
);
1063 /* Find cpu_flags. */
1064 cpu_flags
= next_field (str
, ',', &str
, last
);
1066 /* Find opcode_modifier. */
1067 opcode_modifier
= next_field (str
, ',', &str
, last
);
1069 /* Remove the first {. */
1070 str
= remove_leading_whitespaces (str
);
1073 str
= remove_leading_whitespaces (str
+ 1);
1077 /* There are at least "X}". */
1081 /* Remove trailing white spaces and }. */
1085 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1094 /* Find operand_types. */
1095 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1099 operand_types
[i
] = NULL
;
1103 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1104 if (*operand_types
[i
] == '0')
1107 operand_types
[i
] = NULL
;
1112 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1113 name
, operands
, base_opcode
, extension_opcode
,
1116 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1118 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1120 fprintf (table
, " { ");
1122 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1124 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1127 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1132 fprintf (table
, ",\n ");
1134 process_i386_operand_type (table
, operand_types
[i
], 0,
1137 fprintf (table
, " } },\n");
1140 struct opcode_hash_entry
1142 struct opcode_hash_entry
*next
;
1148 /* Calculate the hash value of an opcode hash entry P. */
1151 opcode_hash_hash (const void *p
)
1153 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1154 return htab_hash_string (entry
->name
);
1157 /* Compare a string Q against an opcode hash entry P. */
1160 opcode_hash_eq (const void *p
, const void *q
)
1162 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1163 const char *name
= (const char *) q
;
1164 return strcmp (name
, entry
->name
) == 0;
1168 process_i386_opcodes (FILE *table
)
1173 char *str
, *p
, *last
, *name
;
1174 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1175 htab_t opcode_hash_table
;
1176 struct opcode_hash_entry
**opcode_array
;
1177 unsigned int opcode_array_size
= 1024;
1180 filename
= "i386-opc.tbl";
1181 fp
= fopen (filename
, "r");
1184 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1188 opcode_array
= (struct opcode_hash_entry
**)
1189 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1191 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1192 opcode_hash_eq
, NULL
,
1195 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1196 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1198 /* Put everything on opcode array. */
1201 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1206 p
= remove_leading_whitespaces (buf
);
1208 /* Skip comments. */
1209 str
= strstr (p
, "//");
1213 /* Remove trailing white spaces. */
1214 remove_trailing_whitespaces (p
);
1219 /* Ignore comments. */
1227 last
= p
+ strlen (p
);
1230 name
= next_field (p
, ',', &str
, last
);
1232 /* Get the slot in hash table. */
1233 hash_slot
= (struct opcode_hash_entry
**)
1234 htab_find_slot_with_hash (opcode_hash_table
, name
,
1235 htab_hash_string (name
),
1238 if (*hash_slot
== NULL
)
1240 /* It is the new one. Put it on opcode array. */
1241 if (i
>= opcode_array_size
)
1243 /* Grow the opcode array when needed. */
1244 opcode_array_size
+= 1024;
1245 opcode_array
= (struct opcode_hash_entry
**)
1246 xrealloc (opcode_array
,
1247 sizeof (*opcode_array
) * opcode_array_size
);
1250 opcode_array
[i
] = (struct opcode_hash_entry
*)
1251 xmalloc (sizeof (struct opcode_hash_entry
));
1252 opcode_array
[i
]->next
= NULL
;
1253 opcode_array
[i
]->name
= xstrdup (name
);
1254 opcode_array
[i
]->opcode
= xstrdup (str
);
1255 opcode_array
[i
]->lineno
= lineno
;
1256 *hash_slot
= opcode_array
[i
];
1261 /* Append it to the existing one. */
1263 while ((*entry
) != NULL
)
1264 entry
= &(*entry
)->next
;
1265 *entry
= (struct opcode_hash_entry
*)
1266 xmalloc (sizeof (struct opcode_hash_entry
));
1267 (*entry
)->next
= NULL
;
1268 (*entry
)->name
= (*hash_slot
)->name
;
1269 (*entry
)->opcode
= xstrdup (str
);
1270 (*entry
)->lineno
= lineno
;
1274 /* Process opcode array. */
1275 for (j
= 0; j
< i
; j
++)
1277 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1281 lineno
= next
->lineno
;
1282 last
= str
+ strlen (str
);
1283 output_i386_opcode (table
, name
, str
, last
, lineno
);
1289 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1291 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1293 process_i386_opcode_modifier (table
, "0", -1);
1295 fprintf (table
, " { ");
1296 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1297 fprintf (table
, " } }\n");
1299 fprintf (table
, "};\n");
1303 process_i386_registers (FILE *table
)
1307 char *str
, *p
, *last
;
1308 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1309 char *dw2_32_num
, *dw2_64_num
;
1312 filename
= "i386-reg.tbl";
1313 fp
= fopen (filename
, "r");
1315 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1318 fprintf (table
, "\n/* i386 register table. */\n\n");
1319 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1323 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1328 p
= remove_leading_whitespaces (buf
);
1330 /* Skip comments. */
1331 str
= strstr (p
, "//");
1335 /* Remove trailing white spaces. */
1336 remove_trailing_whitespaces (p
);
1341 fprintf (table
, "%s\n", p
);
1349 last
= p
+ strlen (p
);
1351 /* Find reg_name. */
1352 reg_name
= next_field (p
, ',', &str
, last
);
1354 /* Find reg_type. */
1355 reg_type
= next_field (str
, ',', &str
, last
);
1357 /* Find reg_flags. */
1358 reg_flags
= next_field (str
, ',', &str
, last
);
1361 reg_num
= next_field (str
, ',', &str
, last
);
1363 fprintf (table
, " { \"%s\",\n ", reg_name
);
1365 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1367 /* Find 32-bit Dwarf2 register number. */
1368 dw2_32_num
= next_field (str
, ',', &str
, last
);
1370 /* Find 64-bit Dwarf2 register number. */
1371 dw2_64_num
= next_field (str
, ',', &str
, last
);
1373 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1374 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1379 fprintf (table
, "};\n");
1381 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1385 process_i386_initializers (void)
1388 FILE *fp
= fopen ("i386-init.h", "w");
1392 fail (_("can't create i386-init.h, errno = %s\n"),
1395 process_copyright (fp
);
1397 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1399 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1400 init
= xstrdup (cpu_flag_init
[i
].init
);
1401 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1405 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1407 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1408 init
= xstrdup (operand_type_init
[i
].init
);
1409 process_i386_operand_type (fp
, init
, 1, " ", -1);
1417 /* Program options. */
1418 #define OPTION_SRCDIR 200
1420 struct option long_options
[] =
1422 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1423 {"debug", no_argument
, NULL
, 'd'},
1424 {"version", no_argument
, NULL
, 'V'},
1425 {"help", no_argument
, NULL
, 'h'},
1426 {0, no_argument
, NULL
, 0}
1430 print_version (void)
1432 printf ("%s: version 1.0\n", program_name
);
1437 usage (FILE * stream
, int status
)
1439 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1445 main (int argc
, char **argv
)
1447 extern int chdir (char *);
1448 char *srcdir
= NULL
;
1450 unsigned int i
, cpumax
;
1453 program_name
= *argv
;
1454 xmalloc_set_program_name (program_name
);
1456 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1481 if (chdir (srcdir
) != 0)
1482 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1483 srcdir
, xstrerror (errno
));
1485 /* cpu_flags isn't sorted by position. */
1487 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1488 if (cpu_flags
[i
].position
> cpumax
)
1489 cpumax
= cpu_flags
[i
].position
;
1491 /* Check the unused bitfield in i386_cpu_flags. */
1493 if ((cpumax
- 1) != CpuMax
)
1494 fail (_("CpuMax != %d!\n"), cpumax
);
1496 if (cpumax
!= CpuMax
)
1497 fail (_("CpuMax != %d!\n"), cpumax
);
1499 c
= CpuNumOfBits
- CpuMax
- 1;
1501 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1504 /* Check the unused bitfield in i386_operand_type. */
1506 c
= OTNumOfBits
- OTMax
- 1;
1508 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1511 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1514 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1515 sizeof (opcode_modifiers
[0]), compare
);
1517 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1518 sizeof (operand_types
[0]), compare
);
1520 table
= fopen ("i386-tbl.h", "w");
1522 fail (_("can't create i386-tbl.h, errno = %s\n"),
1525 process_copyright (table
);
1527 process_i386_opcodes (table
);
1528 process_i386_registers (table
);
1529 process_i386_initializers ();