]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/i386-gen.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / opcodes / i386-gen.c
CommitLineData
82704155 1/* Copyright (C) 2007-2019 Free Software Foundation, Inc.
40b8e679 2
9b201bb5 3 This file is part of the GNU opcodes library.
40b8e679 4
9b201bb5 5 This library is free software; you can redistribute it and/or modify
40b8e679 6 it under the terms of the GNU General Public License as published by
9b201bb5
NC
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
40b8e679 9
9b201bb5
NC
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.
40b8e679
L
14
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
9b201bb5
NC
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
40b8e679 19
40fb9820 20#include "sysdep.h"
40b8e679 21#include <stdio.h>
40b8e679
L
22#include <errno.h>
23#include "getopt.h"
24#include "libiberty.h"
c587b3f9 25#include "hashtab.h"
40b8e679
L
26#include "safe-ctype.h"
27
28#include "i386-opc.h"
29
30#include <libintl.h>
31#define _(String) gettext (String)
32
1d942ae9
JB
33/* Build-time checks are preferrable over runtime ones. Use this construct
34 in preference where possible. */
35#define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
36
40b8e679
L
37static const char *program_name = NULL;
38static int debug = 0;
39
40fb9820
L
40typedef struct initializer
41{
42 const char *name;
43 const char *init;
44} initializer;
45
8acd5377 46static initializer cpu_flag_init[] =
40fb9820
L
47{
48 { "CPU_UNKNOWN_FLAGS",
7a9068fe 49 "~(CpuL1OM|CpuK1OM)" },
40fb9820
L
50 { "CPU_GENERIC32_FLAGS",
51 "Cpu186|Cpu286|Cpu386" },
29c048b6 52 { "CPU_GENERIC64_FLAGS",
1848e567 53 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
40fb9820
L
54 { "CPU_NONE_FLAGS",
55 "0" },
56 { "CPU_I186_FLAGS",
57 "Cpu186" },
58 { "CPU_I286_FLAGS",
1848e567 59 "CPU_I186_FLAGS|Cpu286" },
40fb9820 60 { "CPU_I386_FLAGS",
1848e567 61 "CPU_I286_FLAGS|Cpu386" },
40fb9820 62 { "CPU_I486_FLAGS",
1848e567 63 "CPU_I386_FLAGS|Cpu486" },
40fb9820 64 { "CPU_I586_FLAGS",
0e0eea78 65 "CPU_I486_FLAGS|Cpu387|Cpu586" },
40fb9820 66 { "CPU_I686_FLAGS",
d871f3f4 67 "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" },
22109423 68 { "CPU_PENTIUMPRO_FLAGS",
1848e567 69 "CPU_I686_FLAGS|CpuNop" },
40fb9820 70 { "CPU_P2_FLAGS",
1848e567 71 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
40fb9820 72 { "CPU_P3_FLAGS",
1848e567 73 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
40fb9820 74 { "CPU_P4_FLAGS",
1848e567 75 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
40fb9820 76 { "CPU_NOCONA_FLAGS",
1848e567 77 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
40fb9820 78 { "CPU_CORE_FLAGS",
1848e567 79 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
40fb9820 80 { "CPU_CORE2_FLAGS",
1848e567 81 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
bd5295b2 82 { "CPU_COREI7_FLAGS",
1848e567 83 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
40fb9820 84 { "CPU_K6_FLAGS",
1848e567 85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
40fb9820 86 { "CPU_K6_2_FLAGS",
1848e567 87 "CPU_K6_FLAGS|Cpu3dnow" },
40fb9820 88 { "CPU_ATHLON_FLAGS",
1848e567 89 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
40fb9820 90 { "CPU_K8_FLAGS",
1848e567 91 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
40fb9820 92 { "CPU_AMDFAM10_FLAGS",
1848e567 93 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
68339fdf 94 { "CPU_BDVER1_FLAGS",
59ef5df4 95 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
4cab4add 96 { "CPU_BDVER2_FLAGS",
1848e567 97 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
5e5c50d3 98 { "CPU_BDVER3_FLAGS",
1848e567 99 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
c7b0bd56 100 { "CPU_BDVER4_FLAGS",
1848e567 101 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
029f3522 102 { "CPU_ZNVER1_FLAGS",
59ef5df4 103 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
a9660a6f 104 { "CPU_ZNVER2_FLAGS",
142861df 105 "CPU_ZNVER1_FLAGS|CpuCLWB|CpuRDPID|CpuRDPRU|CpuMCOMMIT|CpuWBNOINVD" },
7b458c12 106 { "CPU_BTVER1_FLAGS",
1848e567 107 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
7b458c12 108 { "CPU_BTVER2_FLAGS",
59ef5df4 109 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
309d3373
JB
110 { "CPU_8087_FLAGS",
111 "Cpu8087" },
112 { "CPU_287_FLAGS",
0e0eea78 113 "Cpu287" },
309d3373 114 { "CPU_387_FLAGS",
0e0eea78 115 "Cpu387" },
1848e567
L
116 { "CPU_687_FLAGS",
117 "CPU_387_FLAGS|Cpu687" },
d871f3f4
L
118 { "CPU_CMOV_FLAGS",
119 "CpuCMOV" },
120 { "CPU_FXSR_FLAGS",
121 "CpuFXSR" },
bd5295b2
L
122 { "CPU_CLFLUSH_FLAGS",
123 "CpuClflush" },
22109423
L
124 { "CPU_NOP_FLAGS",
125 "CpuNop" },
bd5295b2
L
126 { "CPU_SYSCALL_FLAGS",
127 "CpuSYSCALL" },
40fb9820 128 { "CPU_MMX_FLAGS",
6e041cf4 129 "CpuMMX" },
40fb9820 130 { "CPU_SSE_FLAGS",
6e041cf4 131 "CpuSSE" },
40fb9820 132 { "CPU_SSE2_FLAGS",
1848e567 133 "CPU_SSE_FLAGS|CpuSSE2" },
40fb9820 134 { "CPU_SSE3_FLAGS",
1848e567 135 "CPU_SSE2_FLAGS|CpuSSE3" },
40fb9820 136 { "CPU_SSSE3_FLAGS",
1848e567 137 "CPU_SSE3_FLAGS|CpuSSSE3" },
40fb9820 138 { "CPU_SSE4_1_FLAGS",
1848e567 139 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
40fb9820 140 { "CPU_SSE4_2_FLAGS",
1848e567 141 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
6305a203
L
142 { "CPU_VMX_FLAGS",
143 "CpuVMX" },
144 { "CPU_SMX_FLAGS",
145 "CpuSMX" },
f03fe4c1
L
146 { "CPU_XSAVE_FLAGS",
147 "CpuXsave" },
c7b8aa3a 148 { "CPU_XSAVEOPT_FLAGS",
1848e567 149 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
c0f3af97 150 { "CPU_AES_FLAGS",
1848e567 151 "CPU_SSE2_FLAGS|CpuAES" },
594ab6a3 152 { "CPU_PCLMUL_FLAGS",
1848e567 153 "CPU_SSE2_FLAGS|CpuPCLMUL" },
c0f3af97 154 { "CPU_FMA_FLAGS",
1848e567 155 "CPU_AVX_FLAGS|CpuFMA" },
922d8de8 156 { "CPU_FMA4_FLAGS",
1848e567 157 "CPU_AVX_FLAGS|CpuFMA4" },
5dd85c99 158 { "CPU_XOP_FLAGS",
1848e567 159 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
f88c9eb0 160 { "CPU_LWP_FLAGS",
59ef5df4 161 "CPU_XSAVE_FLAGS|CpuLWP" },
f12dc422
L
162 { "CPU_BMI_FLAGS",
163 "CpuBMI" },
2a2a0f38
QN
164 { "CPU_TBM_FLAGS",
165 "CpuTBM" },
f1f8f695
L
166 { "CPU_MOVBE_FLAGS",
167 "CpuMovbe" },
60aa667e
L
168 { "CPU_CX16_FLAGS",
169 "CpuCX16" },
1b7f3fb0
L
170 { "CPU_RDTSCP_FLAGS",
171 "CpuRdtscp" },
f1f8f695
L
172 { "CPU_EPT_FLAGS",
173 "CpuEPT" },
c7b8aa3a
L
174 { "CPU_FSGSBASE_FLAGS",
175 "CpuFSGSBase" },
176 { "CPU_RDRND_FLAGS",
177 "CpuRdRnd" },
178 { "CPU_F16C_FLAGS",
1848e567 179 "CPU_AVX_FLAGS|CpuF16C" },
6c30d220
L
180 { "CPU_BMI2_FLAGS",
181 "CpuBMI2" },
182 { "CPU_LZCNT_FLAGS",
183 "CpuLZCNT" },
42164a71
L
184 { "CPU_HLE_FLAGS",
185 "CpuHLE" },
186 { "CPU_RTM_FLAGS",
187 "CpuRTM" },
6c30d220
L
188 { "CPU_INVPCID_FLAGS",
189 "CpuINVPCID" },
8729a6f6
L
190 { "CPU_VMFUNC_FLAGS",
191 "CpuVMFUNC" },
40fb9820 192 { "CPU_3DNOW_FLAGS",
1848e567 193 "CPU_MMX_FLAGS|Cpu3dnow" },
40fb9820 194 { "CPU_3DNOWA_FLAGS",
1848e567 195 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
40fb9820
L
196 { "CPU_PADLOCK_FLAGS",
197 "CpuPadLock" },
198 { "CPU_SVME_FLAGS",
199 "CpuSVME" },
200 { "CPU_SSE4A_FLAGS",
1848e567 201 "CPU_SSE3_FLAGS|CpuSSE4a" },
40fb9820 202 { "CPU_ABM_FLAGS",
3629bb00 203 "CpuABM" },
c0f3af97 204 { "CPU_AVX_FLAGS",
59ef5df4 205 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
6c30d220 206 { "CPU_AVX2_FLAGS",
1848e567 207 "CPU_AVX_FLAGS|CpuAVX2" },
43234a1e 208 { "CPU_AVX512F_FLAGS",
e951d5ca 209 "CPU_AVX2_FLAGS|CpuAVX512F" },
43234a1e 210 { "CPU_AVX512CD_FLAGS",
1848e567 211 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
43234a1e 212 { "CPU_AVX512ER_FLAGS",
1848e567 213 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
43234a1e 214 { "CPU_AVX512PF_FLAGS",
1848e567 215 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
f3ad7637 216 { "CPU_AVX512DQ_FLAGS",
1848e567 217 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
f3ad7637 218 { "CPU_AVX512BW_FLAGS",
1848e567 219 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
f3ad7637 220 { "CPU_AVX512VL_FLAGS",
6e041cf4 221 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
f3ad7637 222 { "CPU_AVX512IFMA_FLAGS",
1848e567 223 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
f3ad7637 224 { "CPU_AVX512VBMI_FLAGS",
1848e567 225 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
920d2ddc
IT
226 { "CPU_AVX512_4FMAPS_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
47acf0bd
IT
228 { "CPU_AVX512_4VNNIW_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
620214f7
IT
230 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
53467f57
IT
232 { "CPU_AVX512_VBMI2_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
8cfcb765
IT
234 { "CPU_AVX512_VNNI_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
ee6872be
IT
236 { "CPU_AVX512_BITALG_FLAGS",
237 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
d6aab7a1
XG
238 { "CPU_AVX512_BF16_FLAGS",
239 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
8a9036a4
L
240 { "CPU_L1OM_FLAGS",
241 "unknown" },
7a9068fe
L
242 { "CPU_K1OM_FLAGS",
243 "unknown" },
7b6d09fb
L
244 { "CPU_IAMCU_FLAGS",
245 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
e2e1fcde
L
246 { "CPU_ADX_FLAGS",
247 "CpuADX" },
248 { "CPU_RDSEED_FLAGS",
249 "CpuRdSeed" },
250 { "CPU_PRFCHW_FLAGS",
251 "CpuPRFCHW" },
5c111e37
L
252 { "CPU_SMAP_FLAGS",
253 "CpuSMAP" },
7e8b059b 254 { "CPU_MPX_FLAGS",
59ef5df4 255 "CPU_XSAVE_FLAGS|CpuMPX" },
a0046408 256 { "CPU_SHA_FLAGS",
1848e567 257 "CPU_SSE2_FLAGS|CpuSHA" },
963f3586
IT
258 { "CPU_CLFLUSHOPT_FLAGS",
259 "CpuClflushOpt" },
260 { "CPU_XSAVES_FLAGS",
1848e567 261 "CPU_XSAVE_FLAGS|CpuXSAVES" },
963f3586 262 { "CPU_XSAVEC_FLAGS",
1848e567 263 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
dcf893b5
IT
264 { "CPU_PREFETCHWT1_FLAGS",
265 "CpuPREFETCHWT1" },
2cf200a4
IT
266 { "CPU_SE1_FLAGS",
267 "CpuSE1" },
c5e7287a
IT
268 { "CPU_CLWB_FLAGS",
269 "CpuCLWB" },
029f3522
GG
270 { "CPU_CLZERO_FLAGS",
271 "CpuCLZERO" },
9916071f
AP
272 { "CPU_MWAITX_FLAGS",
273 "CpuMWAITX" },
8eab4136 274 { "CPU_OSPKE_FLAGS",
59ef5df4 275 "CPU_XSAVE_FLAGS|CpuOSPKE" },
8bc52696 276 { "CPU_RDPID_FLAGS",
1848e567 277 "CpuRDPID" },
6b40c462
L
278 { "CPU_PTWRITE_FLAGS",
279 "CpuPTWRITE" },
d777820b
IT
280 { "CPU_IBT_FLAGS",
281 "CpuIBT" },
282 { "CPU_SHSTK_FLAGS",
283 "CpuSHSTK" },
48521003
IT
284 { "CPU_GFNI_FLAGS",
285 "CpuGFNI" },
8dcf1fad
IT
286 { "CPU_VAES_FLAGS",
287 "CpuVAES" },
ff1982d5
IT
288 { "CPU_VPCLMULQDQ_FLAGS",
289 "CpuVPCLMULQDQ" },
3233d7d0
IT
290 { "CPU_WBNOINVD_FLAGS",
291 "CpuWBNOINVD" },
be3a8dca
IT
292 { "CPU_PCONFIG_FLAGS",
293 "CpuPCONFIG" },
de89d0a3
IT
294 { "CPU_WAITPKG_FLAGS",
295 "CpuWAITPKG" },
c48935d7
IT
296 { "CPU_CLDEMOTE_FLAGS",
297 "CpuCLDEMOTE" },
c0a30a9f
L
298 { "CPU_MOVDIRI_FLAGS",
299 "CpuMOVDIRI" },
300 { "CPU_MOVDIR64B_FLAGS",
301 "CpuMOVDIR64B" },
5d79adc4
L
302 { "CPU_ENQCMD_FLAGS",
303 "CpuENQCMD" },
9186c494
L
304 { "CPU_AVX512_VP2INTERSECT_FLAGS",
305 "CpuAVX512_VP2INTERSECT" },
142861df
JB
306 { "CPU_RDPRU_FLAGS",
307 "CpuRDPRU" },
308 { "CPU_MCOMMIT_FLAGS",
309 "CpuMCOMMIT" },
1848e567
L
310 { "CPU_ANY_X87_FLAGS",
311 "CPU_ANY_287_FLAGS|Cpu8087" },
312 { "CPU_ANY_287_FLAGS",
313 "CPU_ANY_387_FLAGS|Cpu287" },
314 { "CPU_ANY_387_FLAGS",
315 "CPU_ANY_687_FLAGS|Cpu387" },
316 { "CPU_ANY_687_FLAGS",
317 "Cpu687|CpuFISTTP" },
d871f3f4
L
318 { "CPU_ANY_CMOV_FLAGS",
319 "CpuCMOV" },
320 { "CPU_ANY_FXSR_FLAGS",
321 "CpuFXSR" },
1848e567
L
322 { "CPU_ANY_MMX_FLAGS",
323 "CPU_3DNOWA_FLAGS" },
324 { "CPU_ANY_SSE_FLAGS",
325 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
326 { "CPU_ANY_SSE2_FLAGS",
327 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
328 { "CPU_ANY_SSE3_FLAGS",
329 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
330 { "CPU_ANY_SSSE3_FLAGS",
331 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
332 { "CPU_ANY_SSE4_1_FLAGS",
333 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
334 { "CPU_ANY_SSE4_2_FLAGS",
335 "CpuSSE4_2" },
336 { "CPU_ANY_AVX_FLAGS",
337 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
338 { "CPU_ANY_AVX2_FLAGS",
89199bb5 339 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
144b71e2 340 { "CPU_ANY_AVX512F_FLAGS",
9186c494 341 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
144b71e2
L
342 { "CPU_ANY_AVX512CD_FLAGS",
343 "CpuAVX512CD" },
344 { "CPU_ANY_AVX512ER_FLAGS",
345 "CpuAVX512ER" },
346 { "CPU_ANY_AVX512PF_FLAGS",
347 "CpuAVX512PF" },
348 { "CPU_ANY_AVX512DQ_FLAGS",
349 "CpuAVX512DQ" },
350 { "CPU_ANY_AVX512BW_FLAGS",
351 "CpuAVX512BW" },
352 { "CPU_ANY_AVX512VL_FLAGS",
353 "CpuAVX512VL" },
354 { "CPU_ANY_AVX512IFMA_FLAGS",
355 "CpuAVX512IFMA" },
356 { "CPU_ANY_AVX512VBMI_FLAGS",
357 "CpuAVX512VBMI" },
920d2ddc
IT
358 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
359 "CpuAVX512_4FMAPS" },
47acf0bd
IT
360 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
361 "CpuAVX512_4VNNIW" },
620214f7
IT
362 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
363 "CpuAVX512_VPOPCNTDQ" },
d777820b
IT
364 { "CPU_ANY_IBT_FLAGS",
365 "CpuIBT" },
366 { "CPU_ANY_SHSTK_FLAGS",
367 "CpuSHSTK" },
53467f57
IT
368 { "CPU_ANY_AVX512_VBMI2_FLAGS",
369 "CpuAVX512_VBMI2" },
8cfcb765
IT
370 { "CPU_ANY_AVX512_VNNI_FLAGS",
371 "CpuAVX512_VNNI" },
ee6872be
IT
372 { "CPU_ANY_AVX512_BITALG_FLAGS",
373 "CpuAVX512_BITALG" },
d6aab7a1
XG
374 { "CPU_ANY_AVX512_BF16_FLAGS",
375 "CpuAVX512_BF16" },
c0a30a9f
L
376 { "CPU_ANY_MOVDIRI_FLAGS",
377 "CpuMOVDIRI" },
378 { "CPU_ANY_MOVDIR64B_FLAGS",
379 "CpuMOVDIR64B" },
5d79adc4
L
380 { "CPU_ANY_ENQCMD_FLAGS",
381 "CpuENQCMD" },
9186c494
L
382 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
383 "CpuAVX512_VP2INTERSECT" },
40fb9820
L
384};
385
8acd5377 386static initializer operand_type_init[] =
40fb9820
L
387{
388 { "OPERAND_TYPE_NONE",
389 "0" },
390 { "OPERAND_TYPE_REG8",
bab6aec1 391 "Class=Reg|Byte" },
40fb9820 392 { "OPERAND_TYPE_REG16",
bab6aec1 393 "Class=Reg|Word" },
40fb9820 394 { "OPERAND_TYPE_REG32",
bab6aec1 395 "Class=Reg|Dword" },
40fb9820 396 { "OPERAND_TYPE_REG64",
bab6aec1 397 "Class=Reg|Qword" },
40fb9820
L
398 { "OPERAND_TYPE_IMM1",
399 "Imm1" },
400 { "OPERAND_TYPE_IMM8",
401 "Imm8" },
402 { "OPERAND_TYPE_IMM8S",
403 "Imm8S" },
404 { "OPERAND_TYPE_IMM16",
405 "Imm16" },
406 { "OPERAND_TYPE_IMM32",
407 "Imm32" },
408 { "OPERAND_TYPE_IMM32S",
409 "Imm32S" },
410 { "OPERAND_TYPE_IMM64",
411 "Imm64" },
412 { "OPERAND_TYPE_BASEINDEX",
413 "BaseIndex" },
414 { "OPERAND_TYPE_DISP8",
415 "Disp8" },
416 { "OPERAND_TYPE_DISP16",
417 "Disp16" },
418 { "OPERAND_TYPE_DISP32",
419 "Disp32" },
420 { "OPERAND_TYPE_DISP32S",
421 "Disp32S" },
422 { "OPERAND_TYPE_DISP64",
423 "Disp64" },
424 { "OPERAND_TYPE_INOUTPORTREG",
425 "InOutPortReg" },
426 { "OPERAND_TYPE_SHIFTCOUNT",
427 "ShiftCount" },
428 { "OPERAND_TYPE_CONTROL",
4a5c67ed 429 "Class=RegCR" },
40fb9820 430 { "OPERAND_TYPE_TEST",
4a5c67ed 431 "Class=RegTR" },
40fb9820 432 { "OPERAND_TYPE_DEBUG",
4a5c67ed 433 "Class=RegDR" },
40fb9820 434 { "OPERAND_TYPE_FLOATREG",
bab6aec1 435 "Class=Reg|Tbyte" },
40fb9820 436 { "OPERAND_TYPE_FLOATACC",
3cc17af5 437 "Acc|Tbyte" },
21df382b 438 { "OPERAND_TYPE_SREG",
00cee14f 439 "Class=SReg" },
40fb9820
L
440 { "OPERAND_TYPE_JUMPABSOLUTE",
441 "JumpAbsolute" },
442 { "OPERAND_TYPE_REGMMX",
3528c362 443 "Class=RegMMX" },
40fb9820 444 { "OPERAND_TYPE_REGXMM",
3528c362 445 "Class=RegSIMD|Xmmword" },
1508bbf5 446 { "OPERAND_TYPE_REGYMM",
3528c362 447 "Class=RegSIMD|Ymmword" },
1508bbf5 448 { "OPERAND_TYPE_REGZMM",
3528c362 449 "Class=RegSIMD|Zmmword" },
43234a1e 450 { "OPERAND_TYPE_REGMASK",
f74a6307
JB
451 "Class=RegMask" },
452 { "OPERAND_TYPE_REGBND",
453 "Class=RegBND" },
40fb9820
L
454 { "OPERAND_TYPE_ESSEG",
455 "EsSeg" },
2c703856
JB
456 { "OPERAND_TYPE_ACC8",
457 "Acc|Byte" },
458 { "OPERAND_TYPE_ACC16",
459 "Acc|Word" },
40fb9820 460 { "OPERAND_TYPE_ACC32",
2c703856 461 "Acc|Dword" },
40fb9820 462 { "OPERAND_TYPE_ACC64",
2c703856 463 "Acc|Qword" },
40fb9820
L
464 { "OPERAND_TYPE_DISP16_32",
465 "Disp16|Disp32" },
466 { "OPERAND_TYPE_ANYDISP",
467 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
468 { "OPERAND_TYPE_IMM16_32",
469 "Imm16|Imm32" },
470 { "OPERAND_TYPE_IMM16_32S",
471 "Imm16|Imm32S" },
472 { "OPERAND_TYPE_IMM16_32_32S",
473 "Imm16|Imm32|Imm32S" },
2f81ff92
L
474 { "OPERAND_TYPE_IMM32_64",
475 "Imm32|Imm64" },
40fb9820
L
476 { "OPERAND_TYPE_IMM32_32S_DISP32",
477 "Imm32|Imm32S|Disp32" },
478 { "OPERAND_TYPE_IMM64_DISP64",
479 "Imm64|Disp64" },
480 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
481 "Imm32|Imm32S|Imm64|Disp32" },
482 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
483 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
bab6aec1
JB
484 { "OPERAND_TYPE_ANYIMM",
485 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
40fb9820
L
486};
487
488typedef struct bitfield
489{
490 int position;
491 int value;
492 const char *name;
493} bitfield;
494
495#define BITFIELD(n) { n, 0, #n }
496
497static bitfield cpu_flags[] =
498{
499 BITFIELD (Cpu186),
500 BITFIELD (Cpu286),
501 BITFIELD (Cpu386),
502 BITFIELD (Cpu486),
503 BITFIELD (Cpu586),
504 BITFIELD (Cpu686),
d871f3f4
L
505 BITFIELD (CpuCMOV),
506 BITFIELD (CpuFXSR),
bd5295b2 507 BITFIELD (CpuClflush),
22109423 508 BITFIELD (CpuNop),
bd5295b2 509 BITFIELD (CpuSYSCALL),
309d3373
JB
510 BITFIELD (Cpu8087),
511 BITFIELD (Cpu287),
512 BITFIELD (Cpu387),
513 BITFIELD (Cpu687),
514 BITFIELD (CpuFISTTP),
40fb9820 515 BITFIELD (CpuMMX),
40fb9820
L
516 BITFIELD (CpuSSE),
517 BITFIELD (CpuSSE2),
518 BITFIELD (CpuSSE3),
519 BITFIELD (CpuSSSE3),
520 BITFIELD (CpuSSE4_1),
521 BITFIELD (CpuSSE4_2),
c0f3af97 522 BITFIELD (CpuAVX),
6c30d220 523 BITFIELD (CpuAVX2),
43234a1e
L
524 BITFIELD (CpuAVX512F),
525 BITFIELD (CpuAVX512CD),
526 BITFIELD (CpuAVX512ER),
527 BITFIELD (CpuAVX512PF),
b28d1bda 528 BITFIELD (CpuAVX512VL),
90a915bf 529 BITFIELD (CpuAVX512DQ),
1ba585e8 530 BITFIELD (CpuAVX512BW),
8a9036a4 531 BITFIELD (CpuL1OM),
7a9068fe 532 BITFIELD (CpuK1OM),
7b6d09fb 533 BITFIELD (CpuIAMCU),
40fb9820
L
534 BITFIELD (CpuSSE4a),
535 BITFIELD (Cpu3dnow),
536 BITFIELD (Cpu3dnowA),
537 BITFIELD (CpuPadLock),
538 BITFIELD (CpuSVME),
539 BITFIELD (CpuVMX),
47dd174c 540 BITFIELD (CpuSMX),
40fb9820 541 BITFIELD (CpuABM),
475a2301 542 BITFIELD (CpuXsave),
c7b8aa3a 543 BITFIELD (CpuXsaveopt),
c0f3af97 544 BITFIELD (CpuAES),
594ab6a3 545 BITFIELD (CpuPCLMUL),
c0f3af97 546 BITFIELD (CpuFMA),
f88c9eb0 547 BITFIELD (CpuFMA4),
5dd85c99 548 BITFIELD (CpuXOP),
f88c9eb0 549 BITFIELD (CpuLWP),
f12dc422 550 BITFIELD (CpuBMI),
2a2a0f38 551 BITFIELD (CpuTBM),
c0f3af97 552 BITFIELD (CpuLM),
f1f8f695 553 BITFIELD (CpuMovbe),
60aa667e 554 BITFIELD (CpuCX16),
f1f8f695 555 BITFIELD (CpuEPT),
1b7f3fb0 556 BITFIELD (CpuRdtscp),
c7b8aa3a
L
557 BITFIELD (CpuFSGSBase),
558 BITFIELD (CpuRdRnd),
559 BITFIELD (CpuF16C),
6c30d220
L
560 BITFIELD (CpuBMI2),
561 BITFIELD (CpuLZCNT),
42164a71
L
562 BITFIELD (CpuHLE),
563 BITFIELD (CpuRTM),
6c30d220 564 BITFIELD (CpuINVPCID),
8729a6f6 565 BITFIELD (CpuVMFUNC),
e2e1fcde
L
566 BITFIELD (CpuRDSEED),
567 BITFIELD (CpuADX),
568 BITFIELD (CpuPRFCHW),
5c111e37 569 BITFIELD (CpuSMAP),
a0046408 570 BITFIELD (CpuSHA),
963f3586
IT
571 BITFIELD (CpuClflushOpt),
572 BITFIELD (CpuXSAVES),
573 BITFIELD (CpuXSAVEC),
dcf893b5 574 BITFIELD (CpuPREFETCHWT1),
2cf200a4 575 BITFIELD (CpuSE1),
c5e7287a 576 BITFIELD (CpuCLWB),
40fb9820
L
577 BITFIELD (Cpu64),
578 BITFIELD (CpuNo64),
7e8b059b 579 BITFIELD (CpuMPX),
2cc1b5aa 580 BITFIELD (CpuAVX512IFMA),
14f195c9 581 BITFIELD (CpuAVX512VBMI),
920d2ddc 582 BITFIELD (CpuAVX512_4FMAPS),
47acf0bd 583 BITFIELD (CpuAVX512_4VNNIW),
620214f7 584 BITFIELD (CpuAVX512_VPOPCNTDQ),
53467f57 585 BITFIELD (CpuAVX512_VBMI2),
8cfcb765 586 BITFIELD (CpuAVX512_VNNI),
ee6872be 587 BITFIELD (CpuAVX512_BITALG),
d6aab7a1 588 BITFIELD (CpuAVX512_BF16),
9186c494 589 BITFIELD (CpuAVX512_VP2INTERSECT),
9916071f 590 BITFIELD (CpuMWAITX),
029f3522 591 BITFIELD (CpuCLZERO),
8eab4136 592 BITFIELD (CpuOSPKE),
8bc52696 593 BITFIELD (CpuRDPID),
6b40c462 594 BITFIELD (CpuPTWRITE),
d777820b
IT
595 BITFIELD (CpuIBT),
596 BITFIELD (CpuSHSTK),
48521003 597 BITFIELD (CpuGFNI),
8dcf1fad 598 BITFIELD (CpuVAES),
ff1982d5 599 BITFIELD (CpuVPCLMULQDQ),
3233d7d0 600 BITFIELD (CpuWBNOINVD),
be3a8dca 601 BITFIELD (CpuPCONFIG),
de89d0a3 602 BITFIELD (CpuWAITPKG),
c48935d7 603 BITFIELD (CpuCLDEMOTE),
c0a30a9f
L
604 BITFIELD (CpuMOVDIRI),
605 BITFIELD (CpuMOVDIR64B),
5d79adc4 606 BITFIELD (CpuENQCMD),
142861df
JB
607 BITFIELD (CpuRDPRU),
608 BITFIELD (CpuMCOMMIT),
40fb9820
L
609#ifdef CpuUnused
610 BITFIELD (CpuUnused),
611#endif
612};
613
614static bitfield opcode_modifiers[] =
615{
616 BITFIELD (D),
617 BITFIELD (W),
86fa6981 618 BITFIELD (Load),
40fb9820
L
619 BITFIELD (Modrm),
620 BITFIELD (ShortForm),
621 BITFIELD (Jump),
622 BITFIELD (JumpDword),
623 BITFIELD (JumpByte),
624 BITFIELD (JumpInterSegment),
625 BITFIELD (FloatMF),
626 BITFIELD (FloatR),
673fe0f0 627 BITFIELD (Size),
56ffb741 628 BITFIELD (CheckRegSize),
40fb9820
L
629 BITFIELD (IgnoreSize),
630 BITFIELD (DefaultSize),
631 BITFIELD (No_bSuf),
632 BITFIELD (No_wSuf),
633 BITFIELD (No_lSuf),
634 BITFIELD (No_sSuf),
635 BITFIELD (No_qSuf),
7ce189b3 636 BITFIELD (No_ldSuf),
40fb9820
L
637 BITFIELD (FWait),
638 BITFIELD (IsString),
dfd69174 639 BITFIELD (RegMem),
7e8b059b 640 BITFIELD (BNDPrefixOk),
04ef582a 641 BITFIELD (NoTrackPrefixOk),
c32fa91d 642 BITFIELD (IsLockable),
40fb9820 643 BITFIELD (RegKludge),
c0f3af97 644 BITFIELD (Implicit1stXmm0),
29c048b6 645 BITFIELD (RepPrefixOk),
42164a71 646 BITFIELD (HLEPrefixOk),
ca61edf2
L
647 BITFIELD (ToDword),
648 BITFIELD (ToQword),
75c0a438 649 BITFIELD (AddrPrefixOpReg),
40fb9820
L
650 BITFIELD (IsPrefix),
651 BITFIELD (ImmExt),
652 BITFIELD (NoRex64),
653 BITFIELD (Rex64),
654 BITFIELD (Ugh),
c0f3af97 655 BITFIELD (Vex),
2426c15f 656 BITFIELD (VexVVVV),
1ef99a7b 657 BITFIELD (VexW),
7f399153 658 BITFIELD (VexOpcode),
8cd7925b 659 BITFIELD (VexSources),
6c30d220 660 BITFIELD (VecSIB),
c0f3af97 661 BITFIELD (SSE2AVX),
81f8a913 662 BITFIELD (NoAVX),
43234a1e
L
663 BITFIELD (EVex),
664 BITFIELD (Masking),
43234a1e
L
665 BITFIELD (Broadcast),
666 BITFIELD (StaticRounding),
667 BITFIELD (SAE),
668 BITFIELD (Disp8MemShift),
669 BITFIELD (NoDefMask),
920d2ddc 670 BITFIELD (ImplicitQuadGroup),
b6f8c7c4 671 BITFIELD (Optimize),
1efbbeb4 672 BITFIELD (ATTMnemonic),
e1d4d893 673 BITFIELD (ATTSyntax),
5c07affc 674 BITFIELD (IntelSyntax),
e92bae62
L
675 BITFIELD (AMD64),
676 BITFIELD (Intel64),
40fb9820
L
677};
678
bab6aec1
JB
679#define CLASS(n) #n, n
680
681static const struct {
682 const char *name;
683 enum operand_class value;
684} operand_classes[] = {
685 CLASS (Reg),
00cee14f 686 CLASS (SReg),
4a5c67ed
JB
687 CLASS (RegCR),
688 CLASS (RegDR),
689 CLASS (RegTR),
3528c362
JB
690 CLASS (RegMMX),
691 CLASS (RegSIMD),
f74a6307
JB
692 CLASS (RegMask),
693 CLASS (RegBND),
bab6aec1
JB
694};
695
696#undef CLASS
697
40fb9820
L
698static bitfield operand_types[] =
699{
94ff3a50 700 BITFIELD (Imm1),
40fb9820
L
701 BITFIELD (Imm8),
702 BITFIELD (Imm8S),
703 BITFIELD (Imm16),
704 BITFIELD (Imm32),
705 BITFIELD (Imm32S),
706 BITFIELD (Imm64),
40fb9820
L
707 BITFIELD (BaseIndex),
708 BITFIELD (Disp8),
709 BITFIELD (Disp16),
710 BITFIELD (Disp32),
711 BITFIELD (Disp32S),
712 BITFIELD (Disp64),
713 BITFIELD (InOutPortReg),
714 BITFIELD (ShiftCount),
40fb9820 715 BITFIELD (Acc),
40fb9820
L
716 BITFIELD (JumpAbsolute),
717 BITFIELD (EsSeg),
7d5e4556
L
718 BITFIELD (Byte),
719 BITFIELD (Word),
720 BITFIELD (Dword),
721 BITFIELD (Fword),
722 BITFIELD (Qword),
723 BITFIELD (Tbyte),
724 BITFIELD (Xmmword),
c0f3af97 725 BITFIELD (Ymmword),
43234a1e 726 BITFIELD (Zmmword),
7d5e4556
L
727 BITFIELD (Unspecified),
728 BITFIELD (Anysize),
40fb9820
L
729#ifdef OTUnused
730 BITFIELD (OTUnused),
731#endif
732};
733
3d4d5afa 734static const char *filename;
7ac20022
JB
735static i386_cpu_flags active_cpu_flags;
736static int active_isstring;
3d4d5afa 737
40fb9820
L
738static int
739compare (const void *x, const void *y)
740{
741 const bitfield *xp = (const bitfield *) x;
742 const bitfield *yp = (const bitfield *) y;
743 return xp->position - yp->position;
744}
745
40b8e679
L
746static void
747fail (const char *message, ...)
748{
749 va_list args;
29c048b6 750
40b8e679 751 va_start (args, message);
a6743a54 752 fprintf (stderr, _("%s: error: "), program_name);
40b8e679
L
753 vfprintf (stderr, message, args);
754 va_end (args);
755 xexit (1);
756}
757
72ffa0fb
L
758static void
759process_copyright (FILE *fp)
760{
761 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
82704155 762/* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
72ffa0fb
L
763\n\
764 This file is part of the GNU opcodes library.\n\
765\n\
766 This library is free software; you can redistribute it and/or modify\n\
767 it under the terms of the GNU General Public License as published by\n\
768 the Free Software Foundation; either version 3, or (at your option)\n\
769 any later version.\n\
770\n\
771 It is distributed in the hope that it will be useful, but WITHOUT\n\
772 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
773 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
774 License for more details.\n\
775\n\
776 You should have received a copy of the GNU General Public License\n\
777 along with this program; if not, write to the Free Software\n\
778 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
779 MA 02110-1301, USA. */\n");
780}
781
40b8e679
L
782/* Remove leading white spaces. */
783
784static char *
785remove_leading_whitespaces (char *str)
786{
787 while (ISSPACE (*str))
788 str++;
789 return str;
790}
791
792/* Remove trailing white spaces. */
793
794static void
795remove_trailing_whitespaces (char *str)
796{
797 size_t last = strlen (str);
798
799 if (last == 0)
800 return;
801
802 do
803 {
804 last--;
805 if (ISSPACE (str [last]))
806 str[last] = '\0';
807 else
808 break;
809 }
810 while (last != 0);
811}
812
93b1ec2c 813/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
814 pointer to the one after it. */
815
816static char *
c587b3f9 817next_field (char *str, char sep, char **next, char *last)
40b8e679
L
818{
819 char *p;
820
821 p = remove_leading_whitespaces (str);
93b1ec2c 822 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
823
824 *str = '\0';
825 remove_trailing_whitespaces (p);
826
29c048b6 827 *next = str + 1;
40b8e679 828
c587b3f9
L
829 if (p >= last)
830 abort ();
831
40b8e679
L
832 return p;
833}
834
1848e567
L
835static void set_bitfield (char *, bitfield *, int, unsigned int, int);
836
837static int
3cc17af5
JB
838set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
839 int lineno)
1848e567
L
840{
841 char *str, *next, *last;
842 unsigned int i;
843
844 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
845 if (strcmp (cpu_flag_init[i].name, f) == 0)
846 {
847 /* Turn on selective bits. */
848 char *init = xstrdup (cpu_flag_init[i].init);
849 last = init + strlen (init);
850 for (next = init; next && next < last; )
851 {
852 str = next_field (next, '|', &next, last);
853 if (str)
854 set_bitfield (str, array, 1, size, lineno);
855 }
856 free (init);
857 return 0;
858 }
859
860 return -1;
861}
862
40fb9820 863static void
1848e567 864set_bitfield (char *f, bitfield *array, int value,
8a9036a4 865 unsigned int size, int lineno)
40fb9820
L
866{
867 unsigned int i;
868
309d3373
JB
869 if (strcmp (f, "CpuFP") == 0)
870 {
8a9036a4
L
871 set_bitfield("Cpu387", array, value, size, lineno);
872 set_bitfield("Cpu287", array, value, size, lineno);
309d3373
JB
873 f = "Cpu8087";
874 }
875 else if (strcmp (f, "Mmword") == 0)
7d5e4556
L
876 f= "Qword";
877 else if (strcmp (f, "Oword") == 0)
878 f= "Xmmword";
40fb9820
L
879
880 for (i = 0; i < size; i++)
881 if (strcasecmp (array[i].name, f) == 0)
882 {
8a9036a4 883 array[i].value = value;
40fb9820
L
884 return;
885 }
886
2bf05e57
L
887 if (value)
888 {
889 const char *v = strchr (f, '=');
890
891 if (v)
892 {
893 size_t n = v - f;
894 char *end;
895
896 for (i = 0; i < size; i++)
897 if (strncasecmp (array[i].name, f, n) == 0)
898 {
899 value = strtol (v + 1, &end, 0);
900 if (*end == '\0')
901 {
902 array[i].value = value;
903 return;
904 }
905 break;
906 }
907 }
908 }
909
3cc17af5
JB
910 /* Handle CPU_XXX_FLAGS. */
911 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1848e567
L
912 return;
913
bd5295b2 914 if (lineno != -1)
a6743a54 915 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
bd5295b2 916 else
a6743a54 917 fail (_("unknown bitfield: %s\n"), f);
40fb9820
L
918}
919
920static void
921output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
922 int macro, const char *comma, const char *indent)
923{
924 unsigned int i;
925
7ac20022
JB
926 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
927
40fb9820
L
928 fprintf (table, "%s{ { ", indent);
929
930 for (i = 0; i < size - 1; i++)
931 {
10632b79
L
932 if (((i + 1) % 20) != 0)
933 fprintf (table, "%d, ", flags[i].value);
934 else
935 fprintf (table, "%d,", flags[i].value);
40fb9820
L
936 if (((i + 1) % 20) == 0)
937 {
938 /* We need \\ for macro. */
939 if (macro)
940 fprintf (table, " \\\n %s", indent);
941 else
942 fprintf (table, "\n %s", indent);
943 }
7ac20022
JB
944 if (flags[i].value)
945 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
40fb9820
L
946 }
947
948 fprintf (table, "%d } }%s\n", flags[i].value, comma);
949}
950
951static void
952process_i386_cpu_flag (FILE *table, char *flag, int macro,
bd5295b2
L
953 const char *comma, const char *indent,
954 int lineno)
40fb9820
L
955{
956 char *str, *next, *last;
8a9036a4 957 unsigned int i;
40fb9820
L
958 bitfield flags [ARRAY_SIZE (cpu_flags)];
959
960 /* Copy the default cpu flags. */
961 memcpy (flags, cpu_flags, sizeof (cpu_flags));
962
963 if (strcasecmp (flag, "unknown") == 0)
964 {
40fb9820 965 /* We turn on everything except for cpu64 in case of
8a9036a4
L
966 CPU_UNKNOWN_FLAGS. */
967 for (i = 0; i < ARRAY_SIZE (flags); i++)
968 if (flags[i].position != Cpu64)
969 flags[i].value = 1;
970 }
971 else if (flag[0] == '~')
972 {
973 last = flag + strlen (flag);
974
975 if (flag[1] == '(')
976 {
977 last -= 1;
978 next = flag + 2;
979 if (*last != ')')
a6743a54 980 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
8a9036a4
L
981 lineno, flag);
982 *last = '\0';
983 }
984 else
985 next = flag + 1;
986
987 /* First we turn on everything except for cpu64. */
40fb9820
L
988 for (i = 0; i < ARRAY_SIZE (flags); i++)
989 if (flags[i].position != Cpu64)
990 flags[i].value = 1;
8a9036a4
L
991
992 /* Turn off selective bits. */
993 for (; next && next < last; )
994 {
995 str = next_field (next, '|', &next, last);
996 if (str)
997 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
998 }
40fb9820
L
999 }
1000 else if (strcmp (flag, "0"))
1001 {
8a9036a4 1002 /* Turn on selective bits. */
40fb9820
L
1003 last = flag + strlen (flag);
1004 for (next = flag; next && next < last; )
1005 {
c587b3f9 1006 str = next_field (next, '|', &next, last);
40fb9820 1007 if (str)
8a9036a4 1008 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
40fb9820
L
1009 }
1010 }
1011
1012 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1013 comma, indent);
1014}
1015
1016static void
1017output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1018{
1019 unsigned int i;
1020
1021 fprintf (table, " { ");
1022
1023 for (i = 0; i < size - 1; i++)
1024 {
10632b79
L
1025 if (((i + 1) % 20) != 0)
1026 fprintf (table, "%d, ", modifier[i].value);
1027 else
1028 fprintf (table, "%d,", modifier[i].value);
40fb9820
L
1029 if (((i + 1) % 20) == 0)
1030 fprintf (table, "\n ");
1031 }
1032
1033 fprintf (table, "%d },\n", modifier[i].value);
1034}
1035
4a1b91ea
L
1036static int
1037adjust_broadcast_modifier (char **opnd)
1038{
1039 char *str, *next, *last, *op;
1040 int bcst_type = INT_MAX;
1041
1042 /* Skip the immediate operand. */
1043 op = opnd[0];
1044 if (strcasecmp(op, "Imm8") == 0)
1045 op = opnd[1];
1046
1047 op = xstrdup (op);
1048 last = op + strlen (op);
1049 for (next = op; next && next < last; )
1050 {
1051 str = next_field (next, '|', &next, last);
1052 if (str)
1053 {
1054 if (strcasecmp(str, "Byte") == 0)
1055 {
1056 /* The smalest broadcast type, no need to check
1057 further. */
1058 bcst_type = BYTE_BROADCAST;
1059 break;
1060 }
1061 else if (strcasecmp(str, "Word") == 0)
1062 {
1063 if (bcst_type > WORD_BROADCAST)
1064 bcst_type = WORD_BROADCAST;
1065 }
1066 else if (strcasecmp(str, "Dword") == 0)
1067 {
1068 if (bcst_type > DWORD_BROADCAST)
1069 bcst_type = DWORD_BROADCAST;
1070 }
1071 else if (strcasecmp(str, "Qword") == 0)
1072 {
1073 if (bcst_type > QWORD_BROADCAST)
1074 bcst_type = QWORD_BROADCAST;
1075 }
1076 }
1077 }
1078 free (op);
1079
1080 if (bcst_type == INT_MAX)
1081 fail (_("unknown broadcast operand: %s\n"), op);
1082
1083 return bcst_type;
1084}
1085
40fb9820 1086static void
4a1b91ea 1087process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
40fb9820
L
1088{
1089 char *str, *next, *last;
1090 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1091
7ac20022
JB
1092 active_isstring = 0;
1093
40fb9820
L
1094 /* Copy the default opcode modifier. */
1095 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1096
1097 if (strcmp (mod, "0"))
1098 {
507916b8
JB
1099 unsigned int have_w = 0, bwlq_suf = 0xf;
1100
40fb9820
L
1101 last = mod + strlen (mod);
1102 for (next = mod; next && next < last; )
1103 {
c587b3f9 1104 str = next_field (next, '|', &next, last);
40fb9820 1105 if (str)
7ac20022 1106 {
4a1b91ea
L
1107 int val = 1;
1108 if (strcasecmp(str, "Broadcast") == 0)
1109 val = adjust_broadcast_modifier (opnd);
1110 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
8a9036a4 1111 lineno);
7ac20022
JB
1112 if (strcasecmp(str, "IsString") == 0)
1113 active_isstring = 1;
507916b8
JB
1114
1115 if (strcasecmp(str, "W") == 0)
1116 have_w = 1;
1117
1118 if (strcasecmp(str, "No_bSuf") == 0)
1119 bwlq_suf &= ~1;
1120 if (strcasecmp(str, "No_wSuf") == 0)
1121 bwlq_suf &= ~2;
1122 if (strcasecmp(str, "No_lSuf") == 0)
1123 bwlq_suf &= ~4;
1124 if (strcasecmp(str, "No_qSuf") == 0)
1125 bwlq_suf &= ~8;
7ac20022 1126 }
40fb9820 1127 }
507916b8
JB
1128
1129 if (have_w && !bwlq_suf)
1130 fail ("%s: %d: stray W modifier\n", filename, lineno);
1131 if (have_w && !(bwlq_suf & 1))
1132 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1133 filename, lineno);
1134 if (have_w && !(bwlq_suf & ~1))
1135 fprintf (stderr,
1136 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1137 filename, lineno);
40fb9820
L
1138 }
1139 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1140}
1141
7ac20022
JB
1142enum stage {
1143 stage_macros,
1144 stage_opcodes,
1145 stage_registers,
1146};
1147
40fb9820 1148static void
bab6aec1
JB
1149output_operand_type (FILE *table, enum operand_class class,
1150 const bitfield *types, unsigned int size,
7ac20022 1151 enum stage stage, const char *indent)
40fb9820
L
1152{
1153 unsigned int i;
1154
bab6aec1 1155 fprintf (table, "{ { %d, ", class);
40fb9820
L
1156
1157 for (i = 0; i < size - 1; i++)
1158 {
bab6aec1 1159 if (((i + 2) % 20) != 0)
10632b79
L
1160 fprintf (table, "%d, ", types[i].value);
1161 else
1162 fprintf (table, "%d,", types[i].value);
bab6aec1 1163 if (((i + 2) % 20) == 0)
40fb9820
L
1164 {
1165 /* We need \\ for macro. */
7ac20022 1166 if (stage == stage_macros)
10632b79 1167 fprintf (table, " \\\n%s", indent);
40fb9820
L
1168 else
1169 fprintf (table, "\n%s", indent);
1170 }
1171 }
1172
1173 fprintf (table, "%d } }", types[i].value);
1174}
1175
1176static void
7ac20022 1177process_i386_operand_type (FILE *table, char *op, enum stage stage,
bd5295b2 1178 const char *indent, int lineno)
40fb9820
L
1179{
1180 char *str, *next, *last;
bab6aec1 1181 enum operand_class class = ClassNone;
40fb9820
L
1182 bitfield types [ARRAY_SIZE (operand_types)];
1183
1184 /* Copy the default operand type. */
1185 memcpy (types, operand_types, sizeof (types));
1186
1187 if (strcmp (op, "0"))
1188 {
7ac20022
JB
1189 int baseindex = 0;
1190
40fb9820
L
1191 last = op + strlen (op);
1192 for (next = op; next && next < last; )
1193 {
c587b3f9 1194 str = next_field (next, '|', &next, last);
bab6aec1
JB
1195 if (str)
1196 {
1197 unsigned int i;
1198
1199 if (!strncmp(str, "Class=", 6))
1200 {
1201 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1202 if (!strcmp(str + 6, operand_classes[i].name))
1203 {
1204 class = operand_classes[i].value;
1205 str = NULL;
1206 break;
1207 }
1208 }
1209 }
40fb9820 1210 if (str)
7ac20022
JB
1211 {
1212 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1213 if (strcasecmp(str, "BaseIndex") == 0)
1214 baseindex = 1;
1215 }
1216 }
1217
1218 if (stage == stage_opcodes && baseindex && !active_isstring)
1219 {
1220 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1221 if (!active_cpu_flags.bitfield.cpu64
1222 && !active_cpu_flags.bitfield.cpumpx)
1223 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1224 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1225 if (!active_cpu_flags.bitfield.cpuno64)
1226 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
1227 }
1228 }
bab6aec1 1229 output_operand_type (table, class, types, ARRAY_SIZE (types), stage,
40fb9820
L
1230 indent);
1231}
1232
c587b3f9
L
1233static void
1234output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 1235 char *last, int lineno)
c587b3f9
L
1236{
1237 unsigned int i;
1238 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1239 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1240
1241 /* Find number of operands. */
1242 operands = next_field (str, ',', &str, last);
1243
1244 /* Find base_opcode. */
1245 base_opcode = next_field (str, ',', &str, last);
1246
1247 /* Find extension_opcode. */
1248 extension_opcode = next_field (str, ',', &str, last);
1249
1250 /* Find opcode_length. */
1251 opcode_length = next_field (str, ',', &str, last);
1252
1253 /* Find cpu_flags. */
1254 cpu_flags = next_field (str, ',', &str, last);
1255
1256 /* Find opcode_modifier. */
1257 opcode_modifier = next_field (str, ',', &str, last);
1258
1259 /* Remove the first {. */
1260 str = remove_leading_whitespaces (str);
1261 if (*str != '{')
1262 abort ();
1263 str = remove_leading_whitespaces (str + 1);
1264
1265 i = strlen (str);
1266
1267 /* There are at least "X}". */
1268 if (i < 2)
1269 abort ();
1270
1271 /* Remove trailing white spaces and }. */
1272 do
1273 {
1274 i--;
1275 if (ISSPACE (str[i]) || str[i] == '}')
1276 str[i] = '\0';
1277 else
1278 break;
1279 }
1280 while (i != 0);
1281
1282 last = str + i;
1283
1284 /* Find operand_types. */
1285 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1286 {
1287 if (str >= last)
1288 {
1289 operand_types [i] = NULL;
1290 break;
1291 }
1292
1293 operand_types [i] = next_field (str, ',', &str, last);
1294 if (*operand_types[i] == '0')
1295 {
1296 if (i != 0)
1297 operand_types[i] = NULL;
1298 break;
1299 }
1300 }
1301
1302 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
a2cebd03 1303 name, base_opcode, extension_opcode, opcode_length, operands);
c587b3f9 1304
bd5295b2 1305 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
c587b3f9 1306
4a1b91ea 1307 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
c587b3f9
L
1308
1309 fprintf (table, " { ");
1310
1311 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1312 {
1313 if (operand_types[i] == NULL || *operand_types[i] == '0')
1314 {
1315 if (i == 0)
7ac20022
JB
1316 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1317 lineno);
c587b3f9
L
1318 break;
1319 }
1320
1321 if (i != 0)
1322 fprintf (table, ",\n ");
1323
7ac20022 1324 process_i386_operand_type (table, operand_types[i], stage_opcodes,
bd5295b2 1325 "\t ", lineno);
c587b3f9
L
1326 }
1327 fprintf (table, " } },\n");
1328}
1329
1330struct opcode_hash_entry
1331{
1332 struct opcode_hash_entry *next;
1333 char *name;
1334 char *opcode;
bd5295b2 1335 int lineno;
c587b3f9
L
1336};
1337
1338/* Calculate the hash value of an opcode hash entry P. */
1339
1340static hashval_t
1341opcode_hash_hash (const void *p)
1342{
1343 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1344 return htab_hash_string (entry->name);
1345}
1346
1347/* Compare a string Q against an opcode hash entry P. */
1348
1349static int
1350opcode_hash_eq (const void *p, const void *q)
1351{
1352 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1353 const char *name = (const char *) q;
1354 return strcmp (name, entry->name) == 0;
1355}
1356
40b8e679 1357static void
72ffa0fb 1358process_i386_opcodes (FILE *table)
40b8e679 1359{
3d4d5afa 1360 FILE *fp;
40b8e679 1361 char buf[2048];
c587b3f9
L
1362 unsigned int i, j;
1363 char *str, *p, *last, *name;
1364 struct opcode_hash_entry **hash_slot, **entry, *next;
1365 htab_t opcode_hash_table;
1366 struct opcode_hash_entry **opcode_array;
1367 unsigned int opcode_array_size = 1024;
c30be56e 1368 int lineno = 0, marker = 0;
40b8e679 1369
3d4d5afa 1370 filename = "i386-opc.tbl";
c30be56e 1371 fp = stdin;
40b8e679 1372
c587b3f9
L
1373 i = 0;
1374 opcode_array = (struct opcode_hash_entry **)
1375 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1376
1377 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1378 opcode_hash_eq, NULL,
1379 xcalloc, free);
1380
34edb9ad 1381 fprintf (table, "\n/* i386 opcode table. */\n\n");
d3ce72d0 1382 fprintf (table, "const insn_template i386_optab[] =\n{\n");
40b8e679 1383
c587b3f9 1384 /* Put everything on opcode array. */
40b8e679
L
1385 while (!feof (fp))
1386 {
1387 if (fgets (buf, sizeof (buf), fp) == NULL)
1388 break;
1389
3d4d5afa
L
1390 lineno++;
1391
40b8e679
L
1392 p = remove_leading_whitespaces (buf);
1393
1394 /* Skip comments. */
1395 str = strstr (p, "//");
1396 if (str != NULL)
1397 str[0] = '\0';
1398
1399 /* Remove trailing white spaces. */
1400 remove_trailing_whitespaces (p);
1401
1402 switch (p[0])
1403 {
1404 case '#':
c30be56e
JB
1405 if (!strcmp("### MARKER ###", buf))
1406 marker = 1;
1407 else
1408 {
1409 /* Since we ignore all included files (we only care about their
1410 #define-s here), we don't need to monitor filenames. The final
1411 line number directive is going to refer to the main source file
1412 again. */
1413 char *end;
1414 unsigned long ln;
1415
1416 p = remove_leading_whitespaces (p + 1);
1417 if (!strncmp(p, "line", 4))
1418 p += 4;
1419 ln = strtoul (p, &end, 10);
1420 if (ln > 1 && ln < INT_MAX
1421 && *remove_leading_whitespaces (end) == '"')
1422 lineno = ln - 1;
1423 }
c587b3f9 1424 /* Ignore comments. */
40b8e679
L
1425 case '\0':
1426 continue;
1427 break;
1428 default:
c30be56e
JB
1429 if (!marker)
1430 continue;
40b8e679
L
1431 break;
1432 }
1433
1434 last = p + strlen (p);
1435
1436 /* Find name. */
c587b3f9 1437 name = next_field (p, ',', &str, last);
40b8e679 1438
c587b3f9
L
1439 /* Get the slot in hash table. */
1440 hash_slot = (struct opcode_hash_entry **)
1441 htab_find_slot_with_hash (opcode_hash_table, name,
1442 htab_hash_string (name),
1443 INSERT);
40b8e679 1444
c587b3f9 1445 if (*hash_slot == NULL)
40b8e679 1446 {
c587b3f9
L
1447 /* It is the new one. Put it on opcode array. */
1448 if (i >= opcode_array_size)
40b8e679 1449 {
c587b3f9
L
1450 /* Grow the opcode array when needed. */
1451 opcode_array_size += 1024;
1452 opcode_array = (struct opcode_hash_entry **)
1453 xrealloc (opcode_array,
1454 sizeof (*opcode_array) * opcode_array_size);
40b8e679
L
1455 }
1456
c587b3f9
L
1457 opcode_array[i] = (struct opcode_hash_entry *)
1458 xmalloc (sizeof (struct opcode_hash_entry));
1459 opcode_array[i]->next = NULL;
1460 opcode_array[i]->name = xstrdup (name);
1461 opcode_array[i]->opcode = xstrdup (str);
bd5295b2 1462 opcode_array[i]->lineno = lineno;
c587b3f9
L
1463 *hash_slot = opcode_array[i];
1464 i++;
40b8e679 1465 }
c587b3f9 1466 else
40b8e679 1467 {
c587b3f9
L
1468 /* Append it to the existing one. */
1469 entry = hash_slot;
1470 while ((*entry) != NULL)
1471 entry = &(*entry)->next;
1472 *entry = (struct opcode_hash_entry *)
1473 xmalloc (sizeof (struct opcode_hash_entry));
1474 (*entry)->next = NULL;
1475 (*entry)->name = (*hash_slot)->name;
1476 (*entry)->opcode = xstrdup (str);
bd5295b2 1477 (*entry)->lineno = lineno;
c587b3f9
L
1478 }
1479 }
40b8e679 1480
c587b3f9
L
1481 /* Process opcode array. */
1482 for (j = 0; j < i; j++)
1483 {
1484 for (next = opcode_array[j]; next; next = next->next)
1485 {
1486 name = next->name;
1487 str = next->opcode;
bd5295b2 1488 lineno = next->lineno;
c587b3f9 1489 last = str + strlen (str);
bd5295b2 1490 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1491 }
40b8e679
L
1492 }
1493
34edb9ad
L
1494 fclose (fp);
1495
4dffcebc 1496 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820 1497
bd5295b2 1498 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
40fb9820 1499
4a1b91ea 1500 process_i386_opcode_modifier (table, "0", NULL, -1);
29c048b6 1501
40fb9820 1502 fprintf (table, " { ");
7ac20022 1503 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
40fb9820
L
1504 fprintf (table, " } }\n");
1505
34edb9ad 1506 fprintf (table, "};\n");
40b8e679
L
1507}
1508
1509static void
72ffa0fb 1510process_i386_registers (FILE *table)
40b8e679 1511{
3d4d5afa 1512 FILE *fp;
40b8e679
L
1513 char buf[2048];
1514 char *str, *p, *last;
1515 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1516 char *dw2_32_num, *dw2_64_num;
bd5295b2 1517 int lineno = 0;
40b8e679 1518
3d4d5afa
L
1519 filename = "i386-reg.tbl";
1520 fp = fopen (filename, "r");
40b8e679 1521 if (fp == NULL)
34edb9ad 1522 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1523 xstrerror (errno));
40b8e679 1524
34edb9ad
L
1525 fprintf (table, "\n/* i386 register table. */\n\n");
1526 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1527
1528 while (!feof (fp))
1529 {
1530 if (fgets (buf, sizeof (buf), fp) == NULL)
1531 break;
1532
3d4d5afa
L
1533 lineno++;
1534
40b8e679
L
1535 p = remove_leading_whitespaces (buf);
1536
1537 /* Skip comments. */
1538 str = strstr (p, "//");
1539 if (str != NULL)
1540 str[0] = '\0';
1541
1542 /* Remove trailing white spaces. */
1543 remove_trailing_whitespaces (p);
1544
1545 switch (p[0])
1546 {
1547 case '#':
34edb9ad 1548 fprintf (table, "%s\n", p);
40b8e679
L
1549 case '\0':
1550 continue;
1551 break;
1552 default:
1553 break;
1554 }
1555
1556 last = p + strlen (p);
1557
1558 /* Find reg_name. */
c587b3f9 1559 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1560
1561 /* Find reg_type. */
c587b3f9 1562 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1563
1564 /* Find reg_flags. */
c587b3f9 1565 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1566
1567 /* Find reg_num. */
c587b3f9 1568 reg_num = next_field (str, ',', &str, last);
a60de03c 1569
40fb9820
L
1570 fprintf (table, " { \"%s\",\n ", reg_name);
1571
7ac20022
JB
1572 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1573 lineno);
40fb9820 1574
a60de03c 1575 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1576 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1577
1578 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1579 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1580
1581 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1582 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1583 }
1584
34edb9ad
L
1585 fclose (fp);
1586
1587 fprintf (table, "};\n");
40b8e679 1588
34edb9ad 1589 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1590}
1591
40fb9820
L
1592static void
1593process_i386_initializers (void)
1594{
1595 unsigned int i;
1596 FILE *fp = fopen ("i386-init.h", "w");
1597 char *init;
1598
1599 if (fp == NULL)
1600 fail (_("can't create i386-init.h, errno = %s\n"),
1601 xstrerror (errno));
1602
1603 process_copyright (fp);
1604
1605 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1606 {
1607 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1608 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1609 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1610 free (init);
1611 }
1612
1613 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1614 {
1615 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1616 init = xstrdup (operand_type_init[i].init);
7ac20022 1617 process_i386_operand_type (fp, init, stage_macros, " ", -1);
40fb9820
L
1618 free (init);
1619 }
1620 fprintf (fp, "\n");
1621
1622 fclose (fp);
1623}
1624
40b8e679
L
1625/* Program options. */
1626#define OPTION_SRCDIR 200
1627
29c048b6 1628struct option long_options[] =
40b8e679
L
1629{
1630 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1631 {"debug", no_argument, NULL, 'd'},
1632 {"version", no_argument, NULL, 'V'},
1633 {"help", no_argument, NULL, 'h'},
1634 {0, no_argument, NULL, 0}
1635};
1636
1637static void
1638print_version (void)
1639{
1640 printf ("%s: version 1.0\n", program_name);
1641 xexit (0);
1642}
1643
1644static void
1645usage (FILE * stream, int status)
1646{
1647 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1648 program_name);
1649 xexit (status);
1650}
1651
1652int
1653main (int argc, char **argv)
1654{
1655 extern int chdir (char *);
1656 char *srcdir = NULL;
8b40d594 1657 int c;
e92bae62 1658 unsigned int i, cpumax;
72ffa0fb 1659 FILE *table;
29c048b6 1660
40b8e679
L
1661 program_name = *argv;
1662 xmalloc_set_program_name (program_name);
1663
1664 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1665 switch (c)
1666 {
1667 case OPTION_SRCDIR:
1668 srcdir = optarg;
1669 break;
1670 case 'V':
1671 case 'v':
1672 print_version ();
1673 break;
1674 case 'd':
1675 debug = 1;
1676 break;
1677 case 'h':
1678 case '?':
1679 usage (stderr, 0);
1680 default:
1681 case 0:
1682 break;
1683 }
1684
1685 if (optind != argc)
1686 usage (stdout, 1);
1687
29c048b6 1688 if (srcdir != NULL)
40b8e679
L
1689 if (chdir (srcdir) != 0)
1690 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
1691 srcdir, xstrerror (errno));
1692
e92bae62
L
1693 /* cpu_flags isn't sorted by position. */
1694 cpumax = 0;
1695 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1696 if (cpu_flags[i].position > cpumax)
1697 cpumax = cpu_flags[i].position;
1698
40fb9820 1699 /* Check the unused bitfield in i386_cpu_flags. */
e89c5eaa 1700#ifdef CpuUnused
1d942ae9
JB
1701 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1702
e92bae62
L
1703 if ((cpumax - 1) != CpuMax)
1704 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1705#else
1d942ae9
JB
1706 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1707
e92bae62
L
1708 if (cpumax != CpuMax)
1709 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1710
8b40d594
L
1711 c = CpuNumOfBits - CpuMax - 1;
1712 if (c)
1713 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
1714#endif
1715
1d942ae9
JB
1716 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1717
40fb9820 1718 /* Check the unused bitfield in i386_operand_type. */
1d942ae9 1719#ifdef OTUnused
bab6aec1 1720 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH == OTNum + 1);
1d942ae9 1721#else
bab6aec1 1722 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH == OTNum);
1d942ae9 1723
8b40d594
L
1724 c = OTNumOfBits - OTMax - 1;
1725 if (c)
1726 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
1727#endif
1728
1729 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1730 compare);
1731
1732 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1733 sizeof (opcode_modifiers [0]), compare);
1734
1735 qsort (operand_types, ARRAY_SIZE (operand_types),
1736 sizeof (operand_types [0]), compare);
40b8e679 1737
34edb9ad
L
1738 table = fopen ("i386-tbl.h", "w");
1739 if (table == NULL)
40fb9820
L
1740 fail (_("can't create i386-tbl.h, errno = %s\n"),
1741 xstrerror (errno));
34edb9ad 1742
72ffa0fb 1743 process_copyright (table);
40b8e679 1744
72ffa0fb
L
1745 process_i386_opcodes (table);
1746 process_i386_registers (table);
40fb9820 1747 process_i386_initializers ();
40b8e679 1748
34edb9ad
L
1749 fclose (table);
1750
40b8e679
L
1751 exit (0);
1752}