Add support for Intel ENQCMD[S] instructions
[deliverable/binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.
2
3 This file is part of the GNU opcodes library.
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
19
20 #include "sysdep.h"
21 #include <stdio.h>
22 #include <errno.h>
23 #include "getopt.h"
24 #include "libiberty.h"
25 #include "hashtab.h"
26 #include "safe-ctype.h"
27
28 #include "i386-opc.h"
29
30 #include <libintl.h>
31 #define _(String) gettext (String)
32
33 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_ENQCMD_FLAGS",
299 "CpuENQCMD" },
300 { "CPU_ANY_X87_FLAGS",
301 "CPU_ANY_287_FLAGS|Cpu8087" },
302 { "CPU_ANY_287_FLAGS",
303 "CPU_ANY_387_FLAGS|Cpu287" },
304 { "CPU_ANY_387_FLAGS",
305 "CPU_ANY_687_FLAGS|Cpu387" },
306 { "CPU_ANY_687_FLAGS",
307 "Cpu687|CpuFISTTP" },
308 { "CPU_ANY_CMOV_FLAGS",
309 "CpuCMOV" },
310 { "CPU_ANY_FXSR_FLAGS",
311 "CpuFXSR" },
312 { "CPU_ANY_MMX_FLAGS",
313 "CPU_3DNOWA_FLAGS" },
314 { "CPU_ANY_SSE_FLAGS",
315 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
316 { "CPU_ANY_SSE2_FLAGS",
317 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
318 { "CPU_ANY_SSE3_FLAGS",
319 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
320 { "CPU_ANY_SSSE3_FLAGS",
321 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
322 { "CPU_ANY_SSE4_1_FLAGS",
323 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
324 { "CPU_ANY_SSE4_2_FLAGS",
325 "CpuSSE4_2" },
326 { "CPU_ANY_AVX_FLAGS",
327 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
328 { "CPU_ANY_AVX2_FLAGS",
329 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
330 { "CPU_ANY_AVX512F_FLAGS",
331 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16" },
332 { "CPU_ANY_AVX512CD_FLAGS",
333 "CpuAVX512CD" },
334 { "CPU_ANY_AVX512ER_FLAGS",
335 "CpuAVX512ER" },
336 { "CPU_ANY_AVX512PF_FLAGS",
337 "CpuAVX512PF" },
338 { "CPU_ANY_AVX512DQ_FLAGS",
339 "CpuAVX512DQ" },
340 { "CPU_ANY_AVX512BW_FLAGS",
341 "CpuAVX512BW" },
342 { "CPU_ANY_AVX512VL_FLAGS",
343 "CpuAVX512VL" },
344 { "CPU_ANY_AVX512IFMA_FLAGS",
345 "CpuAVX512IFMA" },
346 { "CPU_ANY_AVX512VBMI_FLAGS",
347 "CpuAVX512VBMI" },
348 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
349 "CpuAVX512_4FMAPS" },
350 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
351 "CpuAVX512_4VNNIW" },
352 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
353 "CpuAVX512_VPOPCNTDQ" },
354 { "CPU_ANY_IBT_FLAGS",
355 "CpuIBT" },
356 { "CPU_ANY_SHSTK_FLAGS",
357 "CpuSHSTK" },
358 { "CPU_ANY_AVX512_VBMI2_FLAGS",
359 "CpuAVX512_VBMI2" },
360 { "CPU_ANY_AVX512_VNNI_FLAGS",
361 "CpuAVX512_VNNI" },
362 { "CPU_ANY_AVX512_BITALG_FLAGS",
363 "CpuAVX512_BITALG" },
364 { "CPU_ANY_AVX512_BF16_FLAGS",
365 "CpuAVX512_BF16" },
366 { "CPU_ANY_MOVDIRI_FLAGS",
367 "CpuMOVDIRI" },
368 { "CPU_ANY_MOVDIR64B_FLAGS",
369 "CpuMOVDIR64B" },
370 { "CPU_ANY_ENQCMD_FLAGS",
371 "CpuENQCMD" },
372 };
373
374 static const initializer operand_type_shorthands[] =
375 {
376 { "Reg8", "Reg|Byte" },
377 { "Reg16", "Reg|Word" },
378 { "Reg32", "Reg|Dword" },
379 { "Reg64", "Reg|Qword" },
380 { "FloatAcc", "Acc|Tbyte" },
381 { "FloatReg", "Reg|Tbyte" },
382 { "RegXMM", "RegSIMD|Xmmword" },
383 { "RegYMM", "RegSIMD|Ymmword" },
384 { "RegZMM", "RegSIMD|Zmmword" },
385 };
386
387 static initializer operand_type_init[] =
388 {
389 { "OPERAND_TYPE_NONE",
390 "0" },
391 { "OPERAND_TYPE_REG8",
392 "Reg8" },
393 { "OPERAND_TYPE_REG16",
394 "Reg16" },
395 { "OPERAND_TYPE_REG32",
396 "Reg32" },
397 { "OPERAND_TYPE_REG64",
398 "Reg64" },
399 { "OPERAND_TYPE_IMM1",
400 "Imm1" },
401 { "OPERAND_TYPE_IMM8",
402 "Imm8" },
403 { "OPERAND_TYPE_IMM8S",
404 "Imm8S" },
405 { "OPERAND_TYPE_IMM16",
406 "Imm16" },
407 { "OPERAND_TYPE_IMM32",
408 "Imm32" },
409 { "OPERAND_TYPE_IMM32S",
410 "Imm32S" },
411 { "OPERAND_TYPE_IMM64",
412 "Imm64" },
413 { "OPERAND_TYPE_BASEINDEX",
414 "BaseIndex" },
415 { "OPERAND_TYPE_DISP8",
416 "Disp8" },
417 { "OPERAND_TYPE_DISP16",
418 "Disp16" },
419 { "OPERAND_TYPE_DISP32",
420 "Disp32" },
421 { "OPERAND_TYPE_DISP32S",
422 "Disp32S" },
423 { "OPERAND_TYPE_DISP64",
424 "Disp64" },
425 { "OPERAND_TYPE_INOUTPORTREG",
426 "InOutPortReg" },
427 { "OPERAND_TYPE_SHIFTCOUNT",
428 "ShiftCount" },
429 { "OPERAND_TYPE_CONTROL",
430 "Control" },
431 { "OPERAND_TYPE_TEST",
432 "Test" },
433 { "OPERAND_TYPE_DEBUG",
434 "FloatReg" },
435 { "OPERAND_TYPE_FLOATREG",
436 "FloatReg" },
437 { "OPERAND_TYPE_FLOATACC",
438 "FloatAcc" },
439 { "OPERAND_TYPE_SREG2",
440 "SReg2" },
441 { "OPERAND_TYPE_SREG3",
442 "SReg3" },
443 { "OPERAND_TYPE_ACC",
444 "Acc" },
445 { "OPERAND_TYPE_JUMPABSOLUTE",
446 "JumpAbsolute" },
447 { "OPERAND_TYPE_REGMMX",
448 "RegMMX" },
449 { "OPERAND_TYPE_REGXMM",
450 "RegXMM" },
451 { "OPERAND_TYPE_REGYMM",
452 "RegYMM" },
453 { "OPERAND_TYPE_REGZMM",
454 "RegZMM" },
455 { "OPERAND_TYPE_REGMASK",
456 "RegMask" },
457 { "OPERAND_TYPE_ESSEG",
458 "EsSeg" },
459 { "OPERAND_TYPE_ACC32",
460 "Reg32|Acc|Dword" },
461 { "OPERAND_TYPE_ACC64",
462 "Reg64|Acc|Qword" },
463 { "OPERAND_TYPE_DISP16_32",
464 "Disp16|Disp32" },
465 { "OPERAND_TYPE_ANYDISP",
466 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
467 { "OPERAND_TYPE_IMM16_32",
468 "Imm16|Imm32" },
469 { "OPERAND_TYPE_IMM16_32S",
470 "Imm16|Imm32S" },
471 { "OPERAND_TYPE_IMM16_32_32S",
472 "Imm16|Imm32|Imm32S" },
473 { "OPERAND_TYPE_IMM32_64",
474 "Imm32|Imm64" },
475 { "OPERAND_TYPE_IMM32_32S_DISP32",
476 "Imm32|Imm32S|Disp32" },
477 { "OPERAND_TYPE_IMM64_DISP64",
478 "Imm64|Disp64" },
479 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
480 "Imm32|Imm32S|Imm64|Disp32" },
481 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
482 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
483 { "OPERAND_TYPE_VEC_IMM4",
484 "Vec_Imm4" },
485 { "OPERAND_TYPE_REGBND",
486 "RegBND" },
487 };
488
489 typedef struct bitfield
490 {
491 int position;
492 int value;
493 const char *name;
494 } bitfield;
495
496 #define BITFIELD(n) { n, 0, #n }
497
498 static bitfield cpu_flags[] =
499 {
500 BITFIELD (Cpu186),
501 BITFIELD (Cpu286),
502 BITFIELD (Cpu386),
503 BITFIELD (Cpu486),
504 BITFIELD (Cpu586),
505 BITFIELD (Cpu686),
506 BITFIELD (CpuCMOV),
507 BITFIELD (CpuFXSR),
508 BITFIELD (CpuClflush),
509 BITFIELD (CpuNop),
510 BITFIELD (CpuSYSCALL),
511 BITFIELD (Cpu8087),
512 BITFIELD (Cpu287),
513 BITFIELD (Cpu387),
514 BITFIELD (Cpu687),
515 BITFIELD (CpuFISTTP),
516 BITFIELD (CpuMMX),
517 BITFIELD (CpuSSE),
518 BITFIELD (CpuSSE2),
519 BITFIELD (CpuSSE3),
520 BITFIELD (CpuSSSE3),
521 BITFIELD (CpuSSE4_1),
522 BITFIELD (CpuSSE4_2),
523 BITFIELD (CpuAVX),
524 BITFIELD (CpuAVX2),
525 BITFIELD (CpuAVX512F),
526 BITFIELD (CpuAVX512CD),
527 BITFIELD (CpuAVX512ER),
528 BITFIELD (CpuAVX512PF),
529 BITFIELD (CpuAVX512VL),
530 BITFIELD (CpuAVX512DQ),
531 BITFIELD (CpuAVX512BW),
532 BITFIELD (CpuL1OM),
533 BITFIELD (CpuK1OM),
534 BITFIELD (CpuIAMCU),
535 BITFIELD (CpuSSE4a),
536 BITFIELD (Cpu3dnow),
537 BITFIELD (Cpu3dnowA),
538 BITFIELD (CpuPadLock),
539 BITFIELD (CpuSVME),
540 BITFIELD (CpuVMX),
541 BITFIELD (CpuSMX),
542 BITFIELD (CpuABM),
543 BITFIELD (CpuXsave),
544 BITFIELD (CpuXsaveopt),
545 BITFIELD (CpuAES),
546 BITFIELD (CpuPCLMUL),
547 BITFIELD (CpuFMA),
548 BITFIELD (CpuFMA4),
549 BITFIELD (CpuXOP),
550 BITFIELD (CpuLWP),
551 BITFIELD (CpuBMI),
552 BITFIELD (CpuTBM),
553 BITFIELD (CpuLM),
554 BITFIELD (CpuMovbe),
555 BITFIELD (CpuCX16),
556 BITFIELD (CpuEPT),
557 BITFIELD (CpuRdtscp),
558 BITFIELD (CpuFSGSBase),
559 BITFIELD (CpuRdRnd),
560 BITFIELD (CpuF16C),
561 BITFIELD (CpuBMI2),
562 BITFIELD (CpuLZCNT),
563 BITFIELD (CpuHLE),
564 BITFIELD (CpuRTM),
565 BITFIELD (CpuINVPCID),
566 BITFIELD (CpuVMFUNC),
567 BITFIELD (CpuRDSEED),
568 BITFIELD (CpuADX),
569 BITFIELD (CpuPRFCHW),
570 BITFIELD (CpuSMAP),
571 BITFIELD (CpuSHA),
572 BITFIELD (CpuClflushOpt),
573 BITFIELD (CpuXSAVES),
574 BITFIELD (CpuXSAVEC),
575 BITFIELD (CpuPREFETCHWT1),
576 BITFIELD (CpuSE1),
577 BITFIELD (CpuCLWB),
578 BITFIELD (Cpu64),
579 BITFIELD (CpuNo64),
580 BITFIELD (CpuMPX),
581 BITFIELD (CpuAVX512IFMA),
582 BITFIELD (CpuAVX512VBMI),
583 BITFIELD (CpuAVX512_4FMAPS),
584 BITFIELD (CpuAVX512_4VNNIW),
585 BITFIELD (CpuAVX512_VPOPCNTDQ),
586 BITFIELD (CpuAVX512_VBMI2),
587 BITFIELD (CpuAVX512_VNNI),
588 BITFIELD (CpuAVX512_BITALG),
589 BITFIELD (CpuAVX512_BF16),
590 BITFIELD (CpuMWAITX),
591 BITFIELD (CpuCLZERO),
592 BITFIELD (CpuOSPKE),
593 BITFIELD (CpuRDPID),
594 BITFIELD (CpuPTWRITE),
595 BITFIELD (CpuIBT),
596 BITFIELD (CpuSHSTK),
597 BITFIELD (CpuGFNI),
598 BITFIELD (CpuVAES),
599 BITFIELD (CpuVPCLMULQDQ),
600 BITFIELD (CpuWBNOINVD),
601 BITFIELD (CpuPCONFIG),
602 BITFIELD (CpuWAITPKG),
603 BITFIELD (CpuCLDEMOTE),
604 BITFIELD (CpuMOVDIRI),
605 BITFIELD (CpuMOVDIR64B),
606 BITFIELD (CpuENQCMD),
607 #ifdef CpuUnused
608 BITFIELD (CpuUnused),
609 #endif
610 };
611
612 static bitfield opcode_modifiers[] =
613 {
614 BITFIELD (D),
615 BITFIELD (W),
616 BITFIELD (Load),
617 BITFIELD (Modrm),
618 BITFIELD (ShortForm),
619 BITFIELD (Jump),
620 BITFIELD (JumpDword),
621 BITFIELD (JumpByte),
622 BITFIELD (JumpInterSegment),
623 BITFIELD (FloatMF),
624 BITFIELD (FloatR),
625 BITFIELD (Size),
626 BITFIELD (CheckRegSize),
627 BITFIELD (IgnoreSize),
628 BITFIELD (DefaultSize),
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 (BNDPrefixOk),
638 BITFIELD (NoTrackPrefixOk),
639 BITFIELD (IsLockable),
640 BITFIELD (RegKludge),
641 BITFIELD (Implicit1stXmm0),
642 BITFIELD (RepPrefixOk),
643 BITFIELD (HLEPrefixOk),
644 BITFIELD (ToDword),
645 BITFIELD (ToQword),
646 BITFIELD (AddrPrefixOpReg),
647 BITFIELD (IsPrefix),
648 BITFIELD (ImmExt),
649 BITFIELD (NoRex64),
650 BITFIELD (Rex64),
651 BITFIELD (Ugh),
652 BITFIELD (Vex),
653 BITFIELD (VexVVVV),
654 BITFIELD (VexW),
655 BITFIELD (VexOpcode),
656 BITFIELD (VexSources),
657 BITFIELD (VecSIB),
658 BITFIELD (SSE2AVX),
659 BITFIELD (NoAVX),
660 BITFIELD (EVex),
661 BITFIELD (Masking),
662 BITFIELD (Broadcast),
663 BITFIELD (StaticRounding),
664 BITFIELD (SAE),
665 BITFIELD (Disp8MemShift),
666 BITFIELD (NoDefMask),
667 BITFIELD (ImplicitQuadGroup),
668 BITFIELD (Optimize),
669 BITFIELD (ATTMnemonic),
670 BITFIELD (ATTSyntax),
671 BITFIELD (IntelSyntax),
672 BITFIELD (AMD64),
673 BITFIELD (Intel64),
674 };
675
676 static bitfield operand_types[] =
677 {
678 BITFIELD (Reg),
679 BITFIELD (RegMMX),
680 BITFIELD (RegSIMD),
681 BITFIELD (RegMask),
682 BITFIELD (Imm1),
683 BITFIELD (Imm8),
684 BITFIELD (Imm8S),
685 BITFIELD (Imm16),
686 BITFIELD (Imm32),
687 BITFIELD (Imm32S),
688 BITFIELD (Imm64),
689 BITFIELD (BaseIndex),
690 BITFIELD (Disp8),
691 BITFIELD (Disp16),
692 BITFIELD (Disp32),
693 BITFIELD (Disp32S),
694 BITFIELD (Disp64),
695 BITFIELD (InOutPortReg),
696 BITFIELD (ShiftCount),
697 BITFIELD (Control),
698 BITFIELD (Debug),
699 BITFIELD (Test),
700 BITFIELD (SReg2),
701 BITFIELD (SReg3),
702 BITFIELD (Acc),
703 BITFIELD (JumpAbsolute),
704 BITFIELD (EsSeg),
705 BITFIELD (RegMem),
706 BITFIELD (Byte),
707 BITFIELD (Word),
708 BITFIELD (Dword),
709 BITFIELD (Fword),
710 BITFIELD (Qword),
711 BITFIELD (Tbyte),
712 BITFIELD (Xmmword),
713 BITFIELD (Ymmword),
714 BITFIELD (Zmmword),
715 BITFIELD (Unspecified),
716 BITFIELD (Anysize),
717 BITFIELD (Vec_Imm4),
718 BITFIELD (RegBND),
719 #ifdef OTUnused
720 BITFIELD (OTUnused),
721 #endif
722 };
723
724 static const char *filename;
725 static i386_cpu_flags active_cpu_flags;
726 static int active_isstring;
727
728 static int
729 compare (const void *x, const void *y)
730 {
731 const bitfield *xp = (const bitfield *) x;
732 const bitfield *yp = (const bitfield *) y;
733 return xp->position - yp->position;
734 }
735
736 static void
737 fail (const char *message, ...)
738 {
739 va_list args;
740
741 va_start (args, message);
742 fprintf (stderr, _("%s: error: "), program_name);
743 vfprintf (stderr, message, args);
744 va_end (args);
745 xexit (1);
746 }
747
748 static void
749 process_copyright (FILE *fp)
750 {
751 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
752 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
753 \n\
754 This file is part of the GNU opcodes library.\n\
755 \n\
756 This library is free software; you can redistribute it and/or modify\n\
757 it under the terms of the GNU General Public License as published by\n\
758 the Free Software Foundation; either version 3, or (at your option)\n\
759 any later version.\n\
760 \n\
761 It is distributed in the hope that it will be useful, but WITHOUT\n\
762 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
763 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
764 License for more details.\n\
765 \n\
766 You should have received a copy of the GNU General Public License\n\
767 along with this program; if not, write to the Free Software\n\
768 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
769 MA 02110-1301, USA. */\n");
770 }
771
772 /* Remove leading white spaces. */
773
774 static char *
775 remove_leading_whitespaces (char *str)
776 {
777 while (ISSPACE (*str))
778 str++;
779 return str;
780 }
781
782 /* Remove trailing white spaces. */
783
784 static void
785 remove_trailing_whitespaces (char *str)
786 {
787 size_t last = strlen (str);
788
789 if (last == 0)
790 return;
791
792 do
793 {
794 last--;
795 if (ISSPACE (str [last]))
796 str[last] = '\0';
797 else
798 break;
799 }
800 while (last != 0);
801 }
802
803 /* Find next field separated by SEP and terminate it. Return a
804 pointer to the one after it. */
805
806 static char *
807 next_field (char *str, char sep, char **next, char *last)
808 {
809 char *p;
810
811 p = remove_leading_whitespaces (str);
812 for (str = p; *str != sep && *str != '\0'; str++);
813
814 *str = '\0';
815 remove_trailing_whitespaces (p);
816
817 *next = str + 1;
818
819 if (p >= last)
820 abort ();
821
822 return p;
823 }
824
825 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
826
827 static int
828 set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
829 int lineno)
830 {
831 char *str, *next, *last;
832 unsigned int i;
833
834 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
835 if (strcmp (cpu_flag_init[i].name, f) == 0)
836 {
837 /* Turn on selective bits. */
838 char *init = xstrdup (cpu_flag_init[i].init);
839 last = init + strlen (init);
840 for (next = init; next && next < last; )
841 {
842 str = next_field (next, '|', &next, last);
843 if (str)
844 set_bitfield (str, array, 1, size, lineno);
845 }
846 free (init);
847 return 0;
848 }
849
850 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
851 if (strcmp (operand_type_shorthands[i].name, f) == 0)
852 {
853 /* Turn on selective bits. */
854 char *init = xstrdup (operand_type_shorthands[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 shorthands. */
917 if (value == 1 && !set_bitfield_from_shorthand (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 last = mod + strlen (mod);
1106 for (next = mod; next && next < last; )
1107 {
1108 str = next_field (next, '|', &next, last);
1109 if (str)
1110 {
1111 int val = 1;
1112 if (strcasecmp(str, "Broadcast") == 0)
1113 val = adjust_broadcast_modifier (opnd);
1114 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1115 lineno);
1116 if (strcasecmp(str, "IsString") == 0)
1117 active_isstring = 1;
1118 }
1119 }
1120 }
1121 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1122 }
1123
1124 enum stage {
1125 stage_macros,
1126 stage_opcodes,
1127 stage_registers,
1128 };
1129
1130 static void
1131 output_operand_type (FILE *table, bitfield *types, unsigned int size,
1132 enum stage stage, const char *indent)
1133 {
1134 unsigned int i;
1135
1136 fprintf (table, "{ { ");
1137
1138 for (i = 0; i < size - 1; i++)
1139 {
1140 if (((i + 1) % 20) != 0)
1141 fprintf (table, "%d, ", types[i].value);
1142 else
1143 fprintf (table, "%d,", types[i].value);
1144 if (((i + 1) % 20) == 0)
1145 {
1146 /* We need \\ for macro. */
1147 if (stage == stage_macros)
1148 fprintf (table, " \\\n%s", indent);
1149 else
1150 fprintf (table, "\n%s", indent);
1151 }
1152 }
1153
1154 fprintf (table, "%d } }", types[i].value);
1155 }
1156
1157 static void
1158 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1159 const char *indent, int lineno)
1160 {
1161 char *str, *next, *last;
1162 bitfield types [ARRAY_SIZE (operand_types)];
1163
1164 /* Copy the default operand type. */
1165 memcpy (types, operand_types, sizeof (types));
1166
1167 if (strcmp (op, "0"))
1168 {
1169 int baseindex = 0;
1170
1171 last = op + strlen (op);
1172 for (next = op; next && next < last; )
1173 {
1174 str = next_field (next, '|', &next, last);
1175 if (str)
1176 {
1177 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1178 if (strcasecmp(str, "BaseIndex") == 0)
1179 baseindex = 1;
1180 }
1181 }
1182
1183 if (stage == stage_opcodes && baseindex && !active_isstring)
1184 {
1185 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1186 if (!active_cpu_flags.bitfield.cpu64
1187 && !active_cpu_flags.bitfield.cpumpx)
1188 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1189 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1190 if (!active_cpu_flags.bitfield.cpuno64)
1191 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1192 }
1193 }
1194 output_operand_type (table, types, ARRAY_SIZE (types), stage,
1195 indent);
1196 }
1197
1198 static void
1199 output_i386_opcode (FILE *table, const char *name, char *str,
1200 char *last, int lineno)
1201 {
1202 unsigned int i;
1203 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1204 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1205
1206 /* Find number of operands. */
1207 operands = next_field (str, ',', &str, last);
1208
1209 /* Find base_opcode. */
1210 base_opcode = next_field (str, ',', &str, last);
1211
1212 /* Find extension_opcode. */
1213 extension_opcode = next_field (str, ',', &str, last);
1214
1215 /* Find opcode_length. */
1216 opcode_length = next_field (str, ',', &str, last);
1217
1218 /* Find cpu_flags. */
1219 cpu_flags = next_field (str, ',', &str, last);
1220
1221 /* Find opcode_modifier. */
1222 opcode_modifier = next_field (str, ',', &str, last);
1223
1224 /* Remove the first {. */
1225 str = remove_leading_whitespaces (str);
1226 if (*str != '{')
1227 abort ();
1228 str = remove_leading_whitespaces (str + 1);
1229
1230 i = strlen (str);
1231
1232 /* There are at least "X}". */
1233 if (i < 2)
1234 abort ();
1235
1236 /* Remove trailing white spaces and }. */
1237 do
1238 {
1239 i--;
1240 if (ISSPACE (str[i]) || str[i] == '}')
1241 str[i] = '\0';
1242 else
1243 break;
1244 }
1245 while (i != 0);
1246
1247 last = str + i;
1248
1249 /* Find operand_types. */
1250 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1251 {
1252 if (str >= last)
1253 {
1254 operand_types [i] = NULL;
1255 break;
1256 }
1257
1258 operand_types [i] = next_field (str, ',', &str, last);
1259 if (*operand_types[i] == '0')
1260 {
1261 if (i != 0)
1262 operand_types[i] = NULL;
1263 break;
1264 }
1265 }
1266
1267 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1268 name, operands, base_opcode, extension_opcode,
1269 opcode_length);
1270
1271 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1272
1273 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
1274
1275 fprintf (table, " { ");
1276
1277 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1278 {
1279 if (operand_types[i] == NULL || *operand_types[i] == '0')
1280 {
1281 if (i == 0)
1282 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1283 lineno);
1284 break;
1285 }
1286
1287 if (i != 0)
1288 fprintf (table, ",\n ");
1289
1290 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1291 "\t ", lineno);
1292 }
1293 fprintf (table, " } },\n");
1294 }
1295
1296 struct opcode_hash_entry
1297 {
1298 struct opcode_hash_entry *next;
1299 char *name;
1300 char *opcode;
1301 int lineno;
1302 };
1303
1304 /* Calculate the hash value of an opcode hash entry P. */
1305
1306 static hashval_t
1307 opcode_hash_hash (const void *p)
1308 {
1309 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1310 return htab_hash_string (entry->name);
1311 }
1312
1313 /* Compare a string Q against an opcode hash entry P. */
1314
1315 static int
1316 opcode_hash_eq (const void *p, const void *q)
1317 {
1318 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1319 const char *name = (const char *) q;
1320 return strcmp (name, entry->name) == 0;
1321 }
1322
1323 static void
1324 process_i386_opcodes (FILE *table)
1325 {
1326 FILE *fp;
1327 char buf[2048];
1328 unsigned int i, j;
1329 char *str, *p, *last, *name;
1330 struct opcode_hash_entry **hash_slot, **entry, *next;
1331 htab_t opcode_hash_table;
1332 struct opcode_hash_entry **opcode_array;
1333 unsigned int opcode_array_size = 1024;
1334 int lineno = 0, marker = 0;
1335
1336 filename = "i386-opc.tbl";
1337 fp = stdin;
1338
1339 i = 0;
1340 opcode_array = (struct opcode_hash_entry **)
1341 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1342
1343 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1344 opcode_hash_eq, NULL,
1345 xcalloc, free);
1346
1347 fprintf (table, "\n/* i386 opcode table. */\n\n");
1348 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1349
1350 /* Put everything on opcode array. */
1351 while (!feof (fp))
1352 {
1353 if (fgets (buf, sizeof (buf), fp) == NULL)
1354 break;
1355
1356 lineno++;
1357
1358 p = remove_leading_whitespaces (buf);
1359
1360 /* Skip comments. */
1361 str = strstr (p, "//");
1362 if (str != NULL)
1363 str[0] = '\0';
1364
1365 /* Remove trailing white spaces. */
1366 remove_trailing_whitespaces (p);
1367
1368 switch (p[0])
1369 {
1370 case '#':
1371 if (!strcmp("### MARKER ###", buf))
1372 marker = 1;
1373 else
1374 {
1375 /* Since we ignore all included files (we only care about their
1376 #define-s here), we don't need to monitor filenames. The final
1377 line number directive is going to refer to the main source file
1378 again. */
1379 char *end;
1380 unsigned long ln;
1381
1382 p = remove_leading_whitespaces (p + 1);
1383 if (!strncmp(p, "line", 4))
1384 p += 4;
1385 ln = strtoul (p, &end, 10);
1386 if (ln > 1 && ln < INT_MAX
1387 && *remove_leading_whitespaces (end) == '"')
1388 lineno = ln - 1;
1389 }
1390 /* Ignore comments. */
1391 case '\0':
1392 continue;
1393 break;
1394 default:
1395 if (!marker)
1396 continue;
1397 break;
1398 }
1399
1400 last = p + strlen (p);
1401
1402 /* Find name. */
1403 name = next_field (p, ',', &str, last);
1404
1405 /* Get the slot in hash table. */
1406 hash_slot = (struct opcode_hash_entry **)
1407 htab_find_slot_with_hash (opcode_hash_table, name,
1408 htab_hash_string (name),
1409 INSERT);
1410
1411 if (*hash_slot == NULL)
1412 {
1413 /* It is the new one. Put it on opcode array. */
1414 if (i >= opcode_array_size)
1415 {
1416 /* Grow the opcode array when needed. */
1417 opcode_array_size += 1024;
1418 opcode_array = (struct opcode_hash_entry **)
1419 xrealloc (opcode_array,
1420 sizeof (*opcode_array) * opcode_array_size);
1421 }
1422
1423 opcode_array[i] = (struct opcode_hash_entry *)
1424 xmalloc (sizeof (struct opcode_hash_entry));
1425 opcode_array[i]->next = NULL;
1426 opcode_array[i]->name = xstrdup (name);
1427 opcode_array[i]->opcode = xstrdup (str);
1428 opcode_array[i]->lineno = lineno;
1429 *hash_slot = opcode_array[i];
1430 i++;
1431 }
1432 else
1433 {
1434 /* Append it to the existing one. */
1435 entry = hash_slot;
1436 while ((*entry) != NULL)
1437 entry = &(*entry)->next;
1438 *entry = (struct opcode_hash_entry *)
1439 xmalloc (sizeof (struct opcode_hash_entry));
1440 (*entry)->next = NULL;
1441 (*entry)->name = (*hash_slot)->name;
1442 (*entry)->opcode = xstrdup (str);
1443 (*entry)->lineno = lineno;
1444 }
1445 }
1446
1447 /* Process opcode array. */
1448 for (j = 0; j < i; j++)
1449 {
1450 for (next = opcode_array[j]; next; next = next->next)
1451 {
1452 name = next->name;
1453 str = next->opcode;
1454 lineno = next->lineno;
1455 last = str + strlen (str);
1456 output_i386_opcode (table, name, str, last, lineno);
1457 }
1458 }
1459
1460 fclose (fp);
1461
1462 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1463
1464 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1465
1466 process_i386_opcode_modifier (table, "0", NULL, -1);
1467
1468 fprintf (table, " { ");
1469 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1470 fprintf (table, " } }\n");
1471
1472 fprintf (table, "};\n");
1473 }
1474
1475 static void
1476 process_i386_registers (FILE *table)
1477 {
1478 FILE *fp;
1479 char buf[2048];
1480 char *str, *p, *last;
1481 char *reg_name, *reg_type, *reg_flags, *reg_num;
1482 char *dw2_32_num, *dw2_64_num;
1483 int lineno = 0;
1484
1485 filename = "i386-reg.tbl";
1486 fp = fopen (filename, "r");
1487 if (fp == NULL)
1488 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1489 xstrerror (errno));
1490
1491 fprintf (table, "\n/* i386 register table. */\n\n");
1492 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1493
1494 while (!feof (fp))
1495 {
1496 if (fgets (buf, sizeof (buf), fp) == NULL)
1497 break;
1498
1499 lineno++;
1500
1501 p = remove_leading_whitespaces (buf);
1502
1503 /* Skip comments. */
1504 str = strstr (p, "//");
1505 if (str != NULL)
1506 str[0] = '\0';
1507
1508 /* Remove trailing white spaces. */
1509 remove_trailing_whitespaces (p);
1510
1511 switch (p[0])
1512 {
1513 case '#':
1514 fprintf (table, "%s\n", p);
1515 case '\0':
1516 continue;
1517 break;
1518 default:
1519 break;
1520 }
1521
1522 last = p + strlen (p);
1523
1524 /* Find reg_name. */
1525 reg_name = next_field (p, ',', &str, last);
1526
1527 /* Find reg_type. */
1528 reg_type = next_field (str, ',', &str, last);
1529
1530 /* Find reg_flags. */
1531 reg_flags = next_field (str, ',', &str, last);
1532
1533 /* Find reg_num. */
1534 reg_num = next_field (str, ',', &str, last);
1535
1536 fprintf (table, " { \"%s\",\n ", reg_name);
1537
1538 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1539 lineno);
1540
1541 /* Find 32-bit Dwarf2 register number. */
1542 dw2_32_num = next_field (str, ',', &str, last);
1543
1544 /* Find 64-bit Dwarf2 register number. */
1545 dw2_64_num = next_field (str, ',', &str, last);
1546
1547 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1548 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1549 }
1550
1551 fclose (fp);
1552
1553 fprintf (table, "};\n");
1554
1555 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1556 }
1557
1558 static void
1559 process_i386_initializers (void)
1560 {
1561 unsigned int i;
1562 FILE *fp = fopen ("i386-init.h", "w");
1563 char *init;
1564
1565 if (fp == NULL)
1566 fail (_("can't create i386-init.h, errno = %s\n"),
1567 xstrerror (errno));
1568
1569 process_copyright (fp);
1570
1571 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1572 {
1573 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1574 init = xstrdup (cpu_flag_init[i].init);
1575 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1576 free (init);
1577 }
1578
1579 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1580 {
1581 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1582 init = xstrdup (operand_type_init[i].init);
1583 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1584 free (init);
1585 }
1586 fprintf (fp, "\n");
1587
1588 fclose (fp);
1589 }
1590
1591 /* Program options. */
1592 #define OPTION_SRCDIR 200
1593
1594 struct option long_options[] =
1595 {
1596 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1597 {"debug", no_argument, NULL, 'd'},
1598 {"version", no_argument, NULL, 'V'},
1599 {"help", no_argument, NULL, 'h'},
1600 {0, no_argument, NULL, 0}
1601 };
1602
1603 static void
1604 print_version (void)
1605 {
1606 printf ("%s: version 1.0\n", program_name);
1607 xexit (0);
1608 }
1609
1610 static void
1611 usage (FILE * stream, int status)
1612 {
1613 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1614 program_name);
1615 xexit (status);
1616 }
1617
1618 int
1619 main (int argc, char **argv)
1620 {
1621 extern int chdir (char *);
1622 char *srcdir = NULL;
1623 int c;
1624 unsigned int i, cpumax;
1625 FILE *table;
1626
1627 program_name = *argv;
1628 xmalloc_set_program_name (program_name);
1629
1630 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1631 switch (c)
1632 {
1633 case OPTION_SRCDIR:
1634 srcdir = optarg;
1635 break;
1636 case 'V':
1637 case 'v':
1638 print_version ();
1639 break;
1640 case 'd':
1641 debug = 1;
1642 break;
1643 case 'h':
1644 case '?':
1645 usage (stderr, 0);
1646 default:
1647 case 0:
1648 break;
1649 }
1650
1651 if (optind != argc)
1652 usage (stdout, 1);
1653
1654 if (srcdir != NULL)
1655 if (chdir (srcdir) != 0)
1656 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1657 srcdir, xstrerror (errno));
1658
1659 /* cpu_flags isn't sorted by position. */
1660 cpumax = 0;
1661 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1662 if (cpu_flags[i].position > cpumax)
1663 cpumax = cpu_flags[i].position;
1664
1665 /* Check the unused bitfield in i386_cpu_flags. */
1666 #ifdef CpuUnused
1667 if ((cpumax - 1) != CpuMax)
1668 fail (_("CpuMax != %d!\n"), cpumax);
1669 #else
1670 if (cpumax != CpuMax)
1671 fail (_("CpuMax != %d!\n"), cpumax);
1672
1673 c = CpuNumOfBits - CpuMax - 1;
1674 if (c)
1675 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1676 #endif
1677
1678 /* Check the unused bitfield in i386_operand_type. */
1679 #ifndef OTUnused
1680 c = OTNumOfBits - OTMax - 1;
1681 if (c)
1682 fail (_("%d unused bits in i386_operand_type.\n"), c);
1683 #endif
1684
1685 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1686 compare);
1687
1688 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1689 sizeof (opcode_modifiers [0]), compare);
1690
1691 qsort (operand_types, ARRAY_SIZE (operand_types),
1692 sizeof (operand_types [0]), compare);
1693
1694 table = fopen ("i386-tbl.h", "w");
1695 if (table == NULL)
1696 fail (_("can't create i386-tbl.h, errno = %s\n"),
1697 xstrerror (errno));
1698
1699 process_copyright (table);
1700
1701 process_i386_opcodes (table);
1702 process_i386_registers (table);
1703 process_i386_initializers ();
1704
1705 fclose (table);
1706
1707 exit (0);
1708 }
This page took 0.063612 seconds and 5 git commands to generate.