1 /* Copyright (C) 2007-2024 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. */
25 #include "libiberty.h"
27 #include "safe-ctype.h"
31 /* Build-time checks are preferrable over runtime ones. Use this construct
32 in preference where possible. */
33 #define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
35 static const char *program_name
= NULL
;
38 typedef struct dependency
41 /* Note: Only direct dependencies should be enumerated. */
45 static const dependency isa_dependencies
[] =
52 "PENTIUMPRO|Clflush|SYSCALL|MMX|SSE2|LM" },
64 "GENERIC64|FISTTP|SSE3|MONITOR|CX16" },
66 "P4|FISTTP|SSE3|MONITOR" },
70 "CORE2|SSE4_2|Rdtscp|LAHF_SAHF" },
72 "186|286|386|486|586|SYSCALL|387|MMX" },
76 "K6_2|686:min|687|Nop|3dnowA" },
78 "ATHLON|Rdtscp|SSE2|LM" },
80 "K8|FISTTP|SSE4A|ABM|MONITOR" },
82 "GENERIC64|FISTTP|Rdtscp|MONITOR|CX16|LAHF_SAHF|XOP|ABM|LWP|SVME|AES|PCLMULQDQ|PRFCHW" },
84 "BDVER1|FMA|BMI|TBM|F16C" },
86 "BDVER2|Xsaveopt|FSGSBase" },
88 "BDVER3|AVX2|Movbe|BMI2|RdRnd|MWAITX" },
90 "GENERIC64|FISTTP|Rdtscp|MONITOR|CX16|LAHF_SAHF|AVX2|SSE4A|ABM|SVME|AES|PCLMULQDQ|PRFCHW|FMA|BMI|F16C|Xsaveopt|FSGSBase|Movbe|BMI2|RdRnd|ADX|RdSeed|SMAP|SHA|XSAVEC|XSAVES|ClflushOpt|CLZERO|MWAITX" },
92 "ZNVER1|CLWB|RDPID|RDPRU|MCOMMIT|WBNOINVD" },
94 "ZNVER2|INVLPGB|TLBSYNC|VAES|VPCLMULQDQ|INVPCID|SNP|OSPKE" },
96 "ZNVER3|AVX512F|AVX512DQ|AVX512IFMA|AVX512CD|AVX512BW|AVX512VL|AVX512_BF16|AVX512VBMI|AVX512_VBMI2|AVX512_VNNI|AVX512_BITALG|AVX512_VPOPCNTDQ|GFNI|RMPQUERY" },
98 "ZNVER4|AVX_VNNI|MOVDIRI|MOVDIR64B|AVX512_VP2INTERSECT|PREFETCHI" },
100 "GENERIC64|FISTTP|MONITOR|CX16|LAHF_SAHF|Rdtscp|SSSE3|SSE4A|ABM|PRFCHW|Clflush|FISTTP|SVME" },
102 "BTVER1|AVX|BMI|F16C|AES|PCLMULQDQ|Movbe|Xsaveopt|PRFCHW" },
114 "586|687|CMOV|FXSR" },
199 { "AVX512_VPOPCNTDQ",
207 { "AVX512_VP2INTERSECT",
242 "AVX512VL|AVX512DQ|AVX512CD|AVX512VBMI|AVX512_VBMI2|AVX512IFMA"
243 "|AVX512_VNNI|AVX512_BF16|AVX512_FP16|AVX512_VPOPCNTDQ|AVX512_BITALG" },
284 /* This array is populated as process_i386_initializers() walks cpu_flags[]. */
285 static unsigned char isa_reverse_deps
[CpuMax
][CpuMax
];
287 typedef struct bitfield
294 #define BITFIELD(n) { Cpu##n, 0, #n }
296 static bitfield cpu_flags
[] =
341 BITFIELD (PCLMULQDQ
),
350 BITFIELD (LAHF_SAHF
),
372 BITFIELD (ClflushOpt
),
375 BITFIELD (PREFETCHWT1
),
379 BITFIELD (AVX512IFMA
),
380 BITFIELD (AVX512VBMI
),
381 BITFIELD (AVX512_4FMAPS
),
382 BITFIELD (AVX512_4VNNIW
),
383 BITFIELD (AVX512_VPOPCNTDQ
),
384 BITFIELD (AVX512_VBMI2
),
385 BITFIELD (AVX512_VNNI
),
386 BITFIELD (AVX512_BITALG
),
387 BITFIELD (AVX512_BF16
),
388 BITFIELD (AVX512_VP2INTERSECT
),
391 BITFIELD (AVX512_FP16
),
392 BITFIELD (PREFETCHI
),
394 BITFIELD (AVX_VNNI_INT8
),
395 BITFIELD (AVX_VNNI_INT16
),
396 BITFIELD (CMPCCXADD
),
399 BITFIELD (AVX_NE_CONVERT
),
414 BITFIELD (VPCLMULQDQ
),
424 BITFIELD (AMX_COMPLEX
),
427 BITFIELD (MOVDIR64B
),
429 BITFIELD (SERIALIZE
),
449 #define BITFIELD(n) { n, 0, #n }
451 static bitfield opcode_modifiers
[] =
460 BITFIELD (CheckOperandSize
),
461 BITFIELD (OperandConstraint
),
462 BITFIELD (MnemonicSize
),
471 BITFIELD (BNDPrefixOk
),
479 BITFIELD (OpcodePrefix
),
484 BITFIELD (Broadcast
),
485 BITFIELD (StaticRounding
),
487 BITFIELD (Disp8MemShift
),
496 #define CLASS(n) #n, n
498 static const struct {
500 enum operand_class value
;
501 } operand_classes
[] = {
515 #define INSTANCE(n) #n, n
517 static const struct {
519 enum operand_instance value
;
520 } operand_instances
[] = {
529 static bitfield operand_types
[] =
538 BITFIELD (BaseIndex
),
553 BITFIELD (Unspecified
),
559 static const char *filename
;
560 static i386_cpu_flags active_cpu_flags
;
561 static int active_isstring
;
563 struct template_arg
{
564 const struct template_arg
*next
;
568 struct template_instance
{
569 const struct template_instance
*next
;
571 const struct template_arg
*args
;
574 struct template_param
{
575 const struct template_param
*next
;
580 struct template *next
;
582 const struct template_instance
*instances
;
583 const struct template_param
*params
;
586 static struct template *templates
;
589 compare (const void *x
, const void *y
)
591 const bitfield
*xp
= (const bitfield
*) x
;
592 const bitfield
*yp
= (const bitfield
*) y
;
593 return xp
->position
- yp
->position
;
597 fail (const char *message
, ...)
601 va_start (args
, message
);
602 fprintf (stderr
, "%s: error: ", program_name
);
603 vfprintf (stderr
, message
, args
);
609 process_copyright (FILE *fp
)
611 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
612 /* Copyright (C) 2007-2024 Free Software Foundation, Inc.\n\
614 This file is part of the GNU opcodes library.\n\
616 This library is free software; you can redistribute it and/or modify\n\
617 it under the terms of the GNU General Public License as published by\n\
618 the Free Software Foundation; either version 3, or (at your option)\n\
619 any later version.\n\
621 It is distributed in the hope that it will be useful, but WITHOUT\n\
622 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
623 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
624 License for more details.\n\
626 You should have received a copy of the GNU General Public License\n\
627 along with this program; if not, write to the Free Software\n\
628 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
629 MA 02110-1301, USA. */\n");
632 /* Remove leading white spaces. */
635 remove_leading_whitespaces (char *str
)
637 while (ISSPACE (*str
))
642 /* Remove trailing white spaces. */
645 remove_trailing_whitespaces (char *str
)
647 size_t last
= strlen (str
);
655 if (ISSPACE (str
[last
]))
663 /* Find next field separated by SEP and terminate it. Return a
664 pointer to the one after it. */
667 next_field (char *str
, char sep
, char **next
, char *last
)
671 p
= remove_leading_whitespaces (str
);
672 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
675 remove_trailing_whitespaces (p
);
685 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
688 set_bitfield (char *f
, bitfield
*array
, int value
,
689 unsigned int size
, int lineno
)
693 /* Ignore empty fields; they may result from template expansions. */
697 for (i
= 0; i
< size
; i
++)
698 if (strcasecmp (array
[i
].name
, f
) == 0)
700 array
[i
].value
= value
;
706 const char *v
= strchr (f
, '=');
713 for (i
= 0; i
< size
; i
++)
714 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
716 value
= strtol (v
+ 1, &end
, 0);
719 array
[i
].value
= value
;
728 fail ("%s: %d: unknown bitfield: %s\n", filename
, lineno
, f
);
730 fail ("unknown bitfield: %s\n", f
);
734 add_isa_dependencies (bitfield
*flags
, const char *f
, int value
,
735 unsigned int reverse
)
741 bool is_isa
= false, orig_is_avx
= is_avx
;
743 /* Need to find base entry for references to auxiliary ones. */
747 *strchr (str
, ':') = '\0';
750 /* isa_dependencies[] prefers "LM" over "64". */
751 else if (!strcmp (f
, "LM"))
753 for (i
= 0; i
< CpuMax
; ++i
)
754 if (strcasecmp (flags
[i
].name
, isa
) == 0)
756 flags
[i
].value
= value
;
757 if (reverse
< ARRAY_SIZE (isa_reverse_deps
[0])
758 /* Don't record the feature itself here. */
760 /* Don't record base architectures. */
762 isa_reverse_deps
[i
][reverse
] = 1;
764 if (i
== CpuAVX
|| i
== CpuXOP
|| i
== CpuVAES
|| i
== CpuVPCLMULQDQ
)
770 /* Do not turn off dependencies. */
771 if (is_isa
&& !value
)
773 is_avx
= orig_is_avx
;
777 for (i
= 0; i
< ARRAY_SIZE (isa_dependencies
); ++i
)
778 if (strcasecmp (isa_dependencies
[i
].name
, f
) == 0)
780 char *deps
= xstrdup (isa_dependencies
[i
].deps
);
782 char *last
= deps
+ strlen (deps
);
784 for (; next
&& next
< last
; )
786 char *str
= next_field (next
, '|', &next
, last
);
788 /* No AVX/XOP -> SSE reverse dependencies. */
789 if (is_avx
&& strncmp (str
, "SSE", 3) == 0)
790 add_isa_dependencies (flags
, str
, value
, CpuMax
);
792 add_isa_dependencies (flags
, str
, value
, reverse
);
796 /* ISA extensions with dependencies need CPU_ANY_*_FLAGS emitted,
797 unless the sole dependency is the "64-bit mode only" one. */
798 if (reverse
< ARRAY_SIZE (isa_reverse_deps
[0])
799 && strcmp (isa_dependencies
[i
].deps
, "64"))
800 isa_reverse_deps
[reverse
][reverse
] = 1;
802 is_avx
= orig_is_avx
;
807 fail ("unknown bitfield: %s\n", f
);
809 is_avx
= orig_is_avx
;
813 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
814 int mode
, const char *comma
, const char *indent
, int lineno
)
816 unsigned int i
= 0, j
= 0;
819 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
821 fprintf (table
, "%s{ { ", indent
);
825 for (j
= ~0u; i
< CpuAttrEnums
; i
++)
831 fail ("%s: %d: invalid combination of CPU identifiers\n",
835 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
838 /* Write 0 to indicate "no associated flag". */
839 fprintf (table
, "%u, ", j
+ 1);
844 for (; i
< size
- 1; i
++, j
++)
846 if (((j
+ 1) % 20) != 0)
847 fprintf (table
, "%d, ", flags
[i
].value
);
849 fprintf (table
, "%d,", flags
[i
].value
);
850 if (((j
+ 1) % 20) == 0)
852 /* We need \\ for macro. */
854 fprintf (table
, " \\\n %s", indent
);
856 fprintf (table
, "\n %s", indent
);
858 if (mode
< 0 && flags
[i
].value
)
859 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
862 #if defined(CpuAttrUnused) != defined(CpuUnused)
865 fprintf (table
, " } }%s\n", comma
);
867 fprintf (table
, "%d, 0 } }%s\n", flags
[i
].value
, comma
);
871 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
875 process_i386_cpu_flag (FILE *table
, char *flag
,
877 const char *comma
, const char *indent
,
878 int lineno
, unsigned int reverse
)
880 char *str
, *next
= flag
, *last
;
884 bitfield all
[ARRAY_SIZE (cpu_flags
)];
885 bitfield any
[ARRAY_SIZE (cpu_flags
)];
887 /* Copy the default cpu flags. */
888 memcpy (all
, cpu_flags
, sizeof (cpu_flags
));
889 memcpy (any
, cpu_flags
, sizeof (cpu_flags
));
893 for (i
= 0; i
< ARRAY_SIZE (isa_reverse_deps
[0]); ++i
)
894 any
[i
].value
= isa_reverse_deps
[reverse
][i
];
900 last
= flag
+ strlen (flag
);
907 fail ("%s: %d: missing `)' in bitfield: %s\n", filename
,
914 /* First we turn on everything except for cpuno64 and - if
915 present - the padding field. */
916 for (i
= 0; i
< ARRAY_SIZE (any
); i
++)
917 if (any
[i
].position
< CpuNo64
)
920 /* Turn off selective bits. */
924 if (name
!= NULL
&& value
!= 0)
926 for (i
= 0; i
< ARRAY_SIZE (any
); i
++)
927 if (strcasecmp (any
[i
].name
, name
) == 0)
929 add_isa_dependencies (any
, name
, 1, reverse
);
935 if (strcmp (flag
, "0"))
937 bool combined
= false;
942 /* Turn on/off selective bits. */
943 last
= flag
+ strlen (flag
);
944 if (name
== NULL
&& strchr (flag
, '&'))
946 for (; next
< last
&& *next
!= '('; )
948 str
= next_field (next
, '&', &next
, last
);
949 set_bitfield (str
, all
, value
, ARRAY_SIZE (all
), lineno
);
954 fail ("%s: %d: missing `)' in bitfield: %s\n", filename
,
961 for (; next
&& next
< last
; )
963 str
= next_field (next
, '|', &next
, last
);
965 add_isa_dependencies (any
, str
, value
, reverse
);
966 else if (combined
|| next
< last
)
967 set_bitfield (str
, any
, value
, ARRAY_SIZE (any
), lineno
);
968 else /* Singular specifiers go into "all". */
969 set_bitfield (str
, all
, value
, ARRAY_SIZE (all
), lineno
);
977 size_t len
= strlen (name
);
978 char *upper
= xmalloc (len
+ 1);
980 /* Cpu64 is special: It specifies a mode dependency, not an ISA one. Zap
981 the flag from ISA initializer macros (and from CPU_ANY_64_FLAGS
982 itself we only care about tracking its dependents. Also don't emit the
983 (otherwise all zero) CPU_64_FLAGS. */
984 if (flag
!= NULL
&& reverse
== Cpu64
)
986 if (is_isa
|| flag
== NULL
)
987 any
[Cpu64
].value
= 0;
989 for (i
= 0; i
< len
; ++i
)
991 /* Don't emit #define-s for auxiliary entries. */
994 upper
[i
] = TOUPPER (name
[i
]);
997 fprintf (table
, "\n#define CPU_%s%s_FLAGS \\\n",
998 flag
!= NULL
? "": "ANY_", upper
);
1003 /* Synthesize "64-bit mode only" dependencies from the dependencies we
1004 have accumulated. */
1005 for (i
= 0; i
< ARRAY_SIZE (isa_reverse_deps
[0]); ++i
)
1006 if (all
[i
].value
&& isa_reverse_deps
[Cpu64
][i
])
1007 all
[Cpu64
].value
= 1;
1009 output_cpu_flags(table
, all
, ARRAY_SIZE (all
), -1, comma
, indent
, lineno
);
1012 output_cpu_flags (table
, any
, ARRAY_SIZE (any
), name
!= NULL
,
1013 comma
, indent
, lineno
);
1017 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1021 fprintf (table
, " { ");
1023 for (i
= 0; i
< size
- 1; i
++)
1025 if (((i
+ 1) % 20) != 0)
1026 fprintf (table
, "%d, ", modifier
[i
].value
);
1028 fprintf (table
, "%d,", modifier
[i
].value
);
1029 if (((i
+ 1) % 20) == 0)
1030 fprintf (table
, "\n ");
1033 fprintf (table
, "%d },\n", modifier
[i
].value
);
1036 /* Returns LOG2 of element size. */
1038 get_element_size (char **opnd
, int lineno
)
1040 char *str
, *next
, *last
, *op
;
1041 const char *full
= opnd
[0];
1042 int elem_size
= INT_MAX
;
1044 /* Find the memory operand. */
1045 while (full
!= NULL
&& strstr(full
, "BaseIndex") == NULL
)
1048 fail ("%s: %d: no memory operand\n", filename
, lineno
);
1050 op
= xstrdup (full
);
1051 last
= op
+ strlen (op
);
1052 for (next
= op
; next
&& next
< last
; )
1054 str
= next_field (next
, '|', &next
, last
);
1057 if (strcasecmp(str
, "Byte") == 0)
1059 /* The smallest element size, no need to check
1064 else if (strcasecmp(str
, "Word") == 0)
1069 else if (strcasecmp(str
, "Dword") == 0)
1074 else if (strcasecmp(str
, "Qword") == 0)
1083 if (elem_size
== INT_MAX
)
1084 fail ("%s: %d: unknown element size: %s\n", filename
, lineno
, full
);
1090 rex2_disallowed (const unsigned long long opcode
, unsigned int length
,
1091 unsigned int space
, const char *cpu_flags
)
1093 /* Some opcodes encode a ModR/M-like byte directly in the opcode. */
1094 unsigned int base_opcode
= opcode
>> (8 * length
- 8);
1096 /* All opcodes listed map0 0x4*, 0x7*, 0xa*, 0xe* and map1 0x3*, 0x8*
1097 are reserved under REX2 and triggers #UD when prefixed with REX2 */
1099 switch (base_opcode
>> 4)
1110 if (space
== SPACE_0F
)
1111 switch (base_opcode
>> 4)
1124 process_i386_opcode_modifier (FILE *table
, char *mod
, unsigned int space
,
1125 unsigned int prefix
, const char *extension_opcode
,
1126 char **opnd
, int lineno
, bool rex2_disallowed
)
1128 char *str
, *next
, *last
;
1129 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1130 static const char *const spaces
[] = {
1131 #define SPACE(n) [SPACE_##n] = #n
1146 active_isstring
= 0;
1148 /* Copy the default opcode modifier. */
1149 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1151 if (strcmp (mod
, "0"))
1153 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1155 last
= mod
+ strlen (mod
);
1156 for (next
= mod
; next
&& next
< last
; )
1158 str
= next_field (next
, '|', &next
, last
);
1163 if (strncmp(str
, "OpcodeSpace", 11) == 0)
1168 fail ("%s:%d: Missing value for `OpcodeSpace'\n",
1171 val
= strtol (str
+ 12, &end
, 0);
1173 fail ("%s:%d: Bogus value `%s' for `OpcodeSpace'\n",
1174 filename
, lineno
, end
);
1179 fail ("%s:%d: Conflicting opcode space specifications\n",
1182 "%s:%d: Warning: redundant opcode space specification\n",
1190 if (strcasecmp(str
, "Broadcast") == 0)
1191 val
= get_element_size (opnd
, lineno
) + BYTE_BROADCAST
;
1192 else if (strcasecmp(str
, "Disp8MemShift") == 0)
1193 val
= get_element_size (opnd
, lineno
);
1195 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1197 if (strcasecmp(str
, "IsString") == 0)
1198 active_isstring
= 1;
1200 if (strcasecmp(str
, "W") == 0)
1203 if (strcasecmp(str
, "No_bSuf") == 0)
1205 if (strcasecmp(str
, "No_wSuf") == 0)
1207 if (strcasecmp(str
, "No_lSuf") == 0)
1209 if (strcasecmp(str
, "No_qSuf") == 0)
1216 if (!modifiers
[OpcodePrefix
].value
)
1217 modifiers
[OpcodePrefix
].value
= prefix
;
1218 else if (modifiers
[OpcodePrefix
].value
!= prefix
)
1219 fail ("%s:%d: Conflicting prefix specifications\n",
1223 "%s:%d: Warning: redundant prefix specification\n",
1227 if (have_w
&& !bwlq_suf
)
1228 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1229 if (have_w
&& !(bwlq_suf
& 1))
1230 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1232 if (have_w
&& !(bwlq_suf
& ~1))
1234 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1238 if (space
>= ARRAY_SIZE (spaces
) || !spaces
[space
])
1239 fail ("%s:%d: Unknown opcode space %u\n", filename
, lineno
, space
);
1241 fprintf (table
, " SPACE_%s, %s,\n",
1242 spaces
[space
], extension_opcode
? extension_opcode
: "None");
1244 /* Rather than evaluating multiple conditions at runtime to determine
1245 whether an EVEX encoding is being dealt with, derive that information
1246 right here. A missing EVex attribute means "dynamic". */
1247 if (!modifiers
[EVex
].value
1248 && (modifiers
[Disp8MemShift
].value
1249 || modifiers
[Broadcast
].value
1250 || modifiers
[Masking
].value
1251 || modifiers
[SAE
].value
))
1252 modifiers
[EVex
].value
= EVEXDYN
;
1254 /* Vex, legacy map2 and map3 and rex2_disallowed do not support EGPR.
1255 For templates supporting both Vex and EVex allowing EGPR. */
1256 if ((modifiers
[Vex
].value
|| space
> SPACE_0F
|| rex2_disallowed
)
1257 && !modifiers
[EVex
].value
)
1258 modifiers
[NoEgpr
].value
= 1;
1260 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1270 output_operand_type (FILE *table
, enum operand_class
class,
1271 enum operand_instance instance
,
1272 const bitfield
*types
, unsigned int size
,
1273 enum stage stage
, const char *indent
)
1277 fprintf (table
, "{ { %d, %d, ", class, instance
);
1279 for (i
= 0; i
< size
- 1; i
++)
1281 if (((i
+ 3) % 20) != 0)
1282 fprintf (table
, "%d, ", types
[i
].value
);
1284 fprintf (table
, "%d,", types
[i
].value
);
1285 if (((i
+ 3) % 20) == 0)
1287 /* We need \\ for macro. */
1288 if (stage
== stage_macros
)
1289 fprintf (table
, " \\\n%s", indent
);
1291 fprintf (table
, "\n%s", indent
);
1295 fprintf (table
, "%d } }", types
[i
].value
);
1299 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1300 const char *indent
, int lineno
)
1302 char *str
, *next
, *last
;
1303 enum operand_class
class = ClassNone
;
1304 enum operand_instance instance
= InstanceNone
;
1305 bitfield types
[ARRAY_SIZE (operand_types
)];
1307 /* Copy the default operand type. */
1308 memcpy (types
, operand_types
, sizeof (types
));
1310 if (strcmp (op
, "0"))
1314 last
= op
+ strlen (op
);
1315 for (next
= op
; next
&& next
< last
; )
1317 str
= next_field (next
, '|', &next
, last
);
1322 if (!strncmp(str
, "Class=", 6))
1324 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1325 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1327 class = operand_classes
[i
].value
;
1333 if (str
&& !strncmp(str
, "Instance=", 9))
1335 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1336 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1338 instance
= operand_instances
[i
].value
;
1346 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1347 if (strcasecmp(str
, "BaseIndex") == 0)
1352 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1354 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1355 if (!active_cpu_flags
.bitfield
.cpu64
1356 && !active_cpu_flags
.bitfield
.cpumpx
)
1357 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1358 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1361 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1365 static char *mkident (const char *mnem
)
1367 char *ident
= xstrdup (mnem
), *p
= ident
;
1380 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1381 char *last
, int lineno
)
1383 unsigned int i
, length
, prefix
= 0, space
= 0;
1384 char *base_opcode
, *extension_opcode
, *end
, *ident
;
1385 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1386 unsigned long long opcode
;
1388 /* Find base_opcode. */
1389 base_opcode
= next_field (str
, ',', &str
, last
);
1391 /* Find extension_opcode, if any. */
1392 extension_opcode
= strchr (base_opcode
, '/');
1393 if (extension_opcode
)
1394 *extension_opcode
++ = '\0';
1396 /* Find cpu_flags. */
1397 cpu_flags
= next_field (str
, ',', &str
, last
);
1399 /* Find opcode_modifier. */
1400 opcode_modifier
= next_field (str
, ',', &str
, last
);
1402 /* Remove the first {. */
1403 str
= remove_leading_whitespaces (str
);
1406 str
= remove_leading_whitespaces (str
+ 1);
1407 remove_trailing_whitespaces (str
);
1409 /* Remove } and trailing white space. */
1411 if (!i
|| str
[i
- 1] != '}')
1414 remove_trailing_whitespaces (str
);
1417 operand_types
[i
= 0] = NULL
;
1420 last
= str
+ strlen (str
);
1422 /* Find operand_types. */
1423 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1427 operand_types
[i
] = NULL
;
1431 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1435 opcode
= strtoull (base_opcode
, &end
, 0);
1437 /* Determine opcode length. */
1438 for (length
= 1; length
< 8; ++length
)
1439 if (!(opcode
>> (8 * length
)))
1442 /* Transform prefixes encoded in the opcode into opcode modifier
1446 switch (opcode
>> (8 * length
- 8))
1448 case 0x66: prefix
= PREFIX_0X66
; break;
1449 case 0xF3: prefix
= PREFIX_0XF3
; break;
1450 case 0xF2: prefix
= PREFIX_0XF2
; break;
1454 opcode
&= (1ULL << (8 * --length
)) - 1;
1457 /* Transform opcode space encoded in the opcode into opcode modifier
1459 if (length
> 1 && (opcode
>> (8 * length
- 8)) == 0xf)
1461 switch ((opcode
>> (8 * length
- 16)) & 0xff)
1463 default: space
= SPACE_0F
; break;
1464 case 0x38: space
= SPACE_0F38
; break;
1465 case 0x3A: space
= SPACE_0F3A
; break;
1468 if (space
!= SPACE_0F
&& --length
== 1)
1469 fail ("%s:%d: %s: unrecognized opcode encoding space\n",
1470 filename
, lineno
, name
);
1471 opcode
&= (1ULL << (8 * --length
)) - 1;
1475 fail ("%s:%d: %s: residual opcode (0x%0*llx) too large\n",
1476 filename
, lineno
, name
, 2 * length
, opcode
);
1478 ident
= mkident (name
);
1479 fprintf (table
, " { MN_%s, 0x%0*llx%s, %u,",
1480 ident
, 2 * (int)length
, opcode
, end
, i
);
1483 process_i386_opcode_modifier (table
, opcode_modifier
, space
, prefix
,
1484 extension_opcode
, operand_types
, lineno
,
1485 rex2_disallowed (opcode
, length
, space
,
1488 process_i386_cpu_flag (table
, cpu_flags
, NULL
, ",", " ", lineno
, CpuMax
);
1490 fprintf (table
, " { ");
1492 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1494 if (!operand_types
[i
])
1497 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1503 fprintf (table
, ",\n ");
1505 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1508 fprintf (table
, " } },\n");
1511 struct opcode_hash_entry
1516 struct opcode_entry
*next
;
1522 /* Calculate the hash value of an opcode hash entry P. */
1525 opcode_hash_hash (const void *p
)
1527 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1528 return htab_hash_string (entry
->name
);
1531 /* Compare a string Q against an opcode hash entry P. */
1534 opcode_hash_eq (const void *p
, const void *q
)
1536 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1537 const char *name
= (const char *) q
;
1538 return strcmp (name
, entry
->name
) == 0;
1542 parse_template (char *buf
, int lineno
)
1544 char sep
, *end
, *name
;
1545 struct template *tmpl
;
1546 struct template_instance
*last_inst
= NULL
;
1548 buf
= remove_leading_whitespaces (buf
+ 1);
1549 end
= strchr (buf
, ':');
1552 struct template *prev
= NULL
;
1554 end
= strchr (buf
, '>');
1556 fail ("%s: %d: missing ':' or '>'\n", filename
, lineno
);
1557 if (*remove_leading_whitespaces (end
+ 1))
1558 fail ("%s: %d: malformed template purge\n", filename
, lineno
);
1560 remove_trailing_whitespaces (buf
);
1561 /* Don't bother freeing the various structures. */
1562 for (tmpl
= templates
; tmpl
!= NULL
; tmpl
= (prev
= tmpl
)->next
)
1563 if (!strcmp (buf
, tmpl
->name
))
1566 fail ("%s: %d: no template '%s'\n", filename
, lineno
, buf
);
1568 prev
->next
= tmpl
->next
;
1570 templates
= tmpl
->next
;
1574 remove_trailing_whitespaces (buf
);
1577 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1578 tmpl
= xmalloc (sizeof (*tmpl
));
1579 tmpl
->name
= xstrdup (buf
);
1581 tmpl
->params
= NULL
;
1583 struct template_param
*param
;
1585 buf
= remove_leading_whitespaces (end
);
1586 end
= strpbrk (buf
, ":,");
1588 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1592 remove_trailing_whitespaces (buf
);
1594 param
= xmalloc (sizeof (*param
));
1595 param
->name
= xstrdup (buf
);
1596 param
->next
= tmpl
->params
;
1597 tmpl
->params
= param
;
1598 } while (sep
== ':');
1600 tmpl
->instances
= NULL
;
1602 struct template_instance
*inst
;
1604 const struct template_param
*param
;
1606 buf
= remove_leading_whitespaces (end
);
1607 end
= strpbrk (buf
, ",>");
1609 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1614 inst
= xmalloc (sizeof (*inst
));
1618 cur
= next_field (buf
, ':', &next
, end
);
1619 inst
->name
= *cur
!= '$' ? xstrdup (cur
) : "";
1621 for (param
= tmpl
->params
; param
; param
= param
->next
)
1623 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1625 cur
= next_field (next
, ':', &next
, end
);
1627 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1628 arg
->val
= xstrdup (cur
);
1629 arg
->next
= inst
->args
;
1633 if (tmpl
->instances
)
1634 last_inst
->next
= inst
;
1636 tmpl
->instances
= inst
;
1638 } while (sep
== ',');
1640 buf
= remove_leading_whitespaces (end
);
1642 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1643 filename
, lineno
, buf
);
1645 tmpl
->next
= templates
;
1650 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1651 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1653 static unsigned int idx
, opcode_array_size
;
1654 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1655 struct opcode_hash_entry
**hash_slot
;
1656 struct opcode_entry
*entry
;
1657 char *ptr1
= strchr(name
, '<'), *ptr2
;
1661 /* Get the slot in hash table. */
1662 hash_slot
= (struct opcode_hash_entry
**)
1663 htab_find_slot_with_hash (opcode_hash_table
, name
,
1664 htab_hash_string (name
),
1667 if (*hash_slot
== NULL
)
1669 /* It is the new one. Put it on opcode array. */
1670 if (idx
>= opcode_array_size
)
1672 /* Grow the opcode array when needed. */
1673 opcode_array_size
+= 1024;
1674 opcode_array
= (struct opcode_hash_entry
**)
1675 xrealloc (opcode_array
,
1676 sizeof (*opcode_array
) * opcode_array_size
);
1677 *opcode_array_p
= opcode_array
;
1680 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1681 xmalloc (sizeof (struct opcode_hash_entry
));
1682 opcode_array
[idx
]->name
= xstrdup (name
);
1683 *hash_slot
= opcode_array
[idx
];
1684 entry
= &opcode_array
[idx
]->entry
;
1689 /* Append it to the existing one. */
1690 struct opcode_entry
**entryp
= &(*hash_slot
)->entry
.next
;
1692 while (*entryp
!= NULL
)
1693 entryp
= &(*entryp
)->next
;
1694 entry
= (struct opcode_entry
*)xmalloc (sizeof (struct opcode_entry
));
1699 entry
->opcode
= xstrdup (str
);
1700 entry
->lineno
= lineno
;
1702 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1703 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1706 const struct template *tmpl
;
1707 const struct template_instance
*inst
;
1710 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1711 remove_trailing_whitespaces (ptr1
);
1715 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1716 if (!strcmp(ptr1
, tmpl
->name
))
1719 fail ("reference to unknown template '%s'\n", ptr1
);
1721 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1723 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1724 char *str2
= xmalloc(2 * strlen(str
));
1727 strcpy (name2
, name
);
1728 strcat (name2
, inst
->name
);
1729 strcat (name2
, ptr2
);
1731 for (ptr1
= str2
, src
= str
; *src
; )
1733 const char *ident
= tmpl
->name
, *end
;
1734 const struct template_param
*param
;
1735 const struct template_arg
*arg
;
1737 if ((*ptr1
= *src
++) != '<')
1742 while (ISSPACE(*src
))
1744 while (*ident
&& *src
== *ident
)
1746 while (ISSPACE(*src
))
1748 if (*src
!= ':' || *ident
!= '\0')
1750 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1751 ptr1
+= ident
- tmpl
->name
;
1754 while (ISSPACE(*++src
))
1758 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1761 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1762 param
= param
->next
, arg
= arg
->next
)
1764 if (end
- src
== strlen (param
->name
)
1765 && !memcmp (src
, param
->name
, end
- src
))
1773 fail ("template '%s' has no parameter '%.*s'\n",
1774 tmpl
->name
, (int)(end
- src
), src
);
1776 while (ISSPACE(*src
))
1779 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1781 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1782 ptr1
+= strlen(arg
->val
);
1788 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1799 static int mnemonic_cmp(const void *p1
, const void *p2
)
1801 const struct opcode_hash_entry
*const *e1
= p1
, *const *e2
= p2
;
1802 const char *s1
= (*e1
)->name
, *s2
= (*e2
)->name
;
1804 size_t l1
= strlen (s1
), l2
= strlen (s2
);
1806 for (i
= 1; i
<= l1
&& i
<= l2
; ++i
)
1808 if (s1
[l1
- i
] != s2
[l2
- i
])
1809 return (unsigned char)s1
[l1
- i
] - (unsigned char)s2
[l2
- i
];
1812 return (int)(l1
- l2
);
1816 process_i386_opcodes (FILE *table
)
1820 unsigned int i
, j
, nr
, offs
;
1822 char *str
, *p
, *last
;
1823 htab_t opcode_hash_table
;
1824 struct opcode_hash_entry
**opcode_array
= NULL
;
1825 int lineno
= 0, marker
= 0;
1827 filename
= "i386-opc.tbl";
1831 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1832 opcode_hash_eq
, NULL
,
1835 fprintf (table
, "\n#include \"i386-mnem.h\"\n");
1836 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1837 fprintf (table
, "static const insn_template i386_optab[] =\n{\n");
1839 /* Put everything on opcode array. */
1844 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1847 p
= remove_leading_whitespaces (buf
);
1853 /* Skip comments. */
1854 str
= strstr (p
, "//");
1858 remove_trailing_whitespaces (p
);
1862 /* Look for line continuation character. */
1863 remove_trailing_whitespaces (p
);
1865 if (!j
|| buf
[j
- 1] != '+')
1867 if (j
>= sizeof (buf
) - 1)
1868 fail ("%s: %d: (continued) line too long\n", filename
, lineno
);
1870 if (fgets (buf
+ j
- 1, sizeof (buf
) - j
+ 1, fp
) == NULL
)
1872 fprintf (stderr
, "%s: Line continuation on last line?\n",
1881 if (!strcmp("### MARKER ###", buf
))
1885 /* Since we ignore all included files (we only care about their
1886 #define-s here), we don't need to monitor filenames. The final
1887 line number directive is going to refer to the main source file
1892 p
= remove_leading_whitespaces (p
+ 1);
1893 if (!strncmp(p
, "line", 4))
1895 ln
= strtoul (p
, &end
, 10);
1896 if (ln
> 1 && ln
< INT_MAX
1897 && *remove_leading_whitespaces (end
) == '"')
1900 /* Ignore comments. */
1905 parse_template (p
, lineno
);
1913 last
= p
+ strlen (p
);
1916 name
= next_field (p
, ',', &str
, last
);
1918 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1922 /* Process opcode array. */
1923 for (j
= 0; j
< i
; j
++)
1925 const char *name
= opcode_array
[j
]->name
;
1926 struct opcode_entry
*next
;
1928 for (next
= &opcode_array
[j
]->entry
; next
; next
= next
->next
)
1931 lineno
= next
->lineno
;
1932 last
= str
+ strlen (str
);
1933 output_i386_opcode (table
, name
, str
, last
, lineno
);
1939 fprintf (table
, "};\n");
1941 /* Generate opcode sets array. */
1942 fprintf (table
, "\n/* i386 opcode sets table. */\n\n");
1943 fprintf (table
, "typedef unsigned short i386_op_off_t;\n");
1944 fprintf (table
, "static const i386_op_off_t i386_op_sets[] =\n{\n ");
1946 for (nr
= j
= 0; j
< i
; j
++)
1948 struct opcode_entry
*next
= &opcode_array
[j
]->entry
;
1950 if ((j
+ 1) % 8 != 0)
1951 fprintf (table
, "%5u,", nr
);
1953 fprintf (table
, "%5u,\n ", nr
);
1962 fprintf (table
, "%5u\n};\n", nr
);
1964 /* Emit mnemonics and associated #define-s. */
1965 qsort (opcode_array
, i
, sizeof (*opcode_array
), mnemonic_cmp
);
1967 fp
= fopen ("i386-mnem.h", "w");
1969 fail ("can't create i386-mnem.h, errno = %s\n",
1972 process_copyright (fp
);
1974 fprintf (table
, "\n/* i386 mnemonics table. */\n\n");
1975 fprintf (table
, "const char i386_mnemonics[] =\n");
1976 fprintf (fp
, "\nextern const char i386_mnemonics[];\n\n");
1979 for (l
= strlen (opcode_array
[offs
= j
= 0]->name
); j
< i
; j
++)
1981 const char *name
= opcode_array
[j
]->name
;
1982 const char *next
= NULL
;
1983 size_t l1
= j
+ 1 < i
? strlen(next
= opcode_array
[j
+ 1]->name
) : 0;
1986 str
= mkident (name
);
1987 if (l
< l1
&& !strcmp(name
, next
+ l1
- l
))
1989 fprintf (fp
, "#define MN_%s ", str
);
1991 str
= mkident (next
);
1992 fprintf (fp
, "(MN_%s + %zu)\n", str
, l1
- l
);
1996 fprintf (table
, " \"\\0\"\"%s\"\n", name
);
1997 fprintf (fp
, "#define MN_%s %#x\n", str
, offs
+ 1);
1998 offs
+= strlen (name
) + 1;
2005 fprintf (table
, " \"\\0\"\".insn\"\n");
2006 fprintf (fp
, "#define MN__insn %#x\n", offs
+ 1);
2008 fprintf (table
, ";\n");
2014 process_i386_registers (FILE *table
)
2018 char *str
, *p
, *last
;
2019 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
2020 char *dw2_32_num
, *dw2_64_num
;
2023 filename
= "i386-reg.tbl";
2024 fp
= fopen (filename
, "r");
2026 fail ("can't find i386-reg.tbl for reading, errno = %s\n",
2029 fprintf (table
, "\n/* i386 register table. */\n\n");
2030 fprintf (table
, "static const reg_entry i386_regtab[] =\n{\n");
2034 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
2039 p
= remove_leading_whitespaces (buf
);
2041 /* Skip comments. */
2042 str
= strstr (p
, "//");
2046 /* Remove trailing white spaces. */
2047 remove_trailing_whitespaces (p
);
2052 fprintf (table
, "%s\n", p
);
2060 last
= p
+ strlen (p
);
2062 /* Find reg_name. */
2063 reg_name
= next_field (p
, ',', &str
, last
);
2065 /* Find reg_type. */
2066 reg_type
= next_field (str
, ',', &str
, last
);
2068 /* Find reg_flags. */
2069 reg_flags
= next_field (str
, ',', &str
, last
);
2072 reg_num
= next_field (str
, ',', &str
, last
);
2074 fprintf (table
, " { \"%s\",\n ", reg_name
);
2076 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
2079 /* Find 32-bit Dwarf2 register number. */
2080 dw2_32_num
= next_field (str
, ',', &str
, last
);
2082 /* Find 64-bit Dwarf2 register number. */
2083 dw2_64_num
= next_field (str
, ',', &str
, last
);
2085 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
2086 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
2091 fprintf (table
, "};\n");
2093 fprintf (table
, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
2097 process_i386_initializers (void)
2100 FILE *fp
= fopen ("i386-init.h", "w");
2103 fail ("can't create i386-init.h, errno = %s\n",
2106 process_copyright (fp
);
2108 for (i
= 0; i
< CpuMax
; i
++)
2109 process_i386_cpu_flag (fp
, "0", cpu_flags
[i
].name
, "", " ", -1, i
);
2111 for (i
= 0; i
< ARRAY_SIZE (isa_dependencies
); i
++)
2113 char *deps
= xstrdup (isa_dependencies
[i
].deps
);
2115 process_i386_cpu_flag (fp
, deps
, isa_dependencies
[i
].name
,
2116 "", " ", -1, CpuMax
);
2120 /* Early x87 is somewhat special: Both 287 and 387 not only add new insns
2121 but also remove some. Hence 8087 isn't a prereq to 287, and 287 isn't
2122 one to 387. We want the reverse to be true though: Disabling 8087 also
2123 is to disable 287+ and later; disabling 287 also means disabling 387+. */
2124 memcpy (isa_reverse_deps
[Cpu287
], isa_reverse_deps
[Cpu387
],
2125 sizeof (isa_reverse_deps
[0]));
2126 isa_reverse_deps
[Cpu287
][Cpu387
] = 1;
2127 memcpy (isa_reverse_deps
[Cpu8087
], isa_reverse_deps
[Cpu287
],
2128 sizeof (isa_reverse_deps
[0]));
2129 isa_reverse_deps
[Cpu8087
][Cpu287
] = 1;
2131 /* While we treat POPCNT as a prereq to SSE4.2, its disabling should not
2132 lead to disabling of anything else. */
2133 memset (isa_reverse_deps
[CpuPOPCNT
], 0, sizeof (isa_reverse_deps
[0]));
2135 for (i
= Cpu686
+ 1; i
< ARRAY_SIZE (isa_reverse_deps
); i
++)
2140 if (memchr(isa_reverse_deps
[i
], 1,
2141 ARRAY_SIZE (isa_reverse_deps
[0])) == NULL
)
2144 isa_reverse_deps
[i
][i
] = 1;
2145 process_i386_cpu_flag (fp
, NULL
, cpu_flags
[i
].name
, "", " ", -1, i
);
2153 /* Program options. */
2154 #define OPTION_SRCDIR 200
2156 struct option long_options
[] =
2158 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2159 {"debug", no_argument
, NULL
, 'd'},
2160 {"version", no_argument
, NULL
, 'V'},
2161 {"help", no_argument
, NULL
, 'h'},
2162 {0, no_argument
, NULL
, 0}
2166 print_version (void)
2168 printf ("%s: version 1.0\n", program_name
);
2173 usage (FILE * stream
, int status
)
2175 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2181 main (int argc
, char **argv
)
2183 extern int chdir (char *);
2184 char *srcdir
= NULL
;
2186 unsigned int i
, cpumax
;
2189 program_name
= *argv
;
2190 xmalloc_set_program_name (program_name
);
2192 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2217 if (chdir (srcdir
) != 0)
2218 fail ("unable to change directory to \"%s\", errno = %s\n",
2219 srcdir
, xstrerror (errno
));
2221 /* cpu_flags isn't sorted by position. */
2223 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
2224 if (cpu_flags
[i
].position
> cpumax
)
2225 cpumax
= cpu_flags
[i
].position
;
2227 /* Check the unused bitfield in i386_cpu_flags. */
2229 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
2231 if ((cpumax
- 1) != CpuMax
)
2232 fail ("CpuMax != %d!\n", cpumax
);
2234 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
2236 if (cpumax
!= CpuMax
)
2237 fail ("CpuMax != %d!\n", cpumax
);
2239 c
= CpuNumOfBits
- CpuMax
- 1;
2241 fail ("%d unused bits in i386_cpu_flags.\n", c
);
2244 /* If this triggers, CpuIsaBits needs to be increased. */
2245 static_assert (CpuAttrEnums
<= (1u << CpuIsaBits
));
2247 /* Check the unused bitfield in i386_cpu_attr. */
2248 #ifndef CpuAttrUnused
2249 c
= CpuAttrNumOfBits
- (CpuIsaBits
+ CpuMax
+ 1 - CpuAttrEnums
);
2251 fail ("%d unused bits in i386_cpu_attr.\n", c
);
2254 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
2256 /* Check the unused bitfield in i386_operand_type. */
2258 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2261 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2264 c
= OTNumOfBits
- OTNum
;
2266 fail ("%d unused bits in i386_operand_type.\n", c
);
2269 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2272 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2273 sizeof (opcode_modifiers
[0]), compare
);
2275 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2276 sizeof (operand_types
[0]), compare
);
2278 process_i386_initializers ();
2280 table
= fopen ("i386-tbl.h", "w");
2282 fail ("can't create i386-tbl.h, errno = %s\n",
2285 process_copyright (table
);
2287 process_i386_opcodes (table
);
2288 process_i386_registers (table
);