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