Revert "Turn off threaded minsym demangling by default"
[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 "Class=Reg|Byte" },
392 { "OPERAND_TYPE_REG16",
393 "Class=Reg|Word" },
394 { "OPERAND_TYPE_REG32",
395 "Class=Reg|Dword" },
396 { "OPERAND_TYPE_REG64",
397 "Class=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 "Instance=RegD|Word" },
426 { "OPERAND_TYPE_SHIFTCOUNT",
427 "Instance=RegC|Byte" },
428 { "OPERAND_TYPE_CONTROL",
429 "Class=RegCR" },
430 { "OPERAND_TYPE_TEST",
431 "Class=RegTR" },
432 { "OPERAND_TYPE_DEBUG",
433 "Class=RegDR" },
434 { "OPERAND_TYPE_FLOATREG",
435 "Class=Reg|Tbyte" },
436 { "OPERAND_TYPE_FLOATACC",
437 "Instance=Accum|Tbyte" },
438 { "OPERAND_TYPE_SREG",
439 "Class=SReg" },
440 { "OPERAND_TYPE_REGMMX",
441 "Class=RegMMX" },
442 { "OPERAND_TYPE_REGXMM",
443 "Class=RegSIMD|Xmmword" },
444 { "OPERAND_TYPE_REGYMM",
445 "Class=RegSIMD|Ymmword" },
446 { "OPERAND_TYPE_REGZMM",
447 "Class=RegSIMD|Zmmword" },
448 { "OPERAND_TYPE_REGMASK",
449 "Class=RegMask" },
450 { "OPERAND_TYPE_REGBND",
451 "Class=RegBND" },
452 { "OPERAND_TYPE_ACC8",
453 "Instance=Accum|Byte" },
454 { "OPERAND_TYPE_ACC16",
455 "Instance=Accum|Word" },
456 { "OPERAND_TYPE_ACC32",
457 "Instance=Accum|Dword" },
458 { "OPERAND_TYPE_ACC64",
459 "Instance=Accum|Qword" },
460 { "OPERAND_TYPE_DISP16_32",
461 "Disp16|Disp32" },
462 { "OPERAND_TYPE_ANYDISP",
463 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
464 { "OPERAND_TYPE_IMM16_32",
465 "Imm16|Imm32" },
466 { "OPERAND_TYPE_IMM16_32S",
467 "Imm16|Imm32S" },
468 { "OPERAND_TYPE_IMM16_32_32S",
469 "Imm16|Imm32|Imm32S" },
470 { "OPERAND_TYPE_IMM32_64",
471 "Imm32|Imm64" },
472 { "OPERAND_TYPE_IMM32_32S_DISP32",
473 "Imm32|Imm32S|Disp32" },
474 { "OPERAND_TYPE_IMM64_DISP64",
475 "Imm64|Disp64" },
476 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
477 "Imm32|Imm32S|Imm64|Disp32" },
478 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
479 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
480 { "OPERAND_TYPE_ANYIMM",
481 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
482 };
483
484 typedef struct bitfield
485 {
486 int position;
487 int value;
488 const char *name;
489 } bitfield;
490
491 #define BITFIELD(n) { n, 0, #n }
492
493 static bitfield cpu_flags[] =
494 {
495 BITFIELD (Cpu186),
496 BITFIELD (Cpu286),
497 BITFIELD (Cpu386),
498 BITFIELD (Cpu486),
499 BITFIELD (Cpu586),
500 BITFIELD (Cpu686),
501 BITFIELD (CpuCMOV),
502 BITFIELD (CpuFXSR),
503 BITFIELD (CpuClflush),
504 BITFIELD (CpuNop),
505 BITFIELD (CpuSYSCALL),
506 BITFIELD (Cpu8087),
507 BITFIELD (Cpu287),
508 BITFIELD (Cpu387),
509 BITFIELD (Cpu687),
510 BITFIELD (CpuFISTTP),
511 BITFIELD (CpuMMX),
512 BITFIELD (CpuSSE),
513 BITFIELD (CpuSSE2),
514 BITFIELD (CpuSSE3),
515 BITFIELD (CpuSSSE3),
516 BITFIELD (CpuSSE4_1),
517 BITFIELD (CpuSSE4_2),
518 BITFIELD (CpuAVX),
519 BITFIELD (CpuAVX2),
520 BITFIELD (CpuAVX512F),
521 BITFIELD (CpuAVX512CD),
522 BITFIELD (CpuAVX512ER),
523 BITFIELD (CpuAVX512PF),
524 BITFIELD (CpuAVX512VL),
525 BITFIELD (CpuAVX512DQ),
526 BITFIELD (CpuAVX512BW),
527 BITFIELD (CpuL1OM),
528 BITFIELD (CpuK1OM),
529 BITFIELD (CpuIAMCU),
530 BITFIELD (CpuSSE4a),
531 BITFIELD (Cpu3dnow),
532 BITFIELD (Cpu3dnowA),
533 BITFIELD (CpuPadLock),
534 BITFIELD (CpuSVME),
535 BITFIELD (CpuVMX),
536 BITFIELD (CpuSMX),
537 BITFIELD (CpuABM),
538 BITFIELD (CpuXsave),
539 BITFIELD (CpuXsaveopt),
540 BITFIELD (CpuAES),
541 BITFIELD (CpuPCLMUL),
542 BITFIELD (CpuFMA),
543 BITFIELD (CpuFMA4),
544 BITFIELD (CpuXOP),
545 BITFIELD (CpuLWP),
546 BITFIELD (CpuBMI),
547 BITFIELD (CpuTBM),
548 BITFIELD (CpuLM),
549 BITFIELD (CpuMovbe),
550 BITFIELD (CpuCX16),
551 BITFIELD (CpuEPT),
552 BITFIELD (CpuRdtscp),
553 BITFIELD (CpuFSGSBase),
554 BITFIELD (CpuRdRnd),
555 BITFIELD (CpuF16C),
556 BITFIELD (CpuBMI2),
557 BITFIELD (CpuLZCNT),
558 BITFIELD (CpuHLE),
559 BITFIELD (CpuRTM),
560 BITFIELD (CpuINVPCID),
561 BITFIELD (CpuVMFUNC),
562 BITFIELD (CpuRDSEED),
563 BITFIELD (CpuADX),
564 BITFIELD (CpuPRFCHW),
565 BITFIELD (CpuSMAP),
566 BITFIELD (CpuSHA),
567 BITFIELD (CpuClflushOpt),
568 BITFIELD (CpuXSAVES),
569 BITFIELD (CpuXSAVEC),
570 BITFIELD (CpuPREFETCHWT1),
571 BITFIELD (CpuSE1),
572 BITFIELD (CpuCLWB),
573 BITFIELD (Cpu64),
574 BITFIELD (CpuNo64),
575 BITFIELD (CpuMPX),
576 BITFIELD (CpuAVX512IFMA),
577 BITFIELD (CpuAVX512VBMI),
578 BITFIELD (CpuAVX512_4FMAPS),
579 BITFIELD (CpuAVX512_4VNNIW),
580 BITFIELD (CpuAVX512_VPOPCNTDQ),
581 BITFIELD (CpuAVX512_VBMI2),
582 BITFIELD (CpuAVX512_VNNI),
583 BITFIELD (CpuAVX512_BITALG),
584 BITFIELD (CpuAVX512_BF16),
585 BITFIELD (CpuAVX512_VP2INTERSECT),
586 BITFIELD (CpuMWAITX),
587 BITFIELD (CpuCLZERO),
588 BITFIELD (CpuOSPKE),
589 BITFIELD (CpuRDPID),
590 BITFIELD (CpuPTWRITE),
591 BITFIELD (CpuIBT),
592 BITFIELD (CpuSHSTK),
593 BITFIELD (CpuGFNI),
594 BITFIELD (CpuVAES),
595 BITFIELD (CpuVPCLMULQDQ),
596 BITFIELD (CpuWBNOINVD),
597 BITFIELD (CpuPCONFIG),
598 BITFIELD (CpuWAITPKG),
599 BITFIELD (CpuCLDEMOTE),
600 BITFIELD (CpuMOVDIRI),
601 BITFIELD (CpuMOVDIR64B),
602 BITFIELD (CpuENQCMD),
603 BITFIELD (CpuRDPRU),
604 BITFIELD (CpuMCOMMIT),
605 #ifdef CpuUnused
606 BITFIELD (CpuUnused),
607 #endif
608 };
609
610 static bitfield opcode_modifiers[] =
611 {
612 BITFIELD (D),
613 BITFIELD (W),
614 BITFIELD (Load),
615 BITFIELD (Modrm),
616 BITFIELD (ShortForm),
617 BITFIELD (Jump),
618 BITFIELD (FloatMF),
619 BITFIELD (FloatR),
620 BITFIELD (Size),
621 BITFIELD (CheckRegSize),
622 BITFIELD (IgnoreSize),
623 BITFIELD (DefaultSize),
624 BITFIELD (Anysize),
625 BITFIELD (No_bSuf),
626 BITFIELD (No_wSuf),
627 BITFIELD (No_lSuf),
628 BITFIELD (No_sSuf),
629 BITFIELD (No_qSuf),
630 BITFIELD (No_ldSuf),
631 BITFIELD (FWait),
632 BITFIELD (IsString),
633 BITFIELD (RegMem),
634 BITFIELD (BNDPrefixOk),
635 BITFIELD (NoTrackPrefixOk),
636 BITFIELD (IsLockable),
637 BITFIELD (RegKludge),
638 BITFIELD (Implicit1stXmm0),
639 BITFIELD (RepPrefixOk),
640 BITFIELD (HLEPrefixOk),
641 BITFIELD (ToDword),
642 BITFIELD (ToQword),
643 BITFIELD (AddrPrefixOpReg),
644 BITFIELD (IsPrefix),
645 BITFIELD (ImmExt),
646 BITFIELD (NoRex64),
647 BITFIELD (Rex64),
648 BITFIELD (Ugh),
649 BITFIELD (Vex),
650 BITFIELD (VexVVVV),
651 BITFIELD (VexW),
652 BITFIELD (VexOpcode),
653 BITFIELD (VexSources),
654 BITFIELD (VecSIB),
655 BITFIELD (SSE2AVX),
656 BITFIELD (NoAVX),
657 BITFIELD (EVex),
658 BITFIELD (Masking),
659 BITFIELD (Broadcast),
660 BITFIELD (StaticRounding),
661 BITFIELD (SAE),
662 BITFIELD (Disp8MemShift),
663 BITFIELD (NoDefMask),
664 BITFIELD (ImplicitQuadGroup),
665 BITFIELD (Optimize),
666 BITFIELD (ATTMnemonic),
667 BITFIELD (ATTSyntax),
668 BITFIELD (IntelSyntax),
669 BITFIELD (AMD64),
670 BITFIELD (Intel64),
671 };
672
673 #define CLASS(n) #n, n
674
675 static const struct {
676 const char *name;
677 enum operand_class value;
678 } operand_classes[] = {
679 CLASS (Reg),
680 CLASS (SReg),
681 CLASS (RegCR),
682 CLASS (RegDR),
683 CLASS (RegTR),
684 CLASS (RegMMX),
685 CLASS (RegSIMD),
686 CLASS (RegMask),
687 CLASS (RegBND),
688 };
689
690 #undef CLASS
691
692 #define INSTANCE(n) #n, n
693
694 static const struct {
695 const char *name;
696 enum operand_instance value;
697 } operand_instances[] = {
698 INSTANCE (Accum),
699 INSTANCE (RegC),
700 INSTANCE (RegD),
701 INSTANCE (RegB),
702 };
703
704 #undef INSTANCE
705
706 static bitfield operand_types[] =
707 {
708 BITFIELD (Imm1),
709 BITFIELD (Imm8),
710 BITFIELD (Imm8S),
711 BITFIELD (Imm16),
712 BITFIELD (Imm32),
713 BITFIELD (Imm32S),
714 BITFIELD (Imm64),
715 BITFIELD (BaseIndex),
716 BITFIELD (Disp8),
717 BITFIELD (Disp16),
718 BITFIELD (Disp32),
719 BITFIELD (Disp32S),
720 BITFIELD (Disp64),
721 BITFIELD (Byte),
722 BITFIELD (Word),
723 BITFIELD (Dword),
724 BITFIELD (Fword),
725 BITFIELD (Qword),
726 BITFIELD (Tbyte),
727 BITFIELD (Xmmword),
728 BITFIELD (Ymmword),
729 BITFIELD (Zmmword),
730 BITFIELD (Unspecified),
731 #ifdef OTUnused
732 BITFIELD (OTUnused),
733 #endif
734 };
735
736 static const char *filename;
737 static i386_cpu_flags active_cpu_flags;
738 static int active_isstring;
739
740 static int
741 compare (const void *x, const void *y)
742 {
743 const bitfield *xp = (const bitfield *) x;
744 const bitfield *yp = (const bitfield *) y;
745 return xp->position - yp->position;
746 }
747
748 static void
749 fail (const char *message, ...)
750 {
751 va_list args;
752
753 va_start (args, message);
754 fprintf (stderr, _("%s: error: "), program_name);
755 vfprintf (stderr, message, args);
756 va_end (args);
757 xexit (1);
758 }
759
760 static void
761 process_copyright (FILE *fp)
762 {
763 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
764 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
765 \n\
766 This file is part of the GNU opcodes library.\n\
767 \n\
768 This library is free software; you can redistribute it and/or modify\n\
769 it under the terms of the GNU General Public License as published by\n\
770 the Free Software Foundation; either version 3, or (at your option)\n\
771 any later version.\n\
772 \n\
773 It is distributed in the hope that it will be useful, but WITHOUT\n\
774 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
775 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
776 License for more details.\n\
777 \n\
778 You should have received a copy of the GNU General Public License\n\
779 along with this program; if not, write to the Free Software\n\
780 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
781 MA 02110-1301, USA. */\n");
782 }
783
784 /* Remove leading white spaces. */
785
786 static char *
787 remove_leading_whitespaces (char *str)
788 {
789 while (ISSPACE (*str))
790 str++;
791 return str;
792 }
793
794 /* Remove trailing white spaces. */
795
796 static void
797 remove_trailing_whitespaces (char *str)
798 {
799 size_t last = strlen (str);
800
801 if (last == 0)
802 return;
803
804 do
805 {
806 last--;
807 if (ISSPACE (str [last]))
808 str[last] = '\0';
809 else
810 break;
811 }
812 while (last != 0);
813 }
814
815 /* Find next field separated by SEP and terminate it. Return a
816 pointer to the one after it. */
817
818 static char *
819 next_field (char *str, char sep, char **next, char *last)
820 {
821 char *p;
822
823 p = remove_leading_whitespaces (str);
824 for (str = p; *str != sep && *str != '\0'; str++);
825
826 *str = '\0';
827 remove_trailing_whitespaces (p);
828
829 *next = str + 1;
830
831 if (p >= last)
832 abort ();
833
834 return p;
835 }
836
837 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
838
839 static int
840 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
841 int lineno)
842 {
843 char *str, *next, *last;
844 unsigned int i;
845
846 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
847 if (strcmp (cpu_flag_init[i].name, f) == 0)
848 {
849 /* Turn on selective bits. */
850 char *init = xstrdup (cpu_flag_init[i].init);
851 last = init + strlen (init);
852 for (next = init; next && next < last; )
853 {
854 str = next_field (next, '|', &next, last);
855 if (str)
856 set_bitfield (str, array, 1, size, lineno);
857 }
858 free (init);
859 return 0;
860 }
861
862 return -1;
863 }
864
865 static void
866 set_bitfield (char *f, bitfield *array, int value,
867 unsigned int size, int lineno)
868 {
869 unsigned int i;
870
871 if (strcmp (f, "CpuFP") == 0)
872 {
873 set_bitfield("Cpu387", array, value, size, lineno);
874 set_bitfield("Cpu287", array, value, size, lineno);
875 f = "Cpu8087";
876 }
877 else if (strcmp (f, "Mmword") == 0)
878 f= "Qword";
879 else if (strcmp (f, "Oword") == 0)
880 f= "Xmmword";
881
882 for (i = 0; i < size; i++)
883 if (strcasecmp (array[i].name, f) == 0)
884 {
885 array[i].value = value;
886 return;
887 }
888
889 if (value)
890 {
891 const char *v = strchr (f, '=');
892
893 if (v)
894 {
895 size_t n = v - f;
896 char *end;
897
898 for (i = 0; i < size; i++)
899 if (strncasecmp (array[i].name, f, n) == 0)
900 {
901 value = strtol (v + 1, &end, 0);
902 if (*end == '\0')
903 {
904 array[i].value = value;
905 return;
906 }
907 break;
908 }
909 }
910 }
911
912 /* Handle CPU_XXX_FLAGS. */
913 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
914 return;
915
916 if (lineno != -1)
917 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
918 else
919 fail (_("unknown bitfield: %s\n"), f);
920 }
921
922 static void
923 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
924 int macro, const char *comma, const char *indent)
925 {
926 unsigned int i;
927
928 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
929
930 fprintf (table, "%s{ { ", indent);
931
932 for (i = 0; i < size - 1; i++)
933 {
934 if (((i + 1) % 20) != 0)
935 fprintf (table, "%d, ", flags[i].value);
936 else
937 fprintf (table, "%d,", flags[i].value);
938 if (((i + 1) % 20) == 0)
939 {
940 /* We need \\ for macro. */
941 if (macro)
942 fprintf (table, " \\\n %s", indent);
943 else
944 fprintf (table, "\n %s", indent);
945 }
946 if (flags[i].value)
947 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
948 }
949
950 fprintf (table, "%d } }%s\n", flags[i].value, comma);
951 }
952
953 static void
954 process_i386_cpu_flag (FILE *table, char *flag, int macro,
955 const char *comma, const char *indent,
956 int lineno)
957 {
958 char *str, *next, *last;
959 unsigned int i;
960 bitfield flags [ARRAY_SIZE (cpu_flags)];
961
962 /* Copy the default cpu flags. */
963 memcpy (flags, cpu_flags, sizeof (cpu_flags));
964
965 if (strcasecmp (flag, "unknown") == 0)
966 {
967 /* We turn on everything except for cpu64 in case of
968 CPU_UNKNOWN_FLAGS. */
969 for (i = 0; i < ARRAY_SIZE (flags); i++)
970 if (flags[i].position != Cpu64)
971 flags[i].value = 1;
972 }
973 else if (flag[0] == '~')
974 {
975 last = flag + strlen (flag);
976
977 if (flag[1] == '(')
978 {
979 last -= 1;
980 next = flag + 2;
981 if (*last != ')')
982 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
983 lineno, flag);
984 *last = '\0';
985 }
986 else
987 next = flag + 1;
988
989 /* First we turn on everything except for cpu64. */
990 for (i = 0; i < ARRAY_SIZE (flags); i++)
991 if (flags[i].position != Cpu64)
992 flags[i].value = 1;
993
994 /* Turn off selective bits. */
995 for (; next && next < last; )
996 {
997 str = next_field (next, '|', &next, last);
998 if (str)
999 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1000 }
1001 }
1002 else if (strcmp (flag, "0"))
1003 {
1004 /* Turn on selective bits. */
1005 last = flag + strlen (flag);
1006 for (next = flag; next && next < last; )
1007 {
1008 str = next_field (next, '|', &next, last);
1009 if (str)
1010 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1011 }
1012 }
1013
1014 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1015 comma, indent);
1016 }
1017
1018 static void
1019 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1020 {
1021 unsigned int i;
1022
1023 fprintf (table, " { ");
1024
1025 for (i = 0; i < size - 1; i++)
1026 {
1027 if (((i + 1) % 20) != 0)
1028 fprintf (table, "%d, ", modifier[i].value);
1029 else
1030 fprintf (table, "%d,", modifier[i].value);
1031 if (((i + 1) % 20) == 0)
1032 fprintf (table, "\n ");
1033 }
1034
1035 fprintf (table, "%d },\n", modifier[i].value);
1036 }
1037
1038 static int
1039 adjust_broadcast_modifier (char **opnd)
1040 {
1041 char *str, *next, *last, *op;
1042 int bcst_type = INT_MAX;
1043
1044 /* Skip the immediate operand. */
1045 op = opnd[0];
1046 if (strcasecmp(op, "Imm8") == 0)
1047 op = opnd[1];
1048
1049 op = xstrdup (op);
1050 last = op + strlen (op);
1051 for (next = op; next && next < last; )
1052 {
1053 str = next_field (next, '|', &next, last);
1054 if (str)
1055 {
1056 if (strcasecmp(str, "Byte") == 0)
1057 {
1058 /* The smalest broadcast type, no need to check
1059 further. */
1060 bcst_type = BYTE_BROADCAST;
1061 break;
1062 }
1063 else if (strcasecmp(str, "Word") == 0)
1064 {
1065 if (bcst_type > WORD_BROADCAST)
1066 bcst_type = WORD_BROADCAST;
1067 }
1068 else if (strcasecmp(str, "Dword") == 0)
1069 {
1070 if (bcst_type > DWORD_BROADCAST)
1071 bcst_type = DWORD_BROADCAST;
1072 }
1073 else if (strcasecmp(str, "Qword") == 0)
1074 {
1075 if (bcst_type > QWORD_BROADCAST)
1076 bcst_type = QWORD_BROADCAST;
1077 }
1078 }
1079 }
1080 free (op);
1081
1082 if (bcst_type == INT_MAX)
1083 fail (_("unknown broadcast operand: %s\n"), op);
1084
1085 return bcst_type;
1086 }
1087
1088 static void
1089 process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
1090 {
1091 char *str, *next, *last;
1092 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1093
1094 active_isstring = 0;
1095
1096 /* Copy the default opcode modifier. */
1097 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1098
1099 if (strcmp (mod, "0"))
1100 {
1101 unsigned int have_w = 0, bwlq_suf = 0xf;
1102
1103 last = mod + strlen (mod);
1104 for (next = mod; next && next < last; )
1105 {
1106 str = next_field (next, '|', &next, last);
1107 if (str)
1108 {
1109 int val = 1;
1110 if (strcasecmp(str, "Broadcast") == 0)
1111 val = adjust_broadcast_modifier (opnd);
1112 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1113 lineno);
1114 if (strcasecmp(str, "IsString") == 0)
1115 active_isstring = 1;
1116
1117 if (strcasecmp(str, "W") == 0)
1118 have_w = 1;
1119
1120 if (strcasecmp(str, "No_bSuf") == 0)
1121 bwlq_suf &= ~1;
1122 if (strcasecmp(str, "No_wSuf") == 0)
1123 bwlq_suf &= ~2;
1124 if (strcasecmp(str, "No_lSuf") == 0)
1125 bwlq_suf &= ~4;
1126 if (strcasecmp(str, "No_qSuf") == 0)
1127 bwlq_suf &= ~8;
1128 }
1129 }
1130
1131 if (have_w && !bwlq_suf)
1132 fail ("%s: %d: stray W modifier\n", filename, lineno);
1133 if (have_w && !(bwlq_suf & 1))
1134 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1135 filename, lineno);
1136 if (have_w && !(bwlq_suf & ~1))
1137 fprintf (stderr,
1138 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1139 filename, lineno);
1140 }
1141 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1142 }
1143
1144 enum stage {
1145 stage_macros,
1146 stage_opcodes,
1147 stage_registers,
1148 };
1149
1150 static void
1151 output_operand_type (FILE *table, enum operand_class class,
1152 enum operand_instance instance,
1153 const bitfield *types, unsigned int size,
1154 enum stage stage, const char *indent)
1155 {
1156 unsigned int i;
1157
1158 fprintf (table, "{ { %d, %d, ", class, instance);
1159
1160 for (i = 0; i < size - 1; i++)
1161 {
1162 if (((i + 3) % 20) != 0)
1163 fprintf (table, "%d, ", types[i].value);
1164 else
1165 fprintf (table, "%d,", types[i].value);
1166 if (((i + 3) % 20) == 0)
1167 {
1168 /* We need \\ for macro. */
1169 if (stage == stage_macros)
1170 fprintf (table, " \\\n%s", indent);
1171 else
1172 fprintf (table, "\n%s", indent);
1173 }
1174 }
1175
1176 fprintf (table, "%d } }", types[i].value);
1177 }
1178
1179 static void
1180 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1181 const char *indent, int lineno)
1182 {
1183 char *str, *next, *last;
1184 enum operand_class class = ClassNone;
1185 enum operand_instance instance = InstanceNone;
1186 bitfield types [ARRAY_SIZE (operand_types)];
1187
1188 /* Copy the default operand type. */
1189 memcpy (types, operand_types, sizeof (types));
1190
1191 if (strcmp (op, "0"))
1192 {
1193 int baseindex = 0;
1194
1195 last = op + strlen (op);
1196 for (next = op; next && next < last; )
1197 {
1198 str = next_field (next, '|', &next, last);
1199 if (str)
1200 {
1201 unsigned int i;
1202
1203 if (!strncmp(str, "Class=", 6))
1204 {
1205 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1206 if (!strcmp(str + 6, operand_classes[i].name))
1207 {
1208 class = operand_classes[i].value;
1209 str = NULL;
1210 break;
1211 }
1212 }
1213
1214 if (str && !strncmp(str, "Instance=", 9))
1215 {
1216 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1217 if (!strcmp(str + 9, operand_instances[i].name))
1218 {
1219 instance = operand_instances[i].value;
1220 str = NULL;
1221 break;
1222 }
1223 }
1224 }
1225 if (str)
1226 {
1227 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1228 if (strcasecmp(str, "BaseIndex") == 0)
1229 baseindex = 1;
1230 }
1231 }
1232
1233 if (stage == stage_opcodes && baseindex && !active_isstring)
1234 {
1235 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1236 if (!active_cpu_flags.bitfield.cpu64
1237 && !active_cpu_flags.bitfield.cpumpx)
1238 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1239 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1240 if (!active_cpu_flags.bitfield.cpuno64)
1241 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1242 }
1243 }
1244 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1245 stage, indent);
1246 }
1247
1248 static void
1249 output_i386_opcode (FILE *table, const char *name, char *str,
1250 char *last, int lineno)
1251 {
1252 unsigned int i;
1253 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1254 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1255
1256 /* Find number of operands. */
1257 operands = next_field (str, ',', &str, last);
1258
1259 /* Find base_opcode. */
1260 base_opcode = next_field (str, ',', &str, last);
1261
1262 /* Find extension_opcode. */
1263 extension_opcode = next_field (str, ',', &str, last);
1264
1265 /* Find opcode_length. */
1266 opcode_length = next_field (str, ',', &str, last);
1267
1268 /* Find cpu_flags. */
1269 cpu_flags = next_field (str, ',', &str, last);
1270
1271 /* Find opcode_modifier. */
1272 opcode_modifier = next_field (str, ',', &str, last);
1273
1274 /* Remove the first {. */
1275 str = remove_leading_whitespaces (str);
1276 if (*str != '{')
1277 abort ();
1278 str = remove_leading_whitespaces (str + 1);
1279
1280 i = strlen (str);
1281
1282 /* There are at least "X}". */
1283 if (i < 2)
1284 abort ();
1285
1286 /* Remove trailing white spaces and }. */
1287 do
1288 {
1289 i--;
1290 if (ISSPACE (str[i]) || str[i] == '}')
1291 str[i] = '\0';
1292 else
1293 break;
1294 }
1295 while (i != 0);
1296
1297 last = str + i;
1298
1299 /* Find operand_types. */
1300 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1301 {
1302 if (str >= last)
1303 {
1304 operand_types [i] = NULL;
1305 break;
1306 }
1307
1308 operand_types [i] = next_field (str, ',', &str, last);
1309 if (*operand_types[i] == '0')
1310 {
1311 if (i != 0)
1312 operand_types[i] = NULL;
1313 break;
1314 }
1315 }
1316
1317 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1318 name, base_opcode, extension_opcode, opcode_length, operands);
1319
1320 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1321
1322 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
1323
1324 fprintf (table, " { ");
1325
1326 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1327 {
1328 if (operand_types[i] == NULL || *operand_types[i] == '0')
1329 {
1330 if (i == 0)
1331 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1332 lineno);
1333 break;
1334 }
1335
1336 if (i != 0)
1337 fprintf (table, ",\n ");
1338
1339 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1340 "\t ", lineno);
1341 }
1342 fprintf (table, " } },\n");
1343 }
1344
1345 struct opcode_hash_entry
1346 {
1347 struct opcode_hash_entry *next;
1348 char *name;
1349 char *opcode;
1350 int lineno;
1351 };
1352
1353 /* Calculate the hash value of an opcode hash entry P. */
1354
1355 static hashval_t
1356 opcode_hash_hash (const void *p)
1357 {
1358 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1359 return htab_hash_string (entry->name);
1360 }
1361
1362 /* Compare a string Q against an opcode hash entry P. */
1363
1364 static int
1365 opcode_hash_eq (const void *p, const void *q)
1366 {
1367 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1368 const char *name = (const char *) q;
1369 return strcmp (name, entry->name) == 0;
1370 }
1371
1372 static void
1373 process_i386_opcodes (FILE *table)
1374 {
1375 FILE *fp;
1376 char buf[2048];
1377 unsigned int i, j;
1378 char *str, *p, *last, *name;
1379 struct opcode_hash_entry **hash_slot, **entry, *next;
1380 htab_t opcode_hash_table;
1381 struct opcode_hash_entry **opcode_array;
1382 unsigned int opcode_array_size = 1024;
1383 int lineno = 0, marker = 0;
1384
1385 filename = "i386-opc.tbl";
1386 fp = stdin;
1387
1388 i = 0;
1389 opcode_array = (struct opcode_hash_entry **)
1390 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1391
1392 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1393 opcode_hash_eq, NULL,
1394 xcalloc, free);
1395
1396 fprintf (table, "\n/* i386 opcode table. */\n\n");
1397 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1398
1399 /* Put everything on opcode array. */
1400 while (!feof (fp))
1401 {
1402 if (fgets (buf, sizeof (buf), fp) == NULL)
1403 break;
1404
1405 lineno++;
1406
1407 p = remove_leading_whitespaces (buf);
1408
1409 /* Skip comments. */
1410 str = strstr (p, "//");
1411 if (str != NULL)
1412 str[0] = '\0';
1413
1414 /* Remove trailing white spaces. */
1415 remove_trailing_whitespaces (p);
1416
1417 switch (p[0])
1418 {
1419 case '#':
1420 if (!strcmp("### MARKER ###", buf))
1421 marker = 1;
1422 else
1423 {
1424 /* Since we ignore all included files (we only care about their
1425 #define-s here), we don't need to monitor filenames. The final
1426 line number directive is going to refer to the main source file
1427 again. */
1428 char *end;
1429 unsigned long ln;
1430
1431 p = remove_leading_whitespaces (p + 1);
1432 if (!strncmp(p, "line", 4))
1433 p += 4;
1434 ln = strtoul (p, &end, 10);
1435 if (ln > 1 && ln < INT_MAX
1436 && *remove_leading_whitespaces (end) == '"')
1437 lineno = ln - 1;
1438 }
1439 /* Ignore comments. */
1440 case '\0':
1441 continue;
1442 break;
1443 default:
1444 if (!marker)
1445 continue;
1446 break;
1447 }
1448
1449 last = p + strlen (p);
1450
1451 /* Find name. */
1452 name = next_field (p, ',', &str, last);
1453
1454 /* Get the slot in hash table. */
1455 hash_slot = (struct opcode_hash_entry **)
1456 htab_find_slot_with_hash (opcode_hash_table, name,
1457 htab_hash_string (name),
1458 INSERT);
1459
1460 if (*hash_slot == NULL)
1461 {
1462 /* It is the new one. Put it on opcode array. */
1463 if (i >= opcode_array_size)
1464 {
1465 /* Grow the opcode array when needed. */
1466 opcode_array_size += 1024;
1467 opcode_array = (struct opcode_hash_entry **)
1468 xrealloc (opcode_array,
1469 sizeof (*opcode_array) * opcode_array_size);
1470 }
1471
1472 opcode_array[i] = (struct opcode_hash_entry *)
1473 xmalloc (sizeof (struct opcode_hash_entry));
1474 opcode_array[i]->next = NULL;
1475 opcode_array[i]->name = xstrdup (name);
1476 opcode_array[i]->opcode = xstrdup (str);
1477 opcode_array[i]->lineno = lineno;
1478 *hash_slot = opcode_array[i];
1479 i++;
1480 }
1481 else
1482 {
1483 /* Append it to the existing one. */
1484 entry = hash_slot;
1485 while ((*entry) != NULL)
1486 entry = &(*entry)->next;
1487 *entry = (struct opcode_hash_entry *)
1488 xmalloc (sizeof (struct opcode_hash_entry));
1489 (*entry)->next = NULL;
1490 (*entry)->name = (*hash_slot)->name;
1491 (*entry)->opcode = xstrdup (str);
1492 (*entry)->lineno = lineno;
1493 }
1494 }
1495
1496 /* Process opcode array. */
1497 for (j = 0; j < i; j++)
1498 {
1499 for (next = opcode_array[j]; next; next = next->next)
1500 {
1501 name = next->name;
1502 str = next->opcode;
1503 lineno = next->lineno;
1504 last = str + strlen (str);
1505 output_i386_opcode (table, name, str, last, lineno);
1506 }
1507 }
1508
1509 fclose (fp);
1510
1511 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1512
1513 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1514
1515 process_i386_opcode_modifier (table, "0", NULL, -1);
1516
1517 fprintf (table, " { ");
1518 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1519 fprintf (table, " } }\n");
1520
1521 fprintf (table, "};\n");
1522 }
1523
1524 static void
1525 process_i386_registers (FILE *table)
1526 {
1527 FILE *fp;
1528 char buf[2048];
1529 char *str, *p, *last;
1530 char *reg_name, *reg_type, *reg_flags, *reg_num;
1531 char *dw2_32_num, *dw2_64_num;
1532 int lineno = 0;
1533
1534 filename = "i386-reg.tbl";
1535 fp = fopen (filename, "r");
1536 if (fp == NULL)
1537 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1538 xstrerror (errno));
1539
1540 fprintf (table, "\n/* i386 register table. */\n\n");
1541 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1542
1543 while (!feof (fp))
1544 {
1545 if (fgets (buf, sizeof (buf), fp) == NULL)
1546 break;
1547
1548 lineno++;
1549
1550 p = remove_leading_whitespaces (buf);
1551
1552 /* Skip comments. */
1553 str = strstr (p, "//");
1554 if (str != NULL)
1555 str[0] = '\0';
1556
1557 /* Remove trailing white spaces. */
1558 remove_trailing_whitespaces (p);
1559
1560 switch (p[0])
1561 {
1562 case '#':
1563 fprintf (table, "%s\n", p);
1564 case '\0':
1565 continue;
1566 break;
1567 default:
1568 break;
1569 }
1570
1571 last = p + strlen (p);
1572
1573 /* Find reg_name. */
1574 reg_name = next_field (p, ',', &str, last);
1575
1576 /* Find reg_type. */
1577 reg_type = next_field (str, ',', &str, last);
1578
1579 /* Find reg_flags. */
1580 reg_flags = next_field (str, ',', &str, last);
1581
1582 /* Find reg_num. */
1583 reg_num = next_field (str, ',', &str, last);
1584
1585 fprintf (table, " { \"%s\",\n ", reg_name);
1586
1587 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1588 lineno);
1589
1590 /* Find 32-bit Dwarf2 register number. */
1591 dw2_32_num = next_field (str, ',', &str, last);
1592
1593 /* Find 64-bit Dwarf2 register number. */
1594 dw2_64_num = next_field (str, ',', &str, last);
1595
1596 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1597 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1598 }
1599
1600 fclose (fp);
1601
1602 fprintf (table, "};\n");
1603
1604 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1605 }
1606
1607 static void
1608 process_i386_initializers (void)
1609 {
1610 unsigned int i;
1611 FILE *fp = fopen ("i386-init.h", "w");
1612 char *init;
1613
1614 if (fp == NULL)
1615 fail (_("can't create i386-init.h, errno = %s\n"),
1616 xstrerror (errno));
1617
1618 process_copyright (fp);
1619
1620 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1621 {
1622 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1623 init = xstrdup (cpu_flag_init[i].init);
1624 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1625 free (init);
1626 }
1627
1628 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1629 {
1630 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1631 init = xstrdup (operand_type_init[i].init);
1632 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1633 free (init);
1634 }
1635 fprintf (fp, "\n");
1636
1637 fclose (fp);
1638 }
1639
1640 /* Program options. */
1641 #define OPTION_SRCDIR 200
1642
1643 struct option long_options[] =
1644 {
1645 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1646 {"debug", no_argument, NULL, 'd'},
1647 {"version", no_argument, NULL, 'V'},
1648 {"help", no_argument, NULL, 'h'},
1649 {0, no_argument, NULL, 0}
1650 };
1651
1652 static void
1653 print_version (void)
1654 {
1655 printf ("%s: version 1.0\n", program_name);
1656 xexit (0);
1657 }
1658
1659 static void
1660 usage (FILE * stream, int status)
1661 {
1662 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1663 program_name);
1664 xexit (status);
1665 }
1666
1667 int
1668 main (int argc, char **argv)
1669 {
1670 extern int chdir (char *);
1671 char *srcdir = NULL;
1672 int c;
1673 unsigned int i, cpumax;
1674 FILE *table;
1675
1676 program_name = *argv;
1677 xmalloc_set_program_name (program_name);
1678
1679 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1680 switch (c)
1681 {
1682 case OPTION_SRCDIR:
1683 srcdir = optarg;
1684 break;
1685 case 'V':
1686 case 'v':
1687 print_version ();
1688 break;
1689 case 'd':
1690 debug = 1;
1691 break;
1692 case 'h':
1693 case '?':
1694 usage (stderr, 0);
1695 default:
1696 case 0:
1697 break;
1698 }
1699
1700 if (optind != argc)
1701 usage (stdout, 1);
1702
1703 if (srcdir != NULL)
1704 if (chdir (srcdir) != 0)
1705 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1706 srcdir, xstrerror (errno));
1707
1708 /* cpu_flags isn't sorted by position. */
1709 cpumax = 0;
1710 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1711 if (cpu_flags[i].position > cpumax)
1712 cpumax = cpu_flags[i].position;
1713
1714 /* Check the unused bitfield in i386_cpu_flags. */
1715 #ifdef CpuUnused
1716 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1717
1718 if ((cpumax - 1) != CpuMax)
1719 fail (_("CpuMax != %d!\n"), cpumax);
1720 #else
1721 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1722
1723 if (cpumax != CpuMax)
1724 fail (_("CpuMax != %d!\n"), cpumax);
1725
1726 c = CpuNumOfBits - CpuMax - 1;
1727 if (c)
1728 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1729 #endif
1730
1731 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1732
1733 /* Check the unused bitfield in i386_operand_type. */
1734 #ifdef OTUnused
1735 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1736 == OTNum + 1);
1737 #else
1738 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1739 == OTNum);
1740
1741 c = OTNumOfBits - OTNum;
1742 if (c)
1743 fail (_("%d unused bits in i386_operand_type.\n"), c);
1744 #endif
1745
1746 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1747 compare);
1748
1749 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1750 sizeof (opcode_modifiers [0]), compare);
1751
1752 qsort (operand_types, ARRAY_SIZE (operand_types),
1753 sizeof (operand_types [0]), compare);
1754
1755 table = fopen ("i386-tbl.h", "w");
1756 if (table == NULL)
1757 fail (_("can't create i386-tbl.h, errno = %s\n"),
1758 xstrerror (errno));
1759
1760 process_copyright (table);
1761
1762 process_i386_opcodes (table);
1763 process_i386_registers (table);
1764 process_i386_initializers ();
1765
1766 fclose (table);
1767
1768 exit (0);
1769 }
This page took 0.067388 seconds and 4 git commands to generate.