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