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