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