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