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