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