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