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