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