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