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