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