x86: re-number PREFIX_0X<nn>
[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
8b65b895 1178static int
4a1b91ea 1179process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
40fb9820
L
1180{
1181 char *str, *next, *last;
1182 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
8b65b895 1183 unsigned int regular_encoding = 1;
40fb9820 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)
8b65b895 1202 {
4a1b91ea 1203 val = adjust_broadcast_modifier (opnd);
8b65b895
L
1204 regular_encoding = 0;
1205 }
1206 else if (strcasecmp(str, "Vex") == 0
1207 || strncasecmp(str, "Vex=", 4) == 0
1208 || strcasecmp(str, "EVex") == 0
1209 || strncasecmp(str, "EVex=", 5) == 0
1210 || strncasecmp(str, "Disp8MemShift=", 14) == 0
1211 || strncasecmp(str, "Masking=", 8) == 0
1212 || strcasecmp(str, "SAE") == 0
1213 || strcasecmp(str, "IsPrefix") == 0)
1214 regular_encoding = 0;
1215
4a1b91ea 1216 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
8b65b895 1217 lineno);
7ac20022
JB
1218 if (strcasecmp(str, "IsString") == 0)
1219 active_isstring = 1;
507916b8
JB
1220
1221 if (strcasecmp(str, "W") == 0)
1222 have_w = 1;
1223
1224 if (strcasecmp(str, "No_bSuf") == 0)
1225 bwlq_suf &= ~1;
1226 if (strcasecmp(str, "No_wSuf") == 0)
1227 bwlq_suf &= ~2;
1228 if (strcasecmp(str, "No_lSuf") == 0)
1229 bwlq_suf &= ~4;
1230 if (strcasecmp(str, "No_qSuf") == 0)
1231 bwlq_suf &= ~8;
7ac20022 1232 }
40fb9820 1233 }
507916b8
JB
1234
1235 if (have_w && !bwlq_suf)
1236 fail ("%s: %d: stray W modifier\n", filename, lineno);
1237 if (have_w && !(bwlq_suf & 1))
1238 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1239 filename, lineno);
1240 if (have_w && !(bwlq_suf & ~1))
1241 fprintf (stderr,
1242 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1243 filename, lineno);
40fb9820
L
1244 }
1245 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
8b65b895
L
1246
1247 return regular_encoding;
40fb9820
L
1248}
1249
7ac20022
JB
1250enum stage {
1251 stage_macros,
1252 stage_opcodes,
1253 stage_registers,
1254};
1255
40fb9820 1256static void
bab6aec1 1257output_operand_type (FILE *table, enum operand_class class,
75e5731b 1258 enum operand_instance instance,
bab6aec1 1259 const bitfield *types, unsigned int size,
7ac20022 1260 enum stage stage, const char *indent)
40fb9820
L
1261{
1262 unsigned int i;
1263
75e5731b 1264 fprintf (table, "{ { %d, %d, ", class, instance);
40fb9820
L
1265
1266 for (i = 0; i < size - 1; i++)
1267 {
75e5731b 1268 if (((i + 3) % 20) != 0)
10632b79
L
1269 fprintf (table, "%d, ", types[i].value);
1270 else
1271 fprintf (table, "%d,", types[i].value);
75e5731b 1272 if (((i + 3) % 20) == 0)
40fb9820
L
1273 {
1274 /* We need \\ for macro. */
7ac20022 1275 if (stage == stage_macros)
10632b79 1276 fprintf (table, " \\\n%s", indent);
40fb9820
L
1277 else
1278 fprintf (table, "\n%s", indent);
1279 }
1280 }
1281
1282 fprintf (table, "%d } }", types[i].value);
1283}
1284
1285static void
7ac20022 1286process_i386_operand_type (FILE *table, char *op, enum stage stage,
bd5295b2 1287 const char *indent, int lineno)
40fb9820
L
1288{
1289 char *str, *next, *last;
bab6aec1 1290 enum operand_class class = ClassNone;
75e5731b 1291 enum operand_instance instance = InstanceNone;
40fb9820
L
1292 bitfield types [ARRAY_SIZE (operand_types)];
1293
1294 /* Copy the default operand type. */
1295 memcpy (types, operand_types, sizeof (types));
1296
1297 if (strcmp (op, "0"))
1298 {
7ac20022
JB
1299 int baseindex = 0;
1300
40fb9820
L
1301 last = op + strlen (op);
1302 for (next = op; next && next < last; )
1303 {
c587b3f9 1304 str = next_field (next, '|', &next, last);
bab6aec1
JB
1305 if (str)
1306 {
1307 unsigned int i;
1308
1309 if (!strncmp(str, "Class=", 6))
1310 {
1311 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1312 if (!strcmp(str + 6, operand_classes[i].name))
1313 {
1314 class = operand_classes[i].value;
1315 str = NULL;
1316 break;
1317 }
1318 }
75e5731b
JB
1319
1320 if (str && !strncmp(str, "Instance=", 9))
1321 {
1322 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1323 if (!strcmp(str + 9, operand_instances[i].name))
1324 {
1325 instance = operand_instances[i].value;
1326 str = NULL;
1327 break;
1328 }
1329 }
bab6aec1 1330 }
40fb9820 1331 if (str)
7ac20022
JB
1332 {
1333 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1334 if (strcasecmp(str, "BaseIndex") == 0)
1335 baseindex = 1;
1336 }
1337 }
1338
1339 if (stage == stage_opcodes && baseindex && !active_isstring)
1340 {
1341 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1342 if (!active_cpu_flags.bitfield.cpu64
1343 && !active_cpu_flags.bitfield.cpumpx)
1344 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
48bcea9f
JB
1345 if (!active_cpu_flags.bitfield.cpu64)
1346 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
7ac20022
JB
1347 if (!active_cpu_flags.bitfield.cpuno64)
1348 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
1349 }
1350 }
75e5731b
JB
1351 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1352 stage, indent);
40fb9820
L
1353}
1354
c587b3f9
L
1355static void
1356output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 1357 char *last, int lineno)
c587b3f9
L
1358{
1359 unsigned int i;
75363b6d 1360 char *base_opcode, *extension_opcode, *opcode_length;
c587b3f9
L
1361 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1362
c587b3f9
L
1363 /* Find base_opcode. */
1364 base_opcode = next_field (str, ',', &str, last);
1365
1366 /* Find extension_opcode. */
1367 extension_opcode = next_field (str, ',', &str, last);
1368
1369 /* Find opcode_length. */
1370 opcode_length = next_field (str, ',', &str, last);
1371
1372 /* Find cpu_flags. */
1373 cpu_flags = next_field (str, ',', &str, last);
1374
1375 /* Find opcode_modifier. */
1376 opcode_modifier = next_field (str, ',', &str, last);
1377
1378 /* Remove the first {. */
1379 str = remove_leading_whitespaces (str);
1380 if (*str != '{')
1381 abort ();
1382 str = remove_leading_whitespaces (str + 1);
75363b6d 1383 remove_trailing_whitespaces (str);
c587b3f9 1384
75363b6d 1385 /* Remove } and trailing white space. */
c587b3f9 1386 i = strlen (str);
75363b6d 1387 if (!i || str[i - 1] != '}')
c587b3f9 1388 abort ();
75363b6d
JB
1389 str[--i] = '\0';
1390 remove_trailing_whitespaces (str);
c587b3f9 1391
75363b6d
JB
1392 if (!*str)
1393 operand_types [i = 0] = NULL;
1394 else
c587b3f9 1395 {
75363b6d 1396 last = str + strlen (str);
c587b3f9 1397
75363b6d
JB
1398 /* Find operand_types. */
1399 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
c587b3f9 1400 {
75363b6d
JB
1401 if (str >= last)
1402 {
1403 operand_types [i] = NULL;
1404 break;
1405 }
c587b3f9 1406
75363b6d 1407 operand_types [i] = next_field (str, ',', &str, last);
c587b3f9
L
1408 }
1409 }
1410
75363b6d
JB
1411 fprintf (table, " { \"%s\", %s, %s, %s, %u,\n",
1412 name, base_opcode, extension_opcode, opcode_length, i);
c587b3f9 1413
8b65b895
L
1414 if (process_i386_opcode_modifier (table, opcode_modifier,
1415 operand_types, lineno))
1416 {
1417 char *end;
1418 unsigned long int length = strtoul (opcode_length, &end, 0);
1419 unsigned long int opcode = strtoul (base_opcode, &end, 0);
1420 switch (length)
1421 {
c1fa250a
LC
1422 case 4:
1423 break;
8b65b895
L
1424 case 3:
1425 if ((opcode >> 24) != 0)
1426 fail (_("%s: %s: (base_opcode >> 24) != 0: %s\n"),
1427 filename, name, base_opcode);
1428 break;
1429 case 2:
1430 if ((opcode >> 16) != 0)
1431 fail (_("%s: %s: (base_opcode >> 16) != 0: %s\n"),
1432 filename, name, base_opcode);
1433 break;
1434 case 1:
1435 if ((opcode >> 8) != 0)
1436 fail (_("%s: %s: (base_opcode >> 8) != 0: %s\n"),
1437 filename, name, base_opcode);
1438 break;
1439 case 0:
1440 if (opcode != 0)
1441 fail (_("%s: %s: base_opcode != 0: %s\n"),
1442 filename, name, base_opcode);
1443 break;
1444 default:
1445 fail (_("%s: %s: invalid opcode length: %s\n"),
1446 filename, name, opcode_length);
1447 break;
1448 }
1449 }
c587b3f9 1450
dac10fb0
JB
1451 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1452
c587b3f9
L
1453 fprintf (table, " { ");
1454
1455 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1456 {
75363b6d 1457 if (!operand_types[i])
c587b3f9
L
1458 {
1459 if (i == 0)
7ac20022
JB
1460 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1461 lineno);
c587b3f9
L
1462 break;
1463 }
1464
1465 if (i != 0)
1466 fprintf (table, ",\n ");
1467
7ac20022 1468 process_i386_operand_type (table, operand_types[i], stage_opcodes,
bd5295b2 1469 "\t ", lineno);
c587b3f9
L
1470 }
1471 fprintf (table, " } },\n");
1472}
1473
1474struct opcode_hash_entry
1475{
1476 struct opcode_hash_entry *next;
1477 char *name;
1478 char *opcode;
bd5295b2 1479 int lineno;
c587b3f9
L
1480};
1481
1482/* Calculate the hash value of an opcode hash entry P. */
1483
1484static hashval_t
1485opcode_hash_hash (const void *p)
1486{
1487 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1488 return htab_hash_string (entry->name);
1489}
1490
1491/* Compare a string Q against an opcode hash entry P. */
1492
1493static int
1494opcode_hash_eq (const void *p, const void *q)
1495{
1496 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1497 const char *name = (const char *) q;
1498 return strcmp (name, entry->name) == 0;
1499}
1500
4c4898e8
JB
1501static void
1502parse_template (char *buf, int lineno)
1503{
1504 char sep, *end, *name;
1505 struct template *tmpl = xmalloc (sizeof (*tmpl));
1506 struct template_instance *last_inst = NULL;
1507
1508 buf = remove_leading_whitespaces (buf + 1);
1509 end = strchr (buf, ':');
1510 if (end == NULL)
1511 fail ("%s: %d: missing ':'\n", filename, lineno);
1512 *end++ = '\0';
1513 remove_trailing_whitespaces (buf);
1514
1515 if (*buf == '\0')
1516 fail ("%s: %d: missing template identifier\n", filename, lineno);
1517 tmpl->name = xstrdup (buf);
1518
1519 tmpl->params = NULL;
1520 do {
1521 struct template_param *param;
1522
1523 buf = remove_leading_whitespaces (end);
1524 end = strpbrk (buf, ":,");
1525 if (end == NULL)
1526 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1527
1528 sep = *end;
1529 *end++ = '\0';
1530 remove_trailing_whitespaces (buf);
1531
1532 param = xmalloc (sizeof (*param));
1533 param->name = xstrdup (buf);
1534 param->next = tmpl->params;
1535 tmpl->params = param;
1536 } while (sep == ':');
1537
1538 tmpl->instances = NULL;
1539 do {
1540 struct template_instance *inst;
1541 char *cur, *next;
1542 const struct template_param *param;
1543
1544 buf = remove_leading_whitespaces (end);
1545 end = strpbrk (buf, ",>");
1546 if (end == NULL)
1547 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1548
1549 sep = *end;
1550 *end++ = '\0';
1551
1552 inst = xmalloc (sizeof (*inst));
c3ffb8f3
AM
1553 inst->next = NULL;
1554 inst->args = NULL;
4c4898e8
JB
1555
1556 cur = next_field (buf, ':', &next, end);
1557 inst->name = xstrdup (cur);
1558
1559 for (param = tmpl->params; param; param = param->next)
1560 {
1561 struct template_arg *arg = xmalloc (sizeof (*arg));
1562
1563 cur = next_field (next, ':', &next, end);
1564 if (next > end)
1565 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1566 arg->val = xstrdup (cur);
1567 arg->next = inst->args;
1568 inst->args = arg;
1569 }
1570
1571 if (tmpl->instances)
1572 last_inst->next = inst;
1573 else
1574 tmpl->instances = inst;
1575 last_inst = inst;
1576 } while (sep == ',');
1577
1578 buf = remove_leading_whitespaces (end);
1579 if (*buf)
1580 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1581 filename, lineno, buf);
1582
1583 tmpl->next = templates;
1584 templates = tmpl;
1585}
1586
1587static unsigned int
1588expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1589 struct opcode_hash_entry ***opcode_array_p, int lineno)
1590{
1591 static unsigned int idx, opcode_array_size;
1592 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1593 struct opcode_hash_entry **hash_slot, **entry;
1594 char *ptr1 = strchr(name, '<'), *ptr2;
1595
1596 if (ptr1 == NULL)
1597 {
1598 /* Get the slot in hash table. */
1599 hash_slot = (struct opcode_hash_entry **)
1600 htab_find_slot_with_hash (opcode_hash_table, name,
1601 htab_hash_string (name),
1602 INSERT);
1603
1604 if (*hash_slot == NULL)
1605 {
1606 /* It is the new one. Put it on opcode array. */
1607 if (idx >= opcode_array_size)
1608 {
1609 /* Grow the opcode array when needed. */
1610 opcode_array_size += 1024;
1611 opcode_array = (struct opcode_hash_entry **)
1612 xrealloc (opcode_array,
1613 sizeof (*opcode_array) * opcode_array_size);
1614 *opcode_array_p = opcode_array;
1615 }
1616
1617 opcode_array[idx] = (struct opcode_hash_entry *)
1618 xmalloc (sizeof (struct opcode_hash_entry));
1619 opcode_array[idx]->next = NULL;
1620 opcode_array[idx]->name = xstrdup (name);
1621 opcode_array[idx]->opcode = xstrdup (str);
1622 opcode_array[idx]->lineno = lineno;
1623 *hash_slot = opcode_array[idx];
1624 idx++;
1625 }
1626 else
1627 {
1628 /* Append it to the existing one. */
1629 entry = hash_slot;
1630 while ((*entry) != NULL)
1631 entry = &(*entry)->next;
1632 *entry = (struct opcode_hash_entry *)
1633 xmalloc (sizeof (struct opcode_hash_entry));
1634 (*entry)->next = NULL;
1635 (*entry)->name = (*hash_slot)->name;
1636 (*entry)->opcode = xstrdup (str);
1637 (*entry)->lineno = lineno;
1638 }
1639 }
1640 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1641 fail ("%s: %d: missing '>'\n", filename, lineno);
1642 else
1643 {
1644 const struct template *tmpl;
1645 const struct template_instance *inst;
1646
1647 *ptr1 = '\0';
1648 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1649 remove_trailing_whitespaces (ptr1);
1650
1651 *ptr2++ = '\0';
1652
1653 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1654 if (!strcmp(ptr1, tmpl->name))
1655 break;
1656 if (!tmpl)
1657 fail ("reference to unknown template '%s'\n", ptr1);
1658
1659 for (inst = tmpl->instances; inst; inst = inst->next)
1660 {
1661 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1662 char *str2 = xmalloc(2 * strlen(str));
1663 const char *src;
1664
1665 strcpy (name2, name);
1666 strcat (name2, inst->name);
1667 strcat (name2, ptr2);
1668
1669 for (ptr1 = str2, src = str; *src; )
1670 {
1671 const char *ident = tmpl->name, *end;
1672 const struct template_param *param;
1673 const struct template_arg *arg;
1674
1675 if ((*ptr1 = *src++) != '<')
1676 {
1677 ++ptr1;
1678 continue;
1679 }
1680 while (ISSPACE(*src))
1681 ++src;
1682 while (*ident && *src == *ident)
1683 ++src, ++ident;
1684 while (ISSPACE(*src))
1685 ++src;
1686 if (*src != ':' || *ident != '\0')
1687 {
1688 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1689 ptr1 += ident - tmpl->name;
1690 continue;
1691 }
1692 while (ISSPACE(*++src))
1693 ;
1694
1695 end = src;
1696 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1697 ++end;
1698
1699 for (param = tmpl->params, arg = inst->args; param;
1700 param = param->next, arg = arg->next)
1701 {
1702 if (end - src == strlen (param->name)
1703 && !memcmp (src, param->name, end - src))
1704 {
1705 src = end;
1706 break;
1707 }
1708 }
1709
1710 if (param == NULL)
1711 fail ("template '%s' has no parameter '%.*s'\n",
1712 tmpl->name, (int)(end - src), src);
1713
1714 while (ISSPACE(*src))
1715 ++src;
1716 if (*src != '>')
1717 fail ("%s: %d: missing '>'\n", filename, lineno);
1718
1719 memcpy(ptr1, arg->val, strlen(arg->val));
1720 ptr1 += strlen(arg->val);
1721 ++src;
1722 }
1723
1724 *ptr1 = '\0';
1725
1726 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1727 lineno);
1728
1729 free (str2);
1730 free (name2);
1731 }
1732 }
1733
1734 return idx;
1735}
1736
40b8e679 1737static void
72ffa0fb 1738process_i386_opcodes (FILE *table)
40b8e679 1739{
3d4d5afa 1740 FILE *fp;
40b8e679 1741 char buf[2048];
c587b3f9
L
1742 unsigned int i, j;
1743 char *str, *p, *last, *name;
c587b3f9 1744 htab_t opcode_hash_table;
4c4898e8 1745 struct opcode_hash_entry **opcode_array = NULL;
c30be56e 1746 int lineno = 0, marker = 0;
40b8e679 1747
3d4d5afa 1748 filename = "i386-opc.tbl";
c30be56e 1749 fp = stdin;
40b8e679 1750
c587b3f9 1751 i = 0;
c587b3f9
L
1752 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1753 opcode_hash_eq, NULL,
1754 xcalloc, free);
1755
34edb9ad 1756 fprintf (table, "\n/* i386 opcode table. */\n\n");
d3ce72d0 1757 fprintf (table, "const insn_template i386_optab[] =\n{\n");
40b8e679 1758
c587b3f9 1759 /* Put everything on opcode array. */
40b8e679
L
1760 while (!feof (fp))
1761 {
1762 if (fgets (buf, sizeof (buf), fp) == NULL)
1763 break;
1764
3d4d5afa
L
1765 lineno++;
1766
40b8e679
L
1767 p = remove_leading_whitespaces (buf);
1768
1769 /* Skip comments. */
1770 str = strstr (p, "//");
1771 if (str != NULL)
1772 str[0] = '\0';
1773
1774 /* Remove trailing white spaces. */
1775 remove_trailing_whitespaces (p);
1776
1777 switch (p[0])
1778 {
1779 case '#':
c30be56e
JB
1780 if (!strcmp("### MARKER ###", buf))
1781 marker = 1;
1782 else
1783 {
1784 /* Since we ignore all included files (we only care about their
1785 #define-s here), we don't need to monitor filenames. The final
1786 line number directive is going to refer to the main source file
1787 again. */
1788 char *end;
1789 unsigned long ln;
1790
1791 p = remove_leading_whitespaces (p + 1);
1792 if (!strncmp(p, "line", 4))
1793 p += 4;
1794 ln = strtoul (p, &end, 10);
1795 if (ln > 1 && ln < INT_MAX
1796 && *remove_leading_whitespaces (end) == '"')
1797 lineno = ln - 1;
1798 }
c587b3f9 1799 /* Ignore comments. */
40b8e679
L
1800 case '\0':
1801 continue;
1802 break;
4c4898e8
JB
1803 case '<':
1804 parse_template (p, lineno);
1805 continue;
40b8e679 1806 default:
c30be56e
JB
1807 if (!marker)
1808 continue;
40b8e679
L
1809 break;
1810 }
1811
1812 last = p + strlen (p);
1813
1814 /* Find name. */
c587b3f9 1815 name = next_field (p, ',', &str, last);
40b8e679 1816
4c4898e8
JB
1817 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1818 lineno);
c587b3f9 1819 }
40b8e679 1820
c587b3f9
L
1821 /* Process opcode array. */
1822 for (j = 0; j < i; j++)
1823 {
4c4898e8
JB
1824 struct opcode_hash_entry *next;
1825
c587b3f9
L
1826 for (next = opcode_array[j]; next; next = next->next)
1827 {
1828 name = next->name;
1829 str = next->opcode;
bd5295b2 1830 lineno = next->lineno;
c587b3f9 1831 last = str + strlen (str);
bd5295b2 1832 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1833 }
40b8e679
L
1834 }
1835
34edb9ad
L
1836 fclose (fp);
1837
4dffcebc 1838 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820 1839
4a1b91ea 1840 process_i386_opcode_modifier (table, "0", NULL, -1);
29c048b6 1841
dac10fb0
JB
1842 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1843
40fb9820 1844 fprintf (table, " { ");
7ac20022 1845 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
40fb9820
L
1846 fprintf (table, " } }\n");
1847
34edb9ad 1848 fprintf (table, "};\n");
40b8e679
L
1849}
1850
1851static void
72ffa0fb 1852process_i386_registers (FILE *table)
40b8e679 1853{
3d4d5afa 1854 FILE *fp;
40b8e679
L
1855 char buf[2048];
1856 char *str, *p, *last;
1857 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1858 char *dw2_32_num, *dw2_64_num;
bd5295b2 1859 int lineno = 0;
40b8e679 1860
3d4d5afa
L
1861 filename = "i386-reg.tbl";
1862 fp = fopen (filename, "r");
40b8e679 1863 if (fp == NULL)
34edb9ad 1864 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1865 xstrerror (errno));
40b8e679 1866
34edb9ad
L
1867 fprintf (table, "\n/* i386 register table. */\n\n");
1868 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1869
1870 while (!feof (fp))
1871 {
1872 if (fgets (buf, sizeof (buf), fp) == NULL)
1873 break;
1874
3d4d5afa
L
1875 lineno++;
1876
40b8e679
L
1877 p = remove_leading_whitespaces (buf);
1878
1879 /* Skip comments. */
1880 str = strstr (p, "//");
1881 if (str != NULL)
1882 str[0] = '\0';
1883
1884 /* Remove trailing white spaces. */
1885 remove_trailing_whitespaces (p);
1886
1887 switch (p[0])
1888 {
1889 case '#':
34edb9ad 1890 fprintf (table, "%s\n", p);
40b8e679
L
1891 case '\0':
1892 continue;
1893 break;
1894 default:
1895 break;
1896 }
1897
1898 last = p + strlen (p);
1899
1900 /* Find reg_name. */
c587b3f9 1901 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1902
1903 /* Find reg_type. */
c587b3f9 1904 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1905
1906 /* Find reg_flags. */
c587b3f9 1907 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1908
1909 /* Find reg_num. */
c587b3f9 1910 reg_num = next_field (str, ',', &str, last);
a60de03c 1911
40fb9820
L
1912 fprintf (table, " { \"%s\",\n ", reg_name);
1913
7ac20022
JB
1914 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1915 lineno);
40fb9820 1916
a60de03c 1917 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1918 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1919
1920 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1921 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1922
1923 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1924 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1925 }
1926
34edb9ad
L
1927 fclose (fp);
1928
1929 fprintf (table, "};\n");
40b8e679 1930
34edb9ad 1931 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1932}
1933
40fb9820
L
1934static void
1935process_i386_initializers (void)
1936{
1937 unsigned int i;
1938 FILE *fp = fopen ("i386-init.h", "w");
1939 char *init;
1940
1941 if (fp == NULL)
1942 fail (_("can't create i386-init.h, errno = %s\n"),
1943 xstrerror (errno));
1944
1945 process_copyright (fp);
1946
1947 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1948 {
1949 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1950 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1951 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1952 free (init);
1953 }
1954
1955 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1956 {
1957 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1958 init = xstrdup (operand_type_init[i].init);
7ac20022 1959 process_i386_operand_type (fp, init, stage_macros, " ", -1);
40fb9820
L
1960 free (init);
1961 }
1962 fprintf (fp, "\n");
1963
1964 fclose (fp);
1965}
1966
40b8e679
L
1967/* Program options. */
1968#define OPTION_SRCDIR 200
1969
29c048b6 1970struct option long_options[] =
40b8e679
L
1971{
1972 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1973 {"debug", no_argument, NULL, 'd'},
1974 {"version", no_argument, NULL, 'V'},
1975 {"help", no_argument, NULL, 'h'},
1976 {0, no_argument, NULL, 0}
1977};
1978
1979static void
1980print_version (void)
1981{
1982 printf ("%s: version 1.0\n", program_name);
1983 xexit (0);
1984}
1985
1986static void
1987usage (FILE * stream, int status)
1988{
1989 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1990 program_name);
1991 xexit (status);
1992}
1993
1994int
1995main (int argc, char **argv)
1996{
1997 extern int chdir (char *);
1998 char *srcdir = NULL;
8b40d594 1999 int c;
e92bae62 2000 unsigned int i, cpumax;
72ffa0fb 2001 FILE *table;
29c048b6 2002
40b8e679
L
2003 program_name = *argv;
2004 xmalloc_set_program_name (program_name);
2005
2006 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2007 switch (c)
2008 {
2009 case OPTION_SRCDIR:
2010 srcdir = optarg;
2011 break;
2012 case 'V':
2013 case 'v':
2014 print_version ();
2015 break;
2016 case 'd':
2017 debug = 1;
2018 break;
2019 case 'h':
2020 case '?':
2021 usage (stderr, 0);
2022 default:
2023 case 0:
2024 break;
2025 }
2026
2027 if (optind != argc)
2028 usage (stdout, 1);
2029
29c048b6 2030 if (srcdir != NULL)
40b8e679
L
2031 if (chdir (srcdir) != 0)
2032 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
2033 srcdir, xstrerror (errno));
2034
e92bae62
L
2035 /* cpu_flags isn't sorted by position. */
2036 cpumax = 0;
2037 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2038 if (cpu_flags[i].position > cpumax)
2039 cpumax = cpu_flags[i].position;
2040
40fb9820 2041 /* Check the unused bitfield in i386_cpu_flags. */
e89c5eaa 2042#ifdef CpuUnused
1d942ae9
JB
2043 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2044
e92bae62
L
2045 if ((cpumax - 1) != CpuMax)
2046 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 2047#else
1d942ae9
JB
2048 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2049
e92bae62
L
2050 if (cpumax != CpuMax)
2051 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 2052
8b40d594
L
2053 c = CpuNumOfBits - CpuMax - 1;
2054 if (c)
2055 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
2056#endif
2057
1d942ae9
JB
2058 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2059
40fb9820 2060 /* Check the unused bitfield in i386_operand_type. */
1d942ae9 2061#ifdef OTUnused
75e5731b
JB
2062 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2063 == OTNum + 1);
1d942ae9 2064#else
75e5731b
JB
2065 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2066 == OTNum);
1d942ae9 2067
51c8edf6 2068 c = OTNumOfBits - OTNum;
8b40d594
L
2069 if (c)
2070 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
2071#endif
2072
2073 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2074 compare);
2075
2076 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2077 sizeof (opcode_modifiers [0]), compare);
2078
2079 qsort (operand_types, ARRAY_SIZE (operand_types),
2080 sizeof (operand_types [0]), compare);
40b8e679 2081
34edb9ad
L
2082 table = fopen ("i386-tbl.h", "w");
2083 if (table == NULL)
40fb9820
L
2084 fail (_("can't create i386-tbl.h, errno = %s\n"),
2085 xstrerror (errno));
34edb9ad 2086
72ffa0fb 2087 process_copyright (table);
40b8e679 2088
72ffa0fb
L
2089 process_i386_opcodes (table);
2090 process_i386_registers (table);
40fb9820 2091 process_i386_initializers ();
40b8e679 2092
34edb9ad
L
2093 fclose (table);
2094
40b8e679
L
2095 exit (0);
2096}
This page took 0.912278 seconds and 4 git commands to generate.