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