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 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
1205 output_operand_type (FILE *table
, enum operand_class
class,
1206 enum operand_instance instance
,
1207 const bitfield
*types
, unsigned int size
,
1208 enum stage stage
, const char *indent
)
1212 fprintf (table
, "{ { %d, %d, ", class, instance
);
1214 for (i
= 0; i
< size
- 1; i
++)
1216 if (((i
+ 3) % 20) != 0)
1217 fprintf (table
, "%d, ", types
[i
].value
);
1219 fprintf (table
, "%d,", types
[i
].value
);
1220 if (((i
+ 3) % 20) == 0)
1222 /* We need \\ for macro. */
1223 if (stage
== stage_macros
)
1224 fprintf (table
, " \\\n%s", indent
);
1226 fprintf (table
, "\n%s", indent
);
1230 fprintf (table
, "%d } }", types
[i
].value
);
1234 process_i386_operand_type (FILE *table
, char *op
, enum stage stage
,
1235 const char *indent
, int lineno
)
1237 char *str
, *next
, *last
;
1238 enum operand_class
class = ClassNone
;
1239 enum operand_instance instance
= InstanceNone
;
1240 bitfield types
[ARRAY_SIZE (operand_types
)];
1242 /* Copy the default operand type. */
1243 memcpy (types
, operand_types
, sizeof (types
));
1245 if (strcmp (op
, "0"))
1249 last
= op
+ strlen (op
);
1250 for (next
= op
; next
&& next
< last
; )
1252 str
= next_field (next
, '|', &next
, last
);
1257 if (!strncmp(str
, "Class=", 6))
1259 for (i
= 0; i
< ARRAY_SIZE(operand_classes
); ++i
)
1260 if (!strcmp(str
+ 6, operand_classes
[i
].name
))
1262 class = operand_classes
[i
].value
;
1268 if (str
&& !strncmp(str
, "Instance=", 9))
1270 for (i
= 0; i
< ARRAY_SIZE(operand_instances
); ++i
)
1271 if (!strcmp(str
+ 9, operand_instances
[i
].name
))
1273 instance
= operand_instances
[i
].value
;
1281 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
1282 if (strcasecmp(str
, "BaseIndex") == 0)
1287 if (stage
== stage_opcodes
&& baseindex
&& !active_isstring
)
1289 set_bitfield("Disp8", types
, 1, ARRAY_SIZE (types
), lineno
);
1290 if (!active_cpu_flags
.bitfield
.cpu64
1291 && !active_cpu_flags
.bitfield
.cpumpx
)
1292 set_bitfield("Disp16", types
, 1, ARRAY_SIZE (types
), lineno
);
1293 set_bitfield("Disp32", types
, 1, ARRAY_SIZE (types
), lineno
);
1296 output_operand_type (table
, class, instance
, types
, ARRAY_SIZE (types
),
1300 static char *mkident (const char *mnem
)
1302 char *ident
= xstrdup (mnem
), *p
= ident
;
1315 output_i386_opcode (FILE *table
, const char *name
, char *str
,
1316 char *last
, int lineno
)
1318 unsigned int i
, length
, prefix
= 0, space
= 0;
1319 char *base_opcode
, *extension_opcode
, *end
, *ident
;
1320 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
1321 unsigned long long opcode
;
1323 /* Find base_opcode. */
1324 base_opcode
= next_field (str
, ',', &str
, last
);
1326 /* Find extension_opcode, if any. */
1327 extension_opcode
= strchr (base_opcode
, '/');
1328 if (extension_opcode
)
1329 *extension_opcode
++ = '\0';
1331 /* Find cpu_flags. */
1332 cpu_flags
= next_field (str
, ',', &str
, last
);
1334 /* Find opcode_modifier. */
1335 opcode_modifier
= next_field (str
, ',', &str
, last
);
1337 /* Remove the first {. */
1338 str
= remove_leading_whitespaces (str
);
1341 str
= remove_leading_whitespaces (str
+ 1);
1342 remove_trailing_whitespaces (str
);
1344 /* Remove } and trailing white space. */
1346 if (!i
|| str
[i
- 1] != '}')
1349 remove_trailing_whitespaces (str
);
1352 operand_types
[i
= 0] = NULL
;
1355 last
= str
+ strlen (str
);
1357 /* Find operand_types. */
1358 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1362 operand_types
[i
] = NULL
;
1366 operand_types
[i
] = next_field (str
, ',', &str
, last
);
1370 opcode
= strtoull (base_opcode
, &end
, 0);
1372 /* Determine opcode length. */
1373 for (length
= 1; length
< 8; ++length
)
1374 if (!(opcode
>> (8 * length
)))
1377 /* Transform prefixes encoded in the opcode into opcode modifier
1381 switch (opcode
>> (8 * length
- 8))
1383 case 0x66: prefix
= PREFIX_0X66
; break;
1384 case 0xF3: prefix
= PREFIX_0XF3
; break;
1385 case 0xF2: prefix
= PREFIX_0XF2
; break;
1389 opcode
&= (1ULL << (8 * --length
)) - 1;
1392 /* Transform opcode space encoded in the opcode into opcode modifier
1394 if (length
> 1 && (opcode
>> (8 * length
- 8)) == 0xf)
1396 switch ((opcode
>> (8 * length
- 16)) & 0xff)
1398 default: space
= SPACE_0F
; break;
1399 case 0x38: space
= SPACE_0F38
; break;
1400 case 0x3A: space
= SPACE_0F3A
; break;
1403 if (space
!= SPACE_0F
&& --length
== 1)
1404 fail ("%s:%d: %s: unrecognized opcode encoding space\n",
1405 filename
, lineno
, name
);
1406 opcode
&= (1ULL << (8 * --length
)) - 1;
1410 fail ("%s:%d: %s: residual opcode (0x%0*llx) too large\n",
1411 filename
, lineno
, name
, 2 * length
, opcode
);
1413 ident
= mkident (name
);
1414 fprintf (table
, " { MN_%s, 0x%0*llx%s, %u,",
1415 ident
, 2 * (int)length
, opcode
, end
, i
);
1418 process_i386_opcode_modifier (table
, opcode_modifier
, space
, prefix
,
1419 extension_opcode
, operand_types
, lineno
);
1421 process_i386_cpu_flag (table
, cpu_flags
, NULL
, ",", " ", lineno
, CpuMax
);
1423 fprintf (table
, " { ");
1425 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
1427 if (!operand_types
[i
])
1430 process_i386_operand_type (table
, "0", stage_opcodes
, "\t ",
1436 fprintf (table
, ",\n ");
1438 process_i386_operand_type (table
, operand_types
[i
], stage_opcodes
,
1441 fprintf (table
, " } },\n");
1444 struct opcode_hash_entry
1449 struct opcode_entry
*next
;
1455 /* Calculate the hash value of an opcode hash entry P. */
1458 opcode_hash_hash (const void *p
)
1460 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1461 return htab_hash_string (entry
->name
);
1464 /* Compare a string Q against an opcode hash entry P. */
1467 opcode_hash_eq (const void *p
, const void *q
)
1469 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
1470 const char *name
= (const char *) q
;
1471 return strcmp (name
, entry
->name
) == 0;
1475 parse_template (char *buf
, int lineno
)
1477 char sep
, *end
, *name
;
1478 struct template *tmpl
;
1479 struct template_instance
*last_inst
= NULL
;
1481 buf
= remove_leading_whitespaces (buf
+ 1);
1482 end
= strchr (buf
, ':');
1485 struct template *prev
= NULL
;
1487 end
= strchr (buf
, '>');
1489 fail ("%s: %d: missing ':' or '>'\n", filename
, lineno
);
1490 if (*remove_leading_whitespaces (end
+ 1))
1491 fail ("%s: %d: malformed template purge\n", filename
, lineno
);
1493 remove_trailing_whitespaces (buf
);
1494 /* Don't bother freeing the various structures. */
1495 for (tmpl
= templates
; tmpl
!= NULL
; tmpl
= (prev
= tmpl
)->next
)
1496 if (!strcmp (buf
, tmpl
->name
))
1499 fail ("%s: %d: no template '%s'\n", filename
, lineno
, buf
);
1501 prev
->next
= tmpl
->next
;
1503 templates
= tmpl
->next
;
1507 remove_trailing_whitespaces (buf
);
1510 fail ("%s: %d: missing template identifier\n", filename
, lineno
);
1511 tmpl
= xmalloc (sizeof (*tmpl
));
1512 tmpl
->name
= xstrdup (buf
);
1514 tmpl
->params
= NULL
;
1516 struct template_param
*param
;
1518 buf
= remove_leading_whitespaces (end
);
1519 end
= strpbrk (buf
, ":,");
1521 fail ("%s: %d: missing ':' or ','\n", filename
, lineno
);
1525 remove_trailing_whitespaces (buf
);
1527 param
= xmalloc (sizeof (*param
));
1528 param
->name
= xstrdup (buf
);
1529 param
->next
= tmpl
->params
;
1530 tmpl
->params
= param
;
1531 } while (sep
== ':');
1533 tmpl
->instances
= NULL
;
1535 struct template_instance
*inst
;
1537 const struct template_param
*param
;
1539 buf
= remove_leading_whitespaces (end
);
1540 end
= strpbrk (buf
, ",>");
1542 fail ("%s: %d: missing ',' or '>'\n", filename
, lineno
);
1547 inst
= xmalloc (sizeof (*inst
));
1551 cur
= next_field (buf
, ':', &next
, end
);
1552 inst
->name
= *cur
!= '$' ? xstrdup (cur
) : "";
1554 for (param
= tmpl
->params
; param
; param
= param
->next
)
1556 struct template_arg
*arg
= xmalloc (sizeof (*arg
));
1558 cur
= next_field (next
, ':', &next
, end
);
1560 fail ("%s: %d: missing argument for '%s'\n", filename
, lineno
, param
->name
);
1561 arg
->val
= xstrdup (cur
);
1562 arg
->next
= inst
->args
;
1566 if (tmpl
->instances
)
1567 last_inst
->next
= inst
;
1569 tmpl
->instances
= inst
;
1571 } while (sep
== ',');
1573 buf
= remove_leading_whitespaces (end
);
1575 fprintf(stderr
, "%s: %d: excess characters '%s'\n",
1576 filename
, lineno
, buf
);
1578 tmpl
->next
= templates
;
1583 expand_templates (char *name
, const char *str
, htab_t opcode_hash_table
,
1584 struct opcode_hash_entry
***opcode_array_p
, int lineno
)
1586 static unsigned int idx
, opcode_array_size
;
1587 struct opcode_hash_entry
**opcode_array
= *opcode_array_p
;
1588 struct opcode_hash_entry
**hash_slot
;
1589 struct opcode_entry
*entry
;
1590 char *ptr1
= strchr(name
, '<'), *ptr2
;
1594 /* Get the slot in hash table. */
1595 hash_slot
= (struct opcode_hash_entry
**)
1596 htab_find_slot_with_hash (opcode_hash_table
, name
,
1597 htab_hash_string (name
),
1600 if (*hash_slot
== NULL
)
1602 /* It is the new one. Put it on opcode array. */
1603 if (idx
>= opcode_array_size
)
1605 /* Grow the opcode array when needed. */
1606 opcode_array_size
+= 1024;
1607 opcode_array
= (struct opcode_hash_entry
**)
1608 xrealloc (opcode_array
,
1609 sizeof (*opcode_array
) * opcode_array_size
);
1610 *opcode_array_p
= opcode_array
;
1613 opcode_array
[idx
] = (struct opcode_hash_entry
*)
1614 xmalloc (sizeof (struct opcode_hash_entry
));
1615 opcode_array
[idx
]->name
= xstrdup (name
);
1616 *hash_slot
= opcode_array
[idx
];
1617 entry
= &opcode_array
[idx
]->entry
;
1622 /* Append it to the existing one. */
1623 struct opcode_entry
**entryp
= &(*hash_slot
)->entry
.next
;
1625 while (*entryp
!= NULL
)
1626 entryp
= &(*entryp
)->next
;
1627 entry
= (struct opcode_entry
*)xmalloc (sizeof (struct opcode_entry
));
1632 entry
->opcode
= xstrdup (str
);
1633 entry
->lineno
= lineno
;
1635 else if ((ptr2
= strchr(ptr1
+ 1, '>')) == NULL
)
1636 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1639 const struct template *tmpl
;
1640 const struct template_instance
*inst
;
1643 ptr1
= remove_leading_whitespaces (ptr1
+ 1);
1644 remove_trailing_whitespaces (ptr1
);
1648 for ( tmpl
= templates
; tmpl
; tmpl
= tmpl
->next
)
1649 if (!strcmp(ptr1
, tmpl
->name
))
1652 fail ("reference to unknown template '%s'\n", ptr1
);
1654 for (inst
= tmpl
->instances
; inst
; inst
= inst
->next
)
1656 char *name2
= xmalloc(strlen(name
) + strlen(inst
->name
) + strlen(ptr2
) + 1);
1657 char *str2
= xmalloc(2 * strlen(str
));
1660 strcpy (name2
, name
);
1661 strcat (name2
, inst
->name
);
1662 strcat (name2
, ptr2
);
1664 for (ptr1
= str2
, src
= str
; *src
; )
1666 const char *ident
= tmpl
->name
, *end
;
1667 const struct template_param
*param
;
1668 const struct template_arg
*arg
;
1670 if ((*ptr1
= *src
++) != '<')
1675 while (ISSPACE(*src
))
1677 while (*ident
&& *src
== *ident
)
1679 while (ISSPACE(*src
))
1681 if (*src
!= ':' || *ident
!= '\0')
1683 memcpy (++ptr1
, tmpl
->name
, ident
- tmpl
->name
);
1684 ptr1
+= ident
- tmpl
->name
;
1687 while (ISSPACE(*++src
))
1691 while (*end
!= '\0' && !ISSPACE(*end
) && *end
!= '>')
1694 for (param
= tmpl
->params
, arg
= inst
->args
; param
;
1695 param
= param
->next
, arg
= arg
->next
)
1697 if (end
- src
== strlen (param
->name
)
1698 && !memcmp (src
, param
->name
, end
- src
))
1706 fail ("template '%s' has no parameter '%.*s'\n",
1707 tmpl
->name
, (int)(end
- src
), src
);
1709 while (ISSPACE(*src
))
1712 fail ("%s: %d: missing '>'\n", filename
, lineno
);
1714 memcpy(ptr1
, arg
->val
, strlen(arg
->val
));
1715 ptr1
+= strlen(arg
->val
);
1721 expand_templates (name2
, str2
, opcode_hash_table
, opcode_array_p
,
1732 static int mnemonic_cmp(const void *p1
, const void *p2
)
1734 const struct opcode_hash_entry
*const *e1
= p1
, *const *e2
= p2
;
1735 const char *s1
= (*e1
)->name
, *s2
= (*e2
)->name
;
1737 size_t l1
= strlen (s1
), l2
= strlen (s2
);
1739 for (i
= 1; i
<= l1
&& i
<= l2
; ++i
)
1741 if (s1
[l1
- i
] != s2
[l2
- i
])
1742 return (unsigned char)s1
[l1
- i
] - (unsigned char)s2
[l2
- i
];
1745 return (int)(l1
- l2
);
1749 process_i386_opcodes (FILE *table
)
1753 unsigned int i
, j
, nr
, offs
;
1755 char *str
, *p
, *last
;
1756 htab_t opcode_hash_table
;
1757 struct opcode_hash_entry
**opcode_array
= NULL
;
1758 int lineno
= 0, marker
= 0;
1760 filename
= "i386-opc.tbl";
1764 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
1765 opcode_hash_eq
, NULL
,
1768 fprintf (table
, "\n#include \"i386-mnem.h\"\n");
1769 fprintf (table
, "\n/* i386 opcode table. */\n\n");
1770 fprintf (table
, "static const insn_template i386_optab[] =\n{\n");
1772 /* Put everything on opcode array. */
1777 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1780 p
= remove_leading_whitespaces (buf
);
1786 /* Skip comments. */
1787 str
= strstr (p
, "//");
1791 remove_trailing_whitespaces (p
);
1795 /* Look for line continuation character. */
1796 remove_trailing_whitespaces (p
);
1798 if (!j
|| buf
[j
- 1] != '+')
1800 if (j
>= sizeof (buf
) - 1)
1801 fail ("%s: %d: (continued) line too long\n", filename
, lineno
);
1803 if (fgets (buf
+ j
- 1, sizeof (buf
) - j
+ 1, fp
) == NULL
)
1805 fprintf (stderr
, "%s: Line continuation on last line?\n",
1814 if (!strcmp("### MARKER ###", buf
))
1818 /* Since we ignore all included files (we only care about their
1819 #define-s here), we don't need to monitor filenames. The final
1820 line number directive is going to refer to the main source file
1825 p
= remove_leading_whitespaces (p
+ 1);
1826 if (!strncmp(p
, "line", 4))
1828 ln
= strtoul (p
, &end
, 10);
1829 if (ln
> 1 && ln
< INT_MAX
1830 && *remove_leading_whitespaces (end
) == '"')
1833 /* Ignore comments. */
1838 parse_template (p
, lineno
);
1846 last
= p
+ strlen (p
);
1849 name
= next_field (p
, ',', &str
, last
);
1851 i
= expand_templates (name
, str
, opcode_hash_table
, &opcode_array
,
1855 /* Process opcode array. */
1856 for (j
= 0; j
< i
; j
++)
1858 const char *name
= opcode_array
[j
]->name
;
1859 struct opcode_entry
*next
;
1861 for (next
= &opcode_array
[j
]->entry
; next
; next
= next
->next
)
1864 lineno
= next
->lineno
;
1865 last
= str
+ strlen (str
);
1866 output_i386_opcode (table
, name
, str
, last
, lineno
);
1872 fprintf (table
, "};\n");
1874 /* Generate opcode sets array. */
1875 fprintf (table
, "\n/* i386 opcode sets table. */\n\n");
1876 fprintf (table
, "static const insn_template *const i386_op_sets[] =\n{\n");
1877 fprintf (table
, " i386_optab,\n");
1879 for (nr
= j
= 0; j
< i
; j
++)
1881 struct opcode_entry
*next
= &opcode_array
[j
]->entry
;
1889 fprintf (table
, " i386_optab + %u,\n", nr
);
1892 fprintf (table
, "};\n");
1894 /* Emit mnemonics and associated #define-s. */
1895 qsort (opcode_array
, i
, sizeof (*opcode_array
), mnemonic_cmp
);
1897 fp
= fopen ("i386-mnem.h", "w");
1899 fail ("can't create i386-mnem.h, errno = %s\n",
1902 process_copyright (fp
);
1904 fprintf (table
, "\n/* i386 mnemonics table. */\n\n");
1905 fprintf (table
, "const char i386_mnemonics[] =\n");
1906 fprintf (fp
, "\nextern const char i386_mnemonics[];\n\n");
1909 for (l
= strlen (opcode_array
[offs
= j
= 0]->name
); j
< i
; j
++)
1911 const char *name
= opcode_array
[j
]->name
;
1912 const char *next
= NULL
;
1913 size_t l1
= j
+ 1 < i
? strlen(next
= opcode_array
[j
+ 1]->name
) : 0;
1916 str
= mkident (name
);
1917 if (l
< l1
&& !strcmp(name
, next
+ l1
- l
))
1919 fprintf (fp
, "#define MN_%s ", str
);
1921 str
= mkident (next
);
1922 fprintf (fp
, "(MN_%s + %zu)\n", str
, l1
- l
);
1926 fprintf (table
, " \"\\0\"\"%s\"\n", name
);
1927 fprintf (fp
, "#define MN_%s %#x\n", str
, offs
+ 1);
1928 offs
+= strlen (name
) + 1;
1935 fprintf (table
, " \"\\0\"\".insn\"\n");
1936 fprintf (fp
, "#define MN__insn %#x\n", offs
+ 1);
1938 fprintf (table
, ";\n");
1944 process_i386_registers (FILE *table
)
1948 char *str
, *p
, *last
;
1949 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1950 char *dw2_32_num
, *dw2_64_num
;
1953 filename
= "i386-reg.tbl";
1954 fp
= fopen (filename
, "r");
1956 fail ("can't find i386-reg.tbl for reading, errno = %s\n",
1959 fprintf (table
, "\n/* i386 register table. */\n\n");
1960 fprintf (table
, "static const reg_entry i386_regtab[] =\n{\n");
1964 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1969 p
= remove_leading_whitespaces (buf
);
1971 /* Skip comments. */
1972 str
= strstr (p
, "//");
1976 /* Remove trailing white spaces. */
1977 remove_trailing_whitespaces (p
);
1982 fprintf (table
, "%s\n", p
);
1990 last
= p
+ strlen (p
);
1992 /* Find reg_name. */
1993 reg_name
= next_field (p
, ',', &str
, last
);
1995 /* Find reg_type. */
1996 reg_type
= next_field (str
, ',', &str
, last
);
1998 /* Find reg_flags. */
1999 reg_flags
= next_field (str
, ',', &str
, last
);
2002 reg_num
= next_field (str
, ',', &str
, last
);
2004 fprintf (table
, " { \"%s\",\n ", reg_name
);
2006 process_i386_operand_type (table
, reg_type
, stage_registers
, "\t",
2009 /* Find 32-bit Dwarf2 register number. */
2010 dw2_32_num
= next_field (str
, ',', &str
, last
);
2012 /* Find 64-bit Dwarf2 register number. */
2013 dw2_64_num
= next_field (str
, ',', &str
, last
);
2015 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
2016 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
2021 fprintf (table
, "};\n");
2023 fprintf (table
, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
2027 process_i386_initializers (void)
2030 FILE *fp
= fopen ("i386-init.h", "w");
2033 fail ("can't create i386-init.h, errno = %s\n",
2036 process_copyright (fp
);
2038 for (i
= 0; i
< CpuMax
; i
++)
2039 process_i386_cpu_flag (fp
, "0", cpu_flags
[i
].name
, "", " ", -1, i
);
2041 for (i
= 0; i
< ARRAY_SIZE (isa_dependencies
); i
++)
2043 char *deps
= xstrdup (isa_dependencies
[i
].deps
);
2045 process_i386_cpu_flag (fp
, deps
, isa_dependencies
[i
].name
,
2046 "", " ", -1, CpuMax
);
2050 /* Early x87 is somewhat special: Both 287 and 387 not only add new insns
2051 but also remove some. Hence 8087 isn't a prereq to 287, and 287 isn't
2052 one to 387. We want the reverse to be true though: Disabling 8087 also
2053 is to disable 287+ and later; disabling 287 also means disabling 387+. */
2054 memcpy (isa_reverse_deps
[Cpu287
], isa_reverse_deps
[Cpu387
],
2055 sizeof (isa_reverse_deps
[0]));
2056 isa_reverse_deps
[Cpu287
][Cpu387
] = 1;
2057 memcpy (isa_reverse_deps
[Cpu8087
], isa_reverse_deps
[Cpu287
],
2058 sizeof (isa_reverse_deps
[0]));
2059 isa_reverse_deps
[Cpu8087
][Cpu287
] = 1;
2061 /* While we treat POPCNT as a prereq to SSE4.2, its disabling should not
2062 lead to disabling of anything else. */
2063 memset (isa_reverse_deps
[CpuPOPCNT
], 0, sizeof (isa_reverse_deps
[0]));
2065 for (i
= Cpu686
+ 1; i
< ARRAY_SIZE (isa_reverse_deps
); i
++)
2070 if (memchr(isa_reverse_deps
[i
], 1,
2071 ARRAY_SIZE (isa_reverse_deps
[0])) == NULL
)
2074 isa_reverse_deps
[i
][i
] = 1;
2075 process_i386_cpu_flag (fp
, NULL
, cpu_flags
[i
].name
, "", " ", -1, i
);
2083 /* Program options. */
2084 #define OPTION_SRCDIR 200
2086 struct option long_options
[] =
2088 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2089 {"debug", no_argument
, NULL
, 'd'},
2090 {"version", no_argument
, NULL
, 'V'},
2091 {"help", no_argument
, NULL
, 'h'},
2092 {0, no_argument
, NULL
, 0}
2096 print_version (void)
2098 printf ("%s: version 1.0\n", program_name
);
2103 usage (FILE * stream
, int status
)
2105 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2111 main (int argc
, char **argv
)
2113 extern int chdir (char *);
2114 char *srcdir
= NULL
;
2116 unsigned int i
, cpumax
;
2119 program_name
= *argv
;
2120 xmalloc_set_program_name (program_name
);
2122 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2147 if (chdir (srcdir
) != 0)
2148 fail ("unable to change directory to \"%s\", errno = %s\n",
2149 srcdir
, xstrerror (errno
));
2151 /* cpu_flags isn't sorted by position. */
2153 for (i
= 0; i
< ARRAY_SIZE (cpu_flags
); i
++)
2154 if (cpu_flags
[i
].position
> cpumax
)
2155 cpumax
= cpu_flags
[i
].position
;
2157 /* Check the unused bitfield in i386_cpu_flags. */
2159 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 2);
2161 if ((cpumax
- 1) != CpuMax
)
2162 fail ("CpuMax != %d!\n", cpumax
);
2164 static_assert (ARRAY_SIZE (cpu_flags
) == CpuMax
+ 1);
2166 if (cpumax
!= CpuMax
)
2167 fail ("CpuMax != %d!\n", cpumax
);
2169 c
= CpuNumOfBits
- CpuMax
- 1;
2171 fail ("%d unused bits in i386_cpu_flags.\n", c
);
2174 /* If this triggers, CpuIsaBits needs to be increased. */
2175 static_assert (CpuAttrEnums
<= (1u << CpuIsaBits
));
2177 /* Check the unused bitfield in i386_cpu_attr. */
2178 #ifndef CpuAttrUnused
2179 c
= CpuAttrNumOfBits
- (CpuIsaBits
+ CpuMax
+ 1 - CpuAttrEnums
);
2181 fail ("%d unused bits in i386_cpu_attr.\n", c
);
2184 static_assert (ARRAY_SIZE (opcode_modifiers
) == Opcode_Modifier_Num
);
2186 /* Check the unused bitfield in i386_operand_type. */
2188 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2191 static_assert (ARRAY_SIZE (operand_types
) + CLASS_WIDTH
+ INSTANCE_WIDTH
2194 c
= OTNumOfBits
- OTNum
;
2196 fail ("%d unused bits in i386_operand_type.\n", c
);
2199 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
2202 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
2203 sizeof (opcode_modifiers
[0]), compare
);
2205 qsort (operand_types
, ARRAY_SIZE (operand_types
),
2206 sizeof (operand_types
[0]), compare
);
2208 process_i386_initializers ();
2210 table
= fopen ("i386-tbl.h", "w");
2212 fail ("can't create i386-tbl.h, errno = %s\n",
2215 process_copyright (table
);
2217 process_i386_opcodes (table
);
2218 process_i386_registers (table
);