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