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