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