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