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