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