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