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