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