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