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