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