PowerPC disassembly of odd sized sections
[deliverable/binutils-gdb.git] / opcodes / i386-gen.c
CommitLineData
b3adc24a 1/* Copyright (C) 2007-2020 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",
272a84b1 93 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuLZCNT|CpuPOPCNT" },
68339fdf 94 { "CPU_BDVER1_FLAGS",
272a84b1 95 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuLZCNT|CpuPOPCNT|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|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",
272a84b1 103 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuSVME|CpuAES|CpuPCLMUL|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",
272a84b1 107 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME" },
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",
272a84b1 141 "CPU_SSE4_1_FLAGS|CpuSSE4_2|CpuPOPCNT" },
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" },
272a84b1
L
184 { "CPU_POPCNT_FLAGS",
185 "CpuPOPCNT" },
42164a71
L
186 { "CPU_HLE_FLAGS",
187 "CpuHLE" },
188 { "CPU_RTM_FLAGS",
189 "CpuRTM" },
6c30d220
L
190 { "CPU_INVPCID_FLAGS",
191 "CpuINVPCID" },
8729a6f6
L
192 { "CPU_VMFUNC_FLAGS",
193 "CpuVMFUNC" },
40fb9820 194 { "CPU_3DNOW_FLAGS",
1848e567 195 "CPU_MMX_FLAGS|Cpu3dnow" },
40fb9820 196 { "CPU_3DNOWA_FLAGS",
1848e567 197 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
40fb9820
L
198 { "CPU_PADLOCK_FLAGS",
199 "CpuPadLock" },
200 { "CPU_SVME_FLAGS",
201 "CpuSVME" },
202 { "CPU_SSE4A_FLAGS",
1848e567 203 "CPU_SSE3_FLAGS|CpuSSE4a" },
40fb9820 204 { "CPU_ABM_FLAGS",
272a84b1 205 "CpuLZCNT|CpuPOPCNT" },
c0f3af97 206 { "CPU_AVX_FLAGS",
59ef5df4 207 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
6c30d220 208 { "CPU_AVX2_FLAGS",
1848e567 209 "CPU_AVX_FLAGS|CpuAVX2" },
43234a1e 210 { "CPU_AVX512F_FLAGS",
e951d5ca 211 "CPU_AVX2_FLAGS|CpuAVX512F" },
43234a1e 212 { "CPU_AVX512CD_FLAGS",
1848e567 213 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
43234a1e 214 { "CPU_AVX512ER_FLAGS",
1848e567 215 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
43234a1e 216 { "CPU_AVX512PF_FLAGS",
1848e567 217 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
f3ad7637 218 { "CPU_AVX512DQ_FLAGS",
1848e567 219 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
f3ad7637 220 { "CPU_AVX512BW_FLAGS",
1848e567 221 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
f3ad7637 222 { "CPU_AVX512VL_FLAGS",
6e041cf4 223 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
f3ad7637 224 { "CPU_AVX512IFMA_FLAGS",
1848e567 225 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
f3ad7637 226 { "CPU_AVX512VBMI_FLAGS",
1848e567 227 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
920d2ddc
IT
228 { "CPU_AVX512_4FMAPS_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
47acf0bd
IT
230 { "CPU_AVX512_4VNNIW_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
620214f7
IT
232 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
53467f57
IT
234 { "CPU_AVX512_VBMI2_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
8cfcb765
IT
236 { "CPU_AVX512_VNNI_FLAGS",
237 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
ee6872be
IT
238 { "CPU_AVX512_BITALG_FLAGS",
239 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
d6aab7a1
XG
240 { "CPU_AVX512_BF16_FLAGS",
241 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
8a9036a4
L
242 { "CPU_L1OM_FLAGS",
243 "unknown" },
7a9068fe
L
244 { "CPU_K1OM_FLAGS",
245 "unknown" },
7b6d09fb
L
246 { "CPU_IAMCU_FLAGS",
247 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
e2e1fcde
L
248 { "CPU_ADX_FLAGS",
249 "CpuADX" },
250 { "CPU_RDSEED_FLAGS",
251 "CpuRdSeed" },
252 { "CPU_PRFCHW_FLAGS",
253 "CpuPRFCHW" },
5c111e37
L
254 { "CPU_SMAP_FLAGS",
255 "CpuSMAP" },
7e8b059b 256 { "CPU_MPX_FLAGS",
59ef5df4 257 "CPU_XSAVE_FLAGS|CpuMPX" },
a0046408 258 { "CPU_SHA_FLAGS",
1848e567 259 "CPU_SSE2_FLAGS|CpuSHA" },
963f3586
IT
260 { "CPU_CLFLUSHOPT_FLAGS",
261 "CpuClflushOpt" },
262 { "CPU_XSAVES_FLAGS",
1848e567 263 "CPU_XSAVE_FLAGS|CpuXSAVES" },
963f3586 264 { "CPU_XSAVEC_FLAGS",
1848e567 265 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
dcf893b5
IT
266 { "CPU_PREFETCHWT1_FLAGS",
267 "CpuPREFETCHWT1" },
2cf200a4
IT
268 { "CPU_SE1_FLAGS",
269 "CpuSE1" },
c5e7287a
IT
270 { "CPU_CLWB_FLAGS",
271 "CpuCLWB" },
029f3522
GG
272 { "CPU_CLZERO_FLAGS",
273 "CpuCLZERO" },
9916071f
AP
274 { "CPU_MWAITX_FLAGS",
275 "CpuMWAITX" },
8eab4136 276 { "CPU_OSPKE_FLAGS",
59ef5df4 277 "CPU_XSAVE_FLAGS|CpuOSPKE" },
8bc52696 278 { "CPU_RDPID_FLAGS",
1848e567 279 "CpuRDPID" },
6b40c462
L
280 { "CPU_PTWRITE_FLAGS",
281 "CpuPTWRITE" },
d777820b
IT
282 { "CPU_IBT_FLAGS",
283 "CpuIBT" },
284 { "CPU_SHSTK_FLAGS",
285 "CpuSHSTK" },
48521003
IT
286 { "CPU_GFNI_FLAGS",
287 "CpuGFNI" },
8dcf1fad
IT
288 { "CPU_VAES_FLAGS",
289 "CpuVAES" },
ff1982d5
IT
290 { "CPU_VPCLMULQDQ_FLAGS",
291 "CpuVPCLMULQDQ" },
3233d7d0
IT
292 { "CPU_WBNOINVD_FLAGS",
293 "CpuWBNOINVD" },
be3a8dca
IT
294 { "CPU_PCONFIG_FLAGS",
295 "CpuPCONFIG" },
de89d0a3
IT
296 { "CPU_WAITPKG_FLAGS",
297 "CpuWAITPKG" },
c48935d7
IT
298 { "CPU_CLDEMOTE_FLAGS",
299 "CpuCLDEMOTE" },
c0a30a9f
L
300 { "CPU_MOVDIRI_FLAGS",
301 "CpuMOVDIRI" },
302 { "CPU_MOVDIR64B_FLAGS",
303 "CpuMOVDIR64B" },
5d79adc4
L
304 { "CPU_ENQCMD_FLAGS",
305 "CpuENQCMD" },
9186c494
L
306 { "CPU_AVX512_VP2INTERSECT_FLAGS",
307 "CpuAVX512_VP2INTERSECT" },
142861df
JB
308 { "CPU_RDPRU_FLAGS",
309 "CpuRDPRU" },
310 { "CPU_MCOMMIT_FLAGS",
311 "CpuMCOMMIT" },
a847e322
JB
312 { "CPU_SEV_ES_FLAGS",
313 "CpuSEV_ES" },
1848e567
L
314 { "CPU_ANY_X87_FLAGS",
315 "CPU_ANY_287_FLAGS|Cpu8087" },
316 { "CPU_ANY_287_FLAGS",
317 "CPU_ANY_387_FLAGS|Cpu287" },
318 { "CPU_ANY_387_FLAGS",
319 "CPU_ANY_687_FLAGS|Cpu387" },
320 { "CPU_ANY_687_FLAGS",
321 "Cpu687|CpuFISTTP" },
d871f3f4
L
322 { "CPU_ANY_CMOV_FLAGS",
323 "CpuCMOV" },
324 { "CPU_ANY_FXSR_FLAGS",
325 "CpuFXSR" },
1848e567
L
326 { "CPU_ANY_MMX_FLAGS",
327 "CPU_3DNOWA_FLAGS" },
328 { "CPU_ANY_SSE_FLAGS",
7deea9aa 329 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
1848e567
L
330 { "CPU_ANY_SSE2_FLAGS",
331 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
332 { "CPU_ANY_SSE3_FLAGS",
7deea9aa 333 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
1848e567
L
334 { "CPU_ANY_SSSE3_FLAGS",
335 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
336 { "CPU_ANY_SSE4_1_FLAGS",
337 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
338 { "CPU_ANY_SSE4_2_FLAGS",
339 "CpuSSE4_2" },
dabec65d 340 { "CPU_ANY_SSE4A_FLAGS",
ce504911 341 "CpuSSE4a" },
1848e567
L
342 { "CPU_ANY_AVX_FLAGS",
343 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
344 { "CPU_ANY_AVX2_FLAGS",
89199bb5 345 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
144b71e2 346 { "CPU_ANY_AVX512F_FLAGS",
9186c494 347 "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
348 { "CPU_ANY_AVX512CD_FLAGS",
349 "CpuAVX512CD" },
350 { "CPU_ANY_AVX512ER_FLAGS",
351 "CpuAVX512ER" },
352 { "CPU_ANY_AVX512PF_FLAGS",
353 "CpuAVX512PF" },
354 { "CPU_ANY_AVX512DQ_FLAGS",
355 "CpuAVX512DQ" },
356 { "CPU_ANY_AVX512BW_FLAGS",
357 "CpuAVX512BW" },
358 { "CPU_ANY_AVX512VL_FLAGS",
359 "CpuAVX512VL" },
360 { "CPU_ANY_AVX512IFMA_FLAGS",
361 "CpuAVX512IFMA" },
362 { "CPU_ANY_AVX512VBMI_FLAGS",
363 "CpuAVX512VBMI" },
920d2ddc
IT
364 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
365 "CpuAVX512_4FMAPS" },
47acf0bd
IT
366 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
367 "CpuAVX512_4VNNIW" },
620214f7
IT
368 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
369 "CpuAVX512_VPOPCNTDQ" },
d777820b
IT
370 { "CPU_ANY_IBT_FLAGS",
371 "CpuIBT" },
372 { "CPU_ANY_SHSTK_FLAGS",
373 "CpuSHSTK" },
53467f57
IT
374 { "CPU_ANY_AVX512_VBMI2_FLAGS",
375 "CpuAVX512_VBMI2" },
8cfcb765
IT
376 { "CPU_ANY_AVX512_VNNI_FLAGS",
377 "CpuAVX512_VNNI" },
ee6872be
IT
378 { "CPU_ANY_AVX512_BITALG_FLAGS",
379 "CpuAVX512_BITALG" },
d6aab7a1
XG
380 { "CPU_ANY_AVX512_BF16_FLAGS",
381 "CpuAVX512_BF16" },
c0a30a9f
L
382 { "CPU_ANY_MOVDIRI_FLAGS",
383 "CpuMOVDIRI" },
384 { "CPU_ANY_MOVDIR64B_FLAGS",
385 "CpuMOVDIR64B" },
5d79adc4
L
386 { "CPU_ANY_ENQCMD_FLAGS",
387 "CpuENQCMD" },
9186c494
L
388 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
389 "CpuAVX512_VP2INTERSECT" },
40fb9820
L
390};
391
8acd5377 392static initializer operand_type_init[] =
40fb9820
L
393{
394 { "OPERAND_TYPE_NONE",
395 "0" },
396 { "OPERAND_TYPE_REG8",
bab6aec1 397 "Class=Reg|Byte" },
40fb9820 398 { "OPERAND_TYPE_REG16",
bab6aec1 399 "Class=Reg|Word" },
40fb9820 400 { "OPERAND_TYPE_REG32",
bab6aec1 401 "Class=Reg|Dword" },
40fb9820 402 { "OPERAND_TYPE_REG64",
bab6aec1 403 "Class=Reg|Qword" },
40fb9820
L
404 { "OPERAND_TYPE_IMM1",
405 "Imm1" },
406 { "OPERAND_TYPE_IMM8",
407 "Imm8" },
408 { "OPERAND_TYPE_IMM8S",
409 "Imm8S" },
410 { "OPERAND_TYPE_IMM16",
411 "Imm16" },
412 { "OPERAND_TYPE_IMM32",
413 "Imm32" },
414 { "OPERAND_TYPE_IMM32S",
415 "Imm32S" },
416 { "OPERAND_TYPE_IMM64",
417 "Imm64" },
418 { "OPERAND_TYPE_BASEINDEX",
419 "BaseIndex" },
420 { "OPERAND_TYPE_DISP8",
421 "Disp8" },
422 { "OPERAND_TYPE_DISP16",
423 "Disp16" },
424 { "OPERAND_TYPE_DISP32",
425 "Disp32" },
426 { "OPERAND_TYPE_DISP32S",
427 "Disp32S" },
428 { "OPERAND_TYPE_DISP64",
429 "Disp64" },
430 { "OPERAND_TYPE_INOUTPORTREG",
75e5731b 431 "Instance=RegD|Word" },
40fb9820 432 { "OPERAND_TYPE_SHIFTCOUNT",
75e5731b 433 "Instance=RegC|Byte" },
40fb9820 434 { "OPERAND_TYPE_CONTROL",
4a5c67ed 435 "Class=RegCR" },
40fb9820 436 { "OPERAND_TYPE_TEST",
4a5c67ed 437 "Class=RegTR" },
40fb9820 438 { "OPERAND_TYPE_DEBUG",
4a5c67ed 439 "Class=RegDR" },
40fb9820 440 { "OPERAND_TYPE_FLOATREG",
bab6aec1 441 "Class=Reg|Tbyte" },
40fb9820 442 { "OPERAND_TYPE_FLOATACC",
75e5731b 443 "Instance=Accum|Tbyte" },
21df382b 444 { "OPERAND_TYPE_SREG",
00cee14f 445 "Class=SReg" },
40fb9820 446 { "OPERAND_TYPE_REGMMX",
3528c362 447 "Class=RegMMX" },
40fb9820 448 { "OPERAND_TYPE_REGXMM",
3528c362 449 "Class=RegSIMD|Xmmword" },
1508bbf5 450 { "OPERAND_TYPE_REGYMM",
3528c362 451 "Class=RegSIMD|Ymmword" },
1508bbf5 452 { "OPERAND_TYPE_REGZMM",
3528c362 453 "Class=RegSIMD|Zmmword" },
43234a1e 454 { "OPERAND_TYPE_REGMASK",
f74a6307
JB
455 "Class=RegMask" },
456 { "OPERAND_TYPE_REGBND",
457 "Class=RegBND" },
2c703856 458 { "OPERAND_TYPE_ACC8",
75e5731b 459 "Instance=Accum|Byte" },
2c703856 460 { "OPERAND_TYPE_ACC16",
75e5731b 461 "Instance=Accum|Word" },
40fb9820 462 { "OPERAND_TYPE_ACC32",
75e5731b 463 "Instance=Accum|Dword" },
40fb9820 464 { "OPERAND_TYPE_ACC64",
75e5731b 465 "Instance=Accum|Qword" },
40fb9820
L
466 { "OPERAND_TYPE_DISP16_32",
467 "Disp16|Disp32" },
468 { "OPERAND_TYPE_ANYDISP",
469 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
470 { "OPERAND_TYPE_IMM16_32",
471 "Imm16|Imm32" },
472 { "OPERAND_TYPE_IMM16_32S",
473 "Imm16|Imm32S" },
474 { "OPERAND_TYPE_IMM16_32_32S",
475 "Imm16|Imm32|Imm32S" },
2f81ff92
L
476 { "OPERAND_TYPE_IMM32_64",
477 "Imm32|Imm64" },
40fb9820
L
478 { "OPERAND_TYPE_IMM32_32S_DISP32",
479 "Imm32|Imm32S|Disp32" },
480 { "OPERAND_TYPE_IMM64_DISP64",
481 "Imm64|Disp64" },
482 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
483 "Imm32|Imm32S|Imm64|Disp32" },
484 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
485 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
bab6aec1
JB
486 { "OPERAND_TYPE_ANYIMM",
487 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
40fb9820
L
488};
489
490typedef struct bitfield
491{
492 int position;
493 int value;
494 const char *name;
495} bitfield;
496
497#define BITFIELD(n) { n, 0, #n }
498
499static bitfield cpu_flags[] =
500{
501 BITFIELD (Cpu186),
502 BITFIELD (Cpu286),
503 BITFIELD (Cpu386),
504 BITFIELD (Cpu486),
505 BITFIELD (Cpu586),
506 BITFIELD (Cpu686),
d871f3f4
L
507 BITFIELD (CpuCMOV),
508 BITFIELD (CpuFXSR),
bd5295b2 509 BITFIELD (CpuClflush),
22109423 510 BITFIELD (CpuNop),
bd5295b2 511 BITFIELD (CpuSYSCALL),
309d3373
JB
512 BITFIELD (Cpu8087),
513 BITFIELD (Cpu287),
514 BITFIELD (Cpu387),
515 BITFIELD (Cpu687),
516 BITFIELD (CpuFISTTP),
40fb9820 517 BITFIELD (CpuMMX),
40fb9820
L
518 BITFIELD (CpuSSE),
519 BITFIELD (CpuSSE2),
520 BITFIELD (CpuSSE3),
521 BITFIELD (CpuSSSE3),
522 BITFIELD (CpuSSE4_1),
523 BITFIELD (CpuSSE4_2),
c0f3af97 524 BITFIELD (CpuAVX),
6c30d220 525 BITFIELD (CpuAVX2),
43234a1e
L
526 BITFIELD (CpuAVX512F),
527 BITFIELD (CpuAVX512CD),
528 BITFIELD (CpuAVX512ER),
529 BITFIELD (CpuAVX512PF),
b28d1bda 530 BITFIELD (CpuAVX512VL),
90a915bf 531 BITFIELD (CpuAVX512DQ),
1ba585e8 532 BITFIELD (CpuAVX512BW),
8a9036a4 533 BITFIELD (CpuL1OM),
7a9068fe 534 BITFIELD (CpuK1OM),
7b6d09fb 535 BITFIELD (CpuIAMCU),
40fb9820
L
536 BITFIELD (CpuSSE4a),
537 BITFIELD (Cpu3dnow),
538 BITFIELD (Cpu3dnowA),
539 BITFIELD (CpuPadLock),
540 BITFIELD (CpuSVME),
541 BITFIELD (CpuVMX),
47dd174c 542 BITFIELD (CpuSMX),
475a2301 543 BITFIELD (CpuXsave),
c7b8aa3a 544 BITFIELD (CpuXsaveopt),
c0f3af97 545 BITFIELD (CpuAES),
594ab6a3 546 BITFIELD (CpuPCLMUL),
c0f3af97 547 BITFIELD (CpuFMA),
f88c9eb0 548 BITFIELD (CpuFMA4),
5dd85c99 549 BITFIELD (CpuXOP),
f88c9eb0 550 BITFIELD (CpuLWP),
f12dc422 551 BITFIELD (CpuBMI),
2a2a0f38 552 BITFIELD (CpuTBM),
c0f3af97 553 BITFIELD (CpuLM),
f1f8f695 554 BITFIELD (CpuMovbe),
60aa667e 555 BITFIELD (CpuCX16),
f1f8f695 556 BITFIELD (CpuEPT),
1b7f3fb0 557 BITFIELD (CpuRdtscp),
c7b8aa3a
L
558 BITFIELD (CpuFSGSBase),
559 BITFIELD (CpuRdRnd),
560 BITFIELD (CpuF16C),
6c30d220
L
561 BITFIELD (CpuBMI2),
562 BITFIELD (CpuLZCNT),
272a84b1 563 BITFIELD (CpuPOPCNT),
42164a71
L
564 BITFIELD (CpuHLE),
565 BITFIELD (CpuRTM),
6c30d220 566 BITFIELD (CpuINVPCID),
8729a6f6 567 BITFIELD (CpuVMFUNC),
e2e1fcde
L
568 BITFIELD (CpuRDSEED),
569 BITFIELD (CpuADX),
570 BITFIELD (CpuPRFCHW),
5c111e37 571 BITFIELD (CpuSMAP),
a0046408 572 BITFIELD (CpuSHA),
963f3586
IT
573 BITFIELD (CpuClflushOpt),
574 BITFIELD (CpuXSAVES),
575 BITFIELD (CpuXSAVEC),
dcf893b5 576 BITFIELD (CpuPREFETCHWT1),
2cf200a4 577 BITFIELD (CpuSE1),
c5e7287a 578 BITFIELD (CpuCLWB),
40fb9820
L
579 BITFIELD (Cpu64),
580 BITFIELD (CpuNo64),
7e8b059b 581 BITFIELD (CpuMPX),
2cc1b5aa 582 BITFIELD (CpuAVX512IFMA),
14f195c9 583 BITFIELD (CpuAVX512VBMI),
920d2ddc 584 BITFIELD (CpuAVX512_4FMAPS),
47acf0bd 585 BITFIELD (CpuAVX512_4VNNIW),
620214f7 586 BITFIELD (CpuAVX512_VPOPCNTDQ),
53467f57 587 BITFIELD (CpuAVX512_VBMI2),
8cfcb765 588 BITFIELD (CpuAVX512_VNNI),
ee6872be 589 BITFIELD (CpuAVX512_BITALG),
d6aab7a1 590 BITFIELD (CpuAVX512_BF16),
9186c494 591 BITFIELD (CpuAVX512_VP2INTERSECT),
9916071f 592 BITFIELD (CpuMWAITX),
029f3522 593 BITFIELD (CpuCLZERO),
8eab4136 594 BITFIELD (CpuOSPKE),
8bc52696 595 BITFIELD (CpuRDPID),
6b40c462 596 BITFIELD (CpuPTWRITE),
d777820b
IT
597 BITFIELD (CpuIBT),
598 BITFIELD (CpuSHSTK),
48521003 599 BITFIELD (CpuGFNI),
8dcf1fad 600 BITFIELD (CpuVAES),
ff1982d5 601 BITFIELD (CpuVPCLMULQDQ),
3233d7d0 602 BITFIELD (CpuWBNOINVD),
be3a8dca 603 BITFIELD (CpuPCONFIG),
de89d0a3 604 BITFIELD (CpuWAITPKG),
c48935d7 605 BITFIELD (CpuCLDEMOTE),
c0a30a9f
L
606 BITFIELD (CpuMOVDIRI),
607 BITFIELD (CpuMOVDIR64B),
5d79adc4 608 BITFIELD (CpuENQCMD),
142861df
JB
609 BITFIELD (CpuRDPRU),
610 BITFIELD (CpuMCOMMIT),
a847e322 611 BITFIELD (CpuSEV_ES),
40fb9820
L
612#ifdef CpuUnused
613 BITFIELD (CpuUnused),
614#endif
615};
616
617static bitfield opcode_modifiers[] =
618{
619 BITFIELD (D),
620 BITFIELD (W),
86fa6981 621 BITFIELD (Load),
40fb9820 622 BITFIELD (Modrm),
40fb9820 623 BITFIELD (Jump),
40fb9820
L
624 BITFIELD (FloatMF),
625 BITFIELD (FloatR),
673fe0f0 626 BITFIELD (Size),
56ffb741 627 BITFIELD (CheckRegSize),
3cd7f3e3 628 BITFIELD (MnemonicSize),
601e8564 629 BITFIELD (Anysize),
40fb9820
L
630 BITFIELD (No_bSuf),
631 BITFIELD (No_wSuf),
632 BITFIELD (No_lSuf),
633 BITFIELD (No_sSuf),
634 BITFIELD (No_qSuf),
7ce189b3 635 BITFIELD (No_ldSuf),
40fb9820
L
636 BITFIELD (FWait),
637 BITFIELD (IsString),
dfd69174 638 BITFIELD (RegMem),
7e8b059b 639 BITFIELD (BNDPrefixOk),
04ef582a 640 BITFIELD (NoTrackPrefixOk),
c32fa91d 641 BITFIELD (IsLockable),
40fb9820 642 BITFIELD (RegKludge),
c0f3af97 643 BITFIELD (Implicit1stXmm0),
29c048b6 644 BITFIELD (RepPrefixOk),
42164a71 645 BITFIELD (HLEPrefixOk),
ca61edf2
L
646 BITFIELD (ToDword),
647 BITFIELD (ToQword),
75c0a438 648 BITFIELD (AddrPrefixOpReg),
40fb9820
L
649 BITFIELD (IsPrefix),
650 BITFIELD (ImmExt),
651 BITFIELD (NoRex64),
40fb9820 652 BITFIELD (Ugh),
c0f3af97 653 BITFIELD (Vex),
2426c15f 654 BITFIELD (VexVVVV),
1ef99a7b 655 BITFIELD (VexW),
7f399153 656 BITFIELD (VexOpcode),
8cd7925b 657 BITFIELD (VexSources),
6c30d220 658 BITFIELD (VecSIB),
c0f3af97 659 BITFIELD (SSE2AVX),
81f8a913 660 BITFIELD (NoAVX),
43234a1e
L
661 BITFIELD (EVex),
662 BITFIELD (Masking),
43234a1e
L
663 BITFIELD (Broadcast),
664 BITFIELD (StaticRounding),
665 BITFIELD (SAE),
666 BITFIELD (Disp8MemShift),
667 BITFIELD (NoDefMask),
920d2ddc 668 BITFIELD (ImplicitQuadGroup),
b6f8c7c4 669 BITFIELD (Optimize),
1efbbeb4 670 BITFIELD (ATTMnemonic),
e1d4d893 671 BITFIELD (ATTSyntax),
5c07affc 672 BITFIELD (IntelSyntax),
4b5aaf5f 673 BITFIELD (ISA64),
40fb9820
L
674};
675
bab6aec1
JB
676#define CLASS(n) #n, n
677
678static const struct {
679 const char *name;
680 enum operand_class value;
681} operand_classes[] = {
682 CLASS (Reg),
00cee14f 683 CLASS (SReg),
4a5c67ed
JB
684 CLASS (RegCR),
685 CLASS (RegDR),
686 CLASS (RegTR),
3528c362
JB
687 CLASS (RegMMX),
688 CLASS (RegSIMD),
f74a6307
JB
689 CLASS (RegMask),
690 CLASS (RegBND),
bab6aec1
JB
691};
692
693#undef CLASS
694
75e5731b
JB
695#define INSTANCE(n) #n, n
696
697static const struct {
698 const char *name;
699 enum operand_instance value;
700} operand_instances[] = {
701 INSTANCE (Accum),
702 INSTANCE (RegC),
703 INSTANCE (RegD),
474da251 704 INSTANCE (RegB),
75e5731b
JB
705};
706
707#undef INSTANCE
708
40fb9820
L
709static bitfield operand_types[] =
710{
94ff3a50 711 BITFIELD (Imm1),
40fb9820
L
712 BITFIELD (Imm8),
713 BITFIELD (Imm8S),
714 BITFIELD (Imm16),
715 BITFIELD (Imm32),
716 BITFIELD (Imm32S),
717 BITFIELD (Imm64),
40fb9820
L
718 BITFIELD (BaseIndex),
719 BITFIELD (Disp8),
720 BITFIELD (Disp16),
721 BITFIELD (Disp32),
722 BITFIELD (Disp32S),
723 BITFIELD (Disp64),
7d5e4556
L
724 BITFIELD (Byte),
725 BITFIELD (Word),
726 BITFIELD (Dword),
727 BITFIELD (Fword),
728 BITFIELD (Qword),
729 BITFIELD (Tbyte),
730 BITFIELD (Xmmword),
c0f3af97 731 BITFIELD (Ymmword),
43234a1e 732 BITFIELD (Zmmword),
7d5e4556 733 BITFIELD (Unspecified),
40fb9820
L
734#ifdef OTUnused
735 BITFIELD (OTUnused),
736#endif
737};
738
3d4d5afa 739static const char *filename;
7ac20022
JB
740static i386_cpu_flags active_cpu_flags;
741static int active_isstring;
3d4d5afa 742
4c4898e8
JB
743struct template_arg {
744 const struct template_arg *next;
745 const char *val;
746};
747
748struct template_instance {
749 const struct template_instance *next;
750 const char *name;
751 const struct template_arg *args;
752};
753
754struct template_param {
755 const struct template_param *next;
756 const char *name;
757};
758
759struct template {
760 const struct template *next;
761 const char *name;
762 const struct template_instance *instances;
763 const struct template_param *params;
764};
765
766static const struct template *templates;
767
40fb9820
L
768static int
769compare (const void *x, const void *y)
770{
771 const bitfield *xp = (const bitfield *) x;
772 const bitfield *yp = (const bitfield *) y;
773 return xp->position - yp->position;
774}
775
40b8e679
L
776static void
777fail (const char *message, ...)
778{
779 va_list args;
29c048b6 780
40b8e679 781 va_start (args, message);
a6743a54 782 fprintf (stderr, _("%s: error: "), program_name);
40b8e679
L
783 vfprintf (stderr, message, args);
784 va_end (args);
785 xexit (1);
786}
787
72ffa0fb
L
788static void
789process_copyright (FILE *fp)
790{
791 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
b3adc24a 792/* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
72ffa0fb
L
793\n\
794 This file is part of the GNU opcodes library.\n\
795\n\
796 This library is free software; you can redistribute it and/or modify\n\
797 it under the terms of the GNU General Public License as published by\n\
798 the Free Software Foundation; either version 3, or (at your option)\n\
799 any later version.\n\
800\n\
801 It is distributed in the hope that it will be useful, but WITHOUT\n\
802 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
803 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
804 License for more details.\n\
805\n\
806 You should have received a copy of the GNU General Public License\n\
807 along with this program; if not, write to the Free Software\n\
808 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
809 MA 02110-1301, USA. */\n");
810}
811
40b8e679
L
812/* Remove leading white spaces. */
813
814static char *
815remove_leading_whitespaces (char *str)
816{
817 while (ISSPACE (*str))
818 str++;
819 return str;
820}
821
822/* Remove trailing white spaces. */
823
824static void
825remove_trailing_whitespaces (char *str)
826{
827 size_t last = strlen (str);
828
829 if (last == 0)
830 return;
831
832 do
833 {
834 last--;
835 if (ISSPACE (str [last]))
836 str[last] = '\0';
837 else
838 break;
839 }
840 while (last != 0);
841}
842
93b1ec2c 843/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
844 pointer to the one after it. */
845
846static char *
c587b3f9 847next_field (char *str, char sep, char **next, char *last)
40b8e679
L
848{
849 char *p;
850
851 p = remove_leading_whitespaces (str);
93b1ec2c 852 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
853
854 *str = '\0';
855 remove_trailing_whitespaces (p);
856
29c048b6 857 *next = str + 1;
40b8e679 858
c587b3f9
L
859 if (p >= last)
860 abort ();
861
40b8e679
L
862 return p;
863}
864
1848e567
L
865static void set_bitfield (char *, bitfield *, int, unsigned int, int);
866
867static int
3cc17af5
JB
868set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
869 int lineno)
1848e567
L
870{
871 char *str, *next, *last;
872 unsigned int i;
873
874 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
875 if (strcmp (cpu_flag_init[i].name, f) == 0)
876 {
877 /* Turn on selective bits. */
878 char *init = xstrdup (cpu_flag_init[i].init);
879 last = init + strlen (init);
880 for (next = init; next && next < last; )
881 {
882 str = next_field (next, '|', &next, last);
883 if (str)
884 set_bitfield (str, array, 1, size, lineno);
885 }
886 free (init);
887 return 0;
888 }
889
890 return -1;
891}
892
40fb9820 893static void
1848e567 894set_bitfield (char *f, bitfield *array, int value,
8a9036a4 895 unsigned int size, int lineno)
40fb9820
L
896{
897 unsigned int i;
898
3677e4c1
JB
899 /* Ignore empty fields; they may result from template expansions. */
900 if (*f == '\0')
901 return;
902
309d3373
JB
903 if (strcmp (f, "CpuFP") == 0)
904 {
8a9036a4
L
905 set_bitfield("Cpu387", array, value, size, lineno);
906 set_bitfield("Cpu287", array, value, size, lineno);
309d3373
JB
907 f = "Cpu8087";
908 }
909 else if (strcmp (f, "Mmword") == 0)
7d5e4556
L
910 f= "Qword";
911 else if (strcmp (f, "Oword") == 0)
912 f= "Xmmword";
40fb9820
L
913
914 for (i = 0; i < size; i++)
915 if (strcasecmp (array[i].name, f) == 0)
916 {
8a9036a4 917 array[i].value = value;
40fb9820
L
918 return;
919 }
920
2bf05e57
L
921 if (value)
922 {
923 const char *v = strchr (f, '=');
924
925 if (v)
926 {
927 size_t n = v - f;
928 char *end;
929
930 for (i = 0; i < size; i++)
931 if (strncasecmp (array[i].name, f, n) == 0)
932 {
933 value = strtol (v + 1, &end, 0);
934 if (*end == '\0')
935 {
936 array[i].value = value;
937 return;
938 }
939 break;
940 }
941 }
942 }
943
3cc17af5
JB
944 /* Handle CPU_XXX_FLAGS. */
945 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1848e567
L
946 return;
947
bd5295b2 948 if (lineno != -1)
a6743a54 949 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
bd5295b2 950 else
a6743a54 951 fail (_("unknown bitfield: %s\n"), f);
40fb9820
L
952}
953
954static void
955output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
956 int macro, const char *comma, const char *indent)
957{
958 unsigned int i;
959
7ac20022
JB
960 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
961
40fb9820
L
962 fprintf (table, "%s{ { ", indent);
963
964 for (i = 0; i < size - 1; i++)
965 {
10632b79
L
966 if (((i + 1) % 20) != 0)
967 fprintf (table, "%d, ", flags[i].value);
968 else
969 fprintf (table, "%d,", flags[i].value);
40fb9820
L
970 if (((i + 1) % 20) == 0)
971 {
972 /* We need \\ for macro. */
973 if (macro)
974 fprintf (table, " \\\n %s", indent);
975 else
976 fprintf (table, "\n %s", indent);
977 }
7ac20022
JB
978 if (flags[i].value)
979 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
40fb9820
L
980 }
981
982 fprintf (table, "%d } }%s\n", flags[i].value, comma);
983}
984
985static void
986process_i386_cpu_flag (FILE *table, char *flag, int macro,
bd5295b2
L
987 const char *comma, const char *indent,
988 int lineno)
40fb9820
L
989{
990 char *str, *next, *last;
8a9036a4 991 unsigned int i;
40fb9820
L
992 bitfield flags [ARRAY_SIZE (cpu_flags)];
993
994 /* Copy the default cpu flags. */
995 memcpy (flags, cpu_flags, sizeof (cpu_flags));
996
997 if (strcasecmp (flag, "unknown") == 0)
998 {
40fb9820 999 /* We turn on everything except for cpu64 in case of
8a9036a4
L
1000 CPU_UNKNOWN_FLAGS. */
1001 for (i = 0; i < ARRAY_SIZE (flags); i++)
1002 if (flags[i].position != Cpu64)
1003 flags[i].value = 1;
1004 }
1005 else if (flag[0] == '~')
1006 {
1007 last = flag + strlen (flag);
1008
1009 if (flag[1] == '(')
1010 {
1011 last -= 1;
1012 next = flag + 2;
1013 if (*last != ')')
a6743a54 1014 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
8a9036a4
L
1015 lineno, flag);
1016 *last = '\0';
1017 }
1018 else
1019 next = flag + 1;
1020
1021 /* First we turn on everything except for cpu64. */
40fb9820
L
1022 for (i = 0; i < ARRAY_SIZE (flags); i++)
1023 if (flags[i].position != Cpu64)
1024 flags[i].value = 1;
8a9036a4
L
1025
1026 /* Turn off selective bits. */
1027 for (; next && next < last; )
1028 {
1029 str = next_field (next, '|', &next, last);
1030 if (str)
1031 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1032 }
40fb9820
L
1033 }
1034 else if (strcmp (flag, "0"))
1035 {
8a9036a4 1036 /* Turn on selective bits. */
40fb9820
L
1037 last = flag + strlen (flag);
1038 for (next = flag; next && next < last; )
1039 {
c587b3f9 1040 str = next_field (next, '|', &next, last);
40fb9820 1041 if (str)
8a9036a4 1042 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
40fb9820
L
1043 }
1044 }
1045
1046 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1047 comma, indent);
1048}
1049
1050static void
1051output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1052{
1053 unsigned int i;
1054
1055 fprintf (table, " { ");
1056
1057 for (i = 0; i < size - 1; i++)
1058 {
10632b79
L
1059 if (((i + 1) % 20) != 0)
1060 fprintf (table, "%d, ", modifier[i].value);
1061 else
1062 fprintf (table, "%d,", modifier[i].value);
40fb9820
L
1063 if (((i + 1) % 20) == 0)
1064 fprintf (table, "\n ");
1065 }
1066
1067 fprintf (table, "%d },\n", modifier[i].value);
1068}
1069
4a1b91ea
L
1070static int
1071adjust_broadcast_modifier (char **opnd)
1072{
1073 char *str, *next, *last, *op;
1074 int bcst_type = INT_MAX;
1075
1076 /* Skip the immediate operand. */
1077 op = opnd[0];
1078 if (strcasecmp(op, "Imm8") == 0)
1079 op = opnd[1];
1080
1081 op = xstrdup (op);
1082 last = op + strlen (op);
1083 for (next = op; next && next < last; )
1084 {
1085 str = next_field (next, '|', &next, last);
1086 if (str)
1087 {
1088 if (strcasecmp(str, "Byte") == 0)
1089 {
1090 /* The smalest broadcast type, no need to check
1091 further. */
1092 bcst_type = BYTE_BROADCAST;
1093 break;
1094 }
1095 else if (strcasecmp(str, "Word") == 0)
1096 {
1097 if (bcst_type > WORD_BROADCAST)
1098 bcst_type = WORD_BROADCAST;
1099 }
1100 else if (strcasecmp(str, "Dword") == 0)
1101 {
1102 if (bcst_type > DWORD_BROADCAST)
1103 bcst_type = DWORD_BROADCAST;
1104 }
1105 else if (strcasecmp(str, "Qword") == 0)
1106 {
1107 if (bcst_type > QWORD_BROADCAST)
1108 bcst_type = QWORD_BROADCAST;
1109 }
1110 }
1111 }
1112 free (op);
1113
1114 if (bcst_type == INT_MAX)
1115 fail (_("unknown broadcast operand: %s\n"), op);
1116
1117 return bcst_type;
1118}
1119
40fb9820 1120static void
4a1b91ea 1121process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
40fb9820
L
1122{
1123 char *str, *next, *last;
1124 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1125
7ac20022
JB
1126 active_isstring = 0;
1127
40fb9820
L
1128 /* Copy the default opcode modifier. */
1129 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1130
1131 if (strcmp (mod, "0"))
1132 {
507916b8
JB
1133 unsigned int have_w = 0, bwlq_suf = 0xf;
1134
40fb9820
L
1135 last = mod + strlen (mod);
1136 for (next = mod; next && next < last; )
1137 {
c587b3f9 1138 str = next_field (next, '|', &next, last);
40fb9820 1139 if (str)
7ac20022 1140 {
4a1b91ea
L
1141 int val = 1;
1142 if (strcasecmp(str, "Broadcast") == 0)
1143 val = adjust_broadcast_modifier (opnd);
1144 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
8a9036a4 1145 lineno);
7ac20022
JB
1146 if (strcasecmp(str, "IsString") == 0)
1147 active_isstring = 1;
507916b8
JB
1148
1149 if (strcasecmp(str, "W") == 0)
1150 have_w = 1;
1151
1152 if (strcasecmp(str, "No_bSuf") == 0)
1153 bwlq_suf &= ~1;
1154 if (strcasecmp(str, "No_wSuf") == 0)
1155 bwlq_suf &= ~2;
1156 if (strcasecmp(str, "No_lSuf") == 0)
1157 bwlq_suf &= ~4;
1158 if (strcasecmp(str, "No_qSuf") == 0)
1159 bwlq_suf &= ~8;
7ac20022 1160 }
40fb9820 1161 }
507916b8
JB
1162
1163 if (have_w && !bwlq_suf)
1164 fail ("%s: %d: stray W modifier\n", filename, lineno);
1165 if (have_w && !(bwlq_suf & 1))
1166 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1167 filename, lineno);
1168 if (have_w && !(bwlq_suf & ~1))
1169 fprintf (stderr,
1170 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1171 filename, lineno);
40fb9820
L
1172 }
1173 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1174}
1175
7ac20022
JB
1176enum stage {
1177 stage_macros,
1178 stage_opcodes,
1179 stage_registers,
1180};
1181
40fb9820 1182static void
bab6aec1 1183output_operand_type (FILE *table, enum operand_class class,
75e5731b 1184 enum operand_instance instance,
bab6aec1 1185 const bitfield *types, unsigned int size,
7ac20022 1186 enum stage stage, const char *indent)
40fb9820
L
1187{
1188 unsigned int i;
1189
75e5731b 1190 fprintf (table, "{ { %d, %d, ", class, instance);
40fb9820
L
1191
1192 for (i = 0; i < size - 1; i++)
1193 {
75e5731b 1194 if (((i + 3) % 20) != 0)
10632b79
L
1195 fprintf (table, "%d, ", types[i].value);
1196 else
1197 fprintf (table, "%d,", types[i].value);
75e5731b 1198 if (((i + 3) % 20) == 0)
40fb9820
L
1199 {
1200 /* We need \\ for macro. */
7ac20022 1201 if (stage == stage_macros)
10632b79 1202 fprintf (table, " \\\n%s", indent);
40fb9820
L
1203 else
1204 fprintf (table, "\n%s", indent);
1205 }
1206 }
1207
1208 fprintf (table, "%d } }", types[i].value);
1209}
1210
1211static void
7ac20022 1212process_i386_operand_type (FILE *table, char *op, enum stage stage,
bd5295b2 1213 const char *indent, int lineno)
40fb9820
L
1214{
1215 char *str, *next, *last;
bab6aec1 1216 enum operand_class class = ClassNone;
75e5731b 1217 enum operand_instance instance = InstanceNone;
40fb9820
L
1218 bitfield types [ARRAY_SIZE (operand_types)];
1219
1220 /* Copy the default operand type. */
1221 memcpy (types, operand_types, sizeof (types));
1222
1223 if (strcmp (op, "0"))
1224 {
7ac20022
JB
1225 int baseindex = 0;
1226
40fb9820
L
1227 last = op + strlen (op);
1228 for (next = op; next && next < last; )
1229 {
c587b3f9 1230 str = next_field (next, '|', &next, last);
bab6aec1
JB
1231 if (str)
1232 {
1233 unsigned int i;
1234
1235 if (!strncmp(str, "Class=", 6))
1236 {
1237 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1238 if (!strcmp(str + 6, operand_classes[i].name))
1239 {
1240 class = operand_classes[i].value;
1241 str = NULL;
1242 break;
1243 }
1244 }
75e5731b
JB
1245
1246 if (str && !strncmp(str, "Instance=", 9))
1247 {
1248 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1249 if (!strcmp(str + 9, operand_instances[i].name))
1250 {
1251 instance = operand_instances[i].value;
1252 str = NULL;
1253 break;
1254 }
1255 }
bab6aec1 1256 }
40fb9820 1257 if (str)
7ac20022
JB
1258 {
1259 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1260 if (strcasecmp(str, "BaseIndex") == 0)
1261 baseindex = 1;
1262 }
1263 }
1264
1265 if (stage == stage_opcodes && baseindex && !active_isstring)
1266 {
1267 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1268 if (!active_cpu_flags.bitfield.cpu64
1269 && !active_cpu_flags.bitfield.cpumpx)
1270 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
48bcea9f
JB
1271 if (!active_cpu_flags.bitfield.cpu64)
1272 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
7ac20022
JB
1273 if (!active_cpu_flags.bitfield.cpuno64)
1274 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
1275 }
1276 }
75e5731b
JB
1277 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1278 stage, indent);
40fb9820
L
1279}
1280
c587b3f9
L
1281static void
1282output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 1283 char *last, int lineno)
c587b3f9
L
1284{
1285 unsigned int i;
1286 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1287 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1288
1289 /* Find number of operands. */
1290 operands = next_field (str, ',', &str, last);
1291
1292 /* Find base_opcode. */
1293 base_opcode = next_field (str, ',', &str, last);
1294
1295 /* Find extension_opcode. */
1296 extension_opcode = next_field (str, ',', &str, last);
1297
1298 /* Find opcode_length. */
1299 opcode_length = next_field (str, ',', &str, last);
1300
1301 /* Find cpu_flags. */
1302 cpu_flags = next_field (str, ',', &str, last);
1303
1304 /* Find opcode_modifier. */
1305 opcode_modifier = next_field (str, ',', &str, last);
1306
1307 /* Remove the first {. */
1308 str = remove_leading_whitespaces (str);
1309 if (*str != '{')
1310 abort ();
1311 str = remove_leading_whitespaces (str + 1);
1312
1313 i = strlen (str);
1314
1315 /* There are at least "X}". */
1316 if (i < 2)
1317 abort ();
1318
1319 /* Remove trailing white spaces and }. */
1320 do
1321 {
1322 i--;
1323 if (ISSPACE (str[i]) || str[i] == '}')
1324 str[i] = '\0';
1325 else
1326 break;
1327 }
1328 while (i != 0);
1329
1330 last = str + i;
1331
1332 /* Find operand_types. */
1333 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1334 {
1335 if (str >= last)
1336 {
1337 operand_types [i] = NULL;
1338 break;
1339 }
1340
1341 operand_types [i] = next_field (str, ',', &str, last);
1342 if (*operand_types[i] == '0')
1343 {
1344 if (i != 0)
1345 operand_types[i] = NULL;
1346 break;
1347 }
1348 }
1349
1350 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
a2cebd03 1351 name, base_opcode, extension_opcode, opcode_length, operands);
c587b3f9 1352
bd5295b2 1353 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
c587b3f9 1354
4a1b91ea 1355 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
c587b3f9
L
1356
1357 fprintf (table, " { ");
1358
1359 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1360 {
1361 if (operand_types[i] == NULL || *operand_types[i] == '0')
1362 {
1363 if (i == 0)
7ac20022
JB
1364 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1365 lineno);
c587b3f9
L
1366 break;
1367 }
1368
1369 if (i != 0)
1370 fprintf (table, ",\n ");
1371
7ac20022 1372 process_i386_operand_type (table, operand_types[i], stage_opcodes,
bd5295b2 1373 "\t ", lineno);
c587b3f9
L
1374 }
1375 fprintf (table, " } },\n");
1376}
1377
1378struct opcode_hash_entry
1379{
1380 struct opcode_hash_entry *next;
1381 char *name;
1382 char *opcode;
bd5295b2 1383 int lineno;
c587b3f9
L
1384};
1385
1386/* Calculate the hash value of an opcode hash entry P. */
1387
1388static hashval_t
1389opcode_hash_hash (const void *p)
1390{
1391 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1392 return htab_hash_string (entry->name);
1393}
1394
1395/* Compare a string Q against an opcode hash entry P. */
1396
1397static int
1398opcode_hash_eq (const void *p, const void *q)
1399{
1400 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1401 const char *name = (const char *) q;
1402 return strcmp (name, entry->name) == 0;
1403}
1404
4c4898e8
JB
1405static void
1406parse_template (char *buf, int lineno)
1407{
1408 char sep, *end, *name;
1409 struct template *tmpl = xmalloc (sizeof (*tmpl));
1410 struct template_instance *last_inst = NULL;
1411
1412 buf = remove_leading_whitespaces (buf + 1);
1413 end = strchr (buf, ':');
1414 if (end == NULL)
1415 fail ("%s: %d: missing ':'\n", filename, lineno);
1416 *end++ = '\0';
1417 remove_trailing_whitespaces (buf);
1418
1419 if (*buf == '\0')
1420 fail ("%s: %d: missing template identifier\n", filename, lineno);
1421 tmpl->name = xstrdup (buf);
1422
1423 tmpl->params = NULL;
1424 do {
1425 struct template_param *param;
1426
1427 buf = remove_leading_whitespaces (end);
1428 end = strpbrk (buf, ":,");
1429 if (end == NULL)
1430 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1431
1432 sep = *end;
1433 *end++ = '\0';
1434 remove_trailing_whitespaces (buf);
1435
1436 param = xmalloc (sizeof (*param));
1437 param->name = xstrdup (buf);
1438 param->next = tmpl->params;
1439 tmpl->params = param;
1440 } while (sep == ':');
1441
1442 tmpl->instances = NULL;
1443 do {
1444 struct template_instance *inst;
1445 char *cur, *next;
1446 const struct template_param *param;
1447
1448 buf = remove_leading_whitespaces (end);
1449 end = strpbrk (buf, ",>");
1450 if (end == NULL)
1451 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1452
1453 sep = *end;
1454 *end++ = '\0';
1455
1456 inst = xmalloc (sizeof (*inst));
1457
1458 cur = next_field (buf, ':', &next, end);
1459 inst->name = xstrdup (cur);
1460
1461 for (param = tmpl->params; param; param = param->next)
1462 {
1463 struct template_arg *arg = xmalloc (sizeof (*arg));
1464
1465 cur = next_field (next, ':', &next, end);
1466 if (next > end)
1467 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1468 arg->val = xstrdup (cur);
1469 arg->next = inst->args;
1470 inst->args = arg;
1471 }
1472
1473 if (tmpl->instances)
1474 last_inst->next = inst;
1475 else
1476 tmpl->instances = inst;
1477 last_inst = inst;
1478 } while (sep == ',');
1479
1480 buf = remove_leading_whitespaces (end);
1481 if (*buf)
1482 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1483 filename, lineno, buf);
1484
1485 tmpl->next = templates;
1486 templates = tmpl;
1487}
1488
1489static unsigned int
1490expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1491 struct opcode_hash_entry ***opcode_array_p, int lineno)
1492{
1493 static unsigned int idx, opcode_array_size;
1494 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1495 struct opcode_hash_entry **hash_slot, **entry;
1496 char *ptr1 = strchr(name, '<'), *ptr2;
1497
1498 if (ptr1 == NULL)
1499 {
1500 /* Get the slot in hash table. */
1501 hash_slot = (struct opcode_hash_entry **)
1502 htab_find_slot_with_hash (opcode_hash_table, name,
1503 htab_hash_string (name),
1504 INSERT);
1505
1506 if (*hash_slot == NULL)
1507 {
1508 /* It is the new one. Put it on opcode array. */
1509 if (idx >= opcode_array_size)
1510 {
1511 /* Grow the opcode array when needed. */
1512 opcode_array_size += 1024;
1513 opcode_array = (struct opcode_hash_entry **)
1514 xrealloc (opcode_array,
1515 sizeof (*opcode_array) * opcode_array_size);
1516 *opcode_array_p = opcode_array;
1517 }
1518
1519 opcode_array[idx] = (struct opcode_hash_entry *)
1520 xmalloc (sizeof (struct opcode_hash_entry));
1521 opcode_array[idx]->next = NULL;
1522 opcode_array[idx]->name = xstrdup (name);
1523 opcode_array[idx]->opcode = xstrdup (str);
1524 opcode_array[idx]->lineno = lineno;
1525 *hash_slot = opcode_array[idx];
1526 idx++;
1527 }
1528 else
1529 {
1530 /* Append it to the existing one. */
1531 entry = hash_slot;
1532 while ((*entry) != NULL)
1533 entry = &(*entry)->next;
1534 *entry = (struct opcode_hash_entry *)
1535 xmalloc (sizeof (struct opcode_hash_entry));
1536 (*entry)->next = NULL;
1537 (*entry)->name = (*hash_slot)->name;
1538 (*entry)->opcode = xstrdup (str);
1539 (*entry)->lineno = lineno;
1540 }
1541 }
1542 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1543 fail ("%s: %d: missing '>'\n", filename, lineno);
1544 else
1545 {
1546 const struct template *tmpl;
1547 const struct template_instance *inst;
1548
1549 *ptr1 = '\0';
1550 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1551 remove_trailing_whitespaces (ptr1);
1552
1553 *ptr2++ = '\0';
1554
1555 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1556 if (!strcmp(ptr1, tmpl->name))
1557 break;
1558 if (!tmpl)
1559 fail ("reference to unknown template '%s'\n", ptr1);
1560
1561 for (inst = tmpl->instances; inst; inst = inst->next)
1562 {
1563 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1564 char *str2 = xmalloc(2 * strlen(str));
1565 const char *src;
1566
1567 strcpy (name2, name);
1568 strcat (name2, inst->name);
1569 strcat (name2, ptr2);
1570
1571 for (ptr1 = str2, src = str; *src; )
1572 {
1573 const char *ident = tmpl->name, *end;
1574 const struct template_param *param;
1575 const struct template_arg *arg;
1576
1577 if ((*ptr1 = *src++) != '<')
1578 {
1579 ++ptr1;
1580 continue;
1581 }
1582 while (ISSPACE(*src))
1583 ++src;
1584 while (*ident && *src == *ident)
1585 ++src, ++ident;
1586 while (ISSPACE(*src))
1587 ++src;
1588 if (*src != ':' || *ident != '\0')
1589 {
1590 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1591 ptr1 += ident - tmpl->name;
1592 continue;
1593 }
1594 while (ISSPACE(*++src))
1595 ;
1596
1597 end = src;
1598 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1599 ++end;
1600
1601 for (param = tmpl->params, arg = inst->args; param;
1602 param = param->next, arg = arg->next)
1603 {
1604 if (end - src == strlen (param->name)
1605 && !memcmp (src, param->name, end - src))
1606 {
1607 src = end;
1608 break;
1609 }
1610 }
1611
1612 if (param == NULL)
1613 fail ("template '%s' has no parameter '%.*s'\n",
1614 tmpl->name, (int)(end - src), src);
1615
1616 while (ISSPACE(*src))
1617 ++src;
1618 if (*src != '>')
1619 fail ("%s: %d: missing '>'\n", filename, lineno);
1620
1621 memcpy(ptr1, arg->val, strlen(arg->val));
1622 ptr1 += strlen(arg->val);
1623 ++src;
1624 }
1625
1626 *ptr1 = '\0';
1627
1628 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1629 lineno);
1630
1631 free (str2);
1632 free (name2);
1633 }
1634 }
1635
1636 return idx;
1637}
1638
40b8e679 1639static void
72ffa0fb 1640process_i386_opcodes (FILE *table)
40b8e679 1641{
3d4d5afa 1642 FILE *fp;
40b8e679 1643 char buf[2048];
c587b3f9
L
1644 unsigned int i, j;
1645 char *str, *p, *last, *name;
c587b3f9 1646 htab_t opcode_hash_table;
4c4898e8 1647 struct opcode_hash_entry **opcode_array = NULL;
c30be56e 1648 int lineno = 0, marker = 0;
40b8e679 1649
3d4d5afa 1650 filename = "i386-opc.tbl";
c30be56e 1651 fp = stdin;
40b8e679 1652
c587b3f9 1653 i = 0;
c587b3f9
L
1654 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1655 opcode_hash_eq, NULL,
1656 xcalloc, free);
1657
34edb9ad 1658 fprintf (table, "\n/* i386 opcode table. */\n\n");
d3ce72d0 1659 fprintf (table, "const insn_template i386_optab[] =\n{\n");
40b8e679 1660
c587b3f9 1661 /* Put everything on opcode array. */
40b8e679
L
1662 while (!feof (fp))
1663 {
1664 if (fgets (buf, sizeof (buf), fp) == NULL)
1665 break;
1666
3d4d5afa
L
1667 lineno++;
1668
40b8e679
L
1669 p = remove_leading_whitespaces (buf);
1670
1671 /* Skip comments. */
1672 str = strstr (p, "//");
1673 if (str != NULL)
1674 str[0] = '\0';
1675
1676 /* Remove trailing white spaces. */
1677 remove_trailing_whitespaces (p);
1678
1679 switch (p[0])
1680 {
1681 case '#':
c30be56e
JB
1682 if (!strcmp("### MARKER ###", buf))
1683 marker = 1;
1684 else
1685 {
1686 /* Since we ignore all included files (we only care about their
1687 #define-s here), we don't need to monitor filenames. The final
1688 line number directive is going to refer to the main source file
1689 again. */
1690 char *end;
1691 unsigned long ln;
1692
1693 p = remove_leading_whitespaces (p + 1);
1694 if (!strncmp(p, "line", 4))
1695 p += 4;
1696 ln = strtoul (p, &end, 10);
1697 if (ln > 1 && ln < INT_MAX
1698 && *remove_leading_whitespaces (end) == '"')
1699 lineno = ln - 1;
1700 }
c587b3f9 1701 /* Ignore comments. */
40b8e679
L
1702 case '\0':
1703 continue;
1704 break;
4c4898e8
JB
1705 case '<':
1706 parse_template (p, lineno);
1707 continue;
40b8e679 1708 default:
c30be56e
JB
1709 if (!marker)
1710 continue;
40b8e679
L
1711 break;
1712 }
1713
1714 last = p + strlen (p);
1715
1716 /* Find name. */
c587b3f9 1717 name = next_field (p, ',', &str, last);
40b8e679 1718
4c4898e8
JB
1719 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1720 lineno);
c587b3f9 1721 }
40b8e679 1722
c587b3f9
L
1723 /* Process opcode array. */
1724 for (j = 0; j < i; j++)
1725 {
4c4898e8
JB
1726 struct opcode_hash_entry *next;
1727
c587b3f9
L
1728 for (next = opcode_array[j]; next; next = next->next)
1729 {
1730 name = next->name;
1731 str = next->opcode;
bd5295b2 1732 lineno = next->lineno;
c587b3f9 1733 last = str + strlen (str);
bd5295b2 1734 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1735 }
40b8e679
L
1736 }
1737
34edb9ad
L
1738 fclose (fp);
1739
4dffcebc 1740 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820 1741
bd5295b2 1742 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
40fb9820 1743
4a1b91ea 1744 process_i386_opcode_modifier (table, "0", NULL, -1);
29c048b6 1745
40fb9820 1746 fprintf (table, " { ");
7ac20022 1747 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
40fb9820
L
1748 fprintf (table, " } }\n");
1749
34edb9ad 1750 fprintf (table, "};\n");
40b8e679
L
1751}
1752
1753static void
72ffa0fb 1754process_i386_registers (FILE *table)
40b8e679 1755{
3d4d5afa 1756 FILE *fp;
40b8e679
L
1757 char buf[2048];
1758 char *str, *p, *last;
1759 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1760 char *dw2_32_num, *dw2_64_num;
bd5295b2 1761 int lineno = 0;
40b8e679 1762
3d4d5afa
L
1763 filename = "i386-reg.tbl";
1764 fp = fopen (filename, "r");
40b8e679 1765 if (fp == NULL)
34edb9ad 1766 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1767 xstrerror (errno));
40b8e679 1768
34edb9ad
L
1769 fprintf (table, "\n/* i386 register table. */\n\n");
1770 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1771
1772 while (!feof (fp))
1773 {
1774 if (fgets (buf, sizeof (buf), fp) == NULL)
1775 break;
1776
3d4d5afa
L
1777 lineno++;
1778
40b8e679
L
1779 p = remove_leading_whitespaces (buf);
1780
1781 /* Skip comments. */
1782 str = strstr (p, "//");
1783 if (str != NULL)
1784 str[0] = '\0';
1785
1786 /* Remove trailing white spaces. */
1787 remove_trailing_whitespaces (p);
1788
1789 switch (p[0])
1790 {
1791 case '#':
34edb9ad 1792 fprintf (table, "%s\n", p);
40b8e679
L
1793 case '\0':
1794 continue;
1795 break;
1796 default:
1797 break;
1798 }
1799
1800 last = p + strlen (p);
1801
1802 /* Find reg_name. */
c587b3f9 1803 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1804
1805 /* Find reg_type. */
c587b3f9 1806 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1807
1808 /* Find reg_flags. */
c587b3f9 1809 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1810
1811 /* Find reg_num. */
c587b3f9 1812 reg_num = next_field (str, ',', &str, last);
a60de03c 1813
40fb9820
L
1814 fprintf (table, " { \"%s\",\n ", reg_name);
1815
7ac20022
JB
1816 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1817 lineno);
40fb9820 1818
a60de03c 1819 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1820 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1821
1822 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1823 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1824
1825 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1826 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1827 }
1828
34edb9ad
L
1829 fclose (fp);
1830
1831 fprintf (table, "};\n");
40b8e679 1832
34edb9ad 1833 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1834}
1835
40fb9820
L
1836static void
1837process_i386_initializers (void)
1838{
1839 unsigned int i;
1840 FILE *fp = fopen ("i386-init.h", "w");
1841 char *init;
1842
1843 if (fp == NULL)
1844 fail (_("can't create i386-init.h, errno = %s\n"),
1845 xstrerror (errno));
1846
1847 process_copyright (fp);
1848
1849 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1850 {
1851 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1852 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1853 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1854 free (init);
1855 }
1856
1857 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1858 {
1859 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1860 init = xstrdup (operand_type_init[i].init);
7ac20022 1861 process_i386_operand_type (fp, init, stage_macros, " ", -1);
40fb9820
L
1862 free (init);
1863 }
1864 fprintf (fp, "\n");
1865
1866 fclose (fp);
1867}
1868
40b8e679
L
1869/* Program options. */
1870#define OPTION_SRCDIR 200
1871
29c048b6 1872struct option long_options[] =
40b8e679
L
1873{
1874 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1875 {"debug", no_argument, NULL, 'd'},
1876 {"version", no_argument, NULL, 'V'},
1877 {"help", no_argument, NULL, 'h'},
1878 {0, no_argument, NULL, 0}
1879};
1880
1881static void
1882print_version (void)
1883{
1884 printf ("%s: version 1.0\n", program_name);
1885 xexit (0);
1886}
1887
1888static void
1889usage (FILE * stream, int status)
1890{
1891 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1892 program_name);
1893 xexit (status);
1894}
1895
1896int
1897main (int argc, char **argv)
1898{
1899 extern int chdir (char *);
1900 char *srcdir = NULL;
8b40d594 1901 int c;
e92bae62 1902 unsigned int i, cpumax;
72ffa0fb 1903 FILE *table;
29c048b6 1904
40b8e679
L
1905 program_name = *argv;
1906 xmalloc_set_program_name (program_name);
1907
1908 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1909 switch (c)
1910 {
1911 case OPTION_SRCDIR:
1912 srcdir = optarg;
1913 break;
1914 case 'V':
1915 case 'v':
1916 print_version ();
1917 break;
1918 case 'd':
1919 debug = 1;
1920 break;
1921 case 'h':
1922 case '?':
1923 usage (stderr, 0);
1924 default:
1925 case 0:
1926 break;
1927 }
1928
1929 if (optind != argc)
1930 usage (stdout, 1);
1931
29c048b6 1932 if (srcdir != NULL)
40b8e679
L
1933 if (chdir (srcdir) != 0)
1934 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
1935 srcdir, xstrerror (errno));
1936
e92bae62
L
1937 /* cpu_flags isn't sorted by position. */
1938 cpumax = 0;
1939 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1940 if (cpu_flags[i].position > cpumax)
1941 cpumax = cpu_flags[i].position;
1942
40fb9820 1943 /* Check the unused bitfield in i386_cpu_flags. */
e89c5eaa 1944#ifdef CpuUnused
1d942ae9
JB
1945 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1946
e92bae62
L
1947 if ((cpumax - 1) != CpuMax)
1948 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1949#else
1d942ae9
JB
1950 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1951
e92bae62
L
1952 if (cpumax != CpuMax)
1953 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1954
8b40d594
L
1955 c = CpuNumOfBits - CpuMax - 1;
1956 if (c)
1957 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
1958#endif
1959
1d942ae9
JB
1960 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1961
40fb9820 1962 /* Check the unused bitfield in i386_operand_type. */
1d942ae9 1963#ifdef OTUnused
75e5731b
JB
1964 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1965 == OTNum + 1);
1d942ae9 1966#else
75e5731b
JB
1967 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1968 == OTNum);
1d942ae9 1969
51c8edf6 1970 c = OTNumOfBits - OTNum;
8b40d594
L
1971 if (c)
1972 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
1973#endif
1974
1975 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1976 compare);
1977
1978 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1979 sizeof (opcode_modifiers [0]), compare);
1980
1981 qsort (operand_types, ARRAY_SIZE (operand_types),
1982 sizeof (operand_types [0]), compare);
40b8e679 1983
34edb9ad
L
1984 table = fopen ("i386-tbl.h", "w");
1985 if (table == NULL)
40fb9820
L
1986 fail (_("can't create i386-tbl.h, errno = %s\n"),
1987 xstrerror (errno));
34edb9ad 1988
72ffa0fb 1989 process_copyright (table);
40b8e679 1990
72ffa0fb
L
1991 process_i386_opcodes (table);
1992 process_i386_registers (table);
40fb9820 1993 process_i386_initializers ();
40b8e679 1994
34edb9ad
L
1995 fclose (table);
1996
40b8e679
L
1997 exit (0);
1998}
This page took 0.910161 seconds and 4 git commands to generate.