x86: make JumpAbsolute an insn attribute
[deliverable/binutils-gdb.git] / opcodes / i386-gen.c
CommitLineData
82704155 1/* Copyright (C) 2007-2019 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
L
615 BITFIELD (Modrm),
616 BITFIELD (ShortForm),
617 BITFIELD (Jump),
618 BITFIELD (JumpDword),
619 BITFIELD (JumpByte),
620 BITFIELD (JumpInterSegment),
6f2f06be 621 BITFIELD (JumpAbsolute),
40fb9820
L
622 BITFIELD (FloatMF),
623 BITFIELD (FloatR),
673fe0f0 624 BITFIELD (Size),
56ffb741 625 BITFIELD (CheckRegSize),
40fb9820
L
626 BITFIELD (IgnoreSize),
627 BITFIELD (DefaultSize),
601e8564 628 BITFIELD (Anysize),
40fb9820
L
629 BITFIELD (No_bSuf),
630 BITFIELD (No_wSuf),
631 BITFIELD (No_lSuf),
632 BITFIELD (No_sSuf),
633 BITFIELD (No_qSuf),
7ce189b3 634 BITFIELD (No_ldSuf),
40fb9820
L
635 BITFIELD (FWait),
636 BITFIELD (IsString),
dfd69174 637 BITFIELD (RegMem),
7e8b059b 638 BITFIELD (BNDPrefixOk),
04ef582a 639 BITFIELD (NoTrackPrefixOk),
c32fa91d 640 BITFIELD (IsLockable),
40fb9820 641 BITFIELD (RegKludge),
c0f3af97 642 BITFIELD (Implicit1stXmm0),
29c048b6 643 BITFIELD (RepPrefixOk),
42164a71 644 BITFIELD (HLEPrefixOk),
ca61edf2
L
645 BITFIELD (ToDword),
646 BITFIELD (ToQword),
75c0a438 647 BITFIELD (AddrPrefixOpReg),
40fb9820
L
648 BITFIELD (IsPrefix),
649 BITFIELD (ImmExt),
650 BITFIELD (NoRex64),
651 BITFIELD (Rex64),
652 BITFIELD (Ugh),
c0f3af97 653 BITFIELD (Vex),
2426c15f 654 BITFIELD (VexVVVV),
1ef99a7b 655 BITFIELD (VexW),
7f399153 656 BITFIELD (VexOpcode),
8cd7925b 657 BITFIELD (VexSources),
6c30d220 658 BITFIELD (VecSIB),
c0f3af97 659 BITFIELD (SSE2AVX),
81f8a913 660 BITFIELD (NoAVX),
43234a1e
L
661 BITFIELD (EVex),
662 BITFIELD (Masking),
43234a1e
L
663 BITFIELD (Broadcast),
664 BITFIELD (StaticRounding),
665 BITFIELD (SAE),
666 BITFIELD (Disp8MemShift),
667 BITFIELD (NoDefMask),
920d2ddc 668 BITFIELD (ImplicitQuadGroup),
b6f8c7c4 669 BITFIELD (Optimize),
1efbbeb4 670 BITFIELD (ATTMnemonic),
e1d4d893 671 BITFIELD (ATTSyntax),
5c07affc 672 BITFIELD (IntelSyntax),
e92bae62
L
673 BITFIELD (AMD64),
674 BITFIELD (Intel64),
40fb9820
L
675};
676
bab6aec1
JB
677#define CLASS(n) #n, n
678
679static const struct {
680 const char *name;
681 enum operand_class value;
682} operand_classes[] = {
683 CLASS (Reg),
00cee14f 684 CLASS (SReg),
4a5c67ed
JB
685 CLASS (RegCR),
686 CLASS (RegDR),
687 CLASS (RegTR),
3528c362
JB
688 CLASS (RegMMX),
689 CLASS (RegSIMD),
f74a6307
JB
690 CLASS (RegMask),
691 CLASS (RegBND),
bab6aec1
JB
692};
693
694#undef CLASS
695
75e5731b
JB
696#define INSTANCE(n) #n, n
697
698static const struct {
699 const char *name;
700 enum operand_instance value;
701} operand_instances[] = {
702 INSTANCE (Accum),
703 INSTANCE (RegC),
704 INSTANCE (RegD),
474da251 705 INSTANCE (RegB),
75e5731b
JB
706};
707
708#undef INSTANCE
709
40fb9820
L
710static bitfield operand_types[] =
711{
94ff3a50 712 BITFIELD (Imm1),
40fb9820
L
713 BITFIELD (Imm8),
714 BITFIELD (Imm8S),
715 BITFIELD (Imm16),
716 BITFIELD (Imm32),
717 BITFIELD (Imm32S),
718 BITFIELD (Imm64),
40fb9820
L
719 BITFIELD (BaseIndex),
720 BITFIELD (Disp8),
721 BITFIELD (Disp16),
722 BITFIELD (Disp32),
723 BITFIELD (Disp32S),
724 BITFIELD (Disp64),
7d5e4556
L
725 BITFIELD (Byte),
726 BITFIELD (Word),
727 BITFIELD (Dword),
728 BITFIELD (Fword),
729 BITFIELD (Qword),
730 BITFIELD (Tbyte),
731 BITFIELD (Xmmword),
c0f3af97 732 BITFIELD (Ymmword),
43234a1e 733 BITFIELD (Zmmword),
7d5e4556 734 BITFIELD (Unspecified),
40fb9820
L
735#ifdef OTUnused
736 BITFIELD (OTUnused),
737#endif
738};
739
3d4d5afa 740static const char *filename;
7ac20022
JB
741static i386_cpu_flags active_cpu_flags;
742static int active_isstring;
3d4d5afa 743
40fb9820
L
744static int
745compare (const void *x, const void *y)
746{
747 const bitfield *xp = (const bitfield *) x;
748 const bitfield *yp = (const bitfield *) y;
749 return xp->position - yp->position;
750}
751
40b8e679
L
752static void
753fail (const char *message, ...)
754{
755 va_list args;
29c048b6 756
40b8e679 757 va_start (args, message);
a6743a54 758 fprintf (stderr, _("%s: error: "), program_name);
40b8e679
L
759 vfprintf (stderr, message, args);
760 va_end (args);
761 xexit (1);
762}
763
72ffa0fb
L
764static void
765process_copyright (FILE *fp)
766{
767 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
82704155 768/* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
72ffa0fb
L
769\n\
770 This file is part of the GNU opcodes library.\n\
771\n\
772 This library is free software; you can redistribute it and/or modify\n\
773 it under the terms of the GNU General Public License as published by\n\
774 the Free Software Foundation; either version 3, or (at your option)\n\
775 any later version.\n\
776\n\
777 It is distributed in the hope that it will be useful, but WITHOUT\n\
778 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
779 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
780 License for more details.\n\
781\n\
782 You should have received a copy of the GNU General Public License\n\
783 along with this program; if not, write to the Free Software\n\
784 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
785 MA 02110-1301, USA. */\n");
786}
787
40b8e679
L
788/* Remove leading white spaces. */
789
790static char *
791remove_leading_whitespaces (char *str)
792{
793 while (ISSPACE (*str))
794 str++;
795 return str;
796}
797
798/* Remove trailing white spaces. */
799
800static void
801remove_trailing_whitespaces (char *str)
802{
803 size_t last = strlen (str);
804
805 if (last == 0)
806 return;
807
808 do
809 {
810 last--;
811 if (ISSPACE (str [last]))
812 str[last] = '\0';
813 else
814 break;
815 }
816 while (last != 0);
817}
818
93b1ec2c 819/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
820 pointer to the one after it. */
821
822static char *
c587b3f9 823next_field (char *str, char sep, char **next, char *last)
40b8e679
L
824{
825 char *p;
826
827 p = remove_leading_whitespaces (str);
93b1ec2c 828 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
829
830 *str = '\0';
831 remove_trailing_whitespaces (p);
832
29c048b6 833 *next = str + 1;
40b8e679 834
c587b3f9
L
835 if (p >= last)
836 abort ();
837
40b8e679
L
838 return p;
839}
840
1848e567
L
841static void set_bitfield (char *, bitfield *, int, unsigned int, int);
842
843static int
3cc17af5
JB
844set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
845 int lineno)
1848e567
L
846{
847 char *str, *next, *last;
848 unsigned int i;
849
850 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
851 if (strcmp (cpu_flag_init[i].name, f) == 0)
852 {
853 /* Turn on selective bits. */
854 char *init = xstrdup (cpu_flag_init[i].init);
855 last = init + strlen (init);
856 for (next = init; next && next < last; )
857 {
858 str = next_field (next, '|', &next, last);
859 if (str)
860 set_bitfield (str, array, 1, size, lineno);
861 }
862 free (init);
863 return 0;
864 }
865
866 return -1;
867}
868
40fb9820 869static void
1848e567 870set_bitfield (char *f, bitfield *array, int value,
8a9036a4 871 unsigned int size, int lineno)
40fb9820
L
872{
873 unsigned int i;
874
309d3373
JB
875 if (strcmp (f, "CpuFP") == 0)
876 {
8a9036a4
L
877 set_bitfield("Cpu387", array, value, size, lineno);
878 set_bitfield("Cpu287", array, value, size, lineno);
309d3373
JB
879 f = "Cpu8087";
880 }
881 else if (strcmp (f, "Mmword") == 0)
7d5e4556
L
882 f= "Qword";
883 else if (strcmp (f, "Oword") == 0)
884 f= "Xmmword";
40fb9820
L
885
886 for (i = 0; i < size; i++)
887 if (strcasecmp (array[i].name, f) == 0)
888 {
8a9036a4 889 array[i].value = value;
40fb9820
L
890 return;
891 }
892
2bf05e57
L
893 if (value)
894 {
895 const char *v = strchr (f, '=');
896
897 if (v)
898 {
899 size_t n = v - f;
900 char *end;
901
902 for (i = 0; i < size; i++)
903 if (strncasecmp (array[i].name, f, n) == 0)
904 {
905 value = strtol (v + 1, &end, 0);
906 if (*end == '\0')
907 {
908 array[i].value = value;
909 return;
910 }
911 break;
912 }
913 }
914 }
915
3cc17af5
JB
916 /* Handle CPU_XXX_FLAGS. */
917 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1848e567
L
918 return;
919
bd5295b2 920 if (lineno != -1)
a6743a54 921 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
bd5295b2 922 else
a6743a54 923 fail (_("unknown bitfield: %s\n"), f);
40fb9820
L
924}
925
926static void
927output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
928 int macro, const char *comma, const char *indent)
929{
930 unsigned int i;
931
7ac20022
JB
932 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
933
40fb9820
L
934 fprintf (table, "%s{ { ", indent);
935
936 for (i = 0; i < size - 1; i++)
937 {
10632b79
L
938 if (((i + 1) % 20) != 0)
939 fprintf (table, "%d, ", flags[i].value);
940 else
941 fprintf (table, "%d,", flags[i].value);
40fb9820
L
942 if (((i + 1) % 20) == 0)
943 {
944 /* We need \\ for macro. */
945 if (macro)
946 fprintf (table, " \\\n %s", indent);
947 else
948 fprintf (table, "\n %s", indent);
949 }
7ac20022
JB
950 if (flags[i].value)
951 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
40fb9820
L
952 }
953
954 fprintf (table, "%d } }%s\n", flags[i].value, comma);
955}
956
957static void
958process_i386_cpu_flag (FILE *table, char *flag, int macro,
bd5295b2
L
959 const char *comma, const char *indent,
960 int lineno)
40fb9820
L
961{
962 char *str, *next, *last;
8a9036a4 963 unsigned int i;
40fb9820
L
964 bitfield flags [ARRAY_SIZE (cpu_flags)];
965
966 /* Copy the default cpu flags. */
967 memcpy (flags, cpu_flags, sizeof (cpu_flags));
968
969 if (strcasecmp (flag, "unknown") == 0)
970 {
40fb9820 971 /* We turn on everything except for cpu64 in case of
8a9036a4
L
972 CPU_UNKNOWN_FLAGS. */
973 for (i = 0; i < ARRAY_SIZE (flags); i++)
974 if (flags[i].position != Cpu64)
975 flags[i].value = 1;
976 }
977 else if (flag[0] == '~')
978 {
979 last = flag + strlen (flag);
980
981 if (flag[1] == '(')
982 {
983 last -= 1;
984 next = flag + 2;
985 if (*last != ')')
a6743a54 986 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
8a9036a4
L
987 lineno, flag);
988 *last = '\0';
989 }
990 else
991 next = flag + 1;
992
993 /* First we turn on everything except for cpu64. */
40fb9820
L
994 for (i = 0; i < ARRAY_SIZE (flags); i++)
995 if (flags[i].position != Cpu64)
996 flags[i].value = 1;
8a9036a4
L
997
998 /* Turn off selective bits. */
999 for (; next && next < last; )
1000 {
1001 str = next_field (next, '|', &next, last);
1002 if (str)
1003 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1004 }
40fb9820
L
1005 }
1006 else if (strcmp (flag, "0"))
1007 {
8a9036a4 1008 /* Turn on selective bits. */
40fb9820
L
1009 last = flag + strlen (flag);
1010 for (next = flag; next && next < last; )
1011 {
c587b3f9 1012 str = next_field (next, '|', &next, last);
40fb9820 1013 if (str)
8a9036a4 1014 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
40fb9820
L
1015 }
1016 }
1017
1018 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1019 comma, indent);
1020}
1021
1022static void
1023output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1024{
1025 unsigned int i;
1026
1027 fprintf (table, " { ");
1028
1029 for (i = 0; i < size - 1; i++)
1030 {
10632b79
L
1031 if (((i + 1) % 20) != 0)
1032 fprintf (table, "%d, ", modifier[i].value);
1033 else
1034 fprintf (table, "%d,", modifier[i].value);
40fb9820
L
1035 if (((i + 1) % 20) == 0)
1036 fprintf (table, "\n ");
1037 }
1038
1039 fprintf (table, "%d },\n", modifier[i].value);
1040}
1041
4a1b91ea
L
1042static int
1043adjust_broadcast_modifier (char **opnd)
1044{
1045 char *str, *next, *last, *op;
1046 int bcst_type = INT_MAX;
1047
1048 /* Skip the immediate operand. */
1049 op = opnd[0];
1050 if (strcasecmp(op, "Imm8") == 0)
1051 op = opnd[1];
1052
1053 op = xstrdup (op);
1054 last = op + strlen (op);
1055 for (next = op; next && next < last; )
1056 {
1057 str = next_field (next, '|', &next, last);
1058 if (str)
1059 {
1060 if (strcasecmp(str, "Byte") == 0)
1061 {
1062 /* The smalest broadcast type, no need to check
1063 further. */
1064 bcst_type = BYTE_BROADCAST;
1065 break;
1066 }
1067 else if (strcasecmp(str, "Word") == 0)
1068 {
1069 if (bcst_type > WORD_BROADCAST)
1070 bcst_type = WORD_BROADCAST;
1071 }
1072 else if (strcasecmp(str, "Dword") == 0)
1073 {
1074 if (bcst_type > DWORD_BROADCAST)
1075 bcst_type = DWORD_BROADCAST;
1076 }
1077 else if (strcasecmp(str, "Qword") == 0)
1078 {
1079 if (bcst_type > QWORD_BROADCAST)
1080 bcst_type = QWORD_BROADCAST;
1081 }
1082 }
1083 }
1084 free (op);
1085
1086 if (bcst_type == INT_MAX)
1087 fail (_("unknown broadcast operand: %s\n"), op);
1088
1089 return bcst_type;
1090}
1091
40fb9820 1092static void
4a1b91ea 1093process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
40fb9820
L
1094{
1095 char *str, *next, *last;
1096 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1097
7ac20022
JB
1098 active_isstring = 0;
1099
40fb9820
L
1100 /* Copy the default opcode modifier. */
1101 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1102
1103 if (strcmp (mod, "0"))
1104 {
507916b8
JB
1105 unsigned int have_w = 0, bwlq_suf = 0xf;
1106
40fb9820
L
1107 last = mod + strlen (mod);
1108 for (next = mod; next && next < last; )
1109 {
c587b3f9 1110 str = next_field (next, '|', &next, last);
40fb9820 1111 if (str)
7ac20022 1112 {
4a1b91ea
L
1113 int val = 1;
1114 if (strcasecmp(str, "Broadcast") == 0)
1115 val = adjust_broadcast_modifier (opnd);
1116 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
8a9036a4 1117 lineno);
7ac20022
JB
1118 if (strcasecmp(str, "IsString") == 0)
1119 active_isstring = 1;
507916b8
JB
1120
1121 if (strcasecmp(str, "W") == 0)
1122 have_w = 1;
1123
1124 if (strcasecmp(str, "No_bSuf") == 0)
1125 bwlq_suf &= ~1;
1126 if (strcasecmp(str, "No_wSuf") == 0)
1127 bwlq_suf &= ~2;
1128 if (strcasecmp(str, "No_lSuf") == 0)
1129 bwlq_suf &= ~4;
1130 if (strcasecmp(str, "No_qSuf") == 0)
1131 bwlq_suf &= ~8;
7ac20022 1132 }
40fb9820 1133 }
507916b8
JB
1134
1135 if (have_w && !bwlq_suf)
1136 fail ("%s: %d: stray W modifier\n", filename, lineno);
1137 if (have_w && !(bwlq_suf & 1))
1138 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1139 filename, lineno);
1140 if (have_w && !(bwlq_suf & ~1))
1141 fprintf (stderr,
1142 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1143 filename, lineno);
40fb9820
L
1144 }
1145 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1146}
1147
7ac20022
JB
1148enum stage {
1149 stage_macros,
1150 stage_opcodes,
1151 stage_registers,
1152};
1153
40fb9820 1154static void
bab6aec1 1155output_operand_type (FILE *table, enum operand_class class,
75e5731b 1156 enum operand_instance instance,
bab6aec1 1157 const bitfield *types, unsigned int size,
7ac20022 1158 enum stage stage, const char *indent)
40fb9820
L
1159{
1160 unsigned int i;
1161
75e5731b 1162 fprintf (table, "{ { %d, %d, ", class, instance);
40fb9820
L
1163
1164 for (i = 0; i < size - 1; i++)
1165 {
75e5731b 1166 if (((i + 3) % 20) != 0)
10632b79
L
1167 fprintf (table, "%d, ", types[i].value);
1168 else
1169 fprintf (table, "%d,", types[i].value);
75e5731b 1170 if (((i + 3) % 20) == 0)
40fb9820
L
1171 {
1172 /* We need \\ for macro. */
7ac20022 1173 if (stage == stage_macros)
10632b79 1174 fprintf (table, " \\\n%s", indent);
40fb9820
L
1175 else
1176 fprintf (table, "\n%s", indent);
1177 }
1178 }
1179
1180 fprintf (table, "%d } }", types[i].value);
1181}
1182
1183static void
7ac20022 1184process_i386_operand_type (FILE *table, char *op, enum stage stage,
bd5295b2 1185 const char *indent, int lineno)
40fb9820
L
1186{
1187 char *str, *next, *last;
bab6aec1 1188 enum operand_class class = ClassNone;
75e5731b 1189 enum operand_instance instance = InstanceNone;
40fb9820
L
1190 bitfield types [ARRAY_SIZE (operand_types)];
1191
1192 /* Copy the default operand type. */
1193 memcpy (types, operand_types, sizeof (types));
1194
1195 if (strcmp (op, "0"))
1196 {
7ac20022
JB
1197 int baseindex = 0;
1198
40fb9820
L
1199 last = op + strlen (op);
1200 for (next = op; next && next < last; )
1201 {
c587b3f9 1202 str = next_field (next, '|', &next, last);
bab6aec1
JB
1203 if (str)
1204 {
1205 unsigned int i;
1206
1207 if (!strncmp(str, "Class=", 6))
1208 {
1209 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1210 if (!strcmp(str + 6, operand_classes[i].name))
1211 {
1212 class = operand_classes[i].value;
1213 str = NULL;
1214 break;
1215 }
1216 }
75e5731b
JB
1217
1218 if (str && !strncmp(str, "Instance=", 9))
1219 {
1220 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1221 if (!strcmp(str + 9, operand_instances[i].name))
1222 {
1223 instance = operand_instances[i].value;
1224 str = NULL;
1225 break;
1226 }
1227 }
bab6aec1 1228 }
40fb9820 1229 if (str)
7ac20022
JB
1230 {
1231 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1232 if (strcasecmp(str, "BaseIndex") == 0)
1233 baseindex = 1;
1234 }
1235 }
1236
1237 if (stage == stage_opcodes && baseindex && !active_isstring)
1238 {
1239 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1240 if (!active_cpu_flags.bitfield.cpu64
1241 && !active_cpu_flags.bitfield.cpumpx)
1242 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1243 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1244 if (!active_cpu_flags.bitfield.cpuno64)
1245 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
1246 }
1247 }
75e5731b
JB
1248 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1249 stage, indent);
40fb9820
L
1250}
1251
c587b3f9
L
1252static void
1253output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 1254 char *last, int lineno)
c587b3f9
L
1255{
1256 unsigned int i;
1257 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1258 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1259
1260 /* Find number of operands. */
1261 operands = next_field (str, ',', &str, last);
1262
1263 /* Find base_opcode. */
1264 base_opcode = next_field (str, ',', &str, last);
1265
1266 /* Find extension_opcode. */
1267 extension_opcode = next_field (str, ',', &str, last);
1268
1269 /* Find opcode_length. */
1270 opcode_length = next_field (str, ',', &str, last);
1271
1272 /* Find cpu_flags. */
1273 cpu_flags = next_field (str, ',', &str, last);
1274
1275 /* Find opcode_modifier. */
1276 opcode_modifier = next_field (str, ',', &str, last);
1277
1278 /* Remove the first {. */
1279 str = remove_leading_whitespaces (str);
1280 if (*str != '{')
1281 abort ();
1282 str = remove_leading_whitespaces (str + 1);
1283
1284 i = strlen (str);
1285
1286 /* There are at least "X}". */
1287 if (i < 2)
1288 abort ();
1289
1290 /* Remove trailing white spaces and }. */
1291 do
1292 {
1293 i--;
1294 if (ISSPACE (str[i]) || str[i] == '}')
1295 str[i] = '\0';
1296 else
1297 break;
1298 }
1299 while (i != 0);
1300
1301 last = str + i;
1302
1303 /* Find operand_types. */
1304 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1305 {
1306 if (str >= last)
1307 {
1308 operand_types [i] = NULL;
1309 break;
1310 }
1311
1312 operand_types [i] = next_field (str, ',', &str, last);
1313 if (*operand_types[i] == '0')
1314 {
1315 if (i != 0)
1316 operand_types[i] = NULL;
1317 break;
1318 }
1319 }
1320
1321 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
a2cebd03 1322 name, base_opcode, extension_opcode, opcode_length, operands);
c587b3f9 1323
bd5295b2 1324 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
c587b3f9 1325
4a1b91ea 1326 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
c587b3f9
L
1327
1328 fprintf (table, " { ");
1329
1330 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1331 {
1332 if (operand_types[i] == NULL || *operand_types[i] == '0')
1333 {
1334 if (i == 0)
7ac20022
JB
1335 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1336 lineno);
c587b3f9
L
1337 break;
1338 }
1339
1340 if (i != 0)
1341 fprintf (table, ",\n ");
1342
7ac20022 1343 process_i386_operand_type (table, operand_types[i], stage_opcodes,
bd5295b2 1344 "\t ", lineno);
c587b3f9
L
1345 }
1346 fprintf (table, " } },\n");
1347}
1348
1349struct opcode_hash_entry
1350{
1351 struct opcode_hash_entry *next;
1352 char *name;
1353 char *opcode;
bd5295b2 1354 int lineno;
c587b3f9
L
1355};
1356
1357/* Calculate the hash value of an opcode hash entry P. */
1358
1359static hashval_t
1360opcode_hash_hash (const void *p)
1361{
1362 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1363 return htab_hash_string (entry->name);
1364}
1365
1366/* Compare a string Q against an opcode hash entry P. */
1367
1368static int
1369opcode_hash_eq (const void *p, const void *q)
1370{
1371 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1372 const char *name = (const char *) q;
1373 return strcmp (name, entry->name) == 0;
1374}
1375
40b8e679 1376static void
72ffa0fb 1377process_i386_opcodes (FILE *table)
40b8e679 1378{
3d4d5afa 1379 FILE *fp;
40b8e679 1380 char buf[2048];
c587b3f9
L
1381 unsigned int i, j;
1382 char *str, *p, *last, *name;
1383 struct opcode_hash_entry **hash_slot, **entry, *next;
1384 htab_t opcode_hash_table;
1385 struct opcode_hash_entry **opcode_array;
1386 unsigned int opcode_array_size = 1024;
c30be56e 1387 int lineno = 0, marker = 0;
40b8e679 1388
3d4d5afa 1389 filename = "i386-opc.tbl";
c30be56e 1390 fp = stdin;
40b8e679 1391
c587b3f9
L
1392 i = 0;
1393 opcode_array = (struct opcode_hash_entry **)
1394 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1395
1396 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1397 opcode_hash_eq, NULL,
1398 xcalloc, free);
1399
34edb9ad 1400 fprintf (table, "\n/* i386 opcode table. */\n\n");
d3ce72d0 1401 fprintf (table, "const insn_template i386_optab[] =\n{\n");
40b8e679 1402
c587b3f9 1403 /* Put everything on opcode array. */
40b8e679
L
1404 while (!feof (fp))
1405 {
1406 if (fgets (buf, sizeof (buf), fp) == NULL)
1407 break;
1408
3d4d5afa
L
1409 lineno++;
1410
40b8e679
L
1411 p = remove_leading_whitespaces (buf);
1412
1413 /* Skip comments. */
1414 str = strstr (p, "//");
1415 if (str != NULL)
1416 str[0] = '\0';
1417
1418 /* Remove trailing white spaces. */
1419 remove_trailing_whitespaces (p);
1420
1421 switch (p[0])
1422 {
1423 case '#':
c30be56e
JB
1424 if (!strcmp("### MARKER ###", buf))
1425 marker = 1;
1426 else
1427 {
1428 /* Since we ignore all included files (we only care about their
1429 #define-s here), we don't need to monitor filenames. The final
1430 line number directive is going to refer to the main source file
1431 again. */
1432 char *end;
1433 unsigned long ln;
1434
1435 p = remove_leading_whitespaces (p + 1);
1436 if (!strncmp(p, "line", 4))
1437 p += 4;
1438 ln = strtoul (p, &end, 10);
1439 if (ln > 1 && ln < INT_MAX
1440 && *remove_leading_whitespaces (end) == '"')
1441 lineno = ln - 1;
1442 }
c587b3f9 1443 /* Ignore comments. */
40b8e679
L
1444 case '\0':
1445 continue;
1446 break;
1447 default:
c30be56e
JB
1448 if (!marker)
1449 continue;
40b8e679
L
1450 break;
1451 }
1452
1453 last = p + strlen (p);
1454
1455 /* Find name. */
c587b3f9 1456 name = next_field (p, ',', &str, last);
40b8e679 1457
c587b3f9
L
1458 /* Get the slot in hash table. */
1459 hash_slot = (struct opcode_hash_entry **)
1460 htab_find_slot_with_hash (opcode_hash_table, name,
1461 htab_hash_string (name),
1462 INSERT);
40b8e679 1463
c587b3f9 1464 if (*hash_slot == NULL)
40b8e679 1465 {
c587b3f9
L
1466 /* It is the new one. Put it on opcode array. */
1467 if (i >= opcode_array_size)
40b8e679 1468 {
c587b3f9
L
1469 /* Grow the opcode array when needed. */
1470 opcode_array_size += 1024;
1471 opcode_array = (struct opcode_hash_entry **)
1472 xrealloc (opcode_array,
1473 sizeof (*opcode_array) * opcode_array_size);
40b8e679
L
1474 }
1475
c587b3f9
L
1476 opcode_array[i] = (struct opcode_hash_entry *)
1477 xmalloc (sizeof (struct opcode_hash_entry));
1478 opcode_array[i]->next = NULL;
1479 opcode_array[i]->name = xstrdup (name);
1480 opcode_array[i]->opcode = xstrdup (str);
bd5295b2 1481 opcode_array[i]->lineno = lineno;
c587b3f9
L
1482 *hash_slot = opcode_array[i];
1483 i++;
40b8e679 1484 }
c587b3f9 1485 else
40b8e679 1486 {
c587b3f9
L
1487 /* Append it to the existing one. */
1488 entry = hash_slot;
1489 while ((*entry) != NULL)
1490 entry = &(*entry)->next;
1491 *entry = (struct opcode_hash_entry *)
1492 xmalloc (sizeof (struct opcode_hash_entry));
1493 (*entry)->next = NULL;
1494 (*entry)->name = (*hash_slot)->name;
1495 (*entry)->opcode = xstrdup (str);
bd5295b2 1496 (*entry)->lineno = lineno;
c587b3f9
L
1497 }
1498 }
40b8e679 1499
c587b3f9
L
1500 /* Process opcode array. */
1501 for (j = 0; j < i; j++)
1502 {
1503 for (next = opcode_array[j]; next; next = next->next)
1504 {
1505 name = next->name;
1506 str = next->opcode;
bd5295b2 1507 lineno = next->lineno;
c587b3f9 1508 last = str + strlen (str);
bd5295b2 1509 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1510 }
40b8e679
L
1511 }
1512
34edb9ad
L
1513 fclose (fp);
1514
4dffcebc 1515 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820 1516
bd5295b2 1517 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
40fb9820 1518
4a1b91ea 1519 process_i386_opcode_modifier (table, "0", NULL, -1);
29c048b6 1520
40fb9820 1521 fprintf (table, " { ");
7ac20022 1522 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
40fb9820
L
1523 fprintf (table, " } }\n");
1524
34edb9ad 1525 fprintf (table, "};\n");
40b8e679
L
1526}
1527
1528static void
72ffa0fb 1529process_i386_registers (FILE *table)
40b8e679 1530{
3d4d5afa 1531 FILE *fp;
40b8e679
L
1532 char buf[2048];
1533 char *str, *p, *last;
1534 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1535 char *dw2_32_num, *dw2_64_num;
bd5295b2 1536 int lineno = 0;
40b8e679 1537
3d4d5afa
L
1538 filename = "i386-reg.tbl";
1539 fp = fopen (filename, "r");
40b8e679 1540 if (fp == NULL)
34edb9ad 1541 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1542 xstrerror (errno));
40b8e679 1543
34edb9ad
L
1544 fprintf (table, "\n/* i386 register table. */\n\n");
1545 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1546
1547 while (!feof (fp))
1548 {
1549 if (fgets (buf, sizeof (buf), fp) == NULL)
1550 break;
1551
3d4d5afa
L
1552 lineno++;
1553
40b8e679
L
1554 p = remove_leading_whitespaces (buf);
1555
1556 /* Skip comments. */
1557 str = strstr (p, "//");
1558 if (str != NULL)
1559 str[0] = '\0';
1560
1561 /* Remove trailing white spaces. */
1562 remove_trailing_whitespaces (p);
1563
1564 switch (p[0])
1565 {
1566 case '#':
34edb9ad 1567 fprintf (table, "%s\n", p);
40b8e679
L
1568 case '\0':
1569 continue;
1570 break;
1571 default:
1572 break;
1573 }
1574
1575 last = p + strlen (p);
1576
1577 /* Find reg_name. */
c587b3f9 1578 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1579
1580 /* Find reg_type. */
c587b3f9 1581 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1582
1583 /* Find reg_flags. */
c587b3f9 1584 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1585
1586 /* Find reg_num. */
c587b3f9 1587 reg_num = next_field (str, ',', &str, last);
a60de03c 1588
40fb9820
L
1589 fprintf (table, " { \"%s\",\n ", reg_name);
1590
7ac20022
JB
1591 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1592 lineno);
40fb9820 1593
a60de03c 1594 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1595 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1596
1597 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1598 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1599
1600 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1601 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1602 }
1603
34edb9ad
L
1604 fclose (fp);
1605
1606 fprintf (table, "};\n");
40b8e679 1607
34edb9ad 1608 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1609}
1610
40fb9820
L
1611static void
1612process_i386_initializers (void)
1613{
1614 unsigned int i;
1615 FILE *fp = fopen ("i386-init.h", "w");
1616 char *init;
1617
1618 if (fp == NULL)
1619 fail (_("can't create i386-init.h, errno = %s\n"),
1620 xstrerror (errno));
1621
1622 process_copyright (fp);
1623
1624 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1625 {
1626 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1627 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1628 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1629 free (init);
1630 }
1631
1632 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1633 {
1634 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1635 init = xstrdup (operand_type_init[i].init);
7ac20022 1636 process_i386_operand_type (fp, init, stage_macros, " ", -1);
40fb9820
L
1637 free (init);
1638 }
1639 fprintf (fp, "\n");
1640
1641 fclose (fp);
1642}
1643
40b8e679
L
1644/* Program options. */
1645#define OPTION_SRCDIR 200
1646
29c048b6 1647struct option long_options[] =
40b8e679
L
1648{
1649 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1650 {"debug", no_argument, NULL, 'd'},
1651 {"version", no_argument, NULL, 'V'},
1652 {"help", no_argument, NULL, 'h'},
1653 {0, no_argument, NULL, 0}
1654};
1655
1656static void
1657print_version (void)
1658{
1659 printf ("%s: version 1.0\n", program_name);
1660 xexit (0);
1661}
1662
1663static void
1664usage (FILE * stream, int status)
1665{
1666 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1667 program_name);
1668 xexit (status);
1669}
1670
1671int
1672main (int argc, char **argv)
1673{
1674 extern int chdir (char *);
1675 char *srcdir = NULL;
8b40d594 1676 int c;
e92bae62 1677 unsigned int i, cpumax;
72ffa0fb 1678 FILE *table;
29c048b6 1679
40b8e679
L
1680 program_name = *argv;
1681 xmalloc_set_program_name (program_name);
1682
1683 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1684 switch (c)
1685 {
1686 case OPTION_SRCDIR:
1687 srcdir = optarg;
1688 break;
1689 case 'V':
1690 case 'v':
1691 print_version ();
1692 break;
1693 case 'd':
1694 debug = 1;
1695 break;
1696 case 'h':
1697 case '?':
1698 usage (stderr, 0);
1699 default:
1700 case 0:
1701 break;
1702 }
1703
1704 if (optind != argc)
1705 usage (stdout, 1);
1706
29c048b6 1707 if (srcdir != NULL)
40b8e679
L
1708 if (chdir (srcdir) != 0)
1709 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
1710 srcdir, xstrerror (errno));
1711
e92bae62
L
1712 /* cpu_flags isn't sorted by position. */
1713 cpumax = 0;
1714 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1715 if (cpu_flags[i].position > cpumax)
1716 cpumax = cpu_flags[i].position;
1717
40fb9820 1718 /* Check the unused bitfield in i386_cpu_flags. */
e89c5eaa 1719#ifdef CpuUnused
1d942ae9
JB
1720 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1721
e92bae62
L
1722 if ((cpumax - 1) != CpuMax)
1723 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1724#else
1d942ae9
JB
1725 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1726
e92bae62
L
1727 if (cpumax != CpuMax)
1728 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1729
8b40d594
L
1730 c = CpuNumOfBits - CpuMax - 1;
1731 if (c)
1732 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
1733#endif
1734
1d942ae9
JB
1735 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1736
40fb9820 1737 /* Check the unused bitfield in i386_operand_type. */
1d942ae9 1738#ifdef OTUnused
75e5731b
JB
1739 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1740 == OTNum + 1);
1d942ae9 1741#else
75e5731b
JB
1742 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1743 == OTNum);
1d942ae9 1744
51c8edf6 1745 c = OTNumOfBits - OTNum;
8b40d594
L
1746 if (c)
1747 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
1748#endif
1749
1750 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1751 compare);
1752
1753 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1754 sizeof (opcode_modifiers [0]), compare);
1755
1756 qsort (operand_types, ARRAY_SIZE (operand_types),
1757 sizeof (operand_types [0]), compare);
40b8e679 1758
34edb9ad
L
1759 table = fopen ("i386-tbl.h", "w");
1760 if (table == NULL)
40fb9820
L
1761 fail (_("can't create i386-tbl.h, errno = %s\n"),
1762 xstrerror (errno));
34edb9ad 1763
72ffa0fb 1764 process_copyright (table);
40b8e679 1765
72ffa0fb
L
1766 process_i386_opcodes (table);
1767 process_i386_registers (table);
40fb9820 1768 process_i386_initializers ();
40b8e679 1769
34edb9ad
L
1770 fclose (table);
1771
40b8e679
L
1772 exit (0);
1773}
This page took 0.66465 seconds and 4 git commands to generate.