x86: CpuXSAVE is a prereq for various other features
[deliverable/binutils-gdb.git] / opcodes / i386-gen.c
CommitLineData
219d1afa 1/* Copyright (C) 2007-2018 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
33static const char *program_name = NULL;
34static int debug = 0;
35
40fb9820
L
36typedef struct initializer
37{
38 const char *name;
39 const char *init;
40} initializer;
41
8acd5377 42static initializer cpu_flag_init[] =
40fb9820
L
43{
44 { "CPU_UNKNOWN_FLAGS",
7a9068fe 45 "~(CpuL1OM|CpuK1OM)" },
40fb9820
L
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
29c048b6 48 { "CPU_GENERIC64_FLAGS",
1848e567 49 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
40fb9820
L
50 { "CPU_NONE_FLAGS",
51 "0" },
52 { "CPU_I186_FLAGS",
53 "Cpu186" },
54 { "CPU_I286_FLAGS",
1848e567 55 "CPU_I186_FLAGS|Cpu286" },
40fb9820 56 { "CPU_I386_FLAGS",
1848e567 57 "CPU_I286_FLAGS|Cpu386" },
40fb9820 58 { "CPU_I486_FLAGS",
1848e567 59 "CPU_I386_FLAGS|Cpu486" },
40fb9820 60 { "CPU_I586_FLAGS",
0e0eea78 61 "CPU_I486_FLAGS|Cpu387|Cpu586" },
40fb9820 62 { "CPU_I686_FLAGS",
1848e567 63 "CPU_I586_FLAGS|Cpu686|Cpu687" },
22109423 64 { "CPU_PENTIUMPRO_FLAGS",
1848e567 65 "CPU_I686_FLAGS|CpuNop" },
40fb9820 66 { "CPU_P2_FLAGS",
1848e567 67 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
40fb9820 68 { "CPU_P3_FLAGS",
1848e567 69 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
40fb9820 70 { "CPU_P4_FLAGS",
1848e567 71 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
40fb9820 72 { "CPU_NOCONA_FLAGS",
1848e567 73 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
40fb9820 74 { "CPU_CORE_FLAGS",
1848e567 75 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
40fb9820 76 { "CPU_CORE2_FLAGS",
1848e567 77 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
bd5295b2 78 { "CPU_COREI7_FLAGS",
1848e567 79 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
40fb9820 80 { "CPU_K6_FLAGS",
1848e567 81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
40fb9820 82 { "CPU_K6_2_FLAGS",
1848e567 83 "CPU_K6_FLAGS|Cpu3dnow" },
40fb9820 84 { "CPU_ATHLON_FLAGS",
1848e567 85 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
40fb9820 86 { "CPU_K8_FLAGS",
1848e567 87 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
40fb9820 88 { "CPU_AMDFAM10_FLAGS",
1848e567 89 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
68339fdf 90 { "CPU_BDVER1_FLAGS",
59ef5df4 91 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
4cab4add 92 { "CPU_BDVER2_FLAGS",
1848e567 93 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
5e5c50d3 94 { "CPU_BDVER3_FLAGS",
1848e567 95 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
c7b0bd56 96 { "CPU_BDVER4_FLAGS",
1848e567 97 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
029f3522 98 { "CPU_ZNVER1_FLAGS",
59ef5df4 99 "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" },
7b458c12 100 { "CPU_BTVER1_FLAGS",
1848e567 101 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
7b458c12 102 { "CPU_BTVER2_FLAGS",
59ef5df4 103 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
309d3373
JB
104 { "CPU_8087_FLAGS",
105 "Cpu8087" },
106 { "CPU_287_FLAGS",
0e0eea78 107 "Cpu287" },
309d3373 108 { "CPU_387_FLAGS",
0e0eea78 109 "Cpu387" },
1848e567
L
110 { "CPU_687_FLAGS",
111 "CPU_387_FLAGS|Cpu687" },
bd5295b2
L
112 { "CPU_CLFLUSH_FLAGS",
113 "CpuClflush" },
22109423
L
114 { "CPU_NOP_FLAGS",
115 "CpuNop" },
bd5295b2
L
116 { "CPU_SYSCALL_FLAGS",
117 "CpuSYSCALL" },
40fb9820 118 { "CPU_MMX_FLAGS",
6e041cf4 119 "CpuMMX" },
40fb9820 120 { "CPU_SSE_FLAGS",
6e041cf4 121 "CpuSSE" },
40fb9820 122 { "CPU_SSE2_FLAGS",
1848e567 123 "CPU_SSE_FLAGS|CpuSSE2" },
40fb9820 124 { "CPU_SSE3_FLAGS",
1848e567 125 "CPU_SSE2_FLAGS|CpuSSE3" },
40fb9820 126 { "CPU_SSSE3_FLAGS",
1848e567 127 "CPU_SSE3_FLAGS|CpuSSSE3" },
40fb9820 128 { "CPU_SSE4_1_FLAGS",
1848e567 129 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
40fb9820 130 { "CPU_SSE4_2_FLAGS",
1848e567 131 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
6305a203
L
132 { "CPU_VMX_FLAGS",
133 "CpuVMX" },
134 { "CPU_SMX_FLAGS",
135 "CpuSMX" },
f03fe4c1
L
136 { "CPU_XSAVE_FLAGS",
137 "CpuXsave" },
c7b8aa3a 138 { "CPU_XSAVEOPT_FLAGS",
1848e567 139 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
c0f3af97 140 { "CPU_AES_FLAGS",
1848e567 141 "CPU_SSE2_FLAGS|CpuAES" },
594ab6a3 142 { "CPU_PCLMUL_FLAGS",
1848e567 143 "CPU_SSE2_FLAGS|CpuPCLMUL" },
c0f3af97 144 { "CPU_FMA_FLAGS",
1848e567 145 "CPU_AVX_FLAGS|CpuFMA" },
922d8de8 146 { "CPU_FMA4_FLAGS",
1848e567 147 "CPU_AVX_FLAGS|CpuFMA4" },
5dd85c99 148 { "CPU_XOP_FLAGS",
1848e567 149 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
f88c9eb0 150 { "CPU_LWP_FLAGS",
59ef5df4 151 "CPU_XSAVE_FLAGS|CpuLWP" },
f12dc422
L
152 { "CPU_BMI_FLAGS",
153 "CpuBMI" },
2a2a0f38
QN
154 { "CPU_TBM_FLAGS",
155 "CpuTBM" },
f1f8f695
L
156 { "CPU_MOVBE_FLAGS",
157 "CpuMovbe" },
60aa667e
L
158 { "CPU_CX16_FLAGS",
159 "CpuCX16" },
1b7f3fb0
L
160 { "CPU_RDTSCP_FLAGS",
161 "CpuRdtscp" },
f1f8f695
L
162 { "CPU_EPT_FLAGS",
163 "CpuEPT" },
c7b8aa3a
L
164 { "CPU_FSGSBASE_FLAGS",
165 "CpuFSGSBase" },
166 { "CPU_RDRND_FLAGS",
167 "CpuRdRnd" },
168 { "CPU_F16C_FLAGS",
1848e567 169 "CPU_AVX_FLAGS|CpuF16C" },
6c30d220
L
170 { "CPU_BMI2_FLAGS",
171 "CpuBMI2" },
172 { "CPU_LZCNT_FLAGS",
173 "CpuLZCNT" },
42164a71
L
174 { "CPU_HLE_FLAGS",
175 "CpuHLE" },
176 { "CPU_RTM_FLAGS",
177 "CpuRTM" },
6c30d220
L
178 { "CPU_INVPCID_FLAGS",
179 "CpuINVPCID" },
8729a6f6
L
180 { "CPU_VMFUNC_FLAGS",
181 "CpuVMFUNC" },
40fb9820 182 { "CPU_3DNOW_FLAGS",
1848e567 183 "CPU_MMX_FLAGS|Cpu3dnow" },
40fb9820 184 { "CPU_3DNOWA_FLAGS",
1848e567 185 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
40fb9820
L
186 { "CPU_PADLOCK_FLAGS",
187 "CpuPadLock" },
188 { "CPU_SVME_FLAGS",
189 "CpuSVME" },
190 { "CPU_SSE4A_FLAGS",
1848e567 191 "CPU_SSE3_FLAGS|CpuSSE4a" },
40fb9820 192 { "CPU_ABM_FLAGS",
3629bb00 193 "CpuABM" },
c0f3af97 194 { "CPU_AVX_FLAGS",
59ef5df4 195 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
6c30d220 196 { "CPU_AVX2_FLAGS",
1848e567 197 "CPU_AVX_FLAGS|CpuAVX2" },
43234a1e 198 { "CPU_AVX512F_FLAGS",
6e041cf4 199 "CPU_AVX2_FLAGS|CpuVREX|CpuAVX512F" },
43234a1e 200 { "CPU_AVX512CD_FLAGS",
1848e567 201 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
43234a1e 202 { "CPU_AVX512ER_FLAGS",
1848e567 203 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
43234a1e 204 { "CPU_AVX512PF_FLAGS",
1848e567 205 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
f3ad7637 206 { "CPU_AVX512DQ_FLAGS",
1848e567 207 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
f3ad7637 208 { "CPU_AVX512BW_FLAGS",
1848e567 209 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
f3ad7637 210 { "CPU_AVX512VL_FLAGS",
6e041cf4 211 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
f3ad7637 212 { "CPU_AVX512IFMA_FLAGS",
1848e567 213 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
f3ad7637 214 { "CPU_AVX512VBMI_FLAGS",
1848e567 215 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
920d2ddc
IT
216 { "CPU_AVX512_4FMAPS_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
47acf0bd
IT
218 { "CPU_AVX512_4VNNIW_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
620214f7
IT
220 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
53467f57
IT
222 { "CPU_AVX512_VBMI2_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
8cfcb765
IT
224 { "CPU_AVX512_VNNI_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
ee6872be
IT
226 { "CPU_AVX512_BITALG_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
8a9036a4
L
228 { "CPU_L1OM_FLAGS",
229 "unknown" },
7a9068fe
L
230 { "CPU_K1OM_FLAGS",
231 "unknown" },
7b6d09fb
L
232 { "CPU_IAMCU_FLAGS",
233 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
e2e1fcde
L
234 { "CPU_ADX_FLAGS",
235 "CpuADX" },
236 { "CPU_RDSEED_FLAGS",
237 "CpuRdSeed" },
238 { "CPU_PRFCHW_FLAGS",
239 "CpuPRFCHW" },
5c111e37
L
240 { "CPU_SMAP_FLAGS",
241 "CpuSMAP" },
7e8b059b 242 { "CPU_MPX_FLAGS",
59ef5df4 243 "CPU_XSAVE_FLAGS|CpuMPX" },
a0046408 244 { "CPU_SHA_FLAGS",
1848e567 245 "CPU_SSE2_FLAGS|CpuSHA" },
963f3586
IT
246 { "CPU_CLFLUSHOPT_FLAGS",
247 "CpuClflushOpt" },
248 { "CPU_XSAVES_FLAGS",
1848e567 249 "CPU_XSAVE_FLAGS|CpuXSAVES" },
963f3586 250 { "CPU_XSAVEC_FLAGS",
1848e567 251 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
dcf893b5
IT
252 { "CPU_PREFETCHWT1_FLAGS",
253 "CpuPREFETCHWT1" },
2cf200a4
IT
254 { "CPU_SE1_FLAGS",
255 "CpuSE1" },
c5e7287a
IT
256 { "CPU_CLWB_FLAGS",
257 "CpuCLWB" },
029f3522
GG
258 { "CPU_CLZERO_FLAGS",
259 "CpuCLZERO" },
9916071f
AP
260 { "CPU_MWAITX_FLAGS",
261 "CpuMWAITX" },
8eab4136 262 { "CPU_OSPKE_FLAGS",
59ef5df4 263 "CPU_XSAVE_FLAGS|CpuOSPKE" },
8bc52696 264 { "CPU_RDPID_FLAGS",
1848e567 265 "CpuRDPID" },
6b40c462
L
266 { "CPU_PTWRITE_FLAGS",
267 "CpuPTWRITE" },
d777820b
IT
268 { "CPU_IBT_FLAGS",
269 "CpuIBT" },
270 { "CPU_SHSTK_FLAGS",
271 "CpuSHSTK" },
48521003
IT
272 { "CPU_GFNI_FLAGS",
273 "CpuGFNI" },
8dcf1fad
IT
274 { "CPU_VAES_FLAGS",
275 "CpuVAES" },
ff1982d5
IT
276 { "CPU_VPCLMULQDQ_FLAGS",
277 "CpuVPCLMULQDQ" },
3233d7d0
IT
278 { "CPU_WBNOINVD_FLAGS",
279 "CpuWBNOINVD" },
be3a8dca
IT
280 { "CPU_PCONFIG_FLAGS",
281 "CpuPCONFIG" },
de89d0a3
IT
282 { "CPU_WAITPKG_FLAGS",
283 "CpuWAITPKG" },
c48935d7
IT
284 { "CPU_CLDEMOTE_FLAGS",
285 "CpuCLDEMOTE" },
1848e567
L
286 { "CPU_ANY_X87_FLAGS",
287 "CPU_ANY_287_FLAGS|Cpu8087" },
288 { "CPU_ANY_287_FLAGS",
289 "CPU_ANY_387_FLAGS|Cpu287" },
290 { "CPU_ANY_387_FLAGS",
291 "CPU_ANY_687_FLAGS|Cpu387" },
292 { "CPU_ANY_687_FLAGS",
293 "Cpu687|CpuFISTTP" },
294 { "CPU_ANY_MMX_FLAGS",
295 "CPU_3DNOWA_FLAGS" },
296 { "CPU_ANY_SSE_FLAGS",
297 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
298 { "CPU_ANY_SSE2_FLAGS",
299 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
300 { "CPU_ANY_SSE3_FLAGS",
301 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
302 { "CPU_ANY_SSSE3_FLAGS",
303 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
304 { "CPU_ANY_SSE4_1_FLAGS",
305 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
306 { "CPU_ANY_SSE4_2_FLAGS",
307 "CpuSSE4_2" },
308 { "CPU_ANY_AVX_FLAGS",
309 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
310 { "CPU_ANY_AVX2_FLAGS",
311 "CpuAVX2" },
144b71e2 312 { "CPU_ANY_AVX512F_FLAGS",
6e041cf4 313 "CpuVREX|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512F" },
144b71e2
L
314 { "CPU_ANY_AVX512CD_FLAGS",
315 "CpuAVX512CD" },
316 { "CPU_ANY_AVX512ER_FLAGS",
317 "CpuAVX512ER" },
318 { "CPU_ANY_AVX512PF_FLAGS",
319 "CpuAVX512PF" },
320 { "CPU_ANY_AVX512DQ_FLAGS",
321 "CpuAVX512DQ" },
322 { "CPU_ANY_AVX512BW_FLAGS",
323 "CpuAVX512BW" },
324 { "CPU_ANY_AVX512VL_FLAGS",
325 "CpuAVX512VL" },
326 { "CPU_ANY_AVX512IFMA_FLAGS",
327 "CpuAVX512IFMA" },
328 { "CPU_ANY_AVX512VBMI_FLAGS",
329 "CpuAVX512VBMI" },
920d2ddc
IT
330 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
331 "CpuAVX512_4FMAPS" },
47acf0bd
IT
332 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
333 "CpuAVX512_4VNNIW" },
620214f7
IT
334 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
335 "CpuAVX512_VPOPCNTDQ" },
d777820b
IT
336 { "CPU_ANY_IBT_FLAGS",
337 "CpuIBT" },
338 { "CPU_ANY_SHSTK_FLAGS",
339 "CpuSHSTK" },
53467f57
IT
340 { "CPU_ANY_AVX512_VBMI2_FLAGS",
341 "CpuAVX512_VBMI2" },
8cfcb765
IT
342 { "CPU_ANY_AVX512_VNNI_FLAGS",
343 "CpuAVX512_VNNI" },
ee6872be
IT
344 { "CPU_ANY_AVX512_BITALG_FLAGS",
345 "CpuAVX512_BITALG" },
40fb9820
L
346};
347
dc821c5f
JB
348static const initializer operand_type_shorthands[] =
349{
350 { "Reg8", "Reg|Byte" },
351 { "Reg16", "Reg|Word" },
352 { "Reg32", "Reg|Dword" },
353 { "Reg64", "Reg|Qword" },
ca0d63fe
JB
354 { "FloatAcc", "Acc|Tbyte" },
355 { "FloatReg", "Reg|Tbyte" },
1b54b8d7
JB
356 { "RegXMM", "RegSIMD|Xmmword" },
357 { "RegYMM", "RegSIMD|Ymmword" },
358 { "RegZMM", "RegSIMD|Zmmword" },
dc821c5f
JB
359};
360
8acd5377 361static initializer operand_type_init[] =
40fb9820
L
362{
363 { "OPERAND_TYPE_NONE",
364 "0" },
365 { "OPERAND_TYPE_REG8",
366 "Reg8" },
367 { "OPERAND_TYPE_REG16",
368 "Reg16" },
369 { "OPERAND_TYPE_REG32",
370 "Reg32" },
371 { "OPERAND_TYPE_REG64",
372 "Reg64" },
373 { "OPERAND_TYPE_IMM1",
374 "Imm1" },
375 { "OPERAND_TYPE_IMM8",
376 "Imm8" },
377 { "OPERAND_TYPE_IMM8S",
378 "Imm8S" },
379 { "OPERAND_TYPE_IMM16",
380 "Imm16" },
381 { "OPERAND_TYPE_IMM32",
382 "Imm32" },
383 { "OPERAND_TYPE_IMM32S",
384 "Imm32S" },
385 { "OPERAND_TYPE_IMM64",
386 "Imm64" },
387 { "OPERAND_TYPE_BASEINDEX",
388 "BaseIndex" },
389 { "OPERAND_TYPE_DISP8",
390 "Disp8" },
391 { "OPERAND_TYPE_DISP16",
392 "Disp16" },
393 { "OPERAND_TYPE_DISP32",
394 "Disp32" },
395 { "OPERAND_TYPE_DISP32S",
396 "Disp32S" },
397 { "OPERAND_TYPE_DISP64",
398 "Disp64" },
399 { "OPERAND_TYPE_INOUTPORTREG",
400 "InOutPortReg" },
401 { "OPERAND_TYPE_SHIFTCOUNT",
402 "ShiftCount" },
403 { "OPERAND_TYPE_CONTROL",
404 "Control" },
405 { "OPERAND_TYPE_TEST",
406 "Test" },
407 { "OPERAND_TYPE_DEBUG",
408 "FloatReg" },
409 { "OPERAND_TYPE_FLOATREG",
410 "FloatReg" },
411 { "OPERAND_TYPE_FLOATACC",
412 "FloatAcc" },
413 { "OPERAND_TYPE_SREG2",
414 "SReg2" },
415 { "OPERAND_TYPE_SREG3",
416 "SReg3" },
417 { "OPERAND_TYPE_ACC",
418 "Acc" },
419 { "OPERAND_TYPE_JUMPABSOLUTE",
420 "JumpAbsolute" },
421 { "OPERAND_TYPE_REGMMX",
422 "RegMMX" },
423 { "OPERAND_TYPE_REGXMM",
424 "RegXMM" },
1508bbf5
JB
425 { "OPERAND_TYPE_REGYMM",
426 "RegYMM" },
427 { "OPERAND_TYPE_REGZMM",
428 "RegZMM" },
43234a1e
L
429 { "OPERAND_TYPE_REGMASK",
430 "RegMask" },
40fb9820
L
431 { "OPERAND_TYPE_ESSEG",
432 "EsSeg" },
433 { "OPERAND_TYPE_ACC32",
7d5e4556 434 "Reg32|Acc|Dword" },
40fb9820 435 { "OPERAND_TYPE_ACC64",
7d5e4556 436 "Reg64|Acc|Qword" },
65da13b5
L
437 { "OPERAND_TYPE_INOUTPORTREG",
438 "InOutPortReg" },
40fb9820
L
439 { "OPERAND_TYPE_REG16_INOUTPORTREG",
440 "Reg16|InOutPortReg" },
441 { "OPERAND_TYPE_DISP16_32",
442 "Disp16|Disp32" },
443 { "OPERAND_TYPE_ANYDISP",
444 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
445 { "OPERAND_TYPE_IMM16_32",
446 "Imm16|Imm32" },
447 { "OPERAND_TYPE_IMM16_32S",
448 "Imm16|Imm32S" },
449 { "OPERAND_TYPE_IMM16_32_32S",
450 "Imm16|Imm32|Imm32S" },
2f81ff92
L
451 { "OPERAND_TYPE_IMM32_64",
452 "Imm32|Imm64" },
40fb9820
L
453 { "OPERAND_TYPE_IMM32_32S_DISP32",
454 "Imm32|Imm32S|Disp32" },
455 { "OPERAND_TYPE_IMM64_DISP64",
456 "Imm64|Disp64" },
457 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
458 "Imm32|Imm32S|Imm64|Disp32" },
459 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
460 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
a683cc34
SP
461 { "OPERAND_TYPE_VEC_IMM4",
462 "Vec_Imm4" },
7e8b059b
L
463 { "OPERAND_TYPE_REGBND",
464 "RegBND" },
40fb9820
L
465};
466
467typedef struct bitfield
468{
469 int position;
470 int value;
471 const char *name;
472} bitfield;
473
474#define BITFIELD(n) { n, 0, #n }
475
476static bitfield cpu_flags[] =
477{
478 BITFIELD (Cpu186),
479 BITFIELD (Cpu286),
480 BITFIELD (Cpu386),
481 BITFIELD (Cpu486),
482 BITFIELD (Cpu586),
483 BITFIELD (Cpu686),
bd5295b2 484 BITFIELD (CpuClflush),
22109423 485 BITFIELD (CpuNop),
bd5295b2 486 BITFIELD (CpuSYSCALL),
309d3373
JB
487 BITFIELD (Cpu8087),
488 BITFIELD (Cpu287),
489 BITFIELD (Cpu387),
490 BITFIELD (Cpu687),
491 BITFIELD (CpuFISTTP),
40fb9820 492 BITFIELD (CpuMMX),
40fb9820
L
493 BITFIELD (CpuSSE),
494 BITFIELD (CpuSSE2),
495 BITFIELD (CpuSSE3),
496 BITFIELD (CpuSSSE3),
497 BITFIELD (CpuSSE4_1),
498 BITFIELD (CpuSSE4_2),
c0f3af97 499 BITFIELD (CpuAVX),
6c30d220 500 BITFIELD (CpuAVX2),
43234a1e
L
501 BITFIELD (CpuAVX512F),
502 BITFIELD (CpuAVX512CD),
503 BITFIELD (CpuAVX512ER),
504 BITFIELD (CpuAVX512PF),
b28d1bda 505 BITFIELD (CpuAVX512VL),
90a915bf 506 BITFIELD (CpuAVX512DQ),
1ba585e8 507 BITFIELD (CpuAVX512BW),
8a9036a4 508 BITFIELD (CpuL1OM),
7a9068fe 509 BITFIELD (CpuK1OM),
7b6d09fb 510 BITFIELD (CpuIAMCU),
40fb9820
L
511 BITFIELD (CpuSSE4a),
512 BITFIELD (Cpu3dnow),
513 BITFIELD (Cpu3dnowA),
514 BITFIELD (CpuPadLock),
515 BITFIELD (CpuSVME),
516 BITFIELD (CpuVMX),
47dd174c 517 BITFIELD (CpuSMX),
40fb9820 518 BITFIELD (CpuABM),
475a2301 519 BITFIELD (CpuXsave),
c7b8aa3a 520 BITFIELD (CpuXsaveopt),
c0f3af97 521 BITFIELD (CpuAES),
594ab6a3 522 BITFIELD (CpuPCLMUL),
c0f3af97 523 BITFIELD (CpuFMA),
f88c9eb0 524 BITFIELD (CpuFMA4),
5dd85c99 525 BITFIELD (CpuXOP),
f88c9eb0 526 BITFIELD (CpuLWP),
f12dc422 527 BITFIELD (CpuBMI),
2a2a0f38 528 BITFIELD (CpuTBM),
c0f3af97 529 BITFIELD (CpuLM),
f1f8f695 530 BITFIELD (CpuMovbe),
60aa667e 531 BITFIELD (CpuCX16),
f1f8f695 532 BITFIELD (CpuEPT),
1b7f3fb0 533 BITFIELD (CpuRdtscp),
c7b8aa3a
L
534 BITFIELD (CpuFSGSBase),
535 BITFIELD (CpuRdRnd),
536 BITFIELD (CpuF16C),
6c30d220
L
537 BITFIELD (CpuBMI2),
538 BITFIELD (CpuLZCNT),
42164a71
L
539 BITFIELD (CpuHLE),
540 BITFIELD (CpuRTM),
6c30d220 541 BITFIELD (CpuINVPCID),
8729a6f6 542 BITFIELD (CpuVMFUNC),
e2e1fcde
L
543 BITFIELD (CpuRDSEED),
544 BITFIELD (CpuADX),
545 BITFIELD (CpuPRFCHW),
5c111e37 546 BITFIELD (CpuSMAP),
a0046408 547 BITFIELD (CpuSHA),
43234a1e 548 BITFIELD (CpuVREX),
963f3586
IT
549 BITFIELD (CpuClflushOpt),
550 BITFIELD (CpuXSAVES),
551 BITFIELD (CpuXSAVEC),
dcf893b5 552 BITFIELD (CpuPREFETCHWT1),
2cf200a4 553 BITFIELD (CpuSE1),
c5e7287a 554 BITFIELD (CpuCLWB),
40fb9820
L
555 BITFIELD (Cpu64),
556 BITFIELD (CpuNo64),
7e8b059b 557 BITFIELD (CpuMPX),
2cc1b5aa 558 BITFIELD (CpuAVX512IFMA),
14f195c9 559 BITFIELD (CpuAVX512VBMI),
920d2ddc 560 BITFIELD (CpuAVX512_4FMAPS),
47acf0bd 561 BITFIELD (CpuAVX512_4VNNIW),
620214f7 562 BITFIELD (CpuAVX512_VPOPCNTDQ),
53467f57 563 BITFIELD (CpuAVX512_VBMI2),
8cfcb765 564 BITFIELD (CpuAVX512_VNNI),
ee6872be 565 BITFIELD (CpuAVX512_BITALG),
9916071f 566 BITFIELD (CpuMWAITX),
029f3522 567 BITFIELD (CpuCLZERO),
8eab4136 568 BITFIELD (CpuOSPKE),
8bc52696 569 BITFIELD (CpuRDPID),
6b40c462 570 BITFIELD (CpuPTWRITE),
d777820b
IT
571 BITFIELD (CpuIBT),
572 BITFIELD (CpuSHSTK),
48521003 573 BITFIELD (CpuGFNI),
8dcf1fad 574 BITFIELD (CpuVAES),
ff1982d5 575 BITFIELD (CpuVPCLMULQDQ),
3233d7d0 576 BITFIELD (CpuWBNOINVD),
be3a8dca 577 BITFIELD (CpuPCONFIG),
de89d0a3 578 BITFIELD (CpuWAITPKG),
c48935d7 579 BITFIELD (CpuCLDEMOTE),
40fb9820
L
580#ifdef CpuUnused
581 BITFIELD (CpuUnused),
582#endif
583};
584
585static bitfield opcode_modifiers[] =
586{
587 BITFIELD (D),
588 BITFIELD (W),
86fa6981 589 BITFIELD (Load),
40fb9820
L
590 BITFIELD (Modrm),
591 BITFIELD (ShortForm),
592 BITFIELD (Jump),
593 BITFIELD (JumpDword),
594 BITFIELD (JumpByte),
595 BITFIELD (JumpInterSegment),
596 BITFIELD (FloatMF),
597 BITFIELD (FloatR),
40fb9820
L
598 BITFIELD (Size16),
599 BITFIELD (Size32),
600 BITFIELD (Size64),
56ffb741 601 BITFIELD (CheckRegSize),
40fb9820
L
602 BITFIELD (IgnoreSize),
603 BITFIELD (DefaultSize),
604 BITFIELD (No_bSuf),
605 BITFIELD (No_wSuf),
606 BITFIELD (No_lSuf),
607 BITFIELD (No_sSuf),
608 BITFIELD (No_qSuf),
7ce189b3 609 BITFIELD (No_ldSuf),
40fb9820
L
610 BITFIELD (FWait),
611 BITFIELD (IsString),
7e8b059b 612 BITFIELD (BNDPrefixOk),
04ef582a 613 BITFIELD (NoTrackPrefixOk),
c32fa91d 614 BITFIELD (IsLockable),
40fb9820 615 BITFIELD (RegKludge),
c0f3af97 616 BITFIELD (Implicit1stXmm0),
29c048b6 617 BITFIELD (RepPrefixOk),
42164a71 618 BITFIELD (HLEPrefixOk),
ca61edf2
L
619 BITFIELD (ToDword),
620 BITFIELD (ToQword),
621 BITFIELD (AddrPrefixOp0),
40fb9820
L
622 BITFIELD (IsPrefix),
623 BITFIELD (ImmExt),
624 BITFIELD (NoRex64),
625 BITFIELD (Rex64),
626 BITFIELD (Ugh),
c0f3af97 627 BITFIELD (Vex),
2426c15f 628 BITFIELD (VexVVVV),
1ef99a7b 629 BITFIELD (VexW),
7f399153 630 BITFIELD (VexOpcode),
8cd7925b 631 BITFIELD (VexSources),
6c30d220 632 BITFIELD (VecSIB),
c0f3af97 633 BITFIELD (SSE2AVX),
81f8a913 634 BITFIELD (NoAVX),
43234a1e
L
635 BITFIELD (EVex),
636 BITFIELD (Masking),
43234a1e
L
637 BITFIELD (Broadcast),
638 BITFIELD (StaticRounding),
639 BITFIELD (SAE),
640 BITFIELD (Disp8MemShift),
641 BITFIELD (NoDefMask),
920d2ddc 642 BITFIELD (ImplicitQuadGroup),
b6f8c7c4 643 BITFIELD (Optimize),
1efbbeb4 644 BITFIELD (ATTMnemonic),
e1d4d893 645 BITFIELD (ATTSyntax),
5c07affc 646 BITFIELD (IntelSyntax),
e92bae62
L
647 BITFIELD (AMD64),
648 BITFIELD (Intel64),
40fb9820
L
649};
650
651static bitfield operand_types[] =
652{
dc821c5f 653 BITFIELD (Reg),
40fb9820 654 BITFIELD (RegMMX),
1b54b8d7 655 BITFIELD (RegSIMD),
43234a1e 656 BITFIELD (RegMask),
94ff3a50 657 BITFIELD (Imm1),
40fb9820
L
658 BITFIELD (Imm8),
659 BITFIELD (Imm8S),
660 BITFIELD (Imm16),
661 BITFIELD (Imm32),
662 BITFIELD (Imm32S),
663 BITFIELD (Imm64),
40fb9820
L
664 BITFIELD (BaseIndex),
665 BITFIELD (Disp8),
666 BITFIELD (Disp16),
667 BITFIELD (Disp32),
668 BITFIELD (Disp32S),
669 BITFIELD (Disp64),
670 BITFIELD (InOutPortReg),
671 BITFIELD (ShiftCount),
672 BITFIELD (Control),
673 BITFIELD (Debug),
674 BITFIELD (Test),
675 BITFIELD (SReg2),
676 BITFIELD (SReg3),
677 BITFIELD (Acc),
40fb9820
L
678 BITFIELD (JumpAbsolute),
679 BITFIELD (EsSeg),
680 BITFIELD (RegMem),
5c07affc 681 BITFIELD (Mem),
7d5e4556
L
682 BITFIELD (Byte),
683 BITFIELD (Word),
684 BITFIELD (Dword),
685 BITFIELD (Fword),
686 BITFIELD (Qword),
687 BITFIELD (Tbyte),
688 BITFIELD (Xmmword),
c0f3af97 689 BITFIELD (Ymmword),
43234a1e 690 BITFIELD (Zmmword),
7d5e4556
L
691 BITFIELD (Unspecified),
692 BITFIELD (Anysize),
a683cc34 693 BITFIELD (Vec_Imm4),
7e8b059b 694 BITFIELD (RegBND),
40fb9820
L
695#ifdef OTUnused
696 BITFIELD (OTUnused),
697#endif
698};
699
3d4d5afa 700static const char *filename;
7ac20022
JB
701static i386_cpu_flags active_cpu_flags;
702static int active_isstring;
3d4d5afa 703
40fb9820
L
704static int
705compare (const void *x, const void *y)
706{
707 const bitfield *xp = (const bitfield *) x;
708 const bitfield *yp = (const bitfield *) y;
709 return xp->position - yp->position;
710}
711
40b8e679
L
712static void
713fail (const char *message, ...)
714{
715 va_list args;
29c048b6 716
40b8e679 717 va_start (args, message);
a6743a54 718 fprintf (stderr, _("%s: error: "), program_name);
40b8e679
L
719 vfprintf (stderr, message, args);
720 va_end (args);
721 xexit (1);
722}
723
72ffa0fb
L
724static void
725process_copyright (FILE *fp)
726{
727 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
219d1afa 728/* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
72ffa0fb
L
729\n\
730 This file is part of the GNU opcodes library.\n\
731\n\
732 This library is free software; you can redistribute it and/or modify\n\
733 it under the terms of the GNU General Public License as published by\n\
734 the Free Software Foundation; either version 3, or (at your option)\n\
735 any later version.\n\
736\n\
737 It is distributed in the hope that it will be useful, but WITHOUT\n\
738 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
739 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
740 License for more details.\n\
741\n\
742 You should have received a copy of the GNU General Public License\n\
743 along with this program; if not, write to the Free Software\n\
744 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
745 MA 02110-1301, USA. */\n");
746}
747
40b8e679
L
748/* Remove leading white spaces. */
749
750static char *
751remove_leading_whitespaces (char *str)
752{
753 while (ISSPACE (*str))
754 str++;
755 return str;
756}
757
758/* Remove trailing white spaces. */
759
760static void
761remove_trailing_whitespaces (char *str)
762{
763 size_t last = strlen (str);
764
765 if (last == 0)
766 return;
767
768 do
769 {
770 last--;
771 if (ISSPACE (str [last]))
772 str[last] = '\0';
773 else
774 break;
775 }
776 while (last != 0);
777}
778
93b1ec2c 779/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
780 pointer to the one after it. */
781
782static char *
c587b3f9 783next_field (char *str, char sep, char **next, char *last)
40b8e679
L
784{
785 char *p;
786
787 p = remove_leading_whitespaces (str);
93b1ec2c 788 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
789
790 *str = '\0';
791 remove_trailing_whitespaces (p);
792
29c048b6 793 *next = str + 1;
40b8e679 794
c587b3f9
L
795 if (p >= last)
796 abort ();
797
40b8e679
L
798 return p;
799}
800
1848e567
L
801static void set_bitfield (char *, bitfield *, int, unsigned int, int);
802
803static int
dc821c5f
JB
804set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
805 int lineno)
1848e567
L
806{
807 char *str, *next, *last;
808 unsigned int i;
809
810 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
811 if (strcmp (cpu_flag_init[i].name, f) == 0)
812 {
813 /* Turn on selective bits. */
814 char *init = xstrdup (cpu_flag_init[i].init);
815 last = init + strlen (init);
816 for (next = init; next && next < last; )
817 {
818 str = next_field (next, '|', &next, last);
819 if (str)
820 set_bitfield (str, array, 1, size, lineno);
821 }
822 free (init);
823 return 0;
824 }
825
dc821c5f
JB
826 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
827 if (strcmp (operand_type_shorthands[i].name, f) == 0)
828 {
829 /* Turn on selective bits. */
830 char *init = xstrdup (operand_type_shorthands[i].init);
831 last = init + strlen (init);
832 for (next = init; next && next < last; )
833 {
834 str = next_field (next, '|', &next, last);
835 if (str)
836 set_bitfield (str, array, 1, size, lineno);
837 }
838 free (init);
839 return 0;
840 }
841
1848e567
L
842 return -1;
843}
844
40fb9820 845static void
1848e567 846set_bitfield (char *f, bitfield *array, int value,
8a9036a4 847 unsigned int size, int lineno)
40fb9820
L
848{
849 unsigned int i;
850
309d3373
JB
851 if (strcmp (f, "CpuFP") == 0)
852 {
8a9036a4
L
853 set_bitfield("Cpu387", array, value, size, lineno);
854 set_bitfield("Cpu287", array, value, size, lineno);
309d3373
JB
855 f = "Cpu8087";
856 }
857 else if (strcmp (f, "Mmword") == 0)
7d5e4556
L
858 f= "Qword";
859 else if (strcmp (f, "Oword") == 0)
860 f= "Xmmword";
40fb9820
L
861
862 for (i = 0; i < size; i++)
863 if (strcasecmp (array[i].name, f) == 0)
864 {
8a9036a4 865 array[i].value = value;
40fb9820
L
866 return;
867 }
868
2bf05e57
L
869 if (value)
870 {
871 const char *v = strchr (f, '=');
872
873 if (v)
874 {
875 size_t n = v - f;
876 char *end;
877
878 for (i = 0; i < size; i++)
879 if (strncasecmp (array[i].name, f, n) == 0)
880 {
881 value = strtol (v + 1, &end, 0);
882 if (*end == '\0')
883 {
884 array[i].value = value;
885 return;
886 }
887 break;
888 }
889 }
890 }
891
dc821c5f
JB
892 /* Handle shorthands. */
893 if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno))
1848e567
L
894 return;
895
bd5295b2 896 if (lineno != -1)
a6743a54 897 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
bd5295b2 898 else
a6743a54 899 fail (_("unknown bitfield: %s\n"), f);
40fb9820
L
900}
901
902static void
903output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
904 int macro, const char *comma, const char *indent)
905{
906 unsigned int i;
907
7ac20022
JB
908 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
909
40fb9820
L
910 fprintf (table, "%s{ { ", indent);
911
912 for (i = 0; i < size - 1; i++)
913 {
10632b79
L
914 if (((i + 1) % 20) != 0)
915 fprintf (table, "%d, ", flags[i].value);
916 else
917 fprintf (table, "%d,", flags[i].value);
40fb9820
L
918 if (((i + 1) % 20) == 0)
919 {
920 /* We need \\ for macro. */
921 if (macro)
922 fprintf (table, " \\\n %s", indent);
923 else
924 fprintf (table, "\n %s", indent);
925 }
7ac20022
JB
926 if (flags[i].value)
927 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
40fb9820
L
928 }
929
930 fprintf (table, "%d } }%s\n", flags[i].value, comma);
931}
932
933static void
934process_i386_cpu_flag (FILE *table, char *flag, int macro,
bd5295b2
L
935 const char *comma, const char *indent,
936 int lineno)
40fb9820
L
937{
938 char *str, *next, *last;
8a9036a4 939 unsigned int i;
40fb9820
L
940 bitfield flags [ARRAY_SIZE (cpu_flags)];
941
942 /* Copy the default cpu flags. */
943 memcpy (flags, cpu_flags, sizeof (cpu_flags));
944
945 if (strcasecmp (flag, "unknown") == 0)
946 {
40fb9820 947 /* We turn on everything except for cpu64 in case of
8a9036a4
L
948 CPU_UNKNOWN_FLAGS. */
949 for (i = 0; i < ARRAY_SIZE (flags); i++)
950 if (flags[i].position != Cpu64)
951 flags[i].value = 1;
952 }
953 else if (flag[0] == '~')
954 {
955 last = flag + strlen (flag);
956
957 if (flag[1] == '(')
958 {
959 last -= 1;
960 next = flag + 2;
961 if (*last != ')')
a6743a54 962 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
8a9036a4
L
963 lineno, flag);
964 *last = '\0';
965 }
966 else
967 next = flag + 1;
968
969 /* First we turn on everything except for cpu64. */
40fb9820
L
970 for (i = 0; i < ARRAY_SIZE (flags); i++)
971 if (flags[i].position != Cpu64)
972 flags[i].value = 1;
8a9036a4
L
973
974 /* Turn off selective bits. */
975 for (; next && next < last; )
976 {
977 str = next_field (next, '|', &next, last);
978 if (str)
979 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
980 }
40fb9820
L
981 }
982 else if (strcmp (flag, "0"))
983 {
8a9036a4 984 /* Turn on selective bits. */
40fb9820
L
985 last = flag + strlen (flag);
986 for (next = flag; next && next < last; )
987 {
c587b3f9 988 str = next_field (next, '|', &next, last);
40fb9820 989 if (str)
8a9036a4 990 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
40fb9820
L
991 }
992 }
993
994 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
995 comma, indent);
996}
997
998static void
999output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1000{
1001 unsigned int i;
1002
1003 fprintf (table, " { ");
1004
1005 for (i = 0; i < size - 1; i++)
1006 {
10632b79
L
1007 if (((i + 1) % 20) != 0)
1008 fprintf (table, "%d, ", modifier[i].value);
1009 else
1010 fprintf (table, "%d,", modifier[i].value);
40fb9820
L
1011 if (((i + 1) % 20) == 0)
1012 fprintf (table, "\n ");
1013 }
1014
1015 fprintf (table, "%d },\n", modifier[i].value);
1016}
1017
1018static void
bd5295b2 1019process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
40fb9820
L
1020{
1021 char *str, *next, *last;
1022 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1023
7ac20022
JB
1024 active_isstring = 0;
1025
40fb9820
L
1026 /* Copy the default opcode modifier. */
1027 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1028
1029 if (strcmp (mod, "0"))
1030 {
1031 last = mod + strlen (mod);
1032 for (next = mod; next && next < last; )
1033 {
c587b3f9 1034 str = next_field (next, '|', &next, last);
40fb9820 1035 if (str)
7ac20022
JB
1036 {
1037 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
8a9036a4 1038 lineno);
7ac20022
JB
1039 if (strcasecmp(str, "IsString") == 0)
1040 active_isstring = 1;
1041 }
40fb9820
L
1042 }
1043 }
1044 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1045}
1046
7ac20022
JB
1047enum stage {
1048 stage_macros,
1049 stage_opcodes,
1050 stage_registers,
1051};
1052
40fb9820
L
1053static void
1054output_operand_type (FILE *table, bitfield *types, unsigned int size,
7ac20022 1055 enum stage stage, const char *indent)
40fb9820
L
1056{
1057 unsigned int i;
1058
1059 fprintf (table, "{ { ");
1060
1061 for (i = 0; i < size - 1; i++)
1062 {
10632b79
L
1063 if (((i + 1) % 20) != 0)
1064 fprintf (table, "%d, ", types[i].value);
1065 else
1066 fprintf (table, "%d,", types[i].value);
40fb9820
L
1067 if (((i + 1) % 20) == 0)
1068 {
1069 /* We need \\ for macro. */
7ac20022 1070 if (stage == stage_macros)
10632b79 1071 fprintf (table, " \\\n%s", indent);
40fb9820
L
1072 else
1073 fprintf (table, "\n%s", indent);
1074 }
1075 }
1076
1077 fprintf (table, "%d } }", types[i].value);
1078}
1079
1080static void
7ac20022 1081process_i386_operand_type (FILE *table, char *op, enum stage stage,
bd5295b2 1082 const char *indent, int lineno)
40fb9820
L
1083{
1084 char *str, *next, *last;
1085 bitfield types [ARRAY_SIZE (operand_types)];
1086
1087 /* Copy the default operand type. */
1088 memcpy (types, operand_types, sizeof (types));
1089
1090 if (strcmp (op, "0"))
1091 {
7ac20022
JB
1092 int baseindex = 0;
1093
40fb9820
L
1094 last = op + strlen (op);
1095 for (next = op; next && next < last; )
1096 {
c587b3f9 1097 str = next_field (next, '|', &next, last);
40fb9820 1098 if (str)
7ac20022
JB
1099 {
1100 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1101 if (strcasecmp(str, "BaseIndex") == 0)
1102 baseindex = 1;
1103 }
1104 }
1105
1106 if (stage == stage_opcodes && baseindex && !active_isstring)
1107 {
1108 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1109 if (!active_cpu_flags.bitfield.cpu64
1110 && !active_cpu_flags.bitfield.cpumpx)
1111 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1112 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1113 if (!active_cpu_flags.bitfield.cpuno64)
1114 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
1115 }
1116 }
7ac20022 1117 output_operand_type (table, types, ARRAY_SIZE (types), stage,
40fb9820
L
1118 indent);
1119}
1120
c587b3f9
L
1121static void
1122output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 1123 char *last, int lineno)
c587b3f9
L
1124{
1125 unsigned int i;
1126 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1127 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1128
1129 /* Find number of operands. */
1130 operands = next_field (str, ',', &str, last);
1131
1132 /* Find base_opcode. */
1133 base_opcode = next_field (str, ',', &str, last);
1134
1135 /* Find extension_opcode. */
1136 extension_opcode = next_field (str, ',', &str, last);
1137
1138 /* Find opcode_length. */
1139 opcode_length = next_field (str, ',', &str, last);
1140
1141 /* Find cpu_flags. */
1142 cpu_flags = next_field (str, ',', &str, last);
1143
1144 /* Find opcode_modifier. */
1145 opcode_modifier = next_field (str, ',', &str, last);
1146
1147 /* Remove the first {. */
1148 str = remove_leading_whitespaces (str);
1149 if (*str != '{')
1150 abort ();
1151 str = remove_leading_whitespaces (str + 1);
1152
1153 i = strlen (str);
1154
1155 /* There are at least "X}". */
1156 if (i < 2)
1157 abort ();
1158
1159 /* Remove trailing white spaces and }. */
1160 do
1161 {
1162 i--;
1163 if (ISSPACE (str[i]) || str[i] == '}')
1164 str[i] = '\0';
1165 else
1166 break;
1167 }
1168 while (i != 0);
1169
1170 last = str + i;
1171
1172 /* Find operand_types. */
1173 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1174 {
1175 if (str >= last)
1176 {
1177 operand_types [i] = NULL;
1178 break;
1179 }
1180
1181 operand_types [i] = next_field (str, ',', &str, last);
1182 if (*operand_types[i] == '0')
1183 {
1184 if (i != 0)
1185 operand_types[i] = NULL;
1186 break;
1187 }
1188 }
1189
1190 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1191 name, operands, base_opcode, extension_opcode,
1192 opcode_length);
1193
bd5295b2 1194 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
c587b3f9 1195
bd5295b2 1196 process_i386_opcode_modifier (table, opcode_modifier, lineno);
c587b3f9
L
1197
1198 fprintf (table, " { ");
1199
1200 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1201 {
1202 if (operand_types[i] == NULL || *operand_types[i] == '0')
1203 {
1204 if (i == 0)
7ac20022
JB
1205 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1206 lineno);
c587b3f9
L
1207 break;
1208 }
1209
1210 if (i != 0)
1211 fprintf (table, ",\n ");
1212
7ac20022 1213 process_i386_operand_type (table, operand_types[i], stage_opcodes,
bd5295b2 1214 "\t ", lineno);
c587b3f9
L
1215 }
1216 fprintf (table, " } },\n");
1217}
1218
1219struct opcode_hash_entry
1220{
1221 struct opcode_hash_entry *next;
1222 char *name;
1223 char *opcode;
bd5295b2 1224 int lineno;
c587b3f9
L
1225};
1226
1227/* Calculate the hash value of an opcode hash entry P. */
1228
1229static hashval_t
1230opcode_hash_hash (const void *p)
1231{
1232 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1233 return htab_hash_string (entry->name);
1234}
1235
1236/* Compare a string Q against an opcode hash entry P. */
1237
1238static int
1239opcode_hash_eq (const void *p, const void *q)
1240{
1241 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1242 const char *name = (const char *) q;
1243 return strcmp (name, entry->name) == 0;
1244}
1245
40b8e679 1246static void
72ffa0fb 1247process_i386_opcodes (FILE *table)
40b8e679 1248{
3d4d5afa 1249 FILE *fp;
40b8e679 1250 char buf[2048];
c587b3f9
L
1251 unsigned int i, j;
1252 char *str, *p, *last, *name;
1253 struct opcode_hash_entry **hash_slot, **entry, *next;
1254 htab_t opcode_hash_table;
1255 struct opcode_hash_entry **opcode_array;
1256 unsigned int opcode_array_size = 1024;
bd5295b2 1257 int lineno = 0;
40b8e679 1258
3d4d5afa
L
1259 filename = "i386-opc.tbl";
1260 fp = fopen (filename, "r");
1261
40b8e679 1262 if (fp == NULL)
34edb9ad 1263 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
40fb9820 1264 xstrerror (errno));
40b8e679 1265
c587b3f9
L
1266 i = 0;
1267 opcode_array = (struct opcode_hash_entry **)
1268 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1269
1270 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1271 opcode_hash_eq, NULL,
1272 xcalloc, free);
1273
34edb9ad 1274 fprintf (table, "\n/* i386 opcode table. */\n\n");
d3ce72d0 1275 fprintf (table, "const insn_template i386_optab[] =\n{\n");
40b8e679 1276
c587b3f9 1277 /* Put everything on opcode array. */
40b8e679
L
1278 while (!feof (fp))
1279 {
1280 if (fgets (buf, sizeof (buf), fp) == NULL)
1281 break;
1282
3d4d5afa
L
1283 lineno++;
1284
40b8e679
L
1285 p = remove_leading_whitespaces (buf);
1286
1287 /* Skip comments. */
1288 str = strstr (p, "//");
1289 if (str != NULL)
1290 str[0] = '\0';
1291
1292 /* Remove trailing white spaces. */
1293 remove_trailing_whitespaces (p);
1294
1295 switch (p[0])
1296 {
1297 case '#':
c587b3f9 1298 /* Ignore comments. */
40b8e679
L
1299 case '\0':
1300 continue;
1301 break;
1302 default:
1303 break;
1304 }
1305
1306 last = p + strlen (p);
1307
1308 /* Find name. */
c587b3f9 1309 name = next_field (p, ',', &str, last);
40b8e679 1310
c587b3f9
L
1311 /* Get the slot in hash table. */
1312 hash_slot = (struct opcode_hash_entry **)
1313 htab_find_slot_with_hash (opcode_hash_table, name,
1314 htab_hash_string (name),
1315 INSERT);
40b8e679 1316
c587b3f9 1317 if (*hash_slot == NULL)
40b8e679 1318 {
c587b3f9
L
1319 /* It is the new one. Put it on opcode array. */
1320 if (i >= opcode_array_size)
40b8e679 1321 {
c587b3f9
L
1322 /* Grow the opcode array when needed. */
1323 opcode_array_size += 1024;
1324 opcode_array = (struct opcode_hash_entry **)
1325 xrealloc (opcode_array,
1326 sizeof (*opcode_array) * opcode_array_size);
40b8e679
L
1327 }
1328
c587b3f9
L
1329 opcode_array[i] = (struct opcode_hash_entry *)
1330 xmalloc (sizeof (struct opcode_hash_entry));
1331 opcode_array[i]->next = NULL;
1332 opcode_array[i]->name = xstrdup (name);
1333 opcode_array[i]->opcode = xstrdup (str);
bd5295b2 1334 opcode_array[i]->lineno = lineno;
c587b3f9
L
1335 *hash_slot = opcode_array[i];
1336 i++;
40b8e679 1337 }
c587b3f9 1338 else
40b8e679 1339 {
c587b3f9
L
1340 /* Append it to the existing one. */
1341 entry = hash_slot;
1342 while ((*entry) != NULL)
1343 entry = &(*entry)->next;
1344 *entry = (struct opcode_hash_entry *)
1345 xmalloc (sizeof (struct opcode_hash_entry));
1346 (*entry)->next = NULL;
1347 (*entry)->name = (*hash_slot)->name;
1348 (*entry)->opcode = xstrdup (str);
bd5295b2 1349 (*entry)->lineno = lineno;
c587b3f9
L
1350 }
1351 }
40b8e679 1352
c587b3f9
L
1353 /* Process opcode array. */
1354 for (j = 0; j < i; j++)
1355 {
1356 for (next = opcode_array[j]; next; next = next->next)
1357 {
1358 name = next->name;
1359 str = next->opcode;
bd5295b2 1360 lineno = next->lineno;
c587b3f9 1361 last = str + strlen (str);
bd5295b2 1362 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1363 }
40b8e679
L
1364 }
1365
34edb9ad
L
1366 fclose (fp);
1367
4dffcebc 1368 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820 1369
bd5295b2 1370 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
40fb9820 1371
bd5295b2 1372 process_i386_opcode_modifier (table, "0", -1);
29c048b6 1373
40fb9820 1374 fprintf (table, " { ");
7ac20022 1375 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
40fb9820
L
1376 fprintf (table, " } }\n");
1377
34edb9ad 1378 fprintf (table, "};\n");
40b8e679
L
1379}
1380
1381static void
72ffa0fb 1382process_i386_registers (FILE *table)
40b8e679 1383{
3d4d5afa 1384 FILE *fp;
40b8e679
L
1385 char buf[2048];
1386 char *str, *p, *last;
1387 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1388 char *dw2_32_num, *dw2_64_num;
bd5295b2 1389 int lineno = 0;
40b8e679 1390
3d4d5afa
L
1391 filename = "i386-reg.tbl";
1392 fp = fopen (filename, "r");
40b8e679 1393 if (fp == NULL)
34edb9ad 1394 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1395 xstrerror (errno));
40b8e679 1396
34edb9ad
L
1397 fprintf (table, "\n/* i386 register table. */\n\n");
1398 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1399
1400 while (!feof (fp))
1401 {
1402 if (fgets (buf, sizeof (buf), fp) == NULL)
1403 break;
1404
3d4d5afa
L
1405 lineno++;
1406
40b8e679
L
1407 p = remove_leading_whitespaces (buf);
1408
1409 /* Skip comments. */
1410 str = strstr (p, "//");
1411 if (str != NULL)
1412 str[0] = '\0';
1413
1414 /* Remove trailing white spaces. */
1415 remove_trailing_whitespaces (p);
1416
1417 switch (p[0])
1418 {
1419 case '#':
34edb9ad 1420 fprintf (table, "%s\n", p);
40b8e679
L
1421 case '\0':
1422 continue;
1423 break;
1424 default:
1425 break;
1426 }
1427
1428 last = p + strlen (p);
1429
1430 /* Find reg_name. */
c587b3f9 1431 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1432
1433 /* Find reg_type. */
c587b3f9 1434 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1435
1436 /* Find reg_flags. */
c587b3f9 1437 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1438
1439 /* Find reg_num. */
c587b3f9 1440 reg_num = next_field (str, ',', &str, last);
a60de03c 1441
40fb9820
L
1442 fprintf (table, " { \"%s\",\n ", reg_name);
1443
7ac20022
JB
1444 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1445 lineno);
40fb9820 1446
a60de03c 1447 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1448 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1449
1450 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1451 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1452
1453 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1454 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1455 }
1456
34edb9ad
L
1457 fclose (fp);
1458
1459 fprintf (table, "};\n");
40b8e679 1460
34edb9ad 1461 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1462}
1463
40fb9820
L
1464static void
1465process_i386_initializers (void)
1466{
1467 unsigned int i;
1468 FILE *fp = fopen ("i386-init.h", "w");
1469 char *init;
1470
1471 if (fp == NULL)
1472 fail (_("can't create i386-init.h, errno = %s\n"),
1473 xstrerror (errno));
1474
1475 process_copyright (fp);
1476
1477 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1478 {
1479 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1480 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1481 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1482 free (init);
1483 }
1484
1485 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1486 {
1487 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1488 init = xstrdup (operand_type_init[i].init);
7ac20022 1489 process_i386_operand_type (fp, init, stage_macros, " ", -1);
40fb9820
L
1490 free (init);
1491 }
1492 fprintf (fp, "\n");
1493
1494 fclose (fp);
1495}
1496
40b8e679
L
1497/* Program options. */
1498#define OPTION_SRCDIR 200
1499
29c048b6 1500struct option long_options[] =
40b8e679
L
1501{
1502 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1503 {"debug", no_argument, NULL, 'd'},
1504 {"version", no_argument, NULL, 'V'},
1505 {"help", no_argument, NULL, 'h'},
1506 {0, no_argument, NULL, 0}
1507};
1508
1509static void
1510print_version (void)
1511{
1512 printf ("%s: version 1.0\n", program_name);
1513 xexit (0);
1514}
1515
1516static void
1517usage (FILE * stream, int status)
1518{
1519 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1520 program_name);
1521 xexit (status);
1522}
1523
1524int
1525main (int argc, char **argv)
1526{
1527 extern int chdir (char *);
1528 char *srcdir = NULL;
8b40d594 1529 int c;
e92bae62 1530 unsigned int i, cpumax;
72ffa0fb 1531 FILE *table;
29c048b6 1532
40b8e679
L
1533 program_name = *argv;
1534 xmalloc_set_program_name (program_name);
1535
1536 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1537 switch (c)
1538 {
1539 case OPTION_SRCDIR:
1540 srcdir = optarg;
1541 break;
1542 case 'V':
1543 case 'v':
1544 print_version ();
1545 break;
1546 case 'd':
1547 debug = 1;
1548 break;
1549 case 'h':
1550 case '?':
1551 usage (stderr, 0);
1552 default:
1553 case 0:
1554 break;
1555 }
1556
1557 if (optind != argc)
1558 usage (stdout, 1);
1559
29c048b6 1560 if (srcdir != NULL)
40b8e679
L
1561 if (chdir (srcdir) != 0)
1562 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
1563 srcdir, xstrerror (errno));
1564
e92bae62
L
1565 /* cpu_flags isn't sorted by position. */
1566 cpumax = 0;
1567 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1568 if (cpu_flags[i].position > cpumax)
1569 cpumax = cpu_flags[i].position;
1570
40fb9820 1571 /* Check the unused bitfield in i386_cpu_flags. */
e89c5eaa 1572#ifdef CpuUnused
e92bae62
L
1573 if ((cpumax - 1) != CpuMax)
1574 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1575#else
e92bae62
L
1576 if (cpumax != CpuMax)
1577 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1578
8b40d594
L
1579 c = CpuNumOfBits - CpuMax - 1;
1580 if (c)
1581 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
1582#endif
1583
1584 /* Check the unused bitfield in i386_operand_type. */
1585#ifndef OTUnused
8b40d594
L
1586 c = OTNumOfBits - OTMax - 1;
1587 if (c)
1588 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
1589#endif
1590
1591 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1592 compare);
1593
1594 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1595 sizeof (opcode_modifiers [0]), compare);
1596
1597 qsort (operand_types, ARRAY_SIZE (operand_types),
1598 sizeof (operand_types [0]), compare);
40b8e679 1599
34edb9ad
L
1600 table = fopen ("i386-tbl.h", "w");
1601 if (table == NULL)
40fb9820
L
1602 fail (_("can't create i386-tbl.h, errno = %s\n"),
1603 xstrerror (errno));
34edb9ad 1604
72ffa0fb 1605 process_copyright (table);
40b8e679 1606
72ffa0fb
L
1607 process_i386_opcodes (table);
1608 process_i386_registers (table);
40fb9820 1609 process_i386_initializers ();
40b8e679 1610
34edb9ad
L
1611 fclose (table);
1612
40b8e679
L
1613 exit (0);
1614}
This page took 0.805488 seconds and 4 git commands to generate.