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