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