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