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