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