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