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