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