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