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