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