Automatic date update in version.in
[deliverable/binutils-gdb.git] / opcodes / i386-gen.c
CommitLineData
250d07de 1/* Copyright (C) 2007-2021 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),
40fb9820 708 BITFIELD (RegKludge),
c0f3af97 709 BITFIELD (Implicit1stXmm0),
742732c7 710 BITFIELD (PrefixOk),
ca61edf2
L
711 BITFIELD (ToDword),
712 BITFIELD (ToQword),
75c0a438 713 BITFIELD (AddrPrefixOpReg),
40fb9820
L
714 BITFIELD (IsPrefix),
715 BITFIELD (ImmExt),
716 BITFIELD (NoRex64),
40fb9820 717 BITFIELD (Ugh),
57392598 718 BITFIELD (PseudoVexPrefix),
c0f3af97 719 BITFIELD (Vex),
2426c15f 720 BITFIELD (VexVVVV),
1ef99a7b 721 BITFIELD (VexW),
441f6aca 722 BITFIELD (OpcodeSpace),
7b47a312 723 BITFIELD (OpcodePrefix),
8cd7925b 724 BITFIELD (VexSources),
63112cd6 725 BITFIELD (SIB),
c0f3af97 726 BITFIELD (SSE2AVX),
81f8a913 727 BITFIELD (NoAVX),
43234a1e
L
728 BITFIELD (EVex),
729 BITFIELD (Masking),
43234a1e
L
730 BITFIELD (Broadcast),
731 BITFIELD (StaticRounding),
732 BITFIELD (SAE),
733 BITFIELD (Disp8MemShift),
734 BITFIELD (NoDefMask),
920d2ddc 735 BITFIELD (ImplicitQuadGroup),
c2ecccb3 736 BITFIELD (SwapSources),
b6f8c7c4 737 BITFIELD (Optimize),
1efbbeb4 738 BITFIELD (ATTMnemonic),
e1d4d893 739 BITFIELD (ATTSyntax),
5c07affc 740 BITFIELD (IntelSyntax),
4b5aaf5f 741 BITFIELD (ISA64),
40fb9820
L
742};
743
bab6aec1
JB
744#define CLASS(n) #n, n
745
746static const struct {
747 const char *name;
748 enum operand_class value;
749} operand_classes[] = {
750 CLASS (Reg),
00cee14f 751 CLASS (SReg),
4a5c67ed
JB
752 CLASS (RegCR),
753 CLASS (RegDR),
754 CLASS (RegTR),
3528c362
JB
755 CLASS (RegMMX),
756 CLASS (RegSIMD),
f74a6307
JB
757 CLASS (RegMask),
758 CLASS (RegBND),
bab6aec1
JB
759};
760
761#undef CLASS
762
75e5731b
JB
763#define INSTANCE(n) #n, n
764
765static const struct {
766 const char *name;
767 enum operand_instance value;
768} operand_instances[] = {
769 INSTANCE (Accum),
770 INSTANCE (RegC),
771 INSTANCE (RegD),
474da251 772 INSTANCE (RegB),
75e5731b
JB
773};
774
775#undef INSTANCE
776
40fb9820
L
777static bitfield operand_types[] =
778{
94ff3a50 779 BITFIELD (Imm1),
40fb9820
L
780 BITFIELD (Imm8),
781 BITFIELD (Imm8S),
782 BITFIELD (Imm16),
783 BITFIELD (Imm32),
784 BITFIELD (Imm32S),
785 BITFIELD (Imm64),
40fb9820
L
786 BITFIELD (BaseIndex),
787 BITFIELD (Disp8),
788 BITFIELD (Disp16),
789 BITFIELD (Disp32),
790 BITFIELD (Disp32S),
791 BITFIELD (Disp64),
7d5e4556
L
792 BITFIELD (Byte),
793 BITFIELD (Word),
794 BITFIELD (Dword),
795 BITFIELD (Fword),
796 BITFIELD (Qword),
797 BITFIELD (Tbyte),
798 BITFIELD (Xmmword),
c0f3af97 799 BITFIELD (Ymmword),
43234a1e 800 BITFIELD (Zmmword),
260cd341 801 BITFIELD (Tmmword),
7d5e4556 802 BITFIELD (Unspecified),
40fb9820
L
803#ifdef OTUnused
804 BITFIELD (OTUnused),
805#endif
806};
807
3d4d5afa 808static const char *filename;
7ac20022
JB
809static i386_cpu_flags active_cpu_flags;
810static int active_isstring;
3d4d5afa 811
4c4898e8
JB
812struct template_arg {
813 const struct template_arg *next;
814 const char *val;
815};
816
817struct template_instance {
818 const struct template_instance *next;
819 const char *name;
820 const struct template_arg *args;
821};
822
823struct template_param {
824 const struct template_param *next;
825 const char *name;
826};
827
828struct template {
829 const struct template *next;
830 const char *name;
831 const struct template_instance *instances;
832 const struct template_param *params;
833};
834
835static const struct template *templates;
836
40fb9820
L
837static int
838compare (const void *x, const void *y)
839{
840 const bitfield *xp = (const bitfield *) x;
841 const bitfield *yp = (const bitfield *) y;
842 return xp->position - yp->position;
843}
844
40b8e679
L
845static void
846fail (const char *message, ...)
847{
848 va_list args;
29c048b6 849
40b8e679 850 va_start (args, message);
a6743a54 851 fprintf (stderr, _("%s: error: "), program_name);
40b8e679
L
852 vfprintf (stderr, message, args);
853 va_end (args);
854 xexit (1);
855}
856
72ffa0fb
L
857static void
858process_copyright (FILE *fp)
859{
860 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
250d07de 861/* Copyright (C) 2007-2021 Free Software Foundation, Inc.\n\
72ffa0fb
L
862\n\
863 This file is part of the GNU opcodes library.\n\
864\n\
865 This library is free software; you can redistribute it and/or modify\n\
866 it under the terms of the GNU General Public License as published by\n\
867 the Free Software Foundation; either version 3, or (at your option)\n\
868 any later version.\n\
869\n\
870 It is distributed in the hope that it will be useful, but WITHOUT\n\
871 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
872 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
873 License for more details.\n\
874\n\
875 You should have received a copy of the GNU General Public License\n\
876 along with this program; if not, write to the Free Software\n\
877 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
878 MA 02110-1301, USA. */\n");
879}
880
40b8e679
L
881/* Remove leading white spaces. */
882
883static char *
884remove_leading_whitespaces (char *str)
885{
886 while (ISSPACE (*str))
887 str++;
888 return str;
889}
890
891/* Remove trailing white spaces. */
892
893static void
894remove_trailing_whitespaces (char *str)
895{
896 size_t last = strlen (str);
897
898 if (last == 0)
899 return;
900
901 do
902 {
903 last--;
904 if (ISSPACE (str [last]))
905 str[last] = '\0';
906 else
907 break;
908 }
909 while (last != 0);
910}
911
93b1ec2c 912/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
913 pointer to the one after it. */
914
915static char *
c587b3f9 916next_field (char *str, char sep, char **next, char *last)
40b8e679
L
917{
918 char *p;
919
920 p = remove_leading_whitespaces (str);
93b1ec2c 921 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
922
923 *str = '\0';
924 remove_trailing_whitespaces (p);
925
29c048b6 926 *next = str + 1;
40b8e679 927
c587b3f9
L
928 if (p >= last)
929 abort ();
930
40b8e679
L
931 return p;
932}
933
1848e567
L
934static void set_bitfield (char *, bitfield *, int, unsigned int, int);
935
936static int
3cc17af5
JB
937set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
938 int lineno)
1848e567
L
939{
940 char *str, *next, *last;
941 unsigned int i;
942
943 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
944 if (strcmp (cpu_flag_init[i].name, f) == 0)
945 {
946 /* Turn on selective bits. */
947 char *init = xstrdup (cpu_flag_init[i].init);
948 last = init + strlen (init);
949 for (next = init; next && next < last; )
950 {
951 str = next_field (next, '|', &next, last);
952 if (str)
953 set_bitfield (str, array, 1, size, lineno);
954 }
955 free (init);
956 return 0;
957 }
958
959 return -1;
960}
961
40fb9820 962static void
1848e567 963set_bitfield (char *f, bitfield *array, int value,
8a9036a4 964 unsigned int size, int lineno)
40fb9820
L
965{
966 unsigned int i;
967
3677e4c1
JB
968 /* Ignore empty fields; they may result from template expansions. */
969 if (*f == '\0')
970 return;
971
40fb9820
L
972 for (i = 0; i < size; i++)
973 if (strcasecmp (array[i].name, f) == 0)
974 {
8a9036a4 975 array[i].value = value;
40fb9820
L
976 return;
977 }
978
2bf05e57
L
979 if (value)
980 {
981 const char *v = strchr (f, '=');
982
983 if (v)
984 {
985 size_t n = v - f;
986 char *end;
987
988 for (i = 0; i < size; i++)
989 if (strncasecmp (array[i].name, f, n) == 0)
990 {
991 value = strtol (v + 1, &end, 0);
992 if (*end == '\0')
993 {
994 array[i].value = value;
995 return;
996 }
997 break;
998 }
999 }
1000 }
1001
3cc17af5
JB
1002 /* Handle CPU_XXX_FLAGS. */
1003 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1848e567
L
1004 return;
1005
bd5295b2 1006 if (lineno != -1)
a6743a54 1007 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
bd5295b2 1008 else
a6743a54 1009 fail (_("unknown bitfield: %s\n"), f);
40fb9820
L
1010}
1011
1012static void
1013output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
1014 int macro, const char *comma, const char *indent)
1015{
1016 unsigned int i;
1017
7ac20022
JB
1018 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
1019
40fb9820
L
1020 fprintf (table, "%s{ { ", indent);
1021
1022 for (i = 0; i < size - 1; i++)
1023 {
10632b79
L
1024 if (((i + 1) % 20) != 0)
1025 fprintf (table, "%d, ", flags[i].value);
1026 else
1027 fprintf (table, "%d,", flags[i].value);
40fb9820
L
1028 if (((i + 1) % 20) == 0)
1029 {
1030 /* We need \\ for macro. */
1031 if (macro)
1032 fprintf (table, " \\\n %s", indent);
1033 else
1034 fprintf (table, "\n %s", indent);
1035 }
7ac20022
JB
1036 if (flags[i].value)
1037 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
40fb9820
L
1038 }
1039
1040 fprintf (table, "%d } }%s\n", flags[i].value, comma);
1041}
1042
1043static void
1044process_i386_cpu_flag (FILE *table, char *flag, int macro,
bd5295b2
L
1045 const char *comma, const char *indent,
1046 int lineno)
40fb9820
L
1047{
1048 char *str, *next, *last;
8a9036a4 1049 unsigned int i;
40fb9820
L
1050 bitfield flags [ARRAY_SIZE (cpu_flags)];
1051
1052 /* Copy the default cpu flags. */
1053 memcpy (flags, cpu_flags, sizeof (cpu_flags));
1054
1055 if (strcasecmp (flag, "unknown") == 0)
1056 {
40fb9820 1057 /* We turn on everything except for cpu64 in case of
8a9036a4
L
1058 CPU_UNKNOWN_FLAGS. */
1059 for (i = 0; i < ARRAY_SIZE (flags); i++)
1060 if (flags[i].position != Cpu64)
1061 flags[i].value = 1;
1062 }
1063 else if (flag[0] == '~')
1064 {
1065 last = flag + strlen (flag);
1066
1067 if (flag[1] == '(')
1068 {
1069 last -= 1;
1070 next = flag + 2;
1071 if (*last != ')')
a6743a54 1072 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
8a9036a4
L
1073 lineno, flag);
1074 *last = '\0';
1075 }
1076 else
1077 next = flag + 1;
1078
1079 /* First we turn on everything except for cpu64. */
40fb9820
L
1080 for (i = 0; i < ARRAY_SIZE (flags); i++)
1081 if (flags[i].position != Cpu64)
1082 flags[i].value = 1;
8a9036a4
L
1083
1084 /* Turn off selective bits. */
1085 for (; next && next < last; )
1086 {
1087 str = next_field (next, '|', &next, last);
1088 if (str)
1089 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1090 }
40fb9820
L
1091 }
1092 else if (strcmp (flag, "0"))
1093 {
8a9036a4 1094 /* Turn on selective bits. */
40fb9820
L
1095 last = flag + strlen (flag);
1096 for (next = flag; next && next < last; )
1097 {
c587b3f9 1098 str = next_field (next, '|', &next, last);
40fb9820 1099 if (str)
8a9036a4 1100 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
40fb9820
L
1101 }
1102 }
1103
1104 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1105 comma, indent);
1106}
1107
1108static void
1109output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1110{
1111 unsigned int i;
1112
1113 fprintf (table, " { ");
1114
1115 for (i = 0; i < size - 1; i++)
1116 {
10632b79
L
1117 if (((i + 1) % 20) != 0)
1118 fprintf (table, "%d, ", modifier[i].value);
1119 else
1120 fprintf (table, "%d,", modifier[i].value);
40fb9820
L
1121 if (((i + 1) % 20) == 0)
1122 fprintf (table, "\n ");
1123 }
1124
1125 fprintf (table, "%d },\n", modifier[i].value);
1126}
1127
4a1b91ea
L
1128static int
1129adjust_broadcast_modifier (char **opnd)
1130{
1131 char *str, *next, *last, *op;
1132 int bcst_type = INT_MAX;
1133
1134 /* Skip the immediate operand. */
1135 op = opnd[0];
1136 if (strcasecmp(op, "Imm8") == 0)
1137 op = opnd[1];
1138
1139 op = xstrdup (op);
1140 last = op + strlen (op);
1141 for (next = op; next && next < last; )
1142 {
1143 str = next_field (next, '|', &next, last);
1144 if (str)
1145 {
1146 if (strcasecmp(str, "Byte") == 0)
1147 {
1148 /* The smalest broadcast type, no need to check
1149 further. */
1150 bcst_type = BYTE_BROADCAST;
1151 break;
1152 }
1153 else if (strcasecmp(str, "Word") == 0)
1154 {
1155 if (bcst_type > WORD_BROADCAST)
1156 bcst_type = WORD_BROADCAST;
1157 }
1158 else if (strcasecmp(str, "Dword") == 0)
1159 {
1160 if (bcst_type > DWORD_BROADCAST)
1161 bcst_type = DWORD_BROADCAST;
1162 }
1163 else if (strcasecmp(str, "Qword") == 0)
1164 {
1165 if (bcst_type > QWORD_BROADCAST)
1166 bcst_type = QWORD_BROADCAST;
1167 }
1168 }
1169 }
1170 free (op);
1171
1172 if (bcst_type == INT_MAX)
1173 fail (_("unknown broadcast operand: %s\n"), op);
1174
1175 return bcst_type;
1176}
1177
35648716 1178static void
389d00a5
JB
1179process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1180 unsigned int prefix, char **opnd, int lineno)
40fb9820
L
1181{
1182 char *str, *next, *last;
1183 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1184
7ac20022
JB
1185 active_isstring = 0;
1186
40fb9820
L
1187 /* Copy the default opcode modifier. */
1188 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1189
1190 if (strcmp (mod, "0"))
1191 {
507916b8
JB
1192 unsigned int have_w = 0, bwlq_suf = 0xf;
1193
40fb9820
L
1194 last = mod + strlen (mod);
1195 for (next = mod; next && next < last; )
1196 {
c587b3f9 1197 str = next_field (next, '|', &next, last);
40fb9820 1198 if (str)
7ac20022 1199 {
4a1b91ea
L
1200 int val = 1;
1201 if (strcasecmp(str, "Broadcast") == 0)
35648716 1202 val = adjust_broadcast_modifier (opnd);
8b65b895 1203
4a1b91ea 1204 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
8b65b895 1205 lineno);
7ac20022
JB
1206 if (strcasecmp(str, "IsString") == 0)
1207 active_isstring = 1;
507916b8
JB
1208
1209 if (strcasecmp(str, "W") == 0)
1210 have_w = 1;
1211
1212 if (strcasecmp(str, "No_bSuf") == 0)
1213 bwlq_suf &= ~1;
1214 if (strcasecmp(str, "No_wSuf") == 0)
1215 bwlq_suf &= ~2;
1216 if (strcasecmp(str, "No_lSuf") == 0)
1217 bwlq_suf &= ~4;
1218 if (strcasecmp(str, "No_qSuf") == 0)
1219 bwlq_suf &= ~8;
7ac20022 1220 }
40fb9820 1221 }
507916b8 1222
389d00a5
JB
1223 if (space)
1224 {
1225 if (!modifiers[OpcodeSpace].value)
1226 modifiers[OpcodeSpace].value = space;
1227 else if (modifiers[OpcodeSpace].value != space)
1228 fail (_("%s:%d: Conflicting opcode space specifications\n"),
1229 filename, lineno);
1230 else
1231 fprintf (stderr,
1232 _("%s:%d: Warning: redundant opcode space specification\n"),
1233 filename, lineno);
1234 }
1235
35648716
JB
1236 if (prefix)
1237 {
1238 if (!modifiers[OpcodePrefix].value)
1239 modifiers[OpcodePrefix].value = prefix;
1240 else if (modifiers[OpcodePrefix].value != prefix)
1241 fail (_("%s:%d: Conflicting prefix specifications\n"),
1242 filename, lineno);
1243 else
1244 fprintf (stderr,
1245 _("%s:%d: Warning: redundant prefix specification\n"),
1246 filename, lineno);
1247 }
1248
507916b8
JB
1249 if (have_w && !bwlq_suf)
1250 fail ("%s: %d: stray W modifier\n", filename, lineno);
1251 if (have_w && !(bwlq_suf & 1))
1252 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1253 filename, lineno);
1254 if (have_w && !(bwlq_suf & ~1))
1255 fprintf (stderr,
1256 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1257 filename, lineno);
40fb9820
L
1258 }
1259 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1260}
1261
7ac20022
JB
1262enum stage {
1263 stage_macros,
1264 stage_opcodes,
1265 stage_registers,
1266};
1267
40fb9820 1268static void
bab6aec1 1269output_operand_type (FILE *table, enum operand_class class,
75e5731b 1270 enum operand_instance instance,
bab6aec1 1271 const bitfield *types, unsigned int size,
7ac20022 1272 enum stage stage, const char *indent)
40fb9820
L
1273{
1274 unsigned int i;
1275
75e5731b 1276 fprintf (table, "{ { %d, %d, ", class, instance);
40fb9820
L
1277
1278 for (i = 0; i < size - 1; i++)
1279 {
75e5731b 1280 if (((i + 3) % 20) != 0)
10632b79
L
1281 fprintf (table, "%d, ", types[i].value);
1282 else
1283 fprintf (table, "%d,", types[i].value);
75e5731b 1284 if (((i + 3) % 20) == 0)
40fb9820
L
1285 {
1286 /* We need \\ for macro. */
7ac20022 1287 if (stage == stage_macros)
10632b79 1288 fprintf (table, " \\\n%s", indent);
40fb9820
L
1289 else
1290 fprintf (table, "\n%s", indent);
1291 }
1292 }
1293
1294 fprintf (table, "%d } }", types[i].value);
1295}
1296
1297static void
7ac20022 1298process_i386_operand_type (FILE *table, char *op, enum stage stage,
bd5295b2 1299 const char *indent, int lineno)
40fb9820
L
1300{
1301 char *str, *next, *last;
bab6aec1 1302 enum operand_class class = ClassNone;
75e5731b 1303 enum operand_instance instance = InstanceNone;
40fb9820
L
1304 bitfield types [ARRAY_SIZE (operand_types)];
1305
1306 /* Copy the default operand type. */
1307 memcpy (types, operand_types, sizeof (types));
1308
1309 if (strcmp (op, "0"))
1310 {
7ac20022
JB
1311 int baseindex = 0;
1312
40fb9820
L
1313 last = op + strlen (op);
1314 for (next = op; next && next < last; )
1315 {
c587b3f9 1316 str = next_field (next, '|', &next, last);
bab6aec1
JB
1317 if (str)
1318 {
1319 unsigned int i;
1320
1321 if (!strncmp(str, "Class=", 6))
1322 {
1323 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1324 if (!strcmp(str + 6, operand_classes[i].name))
1325 {
1326 class = operand_classes[i].value;
1327 str = NULL;
1328 break;
1329 }
1330 }
75e5731b
JB
1331
1332 if (str && !strncmp(str, "Instance=", 9))
1333 {
1334 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1335 if (!strcmp(str + 9, operand_instances[i].name))
1336 {
1337 instance = operand_instances[i].value;
1338 str = NULL;
1339 break;
1340 }
1341 }
bab6aec1 1342 }
40fb9820 1343 if (str)
7ac20022
JB
1344 {
1345 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1346 if (strcasecmp(str, "BaseIndex") == 0)
1347 baseindex = 1;
1348 }
1349 }
1350
1351 if (stage == stage_opcodes && baseindex && !active_isstring)
1352 {
1353 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1354 if (!active_cpu_flags.bitfield.cpu64
1355 && !active_cpu_flags.bitfield.cpumpx)
1356 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
48bcea9f
JB
1357 if (!active_cpu_flags.bitfield.cpu64)
1358 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
7ac20022
JB
1359 if (!active_cpu_flags.bitfield.cpuno64)
1360 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
1361 }
1362 }
75e5731b
JB
1363 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1364 stage, indent);
40fb9820
L
1365}
1366
c587b3f9
L
1367static void
1368output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 1369 char *last, int lineno)
c587b3f9 1370{
389d00a5 1371 unsigned int i, length, prefix = 0, space = 0;
9a182d04 1372 char *base_opcode, *extension_opcode, *end;
c587b3f9 1373 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
73e45eb2 1374 unsigned long long opcode;
c587b3f9 1375
c587b3f9
L
1376 /* Find base_opcode. */
1377 base_opcode = next_field (str, ',', &str, last);
1378
1379 /* Find extension_opcode. */
1380 extension_opcode = next_field (str, ',', &str, last);
1381
c587b3f9
L
1382 /* Find cpu_flags. */
1383 cpu_flags = next_field (str, ',', &str, last);
1384
1385 /* Find opcode_modifier. */
1386 opcode_modifier = next_field (str, ',', &str, last);
1387
1388 /* Remove the first {. */
1389 str = remove_leading_whitespaces (str);
1390 if (*str != '{')
1391 abort ();
1392 str = remove_leading_whitespaces (str + 1);
75363b6d 1393 remove_trailing_whitespaces (str);
c587b3f9 1394
75363b6d 1395 /* Remove } and trailing white space. */
c587b3f9 1396 i = strlen (str);
75363b6d 1397 if (!i || str[i - 1] != '}')
c587b3f9 1398 abort ();
75363b6d
JB
1399 str[--i] = '\0';
1400 remove_trailing_whitespaces (str);
c587b3f9 1401
75363b6d
JB
1402 if (!*str)
1403 operand_types [i = 0] = NULL;
1404 else
c587b3f9 1405 {
75363b6d 1406 last = str + strlen (str);
c587b3f9 1407
75363b6d
JB
1408 /* Find operand_types. */
1409 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
c587b3f9 1410 {
75363b6d
JB
1411 if (str >= last)
1412 {
1413 operand_types [i] = NULL;
1414 break;
1415 }
c587b3f9 1416
75363b6d 1417 operand_types [i] = next_field (str, ',', &str, last);
c587b3f9
L
1418 }
1419 }
1420
73e45eb2 1421 opcode = strtoull (base_opcode, &end, 0);
c587b3f9 1422
9a182d04 1423 /* Determine opcode length. */
73e45eb2 1424 for (length = 1; length < 8; ++length)
9a182d04
JB
1425 if (!(opcode >> (8 * length)))
1426 break;
1427
35648716
JB
1428 /* Transform prefixes encoded in the opcode into opcode modifier
1429 representation. */
9a182d04 1430 if (length > 1)
8b65b895 1431 {
9a182d04 1432 switch (opcode >> (8 * length - 8))
8b65b895 1433 {
35648716
JB
1434 case 0x66: prefix = PREFIX_0X66; break;
1435 case 0xF3: prefix = PREFIX_0XF3; break;
1436 case 0xF2: prefix = PREFIX_0XF2; break;
8b65b895 1437 }
35648716 1438
9a182d04 1439 if (prefix)
73e45eb2 1440 opcode &= (1ULL << (8 * --length)) - 1;
8b65b895 1441 }
c587b3f9 1442
389d00a5
JB
1443 /* Transform opcode space encoded in the opcode into opcode modifier
1444 representation. */
1445 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1446 {
1447 switch ((opcode >> (8 * length - 16)) & 0xff)
1448 {
1449 default: space = SPACE_0F; break;
1450 case 0x38: space = SPACE_0F38; break;
1451 case 0x3A: space = SPACE_0F3A; break;
1452 }
1453
1454 if (space != SPACE_0F && --length == 1)
1455 fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1456 filename, lineno, name);
73e45eb2 1457 opcode &= (1ULL << (8 * --length)) - 1;
389d00a5
JB
1458 }
1459
73e45eb2
JB
1460 if (length > 2)
1461 fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1462 filename, lineno, name, 2 * length, opcode);
1463
1464 fprintf (table, " { \"%s\", 0x%0*llx%s, %s, %lu,\n",
9a182d04 1465 name, 2 * (int)length, opcode, end, extension_opcode, i);
35648716 1466
389d00a5 1467 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
35648716
JB
1468 operand_types, lineno);
1469
dac10fb0
JB
1470 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1471
c587b3f9
L
1472 fprintf (table, " { ");
1473
1474 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1475 {
75363b6d 1476 if (!operand_types[i])
c587b3f9
L
1477 {
1478 if (i == 0)
7ac20022
JB
1479 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1480 lineno);
c587b3f9
L
1481 break;
1482 }
1483
1484 if (i != 0)
1485 fprintf (table, ",\n ");
1486
7ac20022 1487 process_i386_operand_type (table, operand_types[i], stage_opcodes,
bd5295b2 1488 "\t ", lineno);
c587b3f9
L
1489 }
1490 fprintf (table, " } },\n");
1491}
1492
1493struct opcode_hash_entry
1494{
1495 struct opcode_hash_entry *next;
1496 char *name;
1497 char *opcode;
bd5295b2 1498 int lineno;
c587b3f9
L
1499};
1500
1501/* Calculate the hash value of an opcode hash entry P. */
1502
1503static hashval_t
1504opcode_hash_hash (const void *p)
1505{
1506 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1507 return htab_hash_string (entry->name);
1508}
1509
1510/* Compare a string Q against an opcode hash entry P. */
1511
1512static int
1513opcode_hash_eq (const void *p, const void *q)
1514{
1515 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1516 const char *name = (const char *) q;
1517 return strcmp (name, entry->name) == 0;
1518}
1519
4c4898e8
JB
1520static void
1521parse_template (char *buf, int lineno)
1522{
1523 char sep, *end, *name;
1524 struct template *tmpl = xmalloc (sizeof (*tmpl));
1525 struct template_instance *last_inst = NULL;
1526
1527 buf = remove_leading_whitespaces (buf + 1);
1528 end = strchr (buf, ':');
1529 if (end == NULL)
1530 fail ("%s: %d: missing ':'\n", filename, lineno);
1531 *end++ = '\0';
1532 remove_trailing_whitespaces (buf);
1533
1534 if (*buf == '\0')
1535 fail ("%s: %d: missing template identifier\n", filename, lineno);
1536 tmpl->name = xstrdup (buf);
1537
1538 tmpl->params = NULL;
1539 do {
1540 struct template_param *param;
1541
1542 buf = remove_leading_whitespaces (end);
1543 end = strpbrk (buf, ":,");
1544 if (end == NULL)
1545 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1546
1547 sep = *end;
1548 *end++ = '\0';
1549 remove_trailing_whitespaces (buf);
1550
1551 param = xmalloc (sizeof (*param));
1552 param->name = xstrdup (buf);
1553 param->next = tmpl->params;
1554 tmpl->params = param;
1555 } while (sep == ':');
1556
1557 tmpl->instances = NULL;
1558 do {
1559 struct template_instance *inst;
1560 char *cur, *next;
1561 const struct template_param *param;
1562
1563 buf = remove_leading_whitespaces (end);
1564 end = strpbrk (buf, ",>");
1565 if (end == NULL)
1566 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1567
1568 sep = *end;
1569 *end++ = '\0';
1570
1571 inst = xmalloc (sizeof (*inst));
c3ffb8f3
AM
1572 inst->next = NULL;
1573 inst->args = NULL;
4c4898e8
JB
1574
1575 cur = next_field (buf, ':', &next, end);
5cdaf100 1576 inst->name = *cur != '$' ? xstrdup (cur) : "";
4c4898e8
JB
1577
1578 for (param = tmpl->params; param; param = param->next)
1579 {
1580 struct template_arg *arg = xmalloc (sizeof (*arg));
1581
1582 cur = next_field (next, ':', &next, end);
1583 if (next > end)
1584 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1585 arg->val = xstrdup (cur);
1586 arg->next = inst->args;
1587 inst->args = arg;
1588 }
1589
1590 if (tmpl->instances)
1591 last_inst->next = inst;
1592 else
1593 tmpl->instances = inst;
1594 last_inst = inst;
1595 } while (sep == ',');
1596
1597 buf = remove_leading_whitespaces (end);
1598 if (*buf)
1599 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1600 filename, lineno, buf);
1601
1602 tmpl->next = templates;
1603 templates = tmpl;
1604}
1605
1606static unsigned int
1607expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1608 struct opcode_hash_entry ***opcode_array_p, int lineno)
1609{
1610 static unsigned int idx, opcode_array_size;
1611 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1612 struct opcode_hash_entry **hash_slot, **entry;
1613 char *ptr1 = strchr(name, '<'), *ptr2;
1614
1615 if (ptr1 == NULL)
1616 {
1617 /* Get the slot in hash table. */
1618 hash_slot = (struct opcode_hash_entry **)
1619 htab_find_slot_with_hash (opcode_hash_table, name,
1620 htab_hash_string (name),
1621 INSERT);
1622
1623 if (*hash_slot == NULL)
1624 {
1625 /* It is the new one. Put it on opcode array. */
1626 if (idx >= opcode_array_size)
1627 {
1628 /* Grow the opcode array when needed. */
1629 opcode_array_size += 1024;
1630 opcode_array = (struct opcode_hash_entry **)
1631 xrealloc (opcode_array,
1632 sizeof (*opcode_array) * opcode_array_size);
1633 *opcode_array_p = opcode_array;
1634 }
1635
1636 opcode_array[idx] = (struct opcode_hash_entry *)
1637 xmalloc (sizeof (struct opcode_hash_entry));
1638 opcode_array[idx]->next = NULL;
1639 opcode_array[idx]->name = xstrdup (name);
1640 opcode_array[idx]->opcode = xstrdup (str);
1641 opcode_array[idx]->lineno = lineno;
1642 *hash_slot = opcode_array[idx];
1643 idx++;
1644 }
1645 else
1646 {
1647 /* Append it to the existing one. */
1648 entry = hash_slot;
1649 while ((*entry) != NULL)
1650 entry = &(*entry)->next;
1651 *entry = (struct opcode_hash_entry *)
1652 xmalloc (sizeof (struct opcode_hash_entry));
1653 (*entry)->next = NULL;
1654 (*entry)->name = (*hash_slot)->name;
1655 (*entry)->opcode = xstrdup (str);
1656 (*entry)->lineno = lineno;
1657 }
1658 }
1659 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1660 fail ("%s: %d: missing '>'\n", filename, lineno);
1661 else
1662 {
1663 const struct template *tmpl;
1664 const struct template_instance *inst;
1665
1666 *ptr1 = '\0';
1667 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1668 remove_trailing_whitespaces (ptr1);
1669
1670 *ptr2++ = '\0';
1671
1672 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1673 if (!strcmp(ptr1, tmpl->name))
1674 break;
1675 if (!tmpl)
1676 fail ("reference to unknown template '%s'\n", ptr1);
1677
1678 for (inst = tmpl->instances; inst; inst = inst->next)
1679 {
1680 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1681 char *str2 = xmalloc(2 * strlen(str));
1682 const char *src;
1683
1684 strcpy (name2, name);
1685 strcat (name2, inst->name);
1686 strcat (name2, ptr2);
1687
1688 for (ptr1 = str2, src = str; *src; )
1689 {
1690 const char *ident = tmpl->name, *end;
1691 const struct template_param *param;
1692 const struct template_arg *arg;
1693
1694 if ((*ptr1 = *src++) != '<')
1695 {
1696 ++ptr1;
1697 continue;
1698 }
1699 while (ISSPACE(*src))
1700 ++src;
1701 while (*ident && *src == *ident)
1702 ++src, ++ident;
1703 while (ISSPACE(*src))
1704 ++src;
1705 if (*src != ':' || *ident != '\0')
1706 {
1707 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1708 ptr1 += ident - tmpl->name;
1709 continue;
1710 }
1711 while (ISSPACE(*++src))
1712 ;
1713
1714 end = src;
1715 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1716 ++end;
1717
1718 for (param = tmpl->params, arg = inst->args; param;
1719 param = param->next, arg = arg->next)
1720 {
1721 if (end - src == strlen (param->name)
1722 && !memcmp (src, param->name, end - src))
1723 {
1724 src = end;
1725 break;
1726 }
1727 }
1728
1729 if (param == NULL)
1730 fail ("template '%s' has no parameter '%.*s'\n",
1731 tmpl->name, (int)(end - src), src);
1732
1733 while (ISSPACE(*src))
1734 ++src;
1735 if (*src != '>')
1736 fail ("%s: %d: missing '>'\n", filename, lineno);
1737
1738 memcpy(ptr1, arg->val, strlen(arg->val));
1739 ptr1 += strlen(arg->val);
1740 ++src;
1741 }
1742
1743 *ptr1 = '\0';
1744
1745 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1746 lineno);
1747
1748 free (str2);
1749 free (name2);
1750 }
1751 }
1752
1753 return idx;
1754}
1755
40b8e679 1756static void
72ffa0fb 1757process_i386_opcodes (FILE *table)
40b8e679 1758{
3d4d5afa 1759 FILE *fp;
40b8e679 1760 char buf[2048];
c587b3f9
L
1761 unsigned int i, j;
1762 char *str, *p, *last, *name;
c587b3f9 1763 htab_t opcode_hash_table;
4c4898e8 1764 struct opcode_hash_entry **opcode_array = NULL;
c30be56e 1765 int lineno = 0, marker = 0;
40b8e679 1766
3d4d5afa 1767 filename = "i386-opc.tbl";
c30be56e 1768 fp = stdin;
40b8e679 1769
c587b3f9 1770 i = 0;
c587b3f9
L
1771 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1772 opcode_hash_eq, NULL,
1773 xcalloc, free);
1774
34edb9ad 1775 fprintf (table, "\n/* i386 opcode table. */\n\n");
d3ce72d0 1776 fprintf (table, "const insn_template i386_optab[] =\n{\n");
40b8e679 1777
c587b3f9 1778 /* Put everything on opcode array. */
40b8e679
L
1779 while (!feof (fp))
1780 {
1781 if (fgets (buf, sizeof (buf), fp) == NULL)
1782 break;
1783
3d4d5afa
L
1784 lineno++;
1785
40b8e679
L
1786 p = remove_leading_whitespaces (buf);
1787
1788 /* Skip comments. */
1789 str = strstr (p, "//");
1790 if (str != NULL)
1791 str[0] = '\0';
1792
1793 /* Remove trailing white spaces. */
1794 remove_trailing_whitespaces (p);
1795
1796 switch (p[0])
1797 {
1798 case '#':
c30be56e
JB
1799 if (!strcmp("### MARKER ###", buf))
1800 marker = 1;
1801 else
1802 {
1803 /* Since we ignore all included files (we only care about their
1804 #define-s here), we don't need to monitor filenames. The final
1805 line number directive is going to refer to the main source file
1806 again. */
1807 char *end;
1808 unsigned long ln;
1809
1810 p = remove_leading_whitespaces (p + 1);
1811 if (!strncmp(p, "line", 4))
1812 p += 4;
1813 ln = strtoul (p, &end, 10);
1814 if (ln > 1 && ln < INT_MAX
1815 && *remove_leading_whitespaces (end) == '"')
1816 lineno = ln - 1;
1817 }
c587b3f9 1818 /* Ignore comments. */
40b8e679
L
1819 case '\0':
1820 continue;
1821 break;
4c4898e8
JB
1822 case '<':
1823 parse_template (p, lineno);
1824 continue;
40b8e679 1825 default:
c30be56e
JB
1826 if (!marker)
1827 continue;
40b8e679
L
1828 break;
1829 }
1830
1831 last = p + strlen (p);
1832
1833 /* Find name. */
c587b3f9 1834 name = next_field (p, ',', &str, last);
40b8e679 1835
4c4898e8
JB
1836 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1837 lineno);
c587b3f9 1838 }
40b8e679 1839
c587b3f9
L
1840 /* Process opcode array. */
1841 for (j = 0; j < i; j++)
1842 {
4c4898e8
JB
1843 struct opcode_hash_entry *next;
1844
c587b3f9
L
1845 for (next = opcode_array[j]; next; next = next->next)
1846 {
1847 name = next->name;
1848 str = next->opcode;
bd5295b2 1849 lineno = next->lineno;
c587b3f9 1850 last = str + strlen (str);
bd5295b2 1851 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1852 }
40b8e679
L
1853 }
1854
34edb9ad
L
1855 fclose (fp);
1856
9a182d04 1857 fprintf (table, " { NULL, 0, 0, 0,\n");
40fb9820 1858
389d00a5 1859 process_i386_opcode_modifier (table, "0", 0, 0, NULL, -1);
29c048b6 1860
dac10fb0
JB
1861 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1862
40fb9820 1863 fprintf (table, " { ");
7ac20022 1864 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
40fb9820
L
1865 fprintf (table, " } }\n");
1866
34edb9ad 1867 fprintf (table, "};\n");
40b8e679
L
1868}
1869
1870static void
72ffa0fb 1871process_i386_registers (FILE *table)
40b8e679 1872{
3d4d5afa 1873 FILE *fp;
40b8e679
L
1874 char buf[2048];
1875 char *str, *p, *last;
1876 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1877 char *dw2_32_num, *dw2_64_num;
bd5295b2 1878 int lineno = 0;
40b8e679 1879
3d4d5afa
L
1880 filename = "i386-reg.tbl";
1881 fp = fopen (filename, "r");
40b8e679 1882 if (fp == NULL)
34edb9ad 1883 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1884 xstrerror (errno));
40b8e679 1885
34edb9ad
L
1886 fprintf (table, "\n/* i386 register table. */\n\n");
1887 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1888
1889 while (!feof (fp))
1890 {
1891 if (fgets (buf, sizeof (buf), fp) == NULL)
1892 break;
1893
3d4d5afa
L
1894 lineno++;
1895
40b8e679
L
1896 p = remove_leading_whitespaces (buf);
1897
1898 /* Skip comments. */
1899 str = strstr (p, "//");
1900 if (str != NULL)
1901 str[0] = '\0';
1902
1903 /* Remove trailing white spaces. */
1904 remove_trailing_whitespaces (p);
1905
1906 switch (p[0])
1907 {
1908 case '#':
34edb9ad 1909 fprintf (table, "%s\n", p);
40b8e679
L
1910 case '\0':
1911 continue;
1912 break;
1913 default:
1914 break;
1915 }
1916
1917 last = p + strlen (p);
1918
1919 /* Find reg_name. */
c587b3f9 1920 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1921
1922 /* Find reg_type. */
c587b3f9 1923 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1924
1925 /* Find reg_flags. */
c587b3f9 1926 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1927
1928 /* Find reg_num. */
c587b3f9 1929 reg_num = next_field (str, ',', &str, last);
a60de03c 1930
40fb9820
L
1931 fprintf (table, " { \"%s\",\n ", reg_name);
1932
7ac20022
JB
1933 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1934 lineno);
40fb9820 1935
a60de03c 1936 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1937 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1938
1939 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1940 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1941
1942 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1943 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1944 }
1945
34edb9ad
L
1946 fclose (fp);
1947
1948 fprintf (table, "};\n");
40b8e679 1949
34edb9ad 1950 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1951}
1952
40fb9820
L
1953static void
1954process_i386_initializers (void)
1955{
1956 unsigned int i;
1957 FILE *fp = fopen ("i386-init.h", "w");
1958 char *init;
1959
1960 if (fp == NULL)
1961 fail (_("can't create i386-init.h, errno = %s\n"),
1962 xstrerror (errno));
1963
1964 process_copyright (fp);
1965
1966 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1967 {
1968 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1969 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1970 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1971 free (init);
1972 }
1973
1974 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1975 {
1976 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1977 init = xstrdup (operand_type_init[i].init);
7ac20022 1978 process_i386_operand_type (fp, init, stage_macros, " ", -1);
40fb9820
L
1979 free (init);
1980 }
1981 fprintf (fp, "\n");
1982
1983 fclose (fp);
1984}
1985
40b8e679
L
1986/* Program options. */
1987#define OPTION_SRCDIR 200
1988
29c048b6 1989struct option long_options[] =
40b8e679
L
1990{
1991 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1992 {"debug", no_argument, NULL, 'd'},
1993 {"version", no_argument, NULL, 'V'},
1994 {"help", no_argument, NULL, 'h'},
1995 {0, no_argument, NULL, 0}
1996};
1997
1998static void
1999print_version (void)
2000{
2001 printf ("%s: version 1.0\n", program_name);
2002 xexit (0);
2003}
2004
2005static void
2006usage (FILE * stream, int status)
2007{
2008 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2009 program_name);
2010 xexit (status);
2011}
2012
2013int
2014main (int argc, char **argv)
2015{
2016 extern int chdir (char *);
2017 char *srcdir = NULL;
8b40d594 2018 int c;
e92bae62 2019 unsigned int i, cpumax;
72ffa0fb 2020 FILE *table;
29c048b6 2021
40b8e679
L
2022 program_name = *argv;
2023 xmalloc_set_program_name (program_name);
2024
2025 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2026 switch (c)
2027 {
2028 case OPTION_SRCDIR:
2029 srcdir = optarg;
2030 break;
2031 case 'V':
2032 case 'v':
2033 print_version ();
2034 break;
2035 case 'd':
2036 debug = 1;
2037 break;
2038 case 'h':
2039 case '?':
2040 usage (stderr, 0);
2041 default:
2042 case 0:
2043 break;
2044 }
2045
2046 if (optind != argc)
2047 usage (stdout, 1);
2048
29c048b6 2049 if (srcdir != NULL)
40b8e679
L
2050 if (chdir (srcdir) != 0)
2051 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
2052 srcdir, xstrerror (errno));
2053
e92bae62
L
2054 /* cpu_flags isn't sorted by position. */
2055 cpumax = 0;
2056 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2057 if (cpu_flags[i].position > cpumax)
2058 cpumax = cpu_flags[i].position;
2059
40fb9820 2060 /* Check the unused bitfield in i386_cpu_flags. */
e89c5eaa 2061#ifdef CpuUnused
1d942ae9
JB
2062 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2063
e92bae62
L
2064 if ((cpumax - 1) != CpuMax)
2065 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 2066#else
1d942ae9
JB
2067 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2068
e92bae62
L
2069 if (cpumax != CpuMax)
2070 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 2071
8b40d594
L
2072 c = CpuNumOfBits - CpuMax - 1;
2073 if (c)
2074 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
2075#endif
2076
1d942ae9
JB
2077 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2078
40fb9820 2079 /* Check the unused bitfield in i386_operand_type. */
1d942ae9 2080#ifdef OTUnused
75e5731b
JB
2081 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2082 == OTNum + 1);
1d942ae9 2083#else
75e5731b
JB
2084 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2085 == OTNum);
1d942ae9 2086
51c8edf6 2087 c = OTNumOfBits - OTNum;
8b40d594
L
2088 if (c)
2089 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
2090#endif
2091
2092 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2093 compare);
2094
2095 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2096 sizeof (opcode_modifiers [0]), compare);
2097
2098 qsort (operand_types, ARRAY_SIZE (operand_types),
2099 sizeof (operand_types [0]), compare);
40b8e679 2100
34edb9ad
L
2101 table = fopen ("i386-tbl.h", "w");
2102 if (table == NULL)
40fb9820
L
2103 fail (_("can't create i386-tbl.h, errno = %s\n"),
2104 xstrerror (errno));
34edb9ad 2105
72ffa0fb 2106 process_copyright (table);
40b8e679 2107
72ffa0fb
L
2108 process_i386_opcodes (table);
2109 process_i386_registers (table);
40fb9820 2110 process_i386_initializers ();
40b8e679 2111
34edb9ad
L
2112 fclose (table);
2113
40b8e679
L
2114 exit (0);
2115}
This page took 0.784324 seconds and 4 git commands to generate.