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