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