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_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",
290 static initializer operand_type_init
[] =
292 { "OPERAND_TYPE_NONE",
294 { "OPERAND_TYPE_REG8",
296 { "OPERAND_TYPE_REG16",
298 { "OPERAND_TYPE_REG32",
300 { "OPERAND_TYPE_REG64",
302 { "OPERAND_TYPE_IMM1",
304 { "OPERAND_TYPE_IMM8",
306 { "OPERAND_TYPE_IMM8S",
308 { "OPERAND_TYPE_IMM16",
310 { "OPERAND_TYPE_IMM32",
312 { "OPERAND_TYPE_IMM32S",
314 { "OPERAND_TYPE_IMM64",
316 { "OPERAND_TYPE_BASEINDEX",
318 { "OPERAND_TYPE_DISP8",
320 { "OPERAND_TYPE_DISP16",
322 { "OPERAND_TYPE_DISP32",
324 { "OPERAND_TYPE_DISP32S",
326 { "OPERAND_TYPE_DISP64",
328 { "OPERAND_TYPE_INOUTPORTREG",
330 { "OPERAND_TYPE_SHIFTCOUNT",
332 { "OPERAND_TYPE_CONTROL",
334 { "OPERAND_TYPE_TEST",
336 { "OPERAND_TYPE_DEBUG",
338 { "OPERAND_TYPE_FLOATREG",
340 { "OPERAND_TYPE_FLOATACC",
342 { "OPERAND_TYPE_SREG2",
344 { "OPERAND_TYPE_SREG3",
346 { "OPERAND_TYPE_ACC",
348 { "OPERAND_TYPE_JUMPABSOLUTE",
350 { "OPERAND_TYPE_REGMMX",
352 { "OPERAND_TYPE_REGXMM",
354 { "OPERAND_TYPE_REGYMM",
356 { "OPERAND_TYPE_REGZMM",
358 { "OPERAND_TYPE_REGMASK",
360 { "OPERAND_TYPE_ESSEG",
362 { "OPERAND_TYPE_ACC32",
364 { "OPERAND_TYPE_ACC64",
366 { "OPERAND_TYPE_INOUTPORTREG",
368 { "OPERAND_TYPE_REG16_INOUTPORTREG",
369 "Reg16|InOutPortReg" },
370 { "OPERAND_TYPE_DISP16_32",
372 { "OPERAND_TYPE_ANYDISP",
373 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
374 { "OPERAND_TYPE_IMM16_32",
376 { "OPERAND_TYPE_IMM16_32S",
378 { "OPERAND_TYPE_IMM16_32_32S",
379 "Imm16|Imm32|Imm32S" },
380 { "OPERAND_TYPE_IMM32_64",
382 { "OPERAND_TYPE_IMM32_32S_DISP32",
383 "Imm32|Imm32S|Disp32" },
384 { "OPERAND_TYPE_IMM64_DISP64",
386 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
387 "Imm32|Imm32S|Imm64|Disp32" },
388 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
389 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
390 { "OPERAND_TYPE_VEC_IMM4",
392 { "OPERAND_TYPE_REGBND",
394 { "OPERAND_TYPE_VEC_DISP8",
398 typedef struct bitfield
405 #define BITFIELD(n) { n, 0, #n }
407 static bitfield cpu_flags
[] =
415 BITFIELD (CpuClflush
),
417 BITFIELD (CpuSYSCALL
),
422 BITFIELD (CpuFISTTP
),
428 BITFIELD (CpuSSE4_1
),
429 BITFIELD (CpuSSE4_2
),
432 BITFIELD (CpuAVX512F
),
433 BITFIELD (CpuAVX512CD
),
434 BITFIELD (CpuAVX512ER
),
435 BITFIELD (CpuAVX512PF
),
436 BITFIELD (CpuAVX512VL
),
437 BITFIELD (CpuAVX512DQ
),
438 BITFIELD (CpuAVX512BW
),
444 BITFIELD (Cpu3dnowA
),
445 BITFIELD (CpuPadLock
),
451 BITFIELD (CpuXsaveopt
),
453 BITFIELD (CpuPCLMUL
),
464 BITFIELD (CpuRdtscp
),
465 BITFIELD (CpuFSGSBase
),
472 BITFIELD (CpuINVPCID
),
473 BITFIELD (CpuVMFUNC
),
474 BITFIELD (CpuRDSEED
),
476 BITFIELD (CpuPRFCHW
),
480 BITFIELD (CpuClflushOpt
),
481 BITFIELD (CpuXSAVES
),
482 BITFIELD (CpuXSAVEC
),
483 BITFIELD (CpuPREFETCHWT1
),
486 BITFIELD (CpuPCOMMIT
),
490 BITFIELD (CpuAVX512IFMA
),
491 BITFIELD (CpuAVX512VBMI
),
492 BITFIELD (CpuMWAITX
),
493 BITFIELD (CpuCLZERO
),
496 BITFIELD (CpuRegMMX
),
497 BITFIELD (CpuRegXMM
),
498 BITFIELD (CpuRegYMM
),
499 BITFIELD (CpuRegZMM
),
500 BITFIELD (CpuRegMask
),
502 BITFIELD (CpuUnused
),
506 static bitfield opcode_modifiers
[] =
512 BITFIELD (ShortForm
),
514 BITFIELD (JumpDword
),
516 BITFIELD (JumpInterSegment
),
523 BITFIELD (CheckRegSize
),
524 BITFIELD (IgnoreSize
),
525 BITFIELD (DefaultSize
),
534 BITFIELD (BNDPrefixOk
),
535 BITFIELD (IsLockable
),
536 BITFIELD (RegKludge
),
537 BITFIELD (FirstXmm0
),
538 BITFIELD (Implicit1stXmm0
),
539 BITFIELD (RepPrefixOk
),
540 BITFIELD (HLEPrefixOk
),
543 BITFIELD (AddrPrefixOp0
),
552 BITFIELD (VexOpcode
),
553 BITFIELD (VexSources
),
554 BITFIELD (VexImmExt
),
561 BITFIELD (Broadcast
),
562 BITFIELD (StaticRounding
),
564 BITFIELD (Disp8MemShift
),
565 BITFIELD (NoDefMask
),
567 BITFIELD (ATTMnemonic
),
568 BITFIELD (ATTSyntax
),
569 BITFIELD (IntelSyntax
),
574 static bitfield operand_types
[] =
593 BITFIELD (BaseIndex
),
599 BITFIELD (InOutPortReg
),
600 BITFIELD (ShiftCount
),
608 BITFIELD (JumpAbsolute
),
621 BITFIELD (Unspecified
),
625 BITFIELD (Vec_Disp8
),
631 static const char *filename
;
634 compare (const void *x
, const void *y
)
636 const bitfield
*xp
= (const bitfield
*) x
;
637 const bitfield
*yp
= (const bitfield
*) y
;
638 return xp
->position
- yp
->position
;
642 fail (const char *message
, ...)
646 va_start (args
, message
);
647 fprintf (stderr
, _("%s: Error: "), program_name
);
648 vfprintf (stderr
, message
, args
);
654 process_copyright (FILE *fp
)
656 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
657 /* Copyright (C) 2007-2016 Free Software Foundation, Inc.\n\
659 This file is part of the GNU opcodes library.\n\
661 This library is free software; you can redistribute it and/or modify\n\
662 it under the terms of the GNU General Public License as published by\n\
663 the Free Software Foundation; either version 3, or (at your option)\n\
664 any later version.\n\
666 It is distributed in the hope that it will be useful, but WITHOUT\n\
667 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
668 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
669 License for more details.\n\
671 You should have received a copy of the GNU General Public License\n\
672 along with this program; if not, write to the Free Software\n\
673 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
674 MA 02110-1301, USA. */\n");
677 /* Remove leading white spaces. */
680 remove_leading_whitespaces (char *str
)
682 while (ISSPACE (*str
))
687 /* Remove trailing white spaces. */
690 remove_trailing_whitespaces (char *str
)
692 size_t last
= strlen (str
);
700 if (ISSPACE (str
[last
]))
708 /* Find next field separated by SEP and terminate it. Return a
709 pointer to the one after it. */
712 next_field (char *str
, char sep
, char **next
, char *last
)
716 p
= remove_leading_whitespaces (str
);
717 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
720 remove_trailing_whitespaces (p
);
730 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
733 set_bitfield_from_cpu_flag_init (char *f
, bitfield
*array
,
734 int value
, unsigned int size
,
737 char *str
, *next
, *last
;
740 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
741 if (strcmp (cpu_flag_init
[i
].name
, f
) == 0)
743 /* Turn on selective bits. */
744 char *init
= xstrdup (cpu_flag_init
[i
].init
);
745 last
= init
+ strlen (init
);
746 for (next
= init
; next
&& next
< last
; )
748 str
= next_field (next
, '|', &next
, last
);
750 set_bitfield (str
, array
, 1, size
, lineno
);
760 set_bitfield (char *f
, bitfield
*array
, int value
,
761 unsigned int size
, int lineno
)
765 if (strcmp (f
, "CpuFP") == 0)
767 set_bitfield("Cpu387", array
, value
, size
, lineno
);
768 set_bitfield("Cpu287", array
, value
, size
, lineno
);
771 else if (strcmp (f
, "Mmword") == 0)
773 else if (strcmp (f
, "Oword") == 0)
776 for (i
= 0; i
< size
; i
++)
777 if (strcasecmp (array
[i
].name
, f
) == 0)
779 array
[i
].value
= value
;
785 const char *v
= strchr (f
, '=');
792 for (i
= 0; i
< size
; i
++)
793 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
795 value
= strtol (v
+ 1, &end
, 0);
798 array
[i
].value
= value
;
806 /* Handle CPU_XXX_FLAGS. */
807 if (!set_bitfield_from_cpu_flag_init (f
, array
, value
, size
, lineno
))
811 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
813 fail (_("Unknown bitfield: %s\n"), f
);
817 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
818 int macro
, const char *comma
, const char *indent
)
822 fprintf (table
, "%s{ { ", indent
);
824 for (i
= 0; i
< size
- 1; i
++)
826 if (((i
+ 1) % 20) != 0)
827 fprintf (table
, "%d, ", flags
[i
].value
);
829 fprintf (table
, "%d,", flags
[i
].value
);
830 if (((i
+ 1) % 20) == 0)
832 /* We need \\ for macro. */
834 fprintf (table
, " \\\n %s", indent
);
836 fprintf (table
, "\n %s", indent
);
840 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
844 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
845 const char *comma
, const char *indent
,
848 char *str
, *next
, *last
;
850 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
852 /* Copy the default cpu flags. */
853 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
855 if (strcasecmp (flag
, "unknown") == 0)
857 /* We turn on everything except for cpu64 in case of
858 CPU_UNKNOWN_FLAGS. */
859 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
860 if (flags
[i
].position
!= Cpu64
)
863 else if (flag
[0] == '~')
865 last
= flag
+ strlen (flag
);
872 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
879 /* First we turn on everything except for cpu64. */
880 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
881 if (flags
[i
].position
!= Cpu64
)
884 /* Turn off selective bits. */
885 for (; next
&& next
< last
; )
887 str
= next_field (next
, '|', &next
, last
);
889 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
892 else if (strcmp (flag
, "0"))
894 /* Turn on selective bits. */
895 last
= flag
+ strlen (flag
);
896 for (next
= flag
; next
&& next
< last
; )
898 str
= next_field (next
, '|', &next
, last
);
900 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
904 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
909 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
913 fprintf (table
, " { ");
915 for (i
= 0; i
< size
- 1; i
++)
917 if (((i
+ 1) % 20) != 0)
918 fprintf (table
, "%d, ", modifier
[i
].value
);
920 fprintf (table
, "%d,", modifier
[i
].value
);
921 if (((i
+ 1) % 20) == 0)
922 fprintf (table
, "\n ");
925 fprintf (table
, "%d },\n", modifier
[i
].value
);
929 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
931 char *str
, *next
, *last
;
932 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
934 /* Copy the default opcode modifier. */
935 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
937 if (strcmp (mod
, "0"))
939 last
= mod
+ strlen (mod
);
940 for (next
= mod
; next
&& next
< last
; )
942 str
= next_field (next
, '|', &next
, last
);
944 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
948 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
952 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
953 int macro
, const char *indent
)
957 fprintf (table
, "{ { ");
959 for (i
= 0; i
< size
- 1; i
++)
961 if (((i
+ 1) % 20) != 0)
962 fprintf (table
, "%d, ", types
[i
].value
);
964 fprintf (table
, "%d,", types
[i
].value
);
965 if (((i
+ 1) % 20) == 0)
967 /* We need \\ for macro. */
969 fprintf (table
, " \\\n%s", indent
);
971 fprintf (table
, "\n%s", indent
);
975 fprintf (table
, "%d } }", types
[i
].value
);
979 process_i386_operand_type (FILE *table
, char *op
, int macro
,
980 const char *indent
, int lineno
)
982 char *str
, *next
, *last
;
983 bitfield types
[ARRAY_SIZE (operand_types
)];
985 /* Copy the default operand type. */
986 memcpy (types
, operand_types
, sizeof (types
));
988 if (strcmp (op
, "0"))
990 last
= op
+ strlen (op
);
991 for (next
= op
; next
&& next
< last
; )
993 str
= next_field (next
, '|', &next
, last
);
995 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
998 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
1003 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1004 char *last
, int lineno
)
1007 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
1008 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1010 /* Find number of operands. */
1011 operands
= next_field (str
, ',', &str
, last
);
1013 /* Find base_opcode. */
1014 base_opcode
= next_field (str
, ',', &str
, last
);
1016 /* Find extension_opcode. */
1017 extension_opcode
= next_field (str
, ',', &str
, last
);
1019 /* Find opcode_length. */
1020 opcode_length
= next_field (str
, ',', &str
, last
);
1022 /* Find cpu_flags. */
1023 cpu_flags
= next_field (str
, ',', &str
, last
);
1025 /* Find opcode_modifier. */
1026 opcode_modifier
= next_field (str
, ',', &str
, last
);
1028 /* Remove the first {. */
1029 str
= remove_leading_whitespaces (str
);
1032 str
= remove_leading_whitespaces (str
+ 1);
1036 /* There are at least "X}". */
1040 /* Remove trailing white spaces and }. */
1044 if (ISSPACE (str
[i
]) || str
[i
] == '}')
1053 /* Find operand_types. */
1054 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1058 operand_types
[i
] = NULL
;
1062 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1063 if (*operand_types
[i
] == '0')
1066 operand_types
[i
] = NULL
;
1071 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
1072 name
, operands
, base_opcode
, extension_opcode
,
1075 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
1077 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
1079 fprintf (table
, " { ");
1081 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1083 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
1086 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
1091 fprintf (table
, ",\n ");
1093 process_i386_operand_type (table
, operand_types
[i
], 0,
1096 fprintf (table
, " } },\n");
1099 struct opcode_hash_entry
1101 struct opcode_hash_entry
*next
;
1107 /* Calculate the hash value of an opcode hash entry P. */
1110 opcode_hash_hash (const void *p
)
1112 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1113 return htab_hash_string (entry
->name
);
1116 /* Compare a string Q against an opcode hash entry P. */
1119 opcode_hash_eq (const void *p
, const void *q
)
1121 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1122 const char *name
= (const char *) q
;
1123 return strcmp (name
, entry
->name
) == 0;
1127 process_i386_opcodes (FILE *table
)
1132 char *str
, *p
, *last
, *name
;
1133 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
1134 htab_t opcode_hash_table
;
1135 struct opcode_hash_entry
**opcode_array
;
1136 unsigned int opcode_array_size
= 1024;
1139 filename
= "i386-opc.tbl";
1140 fp
= fopen (filename
, "r");
1143 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1147 opcode_array
= (struct opcode_hash_entry
**)
1148 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
1150 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1151 opcode_hash_eq
, NULL
,
1154 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1155 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
1157 /* Put everything on opcode array. */
1160 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1165 p
= remove_leading_whitespaces (buf
);
1167 /* Skip comments. */
1168 str
= strstr (p
, "//");
1172 /* Remove trailing white spaces. */
1173 remove_trailing_whitespaces (p
);
1178 /* Ignore comments. */
1186 last
= p
+ strlen (p
);
1189 name
= next_field (p
, ',', &str
, last
);
1191 /* Get the slot in hash table. */
1192 hash_slot
= (struct opcode_hash_entry
**)
1193 htab_find_slot_with_hash (opcode_hash_table
, name
,
1194 htab_hash_string (name
),
1197 if (*hash_slot
== NULL
)
1199 /* It is the new one. Put it on opcode array. */
1200 if (i
>= opcode_array_size
)
1202 /* Grow the opcode array when needed. */
1203 opcode_array_size
+= 1024;
1204 opcode_array
= (struct opcode_hash_entry
**)
1205 xrealloc (opcode_array
,
1206 sizeof (*opcode_array
) * opcode_array_size
);
1209 opcode_array
[i
] = (struct opcode_hash_entry
*)
1210 xmalloc (sizeof (struct opcode_hash_entry
));
1211 opcode_array
[i
]->next
= NULL
;
1212 opcode_array
[i
]->name
= xstrdup (name
);
1213 opcode_array
[i
]->opcode
= xstrdup (str
);
1214 opcode_array
[i
]->lineno
= lineno
;
1215 *hash_slot
= opcode_array
[i
];
1220 /* Append it to the existing one. */
1222 while ((*entry
) != NULL
)
1223 entry
= &(*entry
)->next
;
1224 *entry
= (struct opcode_hash_entry
*)
1225 xmalloc (sizeof (struct opcode_hash_entry
));
1226 (*entry
)->next
= NULL
;
1227 (*entry
)->name
= (*hash_slot
)->name
;
1228 (*entry
)->opcode
= xstrdup (str
);
1229 (*entry
)->lineno
= lineno
;
1233 /* Process opcode array. */
1234 for (j
= 0; j
< i
; j
++)
1236 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1240 lineno
= next
->lineno
;
1241 last
= str
+ strlen (str
);
1242 output_i386_opcode (table
, name
, str
, last
, lineno
);
1248 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1250 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1252 process_i386_opcode_modifier (table
, "0", -1);
1254 fprintf (table
, " { ");
1255 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1256 fprintf (table
, " } }\n");
1258 fprintf (table
, "};\n");
1262 process_i386_registers (FILE *table
)
1266 char *str
, *p
, *last
;
1267 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1268 char *dw2_32_num
, *dw2_64_num
;
1271 filename
= "i386-reg.tbl";
1272 fp
= fopen (filename
, "r");
1274 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1277 fprintf (table
, "\n/* i386 register table. */\n\n");
1278 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1282 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1287 p
= remove_leading_whitespaces (buf
);
1289 /* Skip comments. */
1290 str
= strstr (p
, "//");
1294 /* Remove trailing white spaces. */
1295 remove_trailing_whitespaces (p
);
1300 fprintf (table
, "%s\n", p
);
1308 last
= p
+ strlen (p
);
1310 /* Find reg_name. */
1311 reg_name
= next_field (p
, ',', &str
, last
);
1313 /* Find reg_type. */
1314 reg_type
= next_field (str
, ',', &str
, last
);
1316 /* Find reg_flags. */
1317 reg_flags
= next_field (str
, ',', &str
, last
);
1320 reg_num
= next_field (str
, ',', &str
, last
);
1322 fprintf (table
, " { \"%s\",\n ", reg_name
);
1324 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1326 /* Find 32-bit Dwarf2 register number. */
1327 dw2_32_num
= next_field (str
, ',', &str
, last
);
1329 /* Find 64-bit Dwarf2 register number. */
1330 dw2_64_num
= next_field (str
, ',', &str
, last
);
1332 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1333 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1338 fprintf (table
, "};\n");
1340 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1344 process_i386_initializers (void)
1347 FILE *fp
= fopen ("i386-init.h", "w");
1351 fail (_("can't create i386-init.h, errno = %s\n"),
1354 process_copyright (fp
);
1356 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1358 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1359 init
= xstrdup (cpu_flag_init
[i
].init
);
1360 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1364 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1366 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1367 init
= xstrdup (operand_type_init
[i
].init
);
1368 process_i386_operand_type (fp
, init
, 1, " ", -1);
1376 /* Program options. */
1377 #define OPTION_SRCDIR 200
1379 struct option long_options
[] =
1381 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1382 {"debug", no_argument
, NULL
, 'd'},
1383 {"version", no_argument
, NULL
, 'V'},
1384 {"help", no_argument
, NULL
, 'h'},
1385 {0, no_argument
, NULL
, 0}
1389 print_version (void)
1391 printf ("%s: version 1.0\n", program_name
);
1396 usage (FILE * stream
, int status
)
1398 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1404 main (int argc
, char **argv
)
1406 extern int chdir (char *);
1407 char *srcdir
= NULL
;
1409 unsigned int i
, cpumax
;
1412 program_name
= *argv
;
1413 xmalloc_set_program_name (program_name
);
1415 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1440 if (chdir (srcdir
) != 0)
1441 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1442 srcdir
, xstrerror (errno
));
1444 /* cpu_flags isn't sorted by position. */
1446 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
1447 if (cpu_flags
[i
].position
> cpumax
)
1448 cpumax
= cpu_flags
[i
].position
;
1450 /* Check the unused bitfield in i386_cpu_flags. */
1452 if ((cpumax
- 1) != CpuMax
)
1453 fail (_("CpuMax != %d!\n"), cpumax
);
1455 if (cpumax
!= CpuMax
)
1456 fail (_("CpuMax != %d!\n"), cpumax
);
1458 c
= CpuNumOfBits
- CpuMax
- 1;
1460 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1463 /* Check the unused bitfield in i386_operand_type. */
1465 c
= OTNumOfBits
- OTMax
- 1;
1467 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1470 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1473 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1474 sizeof (opcode_modifiers
[0]), compare
);
1476 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1477 sizeof (operand_types
[0]), compare
);
1479 table
= fopen ("i386-tbl.h", "w");
1481 fail (_("can't create i386-tbl.h, errno = %s\n"),
1484 process_copyright (table
);
1486 process_i386_opcodes (table
);
1487 process_i386_registers (table
);
1488 process_i386_initializers ();