x86: replace NoRex64 on VEX-encoded insns
[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),
40fb9820 652 BITFIELD (Ugh),
c0f3af97 653 BITFIELD (Vex),
2426c15f 654 BITFIELD (VexVVVV),
1ef99a7b 655 BITFIELD (VexW),
7f399153 656 BITFIELD (VexOpcode),
8cd7925b 657 BITFIELD (VexSources),
6c30d220 658 BITFIELD (VecSIB),
c0f3af97 659 BITFIELD (SSE2AVX),
81f8a913 660 BITFIELD (NoAVX),
43234a1e
L
661 BITFIELD (EVex),
662 BITFIELD (Masking),
43234a1e
L
663 BITFIELD (Broadcast),
664 BITFIELD (StaticRounding),
665 BITFIELD (SAE),
666 BITFIELD (Disp8MemShift),
667 BITFIELD (NoDefMask),
920d2ddc 668 BITFIELD (ImplicitQuadGroup),
b6f8c7c4 669 BITFIELD (Optimize),
1efbbeb4 670 BITFIELD (ATTMnemonic),
e1d4d893 671 BITFIELD (ATTSyntax),
5c07affc 672 BITFIELD (IntelSyntax),
4b5aaf5f 673 BITFIELD (ISA64),
40fb9820
L
674};
675
bab6aec1
JB
676#define CLASS(n) #n, n
677
678static const struct {
679 const char *name;
680 enum operand_class value;
681} operand_classes[] = {
682 CLASS (Reg),
00cee14f 683 CLASS (SReg),
4a5c67ed
JB
684 CLASS (RegCR),
685 CLASS (RegDR),
686 CLASS (RegTR),
3528c362
JB
687 CLASS (RegMMX),
688 CLASS (RegSIMD),
f74a6307
JB
689 CLASS (RegMask),
690 CLASS (RegBND),
bab6aec1
JB
691};
692
693#undef CLASS
694
75e5731b
JB
695#define INSTANCE(n) #n, n
696
697static const struct {
698 const char *name;
699 enum operand_instance value;
700} operand_instances[] = {
701 INSTANCE (Accum),
702 INSTANCE (RegC),
703 INSTANCE (RegD),
474da251 704 INSTANCE (RegB),
75e5731b
JB
705};
706
707#undef INSTANCE
708
40fb9820
L
709static bitfield operand_types[] =
710{
94ff3a50 711 BITFIELD (Imm1),
40fb9820
L
712 BITFIELD (Imm8),
713 BITFIELD (Imm8S),
714 BITFIELD (Imm16),
715 BITFIELD (Imm32),
716 BITFIELD (Imm32S),
717 BITFIELD (Imm64),
40fb9820
L
718 BITFIELD (BaseIndex),
719 BITFIELD (Disp8),
720 BITFIELD (Disp16),
721 BITFIELD (Disp32),
722 BITFIELD (Disp32S),
723 BITFIELD (Disp64),
7d5e4556
L
724 BITFIELD (Byte),
725 BITFIELD (Word),
726 BITFIELD (Dword),
727 BITFIELD (Fword),
728 BITFIELD (Qword),
729 BITFIELD (Tbyte),
730 BITFIELD (Xmmword),
c0f3af97 731 BITFIELD (Ymmword),
43234a1e 732 BITFIELD (Zmmword),
7d5e4556 733 BITFIELD (Unspecified),
40fb9820
L
734#ifdef OTUnused
735 BITFIELD (OTUnused),
736#endif
737};
738
3d4d5afa 739static const char *filename;
7ac20022
JB
740static i386_cpu_flags active_cpu_flags;
741static int active_isstring;
3d4d5afa 742
40fb9820
L
743static int
744compare (const void *x, const void *y)
745{
746 const bitfield *xp = (const bitfield *) x;
747 const bitfield *yp = (const bitfield *) y;
748 return xp->position - yp->position;
749}
750
40b8e679
L
751static void
752fail (const char *message, ...)
753{
754 va_list args;
29c048b6 755
40b8e679 756 va_start (args, message);
a6743a54 757 fprintf (stderr, _("%s: error: "), program_name);
40b8e679
L
758 vfprintf (stderr, message, args);
759 va_end (args);
760 xexit (1);
761}
762
72ffa0fb
L
763static void
764process_copyright (FILE *fp)
765{
766 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
b3adc24a 767/* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
72ffa0fb
L
768\n\
769 This file is part of the GNU opcodes library.\n\
770\n\
771 This library is free software; you can redistribute it and/or modify\n\
772 it under the terms of the GNU General Public License as published by\n\
773 the Free Software Foundation; either version 3, or (at your option)\n\
774 any later version.\n\
775\n\
776 It is distributed in the hope that it will be useful, but WITHOUT\n\
777 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
778 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
779 License for more details.\n\
780\n\
781 You should have received a copy of the GNU General Public License\n\
782 along with this program; if not, write to the Free Software\n\
783 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
784 MA 02110-1301, USA. */\n");
785}
786
40b8e679
L
787/* Remove leading white spaces. */
788
789static char *
790remove_leading_whitespaces (char *str)
791{
792 while (ISSPACE (*str))
793 str++;
794 return str;
795}
796
797/* Remove trailing white spaces. */
798
799static void
800remove_trailing_whitespaces (char *str)
801{
802 size_t last = strlen (str);
803
804 if (last == 0)
805 return;
806
807 do
808 {
809 last--;
810 if (ISSPACE (str [last]))
811 str[last] = '\0';
812 else
813 break;
814 }
815 while (last != 0);
816}
817
93b1ec2c 818/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
819 pointer to the one after it. */
820
821static char *
c587b3f9 822next_field (char *str, char sep, char **next, char *last)
40b8e679
L
823{
824 char *p;
825
826 p = remove_leading_whitespaces (str);
93b1ec2c 827 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
828
829 *str = '\0';
830 remove_trailing_whitespaces (p);
831
29c048b6 832 *next = str + 1;
40b8e679 833
c587b3f9
L
834 if (p >= last)
835 abort ();
836
40b8e679
L
837 return p;
838}
839
1848e567
L
840static void set_bitfield (char *, bitfield *, int, unsigned int, int);
841
842static int
3cc17af5
JB
843set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
844 int lineno)
1848e567
L
845{
846 char *str, *next, *last;
847 unsigned int i;
848
849 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
850 if (strcmp (cpu_flag_init[i].name, f) == 0)
851 {
852 /* Turn on selective bits. */
853 char *init = xstrdup (cpu_flag_init[i].init);
854 last = init + strlen (init);
855 for (next = init; next && next < last; )
856 {
857 str = next_field (next, '|', &next, last);
858 if (str)
859 set_bitfield (str, array, 1, size, lineno);
860 }
861 free (init);
862 return 0;
863 }
864
865 return -1;
866}
867
40fb9820 868static void
1848e567 869set_bitfield (char *f, bitfield *array, int value,
8a9036a4 870 unsigned int size, int lineno)
40fb9820
L
871{
872 unsigned int i;
873
309d3373
JB
874 if (strcmp (f, "CpuFP") == 0)
875 {
8a9036a4
L
876 set_bitfield("Cpu387", array, value, size, lineno);
877 set_bitfield("Cpu287", array, value, size, lineno);
309d3373
JB
878 f = "Cpu8087";
879 }
880 else if (strcmp (f, "Mmword") == 0)
7d5e4556
L
881 f= "Qword";
882 else if (strcmp (f, "Oword") == 0)
883 f= "Xmmword";
40fb9820
L
884
885 for (i = 0; i < size; i++)
886 if (strcasecmp (array[i].name, f) == 0)
887 {
8a9036a4 888 array[i].value = value;
40fb9820
L
889 return;
890 }
891
2bf05e57
L
892 if (value)
893 {
894 const char *v = strchr (f, '=');
895
896 if (v)
897 {
898 size_t n = v - f;
899 char *end;
900
901 for (i = 0; i < size; i++)
902 if (strncasecmp (array[i].name, f, n) == 0)
903 {
904 value = strtol (v + 1, &end, 0);
905 if (*end == '\0')
906 {
907 array[i].value = value;
908 return;
909 }
910 break;
911 }
912 }
913 }
914
3cc17af5
JB
915 /* Handle CPU_XXX_FLAGS. */
916 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1848e567
L
917 return;
918
bd5295b2 919 if (lineno != -1)
a6743a54 920 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
bd5295b2 921 else
a6743a54 922 fail (_("unknown bitfield: %s\n"), f);
40fb9820
L
923}
924
925static void
926output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
927 int macro, const char *comma, const char *indent)
928{
929 unsigned int i;
930
7ac20022
JB
931 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
932
40fb9820
L
933 fprintf (table, "%s{ { ", indent);
934
935 for (i = 0; i < size - 1; i++)
936 {
10632b79
L
937 if (((i + 1) % 20) != 0)
938 fprintf (table, "%d, ", flags[i].value);
939 else
940 fprintf (table, "%d,", flags[i].value);
40fb9820
L
941 if (((i + 1) % 20) == 0)
942 {
943 /* We need \\ for macro. */
944 if (macro)
945 fprintf (table, " \\\n %s", indent);
946 else
947 fprintf (table, "\n %s", indent);
948 }
7ac20022
JB
949 if (flags[i].value)
950 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
40fb9820
L
951 }
952
953 fprintf (table, "%d } }%s\n", flags[i].value, comma);
954}
955
956static void
957process_i386_cpu_flag (FILE *table, char *flag, int macro,
bd5295b2
L
958 const char *comma, const char *indent,
959 int lineno)
40fb9820
L
960{
961 char *str, *next, *last;
8a9036a4 962 unsigned int i;
40fb9820
L
963 bitfield flags [ARRAY_SIZE (cpu_flags)];
964
965 /* Copy the default cpu flags. */
966 memcpy (flags, cpu_flags, sizeof (cpu_flags));
967
968 if (strcasecmp (flag, "unknown") == 0)
969 {
40fb9820 970 /* We turn on everything except for cpu64 in case of
8a9036a4
L
971 CPU_UNKNOWN_FLAGS. */
972 for (i = 0; i < ARRAY_SIZE (flags); i++)
973 if (flags[i].position != Cpu64)
974 flags[i].value = 1;
975 }
976 else if (flag[0] == '~')
977 {
978 last = flag + strlen (flag);
979
980 if (flag[1] == '(')
981 {
982 last -= 1;
983 next = flag + 2;
984 if (*last != ')')
a6743a54 985 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
8a9036a4
L
986 lineno, flag);
987 *last = '\0';
988 }
989 else
990 next = flag + 1;
991
992 /* First we turn on everything except for cpu64. */
40fb9820
L
993 for (i = 0; i < ARRAY_SIZE (flags); i++)
994 if (flags[i].position != Cpu64)
995 flags[i].value = 1;
8a9036a4
L
996
997 /* Turn off selective bits. */
998 for (; next && next < last; )
999 {
1000 str = next_field (next, '|', &next, last);
1001 if (str)
1002 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1003 }
40fb9820
L
1004 }
1005 else if (strcmp (flag, "0"))
1006 {
8a9036a4 1007 /* Turn on selective bits. */
40fb9820
L
1008 last = flag + strlen (flag);
1009 for (next = flag; next && next < last; )
1010 {
c587b3f9 1011 str = next_field (next, '|', &next, last);
40fb9820 1012 if (str)
8a9036a4 1013 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
40fb9820
L
1014 }
1015 }
1016
1017 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1018 comma, indent);
1019}
1020
1021static void
1022output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1023{
1024 unsigned int i;
1025
1026 fprintf (table, " { ");
1027
1028 for (i = 0; i < size - 1; i++)
1029 {
10632b79
L
1030 if (((i + 1) % 20) != 0)
1031 fprintf (table, "%d, ", modifier[i].value);
1032 else
1033 fprintf (table, "%d,", modifier[i].value);
40fb9820
L
1034 if (((i + 1) % 20) == 0)
1035 fprintf (table, "\n ");
1036 }
1037
1038 fprintf (table, "%d },\n", modifier[i].value);
1039}
1040
4a1b91ea
L
1041static int
1042adjust_broadcast_modifier (char **opnd)
1043{
1044 char *str, *next, *last, *op;
1045 int bcst_type = INT_MAX;
1046
1047 /* Skip the immediate operand. */
1048 op = opnd[0];
1049 if (strcasecmp(op, "Imm8") == 0)
1050 op = opnd[1];
1051
1052 op = xstrdup (op);
1053 last = op + strlen (op);
1054 for (next = op; next && next < last; )
1055 {
1056 str = next_field (next, '|', &next, last);
1057 if (str)
1058 {
1059 if (strcasecmp(str, "Byte") == 0)
1060 {
1061 /* The smalest broadcast type, no need to check
1062 further. */
1063 bcst_type = BYTE_BROADCAST;
1064 break;
1065 }
1066 else if (strcasecmp(str, "Word") == 0)
1067 {
1068 if (bcst_type > WORD_BROADCAST)
1069 bcst_type = WORD_BROADCAST;
1070 }
1071 else if (strcasecmp(str, "Dword") == 0)
1072 {
1073 if (bcst_type > DWORD_BROADCAST)
1074 bcst_type = DWORD_BROADCAST;
1075 }
1076 else if (strcasecmp(str, "Qword") == 0)
1077 {
1078 if (bcst_type > QWORD_BROADCAST)
1079 bcst_type = QWORD_BROADCAST;
1080 }
1081 }
1082 }
1083 free (op);
1084
1085 if (bcst_type == INT_MAX)
1086 fail (_("unknown broadcast operand: %s\n"), op);
1087
1088 return bcst_type;
1089}
1090
40fb9820 1091static void
4a1b91ea 1092process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
40fb9820
L
1093{
1094 char *str, *next, *last;
1095 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1096
7ac20022
JB
1097 active_isstring = 0;
1098
40fb9820
L
1099 /* Copy the default opcode modifier. */
1100 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1101
1102 if (strcmp (mod, "0"))
1103 {
507916b8
JB
1104 unsigned int have_w = 0, bwlq_suf = 0xf;
1105
40fb9820
L
1106 last = mod + strlen (mod);
1107 for (next = mod; next && next < last; )
1108 {
c587b3f9 1109 str = next_field (next, '|', &next, last);
40fb9820 1110 if (str)
7ac20022 1111 {
4a1b91ea
L
1112 int val = 1;
1113 if (strcasecmp(str, "Broadcast") == 0)
1114 val = adjust_broadcast_modifier (opnd);
1115 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
8a9036a4 1116 lineno);
7ac20022
JB
1117 if (strcasecmp(str, "IsString") == 0)
1118 active_isstring = 1;
507916b8
JB
1119
1120 if (strcasecmp(str, "W") == 0)
1121 have_w = 1;
1122
1123 if (strcasecmp(str, "No_bSuf") == 0)
1124 bwlq_suf &= ~1;
1125 if (strcasecmp(str, "No_wSuf") == 0)
1126 bwlq_suf &= ~2;
1127 if (strcasecmp(str, "No_lSuf") == 0)
1128 bwlq_suf &= ~4;
1129 if (strcasecmp(str, "No_qSuf") == 0)
1130 bwlq_suf &= ~8;
7ac20022 1131 }
40fb9820 1132 }
507916b8
JB
1133
1134 if (have_w && !bwlq_suf)
1135 fail ("%s: %d: stray W modifier\n", filename, lineno);
1136 if (have_w && !(bwlq_suf & 1))
1137 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1138 filename, lineno);
1139 if (have_w && !(bwlq_suf & ~1))
1140 fprintf (stderr,
1141 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1142 filename, lineno);
40fb9820
L
1143 }
1144 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1145}
1146
7ac20022
JB
1147enum stage {
1148 stage_macros,
1149 stage_opcodes,
1150 stage_registers,
1151};
1152
40fb9820 1153static void
bab6aec1 1154output_operand_type (FILE *table, enum operand_class class,
75e5731b 1155 enum operand_instance instance,
bab6aec1 1156 const bitfield *types, unsigned int size,
7ac20022 1157 enum stage stage, const char *indent)
40fb9820
L
1158{
1159 unsigned int i;
1160
75e5731b 1161 fprintf (table, "{ { %d, %d, ", class, instance);
40fb9820
L
1162
1163 for (i = 0; i < size - 1; i++)
1164 {
75e5731b 1165 if (((i + 3) % 20) != 0)
10632b79
L
1166 fprintf (table, "%d, ", types[i].value);
1167 else
1168 fprintf (table, "%d,", types[i].value);
75e5731b 1169 if (((i + 3) % 20) == 0)
40fb9820
L
1170 {
1171 /* We need \\ for macro. */
7ac20022 1172 if (stage == stage_macros)
10632b79 1173 fprintf (table, " \\\n%s", indent);
40fb9820
L
1174 else
1175 fprintf (table, "\n%s", indent);
1176 }
1177 }
1178
1179 fprintf (table, "%d } }", types[i].value);
1180}
1181
1182static void
7ac20022 1183process_i386_operand_type (FILE *table, char *op, enum stage stage,
bd5295b2 1184 const char *indent, int lineno)
40fb9820
L
1185{
1186 char *str, *next, *last;
bab6aec1 1187 enum operand_class class = ClassNone;
75e5731b 1188 enum operand_instance instance = InstanceNone;
40fb9820
L
1189 bitfield types [ARRAY_SIZE (operand_types)];
1190
1191 /* Copy the default operand type. */
1192 memcpy (types, operand_types, sizeof (types));
1193
1194 if (strcmp (op, "0"))
1195 {
7ac20022
JB
1196 int baseindex = 0;
1197
40fb9820
L
1198 last = op + strlen (op);
1199 for (next = op; next && next < last; )
1200 {
c587b3f9 1201 str = next_field (next, '|', &next, last);
bab6aec1
JB
1202 if (str)
1203 {
1204 unsigned int i;
1205
1206 if (!strncmp(str, "Class=", 6))
1207 {
1208 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1209 if (!strcmp(str + 6, operand_classes[i].name))
1210 {
1211 class = operand_classes[i].value;
1212 str = NULL;
1213 break;
1214 }
1215 }
75e5731b
JB
1216
1217 if (str && !strncmp(str, "Instance=", 9))
1218 {
1219 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1220 if (!strcmp(str + 9, operand_instances[i].name))
1221 {
1222 instance = operand_instances[i].value;
1223 str = NULL;
1224 break;
1225 }
1226 }
bab6aec1 1227 }
40fb9820 1228 if (str)
7ac20022
JB
1229 {
1230 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1231 if (strcasecmp(str, "BaseIndex") == 0)
1232 baseindex = 1;
1233 }
1234 }
1235
1236 if (stage == stage_opcodes && baseindex && !active_isstring)
1237 {
1238 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1239 if (!active_cpu_flags.bitfield.cpu64
1240 && !active_cpu_flags.bitfield.cpumpx)
1241 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
48bcea9f
JB
1242 if (!active_cpu_flags.bitfield.cpu64)
1243 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
7ac20022
JB
1244 if (!active_cpu_flags.bitfield.cpuno64)
1245 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
1246 }
1247 }
75e5731b
JB
1248 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1249 stage, indent);
40fb9820
L
1250}
1251
c587b3f9
L
1252static void
1253output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 1254 char *last, int lineno)
c587b3f9
L
1255{
1256 unsigned int i;
1257 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1258 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1259
1260 /* Find number of operands. */
1261 operands = next_field (str, ',', &str, last);
1262
1263 /* Find base_opcode. */
1264 base_opcode = next_field (str, ',', &str, last);
1265
1266 /* Find extension_opcode. */
1267 extension_opcode = next_field (str, ',', &str, last);
1268
1269 /* Find opcode_length. */
1270 opcode_length = next_field (str, ',', &str, last);
1271
1272 /* Find cpu_flags. */
1273 cpu_flags = next_field (str, ',', &str, last);
1274
1275 /* Find opcode_modifier. */
1276 opcode_modifier = next_field (str, ',', &str, last);
1277
1278 /* Remove the first {. */
1279 str = remove_leading_whitespaces (str);
1280 if (*str != '{')
1281 abort ();
1282 str = remove_leading_whitespaces (str + 1);
1283
1284 i = strlen (str);
1285
1286 /* There are at least "X}". */
1287 if (i < 2)
1288 abort ();
1289
1290 /* Remove trailing white spaces and }. */
1291 do
1292 {
1293 i--;
1294 if (ISSPACE (str[i]) || str[i] == '}')
1295 str[i] = '\0';
1296 else
1297 break;
1298 }
1299 while (i != 0);
1300
1301 last = str + i;
1302
1303 /* Find operand_types. */
1304 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1305 {
1306 if (str >= last)
1307 {
1308 operand_types [i] = NULL;
1309 break;
1310 }
1311
1312 operand_types [i] = next_field (str, ',', &str, last);
1313 if (*operand_types[i] == '0')
1314 {
1315 if (i != 0)
1316 operand_types[i] = NULL;
1317 break;
1318 }
1319 }
1320
1321 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
a2cebd03 1322 name, base_opcode, extension_opcode, opcode_length, operands);
c587b3f9 1323
bd5295b2 1324 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
c587b3f9 1325
4a1b91ea 1326 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
c587b3f9
L
1327
1328 fprintf (table, " { ");
1329
1330 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1331 {
1332 if (operand_types[i] == NULL || *operand_types[i] == '0')
1333 {
1334 if (i == 0)
7ac20022
JB
1335 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1336 lineno);
c587b3f9
L
1337 break;
1338 }
1339
1340 if (i != 0)
1341 fprintf (table, ",\n ");
1342
7ac20022 1343 process_i386_operand_type (table, operand_types[i], stage_opcodes,
bd5295b2 1344 "\t ", lineno);
c587b3f9
L
1345 }
1346 fprintf (table, " } },\n");
1347}
1348
1349struct opcode_hash_entry
1350{
1351 struct opcode_hash_entry *next;
1352 char *name;
1353 char *opcode;
bd5295b2 1354 int lineno;
c587b3f9
L
1355};
1356
1357/* Calculate the hash value of an opcode hash entry P. */
1358
1359static hashval_t
1360opcode_hash_hash (const void *p)
1361{
1362 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1363 return htab_hash_string (entry->name);
1364}
1365
1366/* Compare a string Q against an opcode hash entry P. */
1367
1368static int
1369opcode_hash_eq (const void *p, const void *q)
1370{
1371 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1372 const char *name = (const char *) q;
1373 return strcmp (name, entry->name) == 0;
1374}
1375
40b8e679 1376static void
72ffa0fb 1377process_i386_opcodes (FILE *table)
40b8e679 1378{
3d4d5afa 1379 FILE *fp;
40b8e679 1380 char buf[2048];
c587b3f9
L
1381 unsigned int i, j;
1382 char *str, *p, *last, *name;
1383 struct opcode_hash_entry **hash_slot, **entry, *next;
1384 htab_t opcode_hash_table;
1385 struct opcode_hash_entry **opcode_array;
1386 unsigned int opcode_array_size = 1024;
c30be56e 1387 int lineno = 0, marker = 0;
40b8e679 1388
3d4d5afa 1389 filename = "i386-opc.tbl";
c30be56e 1390 fp = stdin;
40b8e679 1391
c587b3f9
L
1392 i = 0;
1393 opcode_array = (struct opcode_hash_entry **)
1394 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1395
1396 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1397 opcode_hash_eq, NULL,
1398 xcalloc, free);
1399
34edb9ad 1400 fprintf (table, "\n/* i386 opcode table. */\n\n");
d3ce72d0 1401 fprintf (table, "const insn_template i386_optab[] =\n{\n");
40b8e679 1402
c587b3f9 1403 /* Put everything on opcode array. */
40b8e679
L
1404 while (!feof (fp))
1405 {
1406 if (fgets (buf, sizeof (buf), fp) == NULL)
1407 break;
1408
3d4d5afa
L
1409 lineno++;
1410
40b8e679
L
1411 p = remove_leading_whitespaces (buf);
1412
1413 /* Skip comments. */
1414 str = strstr (p, "//");
1415 if (str != NULL)
1416 str[0] = '\0';
1417
1418 /* Remove trailing white spaces. */
1419 remove_trailing_whitespaces (p);
1420
1421 switch (p[0])
1422 {
1423 case '#':
c30be56e
JB
1424 if (!strcmp("### MARKER ###", buf))
1425 marker = 1;
1426 else
1427 {
1428 /* Since we ignore all included files (we only care about their
1429 #define-s here), we don't need to monitor filenames. The final
1430 line number directive is going to refer to the main source file
1431 again. */
1432 char *end;
1433 unsigned long ln;
1434
1435 p = remove_leading_whitespaces (p + 1);
1436 if (!strncmp(p, "line", 4))
1437 p += 4;
1438 ln = strtoul (p, &end, 10);
1439 if (ln > 1 && ln < INT_MAX
1440 && *remove_leading_whitespaces (end) == '"')
1441 lineno = ln - 1;
1442 }
c587b3f9 1443 /* Ignore comments. */
40b8e679
L
1444 case '\0':
1445 continue;
1446 break;
1447 default:
c30be56e
JB
1448 if (!marker)
1449 continue;
40b8e679
L
1450 break;
1451 }
1452
1453 last = p + strlen (p);
1454
1455 /* Find name. */
c587b3f9 1456 name = next_field (p, ',', &str, last);
40b8e679 1457
c587b3f9
L
1458 /* Get the slot in hash table. */
1459 hash_slot = (struct opcode_hash_entry **)
1460 htab_find_slot_with_hash (opcode_hash_table, name,
1461 htab_hash_string (name),
1462 INSERT);
40b8e679 1463
c587b3f9 1464 if (*hash_slot == NULL)
40b8e679 1465 {
c587b3f9
L
1466 /* It is the new one. Put it on opcode array. */
1467 if (i >= opcode_array_size)
40b8e679 1468 {
c587b3f9
L
1469 /* Grow the opcode array when needed. */
1470 opcode_array_size += 1024;
1471 opcode_array = (struct opcode_hash_entry **)
1472 xrealloc (opcode_array,
1473 sizeof (*opcode_array) * opcode_array_size);
40b8e679
L
1474 }
1475
c587b3f9
L
1476 opcode_array[i] = (struct opcode_hash_entry *)
1477 xmalloc (sizeof (struct opcode_hash_entry));
1478 opcode_array[i]->next = NULL;
1479 opcode_array[i]->name = xstrdup (name);
1480 opcode_array[i]->opcode = xstrdup (str);
bd5295b2 1481 opcode_array[i]->lineno = lineno;
c587b3f9
L
1482 *hash_slot = opcode_array[i];
1483 i++;
40b8e679 1484 }
c587b3f9 1485 else
40b8e679 1486 {
c587b3f9
L
1487 /* Append it to the existing one. */
1488 entry = hash_slot;
1489 while ((*entry) != NULL)
1490 entry = &(*entry)->next;
1491 *entry = (struct opcode_hash_entry *)
1492 xmalloc (sizeof (struct opcode_hash_entry));
1493 (*entry)->next = NULL;
1494 (*entry)->name = (*hash_slot)->name;
1495 (*entry)->opcode = xstrdup (str);
bd5295b2 1496 (*entry)->lineno = lineno;
c587b3f9
L
1497 }
1498 }
40b8e679 1499
c587b3f9
L
1500 /* Process opcode array. */
1501 for (j = 0; j < i; j++)
1502 {
1503 for (next = opcode_array[j]; next; next = next->next)
1504 {
1505 name = next->name;
1506 str = next->opcode;
bd5295b2 1507 lineno = next->lineno;
c587b3f9 1508 last = str + strlen (str);
bd5295b2 1509 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1510 }
40b8e679
L
1511 }
1512
34edb9ad
L
1513 fclose (fp);
1514
4dffcebc 1515 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820 1516
bd5295b2 1517 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
40fb9820 1518
4a1b91ea 1519 process_i386_opcode_modifier (table, "0", NULL, -1);
29c048b6 1520
40fb9820 1521 fprintf (table, " { ");
7ac20022 1522 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
40fb9820
L
1523 fprintf (table, " } }\n");
1524
34edb9ad 1525 fprintf (table, "};\n");
40b8e679
L
1526}
1527
1528static void
72ffa0fb 1529process_i386_registers (FILE *table)
40b8e679 1530{
3d4d5afa 1531 FILE *fp;
40b8e679
L
1532 char buf[2048];
1533 char *str, *p, *last;
1534 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1535 char *dw2_32_num, *dw2_64_num;
bd5295b2 1536 int lineno = 0;
40b8e679 1537
3d4d5afa
L
1538 filename = "i386-reg.tbl";
1539 fp = fopen (filename, "r");
40b8e679 1540 if (fp == NULL)
34edb9ad 1541 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1542 xstrerror (errno));
40b8e679 1543
34edb9ad
L
1544 fprintf (table, "\n/* i386 register table. */\n\n");
1545 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1546
1547 while (!feof (fp))
1548 {
1549 if (fgets (buf, sizeof (buf), fp) == NULL)
1550 break;
1551
3d4d5afa
L
1552 lineno++;
1553
40b8e679
L
1554 p = remove_leading_whitespaces (buf);
1555
1556 /* Skip comments. */
1557 str = strstr (p, "//");
1558 if (str != NULL)
1559 str[0] = '\0';
1560
1561 /* Remove trailing white spaces. */
1562 remove_trailing_whitespaces (p);
1563
1564 switch (p[0])
1565 {
1566 case '#':
34edb9ad 1567 fprintf (table, "%s\n", p);
40b8e679
L
1568 case '\0':
1569 continue;
1570 break;
1571 default:
1572 break;
1573 }
1574
1575 last = p + strlen (p);
1576
1577 /* Find reg_name. */
c587b3f9 1578 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1579
1580 /* Find reg_type. */
c587b3f9 1581 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1582
1583 /* Find reg_flags. */
c587b3f9 1584 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1585
1586 /* Find reg_num. */
c587b3f9 1587 reg_num = next_field (str, ',', &str, last);
a60de03c 1588
40fb9820
L
1589 fprintf (table, " { \"%s\",\n ", reg_name);
1590
7ac20022
JB
1591 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1592 lineno);
40fb9820 1593
a60de03c 1594 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1595 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1596
1597 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1598 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1599
1600 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1601 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1602 }
1603
34edb9ad
L
1604 fclose (fp);
1605
1606 fprintf (table, "};\n");
40b8e679 1607
34edb9ad 1608 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1609}
1610
40fb9820
L
1611static void
1612process_i386_initializers (void)
1613{
1614 unsigned int i;
1615 FILE *fp = fopen ("i386-init.h", "w");
1616 char *init;
1617
1618 if (fp == NULL)
1619 fail (_("can't create i386-init.h, errno = %s\n"),
1620 xstrerror (errno));
1621
1622 process_copyright (fp);
1623
1624 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1625 {
1626 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1627 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1628 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1629 free (init);
1630 }
1631
1632 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1633 {
1634 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1635 init = xstrdup (operand_type_init[i].init);
7ac20022 1636 process_i386_operand_type (fp, init, stage_macros, " ", -1);
40fb9820
L
1637 free (init);
1638 }
1639 fprintf (fp, "\n");
1640
1641 fclose (fp);
1642}
1643
40b8e679
L
1644/* Program options. */
1645#define OPTION_SRCDIR 200
1646
29c048b6 1647struct option long_options[] =
40b8e679
L
1648{
1649 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1650 {"debug", no_argument, NULL, 'd'},
1651 {"version", no_argument, NULL, 'V'},
1652 {"help", no_argument, NULL, 'h'},
1653 {0, no_argument, NULL, 0}
1654};
1655
1656static void
1657print_version (void)
1658{
1659 printf ("%s: version 1.0\n", program_name);
1660 xexit (0);
1661}
1662
1663static void
1664usage (FILE * stream, int status)
1665{
1666 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1667 program_name);
1668 xexit (status);
1669}
1670
1671int
1672main (int argc, char **argv)
1673{
1674 extern int chdir (char *);
1675 char *srcdir = NULL;
8b40d594 1676 int c;
e92bae62 1677 unsigned int i, cpumax;
72ffa0fb 1678 FILE *table;
29c048b6 1679
40b8e679
L
1680 program_name = *argv;
1681 xmalloc_set_program_name (program_name);
1682
1683 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1684 switch (c)
1685 {
1686 case OPTION_SRCDIR:
1687 srcdir = optarg;
1688 break;
1689 case 'V':
1690 case 'v':
1691 print_version ();
1692 break;
1693 case 'd':
1694 debug = 1;
1695 break;
1696 case 'h':
1697 case '?':
1698 usage (stderr, 0);
1699 default:
1700 case 0:
1701 break;
1702 }
1703
1704 if (optind != argc)
1705 usage (stdout, 1);
1706
29c048b6 1707 if (srcdir != NULL)
40b8e679
L
1708 if (chdir (srcdir) != 0)
1709 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
1710 srcdir, xstrerror (errno));
1711
e92bae62
L
1712 /* cpu_flags isn't sorted by position. */
1713 cpumax = 0;
1714 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1715 if (cpu_flags[i].position > cpumax)
1716 cpumax = cpu_flags[i].position;
1717
40fb9820 1718 /* Check the unused bitfield in i386_cpu_flags. */
e89c5eaa 1719#ifdef CpuUnused
1d942ae9
JB
1720 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1721
e92bae62
L
1722 if ((cpumax - 1) != CpuMax)
1723 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1724#else
1d942ae9
JB
1725 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1726
e92bae62
L
1727 if (cpumax != CpuMax)
1728 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1729
8b40d594
L
1730 c = CpuNumOfBits - CpuMax - 1;
1731 if (c)
1732 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
1733#endif
1734
1d942ae9
JB
1735 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1736
40fb9820 1737 /* Check the unused bitfield in i386_operand_type. */
1d942ae9 1738#ifdef OTUnused
75e5731b
JB
1739 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1740 == OTNum + 1);
1d942ae9 1741#else
75e5731b
JB
1742 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1743 == OTNum);
1d942ae9 1744
51c8edf6 1745 c = OTNumOfBits - OTNum;
8b40d594
L
1746 if (c)
1747 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
1748#endif
1749
1750 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1751 compare);
1752
1753 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1754 sizeof (opcode_modifiers [0]), compare);
1755
1756 qsort (operand_types, ARRAY_SIZE (operand_types),
1757 sizeof (operand_types [0]), compare);
40b8e679 1758
34edb9ad
L
1759 table = fopen ("i386-tbl.h", "w");
1760 if (table == NULL)
40fb9820
L
1761 fail (_("can't create i386-tbl.h, errno = %s\n"),
1762 xstrerror (errno));
34edb9ad 1763
72ffa0fb 1764 process_copyright (table);
40b8e679 1765
72ffa0fb
L
1766 process_i386_opcodes (table);
1767 process_i386_registers (table);
40fb9820 1768 process_i386_initializers ();
40b8e679 1769
34edb9ad
L
1770 fclose (table);
1771
40b8e679
L
1772 exit (0);
1773}
This page took 1.020439 seconds and 4 git commands to generate.