1 /* Copyright (C) 2007-2023 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 "GENERIC64|FISTTP|MONITOR|CX16|LAHF_SAHF|Rdtscp|SSSE3|SSE4A|ABM|PRFCHW|Clflush|FISTTP|SVME" },
100 "BTVER1|AVX|BMI|F16C|AES|PCLMULQDQ|Movbe|Xsaveopt|PRFCHW" },
112 "586|687|CMOV|FXSR" },
197 { "AVX512_VPOPCNTDQ",
205 { "AVX512_VP2INTERSECT",
240 "AVX512VL|AVX512DQ|AVX512CD|AVX512VBMI|AVX512_VBMI2|AVX512IFMA"
241 "|AVX512_VNNI|AVX512_BF16|AVX512_FP16|AVX512_VPOPCNTDQ|AVX512_BITALG" },
280 /* This array is populated as process_i386_initializers() walks cpu_flags[]. */
281 static unsigned char isa_reverse_deps
[CpuMax
][CpuMax
];
283 typedef struct bitfield
290 #define BITFIELD(n) { Cpu##n, 0, #n }
292 static bitfield cpu_flags
[] =
337 BITFIELD (PCLMULQDQ
),
346 BITFIELD (LAHF_SAHF
),
368 BITFIELD (ClflushOpt
),
371 BITFIELD (PREFETCHWT1
),
375 BITFIELD (AVX512IFMA
),
376 BITFIELD (AVX512VBMI
),
377 BITFIELD (AVX512_4FMAPS
),
378 BITFIELD (AVX512_4VNNIW
),
379 BITFIELD (AVX512_VPOPCNTDQ
),
380 BITFIELD (AVX512_VBMI2
),
381 BITFIELD (AVX512_VNNI
),
382 BITFIELD (AVX512_BITALG
),
383 BITFIELD (AVX512_BF16
),
384 BITFIELD (AVX512_VP2INTERSECT
),
387 BITFIELD (AVX512_FP16
),
388 BITFIELD (PREFETCHI
),
390 BITFIELD (AVX_VNNI_INT8
),
391 BITFIELD (AVX_VNNI_INT16
),
392 BITFIELD (CMPCCXADD
),
395 BITFIELD (AVX_NE_CONVERT
),
409 BITFIELD (VPCLMULQDQ
),
419 BITFIELD (AMX_COMPLEX
),
422 BITFIELD (MOVDIR64B
),
424 BITFIELD (SERIALIZE
),
444 #define BITFIELD(n) { n, 0, #n }
446 static bitfield opcode_modifiers
[] =
455 BITFIELD (CheckOperandSize
),
456 BITFIELD (OperandConstraint
),
457 BITFIELD (MnemonicSize
),
466 BITFIELD (BNDPrefixOk
),
474 BITFIELD (OpcodePrefix
),
479 BITFIELD (Broadcast
),
480 BITFIELD (StaticRounding
),
482 BITFIELD (Disp8MemShift
),
485 BITFIELD (ATTMnemonic
),
486 BITFIELD (ATTSyntax
),
487 BITFIELD (IntelSyntax
),
491 #define CLASS(n) #n, n
493 static const struct {
495 enum operand_class value
;
496 } operand_classes
[] = {
510 #define INSTANCE(n) #n, n
512 static const struct {
514 enum operand_instance value
;
515 } operand_instances
[] = {
524 static bitfield operand_types
[] =
533 BITFIELD (BaseIndex
),
548 BITFIELD (Unspecified
),
554 static const char *filename
;
555 static i386_cpu_flags active_cpu_flags
;
556 static int active_isstring
;
558 struct template_arg
{
559 const struct template_arg
*next
;
563 struct template_instance
{
564 const struct template_instance
*next
;
566 const struct template_arg
*args
;
569 struct template_param
{
570 const struct template_param
*next
;
575 struct template *next
;
577 const struct template_instance
*instances
;
578 const struct template_param
*params
;
581 static struct template *templates
;
584 compare (const void *x
, const void *y
)
586 const bitfield
*xp
= (const bitfield
*) x
;
587 const bitfield
*yp
= (const bitfield
*) y
;
588 return xp
->position
- yp
->position
;
592 fail (const char *message
, ...)
596 va_start (args
, message
);
597 fprintf (stderr
, "%s: error: ", program_name
);
598 vfprintf (stderr
, message
, args
);
604 process_copyright (FILE *fp
)
606 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
607 /* Copyright (C) 2007-2023 Free Software Foundation, Inc.\n\
609 This file is part of the GNU opcodes library.\n\
611 This library is free software; you can redistribute it and/or modify\n\
612 it under the terms of the GNU General Public License as published by\n\
613 the Free Software Foundation; either version 3, or (at your option)\n\
614 any later version.\n\
616 It is distributed in the hope that it will be useful, but WITHOUT\n\
617 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
618 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
619 License for more details.\n\
621 You should have received a copy of the GNU General Public License\n\
622 along with this program; if not, write to the Free Software\n\
623 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
624 MA 02110-1301, USA. */\n");
627 /* Remove leading white spaces. */
630 remove_leading_whitespaces (char *str
)
632 while (ISSPACE (*str
))
637 /* Remove trailing white spaces. */
640 remove_trailing_whitespaces (char *str
)
642 size_t last
= strlen (str
);
650 if (ISSPACE (str
[last
]))
658 /* Find next field separated by SEP and terminate it. Return a
659 pointer to the one after it. */
662 next_field (char *str
, char sep
, char **next
, char *last
)
666 p
= remove_leading_whitespaces (str
);
667 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
670 remove_trailing_whitespaces (p
);
680 static void set_bitfield (char *, bitfield
*, int, unsigned int, int);
683 set_bitfield (char *f
, bitfield
*array
, int value
,
684 unsigned int size
, int lineno
)
688 /* Ignore empty fields; they may result from template expansions. */
692 for (i
= 0; i
< size
; i
++)
693 if (strcasecmp (array
[i
].name
, f
) == 0)
695 array
[i
].value
= value
;
701 const char *v
= strchr (f
, '=');
708 for (i
= 0; i
< size
; i
++)
709 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
711 value
= strtol (v
+ 1, &end
, 0);
714 array
[i
].value
= value
;
723 fail ("%s: %d: unknown bitfield: %s\n", filename
, lineno
, f
);
725 fail ("unknown bitfield: %s\n", f
);
729 add_isa_dependencies (bitfield
*flags
, const char *f
, int value
,
730 unsigned int reverse
)
736 bool is_isa
= false, orig_is_avx
= is_avx
;
738 /* Need to find base entry for references to auxiliary ones. */
742 *strchr (str
, ':') = '\0';
745 /* isa_dependencies[] prefers "LM" over "64". */
746 else if (!strcmp (f
, "LM"))
748 for (i
= 0; i
< CpuMax
; ++i
)
749 if (strcasecmp (flags
[i
].name
, isa
) == 0)
751 flags
[i
].value
= value
;
752 if (reverse
< ARRAY_SIZE (isa_reverse_deps
[0])
753 /* Don't record the feature itself here. */
755 /* Don't record base architectures. */
757 isa_reverse_deps
[i
][reverse
] = 1;
759 if (i
== CpuAVX
|| i
== CpuXOP
|| i
== CpuVAES
|| i
== CpuVPCLMULQDQ
)
765 /* Do not turn off dependencies. */
766 if (is_isa
&& !value
)
768 is_avx
= orig_is_avx
;
772 for (i
= 0; i
< ARRAY_SIZE (isa_dependencies
); ++i
)
773 if (strcasecmp (isa_dependencies
[i
].name
, f
) == 0)
775 char *deps
= xstrdup (isa_dependencies
[i
].deps
);
777 char *last
= deps
+ strlen (deps
);
779 for (; next
&& next
< last
; )
781 char *str
= next_field (next
, '|', &next
, last
);
783 /* No AVX/XOP -> SSE reverse dependencies. */
784 if (is_avx
&& strncmp (str
, "SSE", 3) == 0)
785 add_isa_dependencies (flags
, str
, value
, CpuMax
);
787 add_isa_dependencies (flags
, str
, value
, reverse
);
791 /* ISA extensions with dependencies need CPU_ANY_*_FLAGS emitted,
792 unless the sole dependency is the "64-bit mode only" one. */
793 if (reverse
< ARRAY_SIZE (isa_reverse_deps
[0])
794 && strcmp (isa_dependencies
[i
].deps
, "64"))
795 isa_reverse_deps
[reverse
][reverse
] = 1;
797 is_avx
= orig_is_avx
;
802 fail ("unknown bitfield: %s\n", f
);
804 is_avx
= orig_is_avx
;
808 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
809 int mode
, const char *comma
, const char *indent
, int lineno
)
811 unsigned int i
= 0, j
= 0;
814 memset (&active_cpu_flags
, 0, sizeof(active_cpu_flags
));
816 fprintf (table
, "%s{ { ", indent
);
820 for (j
= ~0u; i
< CpuAttrEnums
; i
++)
826 fail ("%s: %d: invalid combination of CPU identifiers\n",
830 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
833 /* Write 0 to indicate "no associated flag". */
834 fprintf (table
, "%u, ", j
+ 1);
839 for (; i
< size
- 1; i
++, j
++)
841 if (((j
+ 1) % 20) != 0)
842 fprintf (table
, "%d, ", flags
[i
].value
);
844 fprintf (table
, "%d,", flags
[i
].value
);
845 if (((j
+ 1) % 20) == 0)
847 /* We need \\ for macro. */
849 fprintf (table
, " \\\n %s", indent
);
851 fprintf (table
, "\n %s", indent
);
853 if (mode
< 0 && flags
[i
].value
)
854 active_cpu_flags
.array
[i
/ 32] |= 1U << (i
% 32);
857 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
861 process_i386_cpu_flag (FILE *table
, char *flag
,
863 const char *comma
, const char *indent
,
864 int lineno
, unsigned int reverse
)
866 char *str
, *next
= flag
, *last
;
870 bitfield all
[ARRAY_SIZE (cpu_flags
)];
871 bitfield any
[ARRAY_SIZE (cpu_flags
)];
873 /* Copy the default cpu flags. */
874 memcpy (all
, cpu_flags
, sizeof (cpu_flags
));
875 memcpy (any
, cpu_flags
, sizeof (cpu_flags
));
879 for (i
= 0; i
< ARRAY_SIZE (isa_reverse_deps
[0]); ++i
)
880 any
[i
].value
= isa_reverse_deps
[reverse
][i
];
886 last
= flag
+ strlen (flag
);
893 fail ("%s: %d: missing `)' in bitfield: %s\n", filename
,
900 /* First we turn on everything except for cpuno64 and - if
901 present - the padding field. */
902 for (i
= 0; i
< ARRAY_SIZE (any
); i
++)
903 if (any
[i
].position
< CpuNo64
)
906 /* Turn off selective bits. */
910 if (name
!= NULL
&& value
!= 0)
912 for (i
= 0; i
< ARRAY_SIZE (any
); i
++)
913 if (strcasecmp (any
[i
].name
, name
) == 0)
915 add_isa_dependencies (any
, name
, 1, reverse
);
921 if (strcmp (flag
, "0"))
923 bool combined
= false;
928 /* Turn on/off selective bits. */
929 last
= flag
+ strlen (flag
);
930 if (name
== NULL
&& strchr (flag
, '&'))
932 for (; next
< last
&& *next
!= '('; )
934 str
= next_field (next
, '&', &next
, last
);
935 set_bitfield (str
, all
, value
, ARRAY_SIZE (all
), lineno
);
940 fail ("%s: %d: missing `)' in bitfield: %s\n", filename
,
947 for (; next
&& next
< last
; )
949 str
= next_field (next
, '|', &next
, last
);
951 add_isa_dependencies (any
, str
, value
, reverse
);
952 else if (combined
|| next
< last
)
953 set_bitfield (str
, any
, value
, ARRAY_SIZE (any
), lineno
);
954 else /* Singular specifiers go into "all". */
955 set_bitfield (str
, all
, value
, ARRAY_SIZE (all
), lineno
);
963 size_t len
= strlen (name
);
964 char *upper
= xmalloc (len
+ 1);
966 /* Cpu64 is special: It specifies a mode dependency, not an ISA one. Zap
967 the flag from ISA initializer macros (and from CPU_ANY_64_FLAGS
968 itself we only care about tracking its dependents. Also don't emit the
969 (otherwise all zero) CPU_64_FLAGS. */
970 if (flag
!= NULL
&& reverse
== Cpu64
)
972 if (is_isa
|| flag
== NULL
)
973 any
[Cpu64
].value
= 0;
975 for (i
= 0; i
< len
; ++i
)
977 /* Don't emit #define-s for auxiliary entries. */
980 upper
[i
] = TOUPPER (name
[i
]);
983 fprintf (table
, "\n#define CPU_%s%s_FLAGS \\\n",
984 flag
!= NULL
? "": "ANY_", upper
);
989 /* Synthesize "64-bit mode only" dependencies from the dependencies we
991 for (i
= 0; i
< ARRAY_SIZE (isa_reverse_deps
[0]); ++i
)
992 if (all
[i
].value
&& isa_reverse_deps
[Cpu64
][i
])
993 all
[Cpu64
].value
= 1;
995 output_cpu_flags(table
, all
, ARRAY_SIZE (all
), -1, comma
, indent
, lineno
);
998 output_cpu_flags (table
, any
, ARRAY_SIZE (any
), name
!= NULL
,
999 comma
, indent
, lineno
);
1003 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
1007 fprintf (table
, " { ");
1009 for (i
= 0; i
< size
- 1; i
++)
1011 if (((i
+ 1) % 20) != 0)
1012 fprintf (table
, "%d, ", modifier
[i
].value
);
1014 fprintf (table
, "%d,", modifier
[i
].value
);
1015 if (((i
+ 1) % 20) == 0)
1016 fprintf (table
, "\n ");
1019 fprintf (table
, "%d },\n", modifier
[i
].value
);
1022 /* Returns LOG2 of element size. */
1024 get_element_size (char **opnd
, int lineno
)
1026 char *str
, *next
, *last
, *op
;
1027 const char *full
= opnd
[0];
1028 int elem_size
= INT_MAX
;
1030 /* Find the memory operand. */
1031 while (full
!= NULL
&& strstr(full
, "BaseIndex") == NULL
)
1034 fail ("%s: %d: no memory operand\n", filename
, lineno
);
1036 op
= xstrdup (full
);
1037 last
= op
+ strlen (op
);
1038 for (next
= op
; next
&& next
< last
; )
1040 str
= next_field (next
, '|', &next
, last
);
1043 if (strcasecmp(str
, "Byte") == 0)
1045 /* The smallest element size, no need to check
1050 else if (strcasecmp(str
, "Word") == 0)
1055 else if (strcasecmp(str
, "Dword") == 0)
1060 else if (strcasecmp(str
, "Qword") == 0)
1069 if (elem_size
== INT_MAX
)
1070 fail ("%s: %d: unknown element size: %s\n", filename
, lineno
, full
);
1076 process_i386_opcode_modifier (FILE *table
, char *mod
, unsigned int space
,
1077 unsigned int prefix
, const char *extension_opcode
,
1078 char **opnd
, int lineno
)
1080 char *str
, *next
, *last
;
1081 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
1082 static const char *const spaces
[] = {
1083 #define SPACE(n) [SPACE_##n] = #n
1097 active_isstring
= 0;
1099 /* Copy the default opcode modifier. */
1100 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
1102 if (strcmp (mod
, "0"))
1104 unsigned int have_w
= 0, bwlq_suf
= 0xf;
1106 last
= mod
+ strlen (mod
);
1107 for (next
= mod
; next
&& next
< last
; )
1109 str
= next_field (next
, '|', &next
, last
);
1114 if (strncmp(str
, "OpcodeSpace", 11) == 0)
1119 fail ("%s:%d: Missing value for `OpcodeSpace'\n",
1122 val
= strtol (str
+ 12, &end
, 0);
1124 fail ("%s:%d: Bogus value `%s' for `OpcodeSpace'\n",
1125 filename
, lineno
, end
);
1130 fail ("%s:%d: Conflicting opcode space specifications\n",
1133 "%s:%d: Warning: redundant opcode space specification\n",
1141 if (strcasecmp(str
, "Broadcast") == 0)
1142 val
= get_element_size (opnd
, lineno
) + BYTE_BROADCAST
;
1143 else if (strcasecmp(str
, "Disp8MemShift") == 0)
1144 val
= get_element_size (opnd
, lineno
);
1146 set_bitfield (str
, modifiers
, val
, ARRAY_SIZE (modifiers
),
1148 if (strcasecmp(str
, "IsString") == 0)
1149 active_isstring
= 1;
1151 if (strcasecmp(str
, "W") == 0)
1154 if (strcasecmp(str
, "No_bSuf") == 0)
1156 if (strcasecmp(str
, "No_wSuf") == 0)
1158 if (strcasecmp(str
, "No_lSuf") == 0)
1160 if (strcasecmp(str
, "No_qSuf") == 0)
1167 if (!modifiers
[OpcodePrefix
].value
)
1168 modifiers
[OpcodePrefix
].value
= prefix
;
1169 else if (modifiers
[OpcodePrefix
].value
!= prefix
)
1170 fail ("%s:%d: Conflicting prefix specifications\n",
1174 "%s:%d: Warning: redundant prefix specification\n",
1178 if (have_w
&& !bwlq_suf
)
1179 fail ("%s: %d: stray W modifier\n", filename
, lineno
);
1180 if (have_w
&& !(bwlq_suf
& 1))
1181 fprintf (stderr
, "%s: %d: W modifier without Byte operand(s)\n",
1183 if (have_w
&& !(bwlq_suf
& ~1))
1185 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1189 if (space
>= ARRAY_SIZE (spaces
) || !spaces
[space
])
1190 fail ("%s:%d: Unknown opcode space %u\n", filename
, lineno
, space
);
1192 fprintf (table
, " SPACE_%s, %s,\n",
1193 spaces
[space
], extension_opcode
? extension_opcode
: "None");
1195 /* Rather than evaluating multiple conditions at runtime to determine
1196 whether an EVEX encoding is being dealt with, derive that information
1197 right here. A missing EVex attribute means "dynamic". */
1198 if (!modifiers
[EVex
].value
1199 && (modifiers
[Disp8MemShift
].value
1200 || modifiers
[Broadcast
].value
1201 || modifiers
[Masking
].value
1202 || modifiers
[SAE
].value
))
1203 modifiers
[EVex
].value
= EVEXDYN
;
1205 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1215 output_operand_type (FILE *table
, enum operand_class
class,
1216 enum operand_instance instance
,
1217 const bitfield
*types
, unsigned int size
,
1218 enum stage stage
, const char *indent
)
1222 fprintf (table
, "{ { %d, %d, ", class, instance
);
1224 for (i
= 0; i
< size
- 1; i
++)
1226 if (((i
+ 3) % 20) != 0)
1227 fprintf (table
, "%d, ", types
[i
].value
);
1229 fprintf (table
, "%d,", types
[i
].value
);
1230 if (((i
+ 3) % 20) == 0)
1232 /* We need \\ for macro. */
1233 if (stage
== stage_macros
)
1234 fprintf (table
, " \\\n%s", indent
);
1236 fprintf (table
, "\n%s", indent
);
1240 fprintf (table
, "%d } }", types
[i
].value
);
1244 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1245 const char *indent
, int lineno
)
1247 char *str
, *next
, *last
;
1248 enum operand_class
class = ClassNone
;
1249 enum operand_instance instance
= InstanceNone
;
1250 bitfield types
[ARRAY_SIZE (operand_types
)];
1252 /* Copy the default operand type. */
1253 memcpy (types
, operand_types
, sizeof (types
));
1255 if (strcmp (op
, "0"))
1259 last
= op
+ strlen (op
);
1260 for (next
= op
; next
&& next
< last
; )
1262 str
= next_field (next
, '|', &next
, last
);
1267 if (!strncmp(str
, "Class=", 6))
1269 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1270 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1272 class = operand_classes
[i
].value
;
1278 if (str
&& !strncmp(str
, "Instance=", 9))
1280 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1281 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1283 instance
= operand_instances
[i
].value
;
1291 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1292 if (strcasecmp(str
, "BaseIndex") == 0)
1297 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1299 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1300 if (!active_cpu_flags
.bitfield
.cpu64
1301 && !active_cpu_flags
.bitfield
.cpumpx
)
1302 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1303 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1306 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1310 static char *mkident (const char *mnem
)
1312 char *ident
= xstrdup (mnem
), *p
= ident
;
1325 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1326 char *last
, int lineno
)
1328 unsigned int i
, length
, prefix
= 0, space
= 0;
1329 char *base_opcode
, *extension_opcode
, *end
, *ident
;
1330 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1331 unsigned long long opcode
;
1333 /* Find base_opcode. */
1334 base_opcode
= next_field (str
, ',', &str
, last
);
1336 /* Find extension_opcode, if any. */
1337 extension_opcode
= strchr (base_opcode
, '/');
1338 if (extension_opcode
)
1339 *extension_opcode
++ = '\0';
1341 /* Find cpu_flags. */
1342 cpu_flags
= next_field (str
, ',', &str
, last
);
1344 /* Find opcode_modifier. */
1345 opcode_modifier
= next_field (str
, ',', &str
, last
);
1347 /* Remove the first {. */
1348 str
= remove_leading_whitespaces (str
);
1351 str
= remove_leading_whitespaces (str
+ 1);
1352 remove_trailing_whitespaces (str
);
1354 /* Remove } and trailing white space. */
1356 if (!i
|| str
[i
- 1] != '}')
1359 remove_trailing_whitespaces (str
);
1362 operand_types
[i
= 0] = NULL
;
1365 last
= str
+ strlen (str
);
1367 /* Find operand_types. */
1368 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1372 operand_types
[i
] = NULL
;
1376 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1380 opcode
= strtoull (base_opcode
, &end
, 0);
1382 /* Determine opcode length. */
1383 for (length
= 1; length
< 8; ++length
)
1384 if (!(opcode
>> (8 * length
)))
1387 /* Transform prefixes encoded in the opcode into opcode modifier
1391 switch (opcode
>> (8 * length
- 8))
1393 case 0x66: prefix
= PREFIX_0X66
; break;
1394 case 0xF3: prefix
= PREFIX_0XF3
; break;
1395 case 0xF2: prefix
= PREFIX_0XF2
; break;
1399 opcode
&= (1ULL << (8 * --length
)) - 1;
1402 /* Transform opcode space encoded in the opcode into opcode modifier
1404 if (length
> 1 && (opcode
>> (8 * length
- 8)) == 0xf)
1406 switch ((opcode
>> (8 * length
- 16)) & 0xff)
1408 default: space
= SPACE_0F
; break;
1409 case 0x38: space
= SPACE_0F38
; break;
1410 case 0x3A: space
= SPACE_0F3A
; break;
1413 if (space
!= SPACE_0F
&& --length
== 1)
1414 fail ("%s:%d: %s: unrecognized opcode encoding space\n",
1415 filename
, lineno
, name
);
1416 opcode
&= (1ULL << (8 * --length
)) - 1;
1420 fail ("%s:%d: %s: residual opcode (0x%0*llx) too large\n",
1421 filename
, lineno
, name
, 2 * length
, opcode
);
1423 ident
= mkident (name
);
1424 fprintf (table
, " { MN_%s, 0x%0*llx%s, %u,",
1425 ident
, 2 * (int)length
, opcode
, end
, i
);
1428 process_i386_opcode_modifier (table
, opcode_modifier
, space
, prefix
,
1429 extension_opcode
, operand_types
, lineno
);
1431 process_i386_cpu_flag (table
, cpu_flags
, NULL
, ",", " ", lineno
, CpuMax
);
1433 fprintf (table
, " { ");
1435 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1437 if (!operand_types
[i
])
1440 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1446 fprintf (table
, ",\n ");
1448 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1451 fprintf (table
, " } },\n");
1454 struct opcode_hash_entry
1459 struct opcode_entry
*next
;
1465 /* Calculate the hash value of an opcode hash entry P. */
1468 opcode_hash_hash (const void *p
)
1470 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1471 return htab_hash_string (entry
->name
);
1474 /* Compare a string Q against an opcode hash entry P. */
1477 opcode_hash_eq (const void *p
, const void *q
)
1479 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1480 const char *name
= (const char *) q
;
1481 return strcmp (name
, entry
->name
) == 0;
1485 parse_template (char *buf
, int lineno
)
1487 char sep
, *end
, *name
;
1488 struct template *tmpl
;
1489 struct template_instance
*last_inst
= NULL
;
1491 buf
= remove_leading_whitespaces (buf
+ 1);
1492 end
= strchr (buf
, ':');
1495 struct template *prev
= NULL
;
1497 end
= strchr (buf
, '>');
1499 fail ("%s: %d: missing ':' or '>'\n", filename
, lineno
);
1500 if (*remove_leading_whitespaces (end
+ 1))
1501 fail ("%s: %d: malformed template purge\n", filename
, lineno
);
1503 remove_trailing_whitespaces (buf
);
1504 /* Don't bother freeing the various structures. */
1505 for (tmpl
= templates
; tmpl
!= NULL
; tmpl
= (prev
= tmpl
)->next
)
1506 if (!strcmp (buf
, tmpl
->name
))
1509 fail ("%s: %d: no template '%s'\n", filename
, lineno
, buf
);
1511 prev
->next
= tmpl
->next
;
1513 templates
= tmpl
->next
;
1517 remove_trailing_whitespaces (buf
);
1520 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1521 tmpl
= xmalloc (sizeof (*tmpl
));
1522 tmpl
->name
= xstrdup (buf
);
1524 tmpl
->params
= NULL
;
1526 struct template_param
*param
;
1528 buf
= remove_leading_whitespaces (end
);
1529 end
= strpbrk (buf
, ":,");
1531 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1535 remove_trailing_whitespaces (buf
);
1537 param
= xmalloc (sizeof (*param
));
1538 param
->name
= xstrdup (buf
);
1539 param
->next
= tmpl
->params
;
1540 tmpl
->params
= param
;
1541 } while (sep
== ':');
1543 tmpl
->instances
= NULL
;
1545 struct template_instance
*inst
;
1547 const struct template_param
*param
;
1549 buf
= remove_leading_whitespaces (end
);
1550 end
= strpbrk (buf
, ",>");
1552 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1557 inst
= xmalloc (sizeof (*inst
));
1561 cur
= next_field (buf
, ':', &next
, end
);
1562 inst
->name
= *cur
!= '$' ? xstrdup (cur
) : "";
1564 for (param
= tmpl
->params
; param
; param
= param
->next
)
1566 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1568 cur
= next_field (next
, ':', &next
, end
);
1570 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1571 arg
->val
= xstrdup (cur
);
1572 arg
->next
= inst
->args
;
1576 if (tmpl
->instances
)
1577 last_inst
->next
= inst
;
1579 tmpl
->instances
= inst
;
1581 } while (sep
== ',');
1583 buf
= remove_leading_whitespaces (end
);
1585 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1586 filename
, lineno
, buf
);
1588 tmpl
->next
= templates
;
1593 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1594 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1596 static unsigned int idx
, opcode_array_size
;
1597 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1598 struct opcode_hash_entry
**hash_slot
;
1599 struct opcode_entry
*entry
;
1600 char *ptr1
= strchr(name
, '<'), *ptr2
;
1604 /* Get the slot in hash table. */
1605 hash_slot
= (struct opcode_hash_entry
**)
1606 htab_find_slot_with_hash (opcode_hash_table
, name
,
1607 htab_hash_string (name
),
1610 if (*hash_slot
== NULL
)
1612 /* It is the new one. Put it on opcode array. */
1613 if (idx
>= opcode_array_size
)
1615 /* Grow the opcode array when needed. */
1616 opcode_array_size
+= 1024;
1617 opcode_array
= (struct opcode_hash_entry
**)
1618 xrealloc (opcode_array
,
1619 sizeof (*opcode_array
) * opcode_array_size
);
1620 *opcode_array_p
= opcode_array
;
1623 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1624 xmalloc (sizeof (struct opcode_hash_entry
));
1625 opcode_array
[idx
]->name
= xstrdup (name
);
1626 *hash_slot
= opcode_array
[idx
];
1627 entry
= &opcode_array
[idx
]->entry
;
1632 /* Append it to the existing one. */
1633 struct opcode_entry
**entryp
= &(*hash_slot
)->entry
.next
;
1635 while (*entryp
!= NULL
)
1636 entryp
= &(*entryp
)->next
;
1637 entry
= (struct opcode_entry
*)xmalloc (sizeof (struct opcode_entry
));
1642 entry
->opcode
= xstrdup (str
);
1643 entry
->lineno
= lineno
;
1645 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1646 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1649 const struct template *tmpl
;
1650 const struct template_instance
*inst
;
1653 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1654 remove_trailing_whitespaces (ptr1
);
1658 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1659 if (!strcmp(ptr1
, tmpl
->name
))
1662 fail ("reference to unknown template '%s'\n", ptr1
);
1664 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1666 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1667 char *str2
= xmalloc(2 * strlen(str
));
1670 strcpy (name2
, name
);
1671 strcat (name2
, inst
->name
);
1672 strcat (name2
, ptr2
);
1674 for (ptr1
= str2
, src
= str
; *src
; )
1676 const char *ident
= tmpl
->name
, *end
;
1677 const struct template_param
*param
;
1678 const struct template_arg
*arg
;
1680 if ((*ptr1
= *src
++) != '<')
1685 while (ISSPACE(*src
))
1687 while (*ident
&& *src
== *ident
)
1689 while (ISSPACE(*src
))
1691 if (*src
!= ':' || *ident
!= '\0')
1693 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1694 ptr1
+= ident
- tmpl
->name
;
1697 while (ISSPACE(*++src
))
1701 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1704 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1705 param
= param
->next
, arg
= arg
->next
)
1707 if (end
- src
== strlen (param
->name
)
1708 && !memcmp (src
, param
->name
, end
- src
))
1716 fail ("template '%s' has no parameter '%.*s'\n",
1717 tmpl
->name
, (int)(end
- src
), src
);
1719 while (ISSPACE(*src
))
1722 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1724 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1725 ptr1
+= strlen(arg
->val
);
1731 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1742 static int mnemonic_cmp(const void *p1
, const void *p2
)
1744 const struct opcode_hash_entry
*const *e1
= p1
, *const *e2
= p2
;
1745 const char *s1
= (*e1
)->name
, *s2
= (*e2
)->name
;
1747 size_t l1
= strlen (s1
), l2
= strlen (s2
);
1749 for (i
= 1; i
<= l1
&& i
<= l2
; ++i
)
1751 if (s1
[l1
- i
] != s2
[l2
- i
])
1752 return (unsigned char)s1
[l1
- i
] - (unsigned char)s2
[l2
- i
];
1755 return (int)(l1
- l2
);
1759 process_i386_opcodes (FILE *table
)
1763 unsigned int i
, j
, nr
, offs
;
1765 char *str
, *p
, *last
;
1766 htab_t opcode_hash_table
;
1767 struct opcode_hash_entry
**opcode_array
= NULL
;
1768 int lineno
= 0, marker
= 0;
1770 filename
= "i386-opc.tbl";
1774 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1775 opcode_hash_eq
, NULL
,
1778 fprintf (table
, "\n#include \"i386-mnem.h\"\n");
1779 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1780 fprintf (table
, "static const insn_template i386_optab[] =\n{\n");
1782 /* Put everything on opcode array. */
1787 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1790 p
= remove_leading_whitespaces (buf
);
1796 /* Skip comments. */
1797 str
= strstr (p
, "//");
1801 remove_trailing_whitespaces (p
);
1805 /* Look for line continuation character. */
1806 remove_trailing_whitespaces (p
);
1808 if (!j
|| buf
[j
- 1] != '+')
1810 if (j
>= sizeof (buf
) - 1)
1811 fail ("%s: %d: (continued) line too long\n", filename
, lineno
);
1813 if (fgets (buf
+ j
- 1, sizeof (buf
) - j
+ 1, fp
) == NULL
)
1815 fprintf (stderr
, "%s: Line continuation on last line?\n",
1824 if (!strcmp("### MARKER ###", buf
))
1828 /* Since we ignore all included files (we only care about their
1829 #define-s here), we don't need to monitor filenames. The final
1830 line number directive is going to refer to the main source file
1835 p
= remove_leading_whitespaces (p
+ 1);
1836 if (!strncmp(p
, "line", 4))
1838 ln
= strtoul (p
, &end
, 10);
1839 if (ln
> 1 && ln
< INT_MAX
1840 && *remove_leading_whitespaces (end
) == '"')
1843 /* Ignore comments. */
1848 parse_template (p
, lineno
);
1856 last
= p
+ strlen (p
);
1859 name
= next_field (p
, ',', &str
, last
);
1861 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1865 /* Process opcode array. */
1866 for (j
= 0; j
< i
; j
++)
1868 const char *name
= opcode_array
[j
]->name
;
1869 struct opcode_entry
*next
;
1871 for (next
= &opcode_array
[j
]->entry
; next
; next
= next
->next
)
1874 lineno
= next
->lineno
;
1875 last
= str
+ strlen (str
);
1876 output_i386_opcode (table
, name
, str
, last
, lineno
);
1882 fprintf (table
, "};\n");
1884 /* Generate opcode sets array. */
1885 fprintf (table
, "\n/* i386 opcode sets table. */\n\n");
1886 fprintf (table
, "static const insn_template *const i386_op_sets[] =\n{\n");
1887 fprintf (table
, " i386_optab,\n");
1889 for (nr
= j
= 0; j
< i
; j
++)
1891 struct opcode_entry
*next
= &opcode_array
[j
]->entry
;
1899 fprintf (table
, " i386_optab + %u,\n", nr
);
1902 fprintf (table
, "};\n");
1904 /* Emit mnemonics and associated #define-s. */
1905 qsort (opcode_array
, i
, sizeof (*opcode_array
), mnemonic_cmp
);
1907 fp
= fopen ("i386-mnem.h", "w");
1909 fail ("can't create i386-mnem.h, errno = %s\n",
1912 process_copyright (fp
);
1914 fprintf (table
, "\n/* i386 mnemonics table. */\n\n");
1915 fprintf (table
, "const char i386_mnemonics[] =\n");
1916 fprintf (fp
, "\nextern const char i386_mnemonics[];\n\n");
1919 for (l
= strlen (opcode_array
[offs
= j
= 0]->name
); j
< i
; j
++)
1921 const char *name
= opcode_array
[j
]->name
;
1922 const char *next
= NULL
;
1923 size_t l1
= j
+ 1 < i
? strlen(next
= opcode_array
[j
+ 1]->name
) : 0;
1926 str
= mkident (name
);
1927 if (l
< l1
&& !strcmp(name
, next
+ l1
- l
))
1929 fprintf (fp
, "#define MN_%s ", str
);
1931 str
= mkident (next
);
1932 fprintf (fp
, "(MN_%s + %zu)\n", str
, l1
- l
);
1936 fprintf (table
, " \"\\0\"\"%s\"\n", name
);
1937 fprintf (fp
, "#define MN_%s %#x\n", str
, offs
+ 1);
1938 offs
+= strlen (name
) + 1;
1945 fprintf (table
, " \"\\0\"\".insn\"\n");
1946 fprintf (fp
, "#define MN__insn %#x\n", offs
+ 1);
1948 fprintf (table
, ";\n");
1954 process_i386_registers (FILE *table
)
1958 char *str
, *p
, *last
;
1959 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1960 char *dw2_32_num
, *dw2_64_num
;
1963 filename
= "i386-reg.tbl";
1964 fp
= fopen (filename
, "r");
1966 fail ("can't find i386-reg.tbl for reading, errno = %s\n",
1969 fprintf (table
, "\n/* i386 register table. */\n\n");
1970 fprintf (table
, "static const reg_entry i386_regtab[] =\n{\n");
1974 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1979 p
= remove_leading_whitespaces (buf
);
1981 /* Skip comments. */
1982 str
= strstr (p
, "//");
1986 /* Remove trailing white spaces. */
1987 remove_trailing_whitespaces (p
);
1992 fprintf (table
, "%s\n", p
);
2000 last
= p
+ strlen (p
);
2002 /* Find reg_name. */
2003 reg_name
= next_field (p
, ',', &str
, last
);
2005 /* Find reg_type. */
2006 reg_type
= next_field (str
, ',', &str
, last
);
2008 /* Find reg_flags. */
2009 reg_flags
= next_field (str
, ',', &str
, last
);
2012 reg_num
= next_field (str
, ',', &str
, last
);
2014 fprintf (table
, " { \"%s\",\n ", reg_name
);
2016 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
2019 /* Find 32-bit Dwarf2 register number. */
2020 dw2_32_num
= next_field (str
, ',', &str
, last
);
2022 /* Find 64-bit Dwarf2 register number. */
2023 dw2_64_num
= next_field (str
, ',', &str
, last
);
2025 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
2026 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
2031 fprintf (table
, "};\n");
2033 fprintf (table
, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
2037 process_i386_initializers (void)
2040 FILE *fp
= fopen ("i386-init.h", "w");
2043 fail ("can't create i386-init.h, errno = %s\n",
2046 process_copyright (fp
);
2048 for (i
= 0; i
< CpuMax
; i
++)
2049 process_i386_cpu_flag (fp
, "0", cpu_flags
[i
].name
, "", " ", -1, i
);
2051 for (i
= 0; i
< ARRAY_SIZE (isa_dependencies
); i
++)
2053 char *deps
= xstrdup (isa_dependencies
[i
].deps
);
2055 process_i386_cpu_flag (fp
, deps
, isa_dependencies
[i
].name
,
2056 "", " ", -1, CpuMax
);
2060 /* Early x87 is somewhat special: Both 287 and 387 not only add new insns
2061 but also remove some. Hence 8087 isn't a prereq to 287, and 287 isn't
2062 one to 387. We want the reverse to be true though: Disabling 8087 also
2063 is to disable 287+ and later; disabling 287 also means disabling 387+. */
2064 memcpy (isa_reverse_deps
[Cpu287
], isa_reverse_deps
[Cpu387
],
2065 sizeof (isa_reverse_deps
[0]));
2066 isa_reverse_deps
[Cpu287
][Cpu387
] = 1;
2067 memcpy (isa_reverse_deps
[Cpu8087
], isa_reverse_deps
[Cpu287
],
2068 sizeof (isa_reverse_deps
[0]));
2069 isa_reverse_deps
[Cpu8087
][Cpu287
] = 1;
2071 /* While we treat POPCNT as a prereq to SSE4.2, its disabling should not
2072 lead to disabling of anything else. */
2073 memset (isa_reverse_deps
[CpuPOPCNT
], 0, sizeof (isa_reverse_deps
[0]));
2075 for (i
= Cpu686
+ 1; i
< ARRAY_SIZE (isa_reverse_deps
); i
++)
2080 if (memchr(isa_reverse_deps
[i
], 1,
2081 ARRAY_SIZE (isa_reverse_deps
[0])) == NULL
)
2084 isa_reverse_deps
[i
][i
] = 1;
2085 process_i386_cpu_flag (fp
, NULL
, cpu_flags
[i
].name
, "", " ", -1, i
);
2093 /* Program options. */
2094 #define OPTION_SRCDIR 200
2096 struct option long_options
[] =
2098 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2099 {"debug", no_argument
, NULL
, 'd'},
2100 {"version", no_argument
, NULL
, 'V'},
2101 {"help", no_argument
, NULL
, 'h'},
2102 {0, no_argument
, NULL
, 0}
2106 print_version (void)
2108 printf ("%s: version 1.0\n", program_name
);
2113 usage (FILE * stream
, int status
)
2115 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2121 main (int argc
, char **argv
)
2123 extern int chdir (char *);
2124 char *srcdir
= NULL
;
2126 unsigned int i
, cpumax
;
2129 program_name
= *argv
;
2130 xmalloc_set_program_name (program_name
);
2132 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2157 if (chdir (srcdir
) != 0)
2158 fail ("unable to change directory to \"%s\", errno = %s\n",
2159 srcdir
, xstrerror (errno
));
2161 /* cpu_flags isn't sorted by position. */
2163 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
2164 if (cpu_flags
[i
].position
> cpumax
)
2165 cpumax
= cpu_flags
[i
].position
;
2167 /* Check the unused bitfield in i386_cpu_flags. */
2169 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
2171 if ((cpumax
- 1) != CpuMax
)
2172 fail ("CpuMax != %d!\n", cpumax
);
2174 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
2176 if (cpumax
!= CpuMax
)
2177 fail ("CpuMax != %d!\n", cpumax
);
2179 c
= CpuNumOfBits
- CpuMax
- 1;
2181 fail ("%d unused bits in i386_cpu_flags.\n", c
);
2184 /* If this triggers, CpuIsaBits needs to be increased. */
2185 static_assert (CpuAttrEnums
<= (1u << CpuIsaBits
));
2187 /* Check the unused bitfield in i386_cpu_attr. */
2188 #ifndef CpuAttrUnused
2189 c
= CpuAttrNumOfBits
- (CpuIsaBits
+ CpuMax
+ 1 - CpuAttrEnums
);
2191 fail ("%d unused bits in i386_cpu_attr.\n", c
);
2194 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
2196 /* Check the unused bitfield in i386_operand_type. */
2198 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2201 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2204 c
= OTNumOfBits
- OTNum
;
2206 fail ("%d unused bits in i386_operand_type.\n", c
);
2209 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2212 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2213 sizeof (opcode_modifiers
[0]), compare
);
2215 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2216 sizeof (operand_types
[0]), compare
);
2218 process_i386_initializers ();
2220 table
= fopen ("i386-tbl.h", "w");
2222 fail ("can't create i386-tbl.h, errno = %s\n",
2225 process_copyright (table
);
2227 process_i386_opcodes (table
);
2228 process_i386_registers (table
);