x86: eliminate ImmExt abuse
[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_ESSEG",
455 "EsSeg" },
456 { "OPERAND_TYPE_ACC8",
457 "Instance=Accum|Byte" },
458 { "OPERAND_TYPE_ACC16",
459 "Instance=Accum|Word" },
460 { "OPERAND_TYPE_ACC32",
461 "Instance=Accum|Dword" },
462 { "OPERAND_TYPE_ACC64",
463 "Instance=Accum|Qword" },
464 { "OPERAND_TYPE_DISP16_32",
465 "Disp16|Disp32" },
466 { "OPERAND_TYPE_ANYDISP",
467 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
468 { "OPERAND_TYPE_IMM16_32",
469 "Imm16|Imm32" },
470 { "OPERAND_TYPE_IMM16_32S",
471 "Imm16|Imm32S" },
472 { "OPERAND_TYPE_IMM16_32_32S",
473 "Imm16|Imm32|Imm32S" },
474 { "OPERAND_TYPE_IMM32_64",
475 "Imm32|Imm64" },
476 { "OPERAND_TYPE_IMM32_32S_DISP32",
477 "Imm32|Imm32S|Disp32" },
478 { "OPERAND_TYPE_IMM64_DISP64",
479 "Imm64|Disp64" },
480 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
481 "Imm32|Imm32S|Imm64|Disp32" },
482 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
483 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
484 { "OPERAND_TYPE_ANYIMM",
485 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
486 };
487
488 typedef struct bitfield
489 {
490 int position;
491 int value;
492 const char *name;
493 } bitfield;
494
495 #define BITFIELD(n) { n, 0, #n }
496
497 static bitfield cpu_flags[] =
498 {
499 BITFIELD (Cpu186),
500 BITFIELD (Cpu286),
501 BITFIELD (Cpu386),
502 BITFIELD (Cpu486),
503 BITFIELD (Cpu586),
504 BITFIELD (Cpu686),
505 BITFIELD (CpuCMOV),
506 BITFIELD (CpuFXSR),
507 BITFIELD (CpuClflush),
508 BITFIELD (CpuNop),
509 BITFIELD (CpuSYSCALL),
510 BITFIELD (Cpu8087),
511 BITFIELD (Cpu287),
512 BITFIELD (Cpu387),
513 BITFIELD (Cpu687),
514 BITFIELD (CpuFISTTP),
515 BITFIELD (CpuMMX),
516 BITFIELD (CpuSSE),
517 BITFIELD (CpuSSE2),
518 BITFIELD (CpuSSE3),
519 BITFIELD (CpuSSSE3),
520 BITFIELD (CpuSSE4_1),
521 BITFIELD (CpuSSE4_2),
522 BITFIELD (CpuAVX),
523 BITFIELD (CpuAVX2),
524 BITFIELD (CpuAVX512F),
525 BITFIELD (CpuAVX512CD),
526 BITFIELD (CpuAVX512ER),
527 BITFIELD (CpuAVX512PF),
528 BITFIELD (CpuAVX512VL),
529 BITFIELD (CpuAVX512DQ),
530 BITFIELD (CpuAVX512BW),
531 BITFIELD (CpuL1OM),
532 BITFIELD (CpuK1OM),
533 BITFIELD (CpuIAMCU),
534 BITFIELD (CpuSSE4a),
535 BITFIELD (Cpu3dnow),
536 BITFIELD (Cpu3dnowA),
537 BITFIELD (CpuPadLock),
538 BITFIELD (CpuSVME),
539 BITFIELD (CpuVMX),
540 BITFIELD (CpuSMX),
541 BITFIELD (CpuABM),
542 BITFIELD (CpuXsave),
543 BITFIELD (CpuXsaveopt),
544 BITFIELD (CpuAES),
545 BITFIELD (CpuPCLMUL),
546 BITFIELD (CpuFMA),
547 BITFIELD (CpuFMA4),
548 BITFIELD (CpuXOP),
549 BITFIELD (CpuLWP),
550 BITFIELD (CpuBMI),
551 BITFIELD (CpuTBM),
552 BITFIELD (CpuLM),
553 BITFIELD (CpuMovbe),
554 BITFIELD (CpuCX16),
555 BITFIELD (CpuEPT),
556 BITFIELD (CpuRdtscp),
557 BITFIELD (CpuFSGSBase),
558 BITFIELD (CpuRdRnd),
559 BITFIELD (CpuF16C),
560 BITFIELD (CpuBMI2),
561 BITFIELD (CpuLZCNT),
562 BITFIELD (CpuHLE),
563 BITFIELD (CpuRTM),
564 BITFIELD (CpuINVPCID),
565 BITFIELD (CpuVMFUNC),
566 BITFIELD (CpuRDSEED),
567 BITFIELD (CpuADX),
568 BITFIELD (CpuPRFCHW),
569 BITFIELD (CpuSMAP),
570 BITFIELD (CpuSHA),
571 BITFIELD (CpuClflushOpt),
572 BITFIELD (CpuXSAVES),
573 BITFIELD (CpuXSAVEC),
574 BITFIELD (CpuPREFETCHWT1),
575 BITFIELD (CpuSE1),
576 BITFIELD (CpuCLWB),
577 BITFIELD (Cpu64),
578 BITFIELD (CpuNo64),
579 BITFIELD (CpuMPX),
580 BITFIELD (CpuAVX512IFMA),
581 BITFIELD (CpuAVX512VBMI),
582 BITFIELD (CpuAVX512_4FMAPS),
583 BITFIELD (CpuAVX512_4VNNIW),
584 BITFIELD (CpuAVX512_VPOPCNTDQ),
585 BITFIELD (CpuAVX512_VBMI2),
586 BITFIELD (CpuAVX512_VNNI),
587 BITFIELD (CpuAVX512_BITALG),
588 BITFIELD (CpuAVX512_BF16),
589 BITFIELD (CpuAVX512_VP2INTERSECT),
590 BITFIELD (CpuMWAITX),
591 BITFIELD (CpuCLZERO),
592 BITFIELD (CpuOSPKE),
593 BITFIELD (CpuRDPID),
594 BITFIELD (CpuPTWRITE),
595 BITFIELD (CpuIBT),
596 BITFIELD (CpuSHSTK),
597 BITFIELD (CpuGFNI),
598 BITFIELD (CpuVAES),
599 BITFIELD (CpuVPCLMULQDQ),
600 BITFIELD (CpuWBNOINVD),
601 BITFIELD (CpuPCONFIG),
602 BITFIELD (CpuWAITPKG),
603 BITFIELD (CpuCLDEMOTE),
604 BITFIELD (CpuMOVDIRI),
605 BITFIELD (CpuMOVDIR64B),
606 BITFIELD (CpuENQCMD),
607 BITFIELD (CpuRDPRU),
608 BITFIELD (CpuMCOMMIT),
609 #ifdef CpuUnused
610 BITFIELD (CpuUnused),
611 #endif
612 };
613
614 static bitfield opcode_modifiers[] =
615 {
616 BITFIELD (D),
617 BITFIELD (W),
618 BITFIELD (Load),
619 BITFIELD (Modrm),
620 BITFIELD (ShortForm),
621 BITFIELD (Jump),
622 BITFIELD (JumpDword),
623 BITFIELD (JumpByte),
624 BITFIELD (JumpInterSegment),
625 BITFIELD (FloatMF),
626 BITFIELD (FloatR),
627 BITFIELD (Size),
628 BITFIELD (CheckRegSize),
629 BITFIELD (IgnoreSize),
630 BITFIELD (DefaultSize),
631 BITFIELD (No_bSuf),
632 BITFIELD (No_wSuf),
633 BITFIELD (No_lSuf),
634 BITFIELD (No_sSuf),
635 BITFIELD (No_qSuf),
636 BITFIELD (No_ldSuf),
637 BITFIELD (FWait),
638 BITFIELD (IsString),
639 BITFIELD (RegMem),
640 BITFIELD (BNDPrefixOk),
641 BITFIELD (NoTrackPrefixOk),
642 BITFIELD (IsLockable),
643 BITFIELD (RegKludge),
644 BITFIELD (Implicit1stXmm0),
645 BITFIELD (RepPrefixOk),
646 BITFIELD (HLEPrefixOk),
647 BITFIELD (ToDword),
648 BITFIELD (ToQword),
649 BITFIELD (AddrPrefixOpReg),
650 BITFIELD (IsPrefix),
651 BITFIELD (ImmExt),
652 BITFIELD (NoRex64),
653 BITFIELD (Rex64),
654 BITFIELD (Ugh),
655 BITFIELD (Vex),
656 BITFIELD (VexVVVV),
657 BITFIELD (VexW),
658 BITFIELD (VexOpcode),
659 BITFIELD (VexSources),
660 BITFIELD (VecSIB),
661 BITFIELD (SSE2AVX),
662 BITFIELD (NoAVX),
663 BITFIELD (EVex),
664 BITFIELD (Masking),
665 BITFIELD (Broadcast),
666 BITFIELD (StaticRounding),
667 BITFIELD (SAE),
668 BITFIELD (Disp8MemShift),
669 BITFIELD (NoDefMask),
670 BITFIELD (ImplicitQuadGroup),
671 BITFIELD (Optimize),
672 BITFIELD (ATTMnemonic),
673 BITFIELD (ATTSyntax),
674 BITFIELD (IntelSyntax),
675 BITFIELD (AMD64),
676 BITFIELD (Intel64),
677 };
678
679 #define CLASS(n) #n, n
680
681 static const struct {
682 const char *name;
683 enum operand_class value;
684 } operand_classes[] = {
685 CLASS (Reg),
686 CLASS (SReg),
687 CLASS (RegCR),
688 CLASS (RegDR),
689 CLASS (RegTR),
690 CLASS (RegMMX),
691 CLASS (RegSIMD),
692 CLASS (RegMask),
693 CLASS (RegBND),
694 };
695
696 #undef CLASS
697
698 #define INSTANCE(n) #n, n
699
700 static const struct {
701 const char *name;
702 enum operand_instance value;
703 } operand_instances[] = {
704 INSTANCE (Accum),
705 INSTANCE (RegC),
706 INSTANCE (RegD),
707 INSTANCE (RegB),
708 };
709
710 #undef INSTANCE
711
712 static bitfield operand_types[] =
713 {
714 BITFIELD (Imm1),
715 BITFIELD (Imm8),
716 BITFIELD (Imm8S),
717 BITFIELD (Imm16),
718 BITFIELD (Imm32),
719 BITFIELD (Imm32S),
720 BITFIELD (Imm64),
721 BITFIELD (BaseIndex),
722 BITFIELD (Disp8),
723 BITFIELD (Disp16),
724 BITFIELD (Disp32),
725 BITFIELD (Disp32S),
726 BITFIELD (Disp64),
727 BITFIELD (JumpAbsolute),
728 BITFIELD (EsSeg),
729 BITFIELD (Byte),
730 BITFIELD (Word),
731 BITFIELD (Dword),
732 BITFIELD (Fword),
733 BITFIELD (Qword),
734 BITFIELD (Tbyte),
735 BITFIELD (Xmmword),
736 BITFIELD (Ymmword),
737 BITFIELD (Zmmword),
738 BITFIELD (Unspecified),
739 BITFIELD (Anysize),
740 #ifdef OTUnused
741 BITFIELD (OTUnused),
742 #endif
743 };
744
745 static const char *filename;
746 static i386_cpu_flags active_cpu_flags;
747 static int active_isstring;
748
749 static int
750 compare (const void *x, const void *y)
751 {
752 const bitfield *xp = (const bitfield *) x;
753 const bitfield *yp = (const bitfield *) y;
754 return xp->position - yp->position;
755 }
756
757 static void
758 fail (const char *message, ...)
759 {
760 va_list args;
761
762 va_start (args, message);
763 fprintf (stderr, _("%s: error: "), program_name);
764 vfprintf (stderr, message, args);
765 va_end (args);
766 xexit (1);
767 }
768
769 static void
770 process_copyright (FILE *fp)
771 {
772 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
773 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
774 \n\
775 This file is part of the GNU opcodes library.\n\
776 \n\
777 This library is free software; you can redistribute it and/or modify\n\
778 it under the terms of the GNU General Public License as published by\n\
779 the Free Software Foundation; either version 3, or (at your option)\n\
780 any later version.\n\
781 \n\
782 It is distributed in the hope that it will be useful, but WITHOUT\n\
783 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
784 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
785 License for more details.\n\
786 \n\
787 You should have received a copy of the GNU General Public License\n\
788 along with this program; if not, write to the Free Software\n\
789 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
790 MA 02110-1301, USA. */\n");
791 }
792
793 /* Remove leading white spaces. */
794
795 static char *
796 remove_leading_whitespaces (char *str)
797 {
798 while (ISSPACE (*str))
799 str++;
800 return str;
801 }
802
803 /* Remove trailing white spaces. */
804
805 static void
806 remove_trailing_whitespaces (char *str)
807 {
808 size_t last = strlen (str);
809
810 if (last == 0)
811 return;
812
813 do
814 {
815 last--;
816 if (ISSPACE (str [last]))
817 str[last] = '\0';
818 else
819 break;
820 }
821 while (last != 0);
822 }
823
824 /* Find next field separated by SEP and terminate it. Return a
825 pointer to the one after it. */
826
827 static char *
828 next_field (char *str, char sep, char **next, char *last)
829 {
830 char *p;
831
832 p = remove_leading_whitespaces (str);
833 for (str = p; *str != sep && *str != '\0'; str++);
834
835 *str = '\0';
836 remove_trailing_whitespaces (p);
837
838 *next = str + 1;
839
840 if (p >= last)
841 abort ();
842
843 return p;
844 }
845
846 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
847
848 static int
849 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
850 int lineno)
851 {
852 char *str, *next, *last;
853 unsigned int i;
854
855 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
856 if (strcmp (cpu_flag_init[i].name, f) == 0)
857 {
858 /* Turn on selective bits. */
859 char *init = xstrdup (cpu_flag_init[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 CPU_XXX_FLAGS. */
922 if (value == 1 && !set_bitfield_from_cpu_flag_init (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, enum operand_class class,
1161 enum operand_instance instance,
1162 const bitfield *types, unsigned int size,
1163 enum stage stage, const char *indent)
1164 {
1165 unsigned int i;
1166
1167 fprintf (table, "{ { %d, %d, ", class, instance);
1168
1169 for (i = 0; i < size - 1; i++)
1170 {
1171 if (((i + 3) % 20) != 0)
1172 fprintf (table, "%d, ", types[i].value);
1173 else
1174 fprintf (table, "%d,", types[i].value);
1175 if (((i + 3) % 20) == 0)
1176 {
1177 /* We need \\ for macro. */
1178 if (stage == stage_macros)
1179 fprintf (table, " \\\n%s", indent);
1180 else
1181 fprintf (table, "\n%s", indent);
1182 }
1183 }
1184
1185 fprintf (table, "%d } }", types[i].value);
1186 }
1187
1188 static void
1189 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1190 const char *indent, int lineno)
1191 {
1192 char *str, *next, *last;
1193 enum operand_class class = ClassNone;
1194 enum operand_instance instance = InstanceNone;
1195 bitfield types [ARRAY_SIZE (operand_types)];
1196
1197 /* Copy the default operand type. */
1198 memcpy (types, operand_types, sizeof (types));
1199
1200 if (strcmp (op, "0"))
1201 {
1202 int baseindex = 0;
1203
1204 last = op + strlen (op);
1205 for (next = op; next && next < last; )
1206 {
1207 str = next_field (next, '|', &next, last);
1208 if (str)
1209 {
1210 unsigned int i;
1211
1212 if (!strncmp(str, "Class=", 6))
1213 {
1214 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1215 if (!strcmp(str + 6, operand_classes[i].name))
1216 {
1217 class = operand_classes[i].value;
1218 str = NULL;
1219 break;
1220 }
1221 }
1222
1223 if (str && !strncmp(str, "Instance=", 9))
1224 {
1225 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1226 if (!strcmp(str + 9, operand_instances[i].name))
1227 {
1228 instance = operand_instances[i].value;
1229 str = NULL;
1230 break;
1231 }
1232 }
1233 }
1234 if (str)
1235 {
1236 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1237 if (strcasecmp(str, "BaseIndex") == 0)
1238 baseindex = 1;
1239 }
1240 }
1241
1242 if (stage == stage_opcodes && baseindex && !active_isstring)
1243 {
1244 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1245 if (!active_cpu_flags.bitfield.cpu64
1246 && !active_cpu_flags.bitfield.cpumpx)
1247 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1248 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1249 if (!active_cpu_flags.bitfield.cpuno64)
1250 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1251 }
1252 }
1253 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1254 stage, indent);
1255 }
1256
1257 static void
1258 output_i386_opcode (FILE *table, const char *name, char *str,
1259 char *last, int lineno)
1260 {
1261 unsigned int i;
1262 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1263 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1264
1265 /* Find number of operands. */
1266 operands = next_field (str, ',', &str, last);
1267
1268 /* Find base_opcode. */
1269 base_opcode = next_field (str, ',', &str, last);
1270
1271 /* Find extension_opcode. */
1272 extension_opcode = next_field (str, ',', &str, last);
1273
1274 /* Find opcode_length. */
1275 opcode_length = next_field (str, ',', &str, last);
1276
1277 /* Find cpu_flags. */
1278 cpu_flags = next_field (str, ',', &str, last);
1279
1280 /* Find opcode_modifier. */
1281 opcode_modifier = next_field (str, ',', &str, last);
1282
1283 /* Remove the first {. */
1284 str = remove_leading_whitespaces (str);
1285 if (*str != '{')
1286 abort ();
1287 str = remove_leading_whitespaces (str + 1);
1288
1289 i = strlen (str);
1290
1291 /* There are at least "X}". */
1292 if (i < 2)
1293 abort ();
1294
1295 /* Remove trailing white spaces and }. */
1296 do
1297 {
1298 i--;
1299 if (ISSPACE (str[i]) || str[i] == '}')
1300 str[i] = '\0';
1301 else
1302 break;
1303 }
1304 while (i != 0);
1305
1306 last = str + i;
1307
1308 /* Find operand_types. */
1309 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1310 {
1311 if (str >= last)
1312 {
1313 operand_types [i] = NULL;
1314 break;
1315 }
1316
1317 operand_types [i] = next_field (str, ',', &str, last);
1318 if (*operand_types[i] == '0')
1319 {
1320 if (i != 0)
1321 operand_types[i] = NULL;
1322 break;
1323 }
1324 }
1325
1326 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1327 name, base_opcode, extension_opcode, opcode_length, operands);
1328
1329 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1330
1331 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
1332
1333 fprintf (table, " { ");
1334
1335 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1336 {
1337 if (operand_types[i] == NULL || *operand_types[i] == '0')
1338 {
1339 if (i == 0)
1340 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1341 lineno);
1342 break;
1343 }
1344
1345 if (i != 0)
1346 fprintf (table, ",\n ");
1347
1348 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1349 "\t ", lineno);
1350 }
1351 fprintf (table, " } },\n");
1352 }
1353
1354 struct opcode_hash_entry
1355 {
1356 struct opcode_hash_entry *next;
1357 char *name;
1358 char *opcode;
1359 int lineno;
1360 };
1361
1362 /* Calculate the hash value of an opcode hash entry P. */
1363
1364 static hashval_t
1365 opcode_hash_hash (const void *p)
1366 {
1367 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1368 return htab_hash_string (entry->name);
1369 }
1370
1371 /* Compare a string Q against an opcode hash entry P. */
1372
1373 static int
1374 opcode_hash_eq (const void *p, const void *q)
1375 {
1376 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1377 const char *name = (const char *) q;
1378 return strcmp (name, entry->name) == 0;
1379 }
1380
1381 static void
1382 process_i386_opcodes (FILE *table)
1383 {
1384 FILE *fp;
1385 char buf[2048];
1386 unsigned int i, j;
1387 char *str, *p, *last, *name;
1388 struct opcode_hash_entry **hash_slot, **entry, *next;
1389 htab_t opcode_hash_table;
1390 struct opcode_hash_entry **opcode_array;
1391 unsigned int opcode_array_size = 1024;
1392 int lineno = 0, marker = 0;
1393
1394 filename = "i386-opc.tbl";
1395 fp = stdin;
1396
1397 i = 0;
1398 opcode_array = (struct opcode_hash_entry **)
1399 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1400
1401 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1402 opcode_hash_eq, NULL,
1403 xcalloc, free);
1404
1405 fprintf (table, "\n/* i386 opcode table. */\n\n");
1406 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1407
1408 /* Put everything on opcode array. */
1409 while (!feof (fp))
1410 {
1411 if (fgets (buf, sizeof (buf), fp) == NULL)
1412 break;
1413
1414 lineno++;
1415
1416 p = remove_leading_whitespaces (buf);
1417
1418 /* Skip comments. */
1419 str = strstr (p, "//");
1420 if (str != NULL)
1421 str[0] = '\0';
1422
1423 /* Remove trailing white spaces. */
1424 remove_trailing_whitespaces (p);
1425
1426 switch (p[0])
1427 {
1428 case '#':
1429 if (!strcmp("### MARKER ###", buf))
1430 marker = 1;
1431 else
1432 {
1433 /* Since we ignore all included files (we only care about their
1434 #define-s here), we don't need to monitor filenames. The final
1435 line number directive is going to refer to the main source file
1436 again. */
1437 char *end;
1438 unsigned long ln;
1439
1440 p = remove_leading_whitespaces (p + 1);
1441 if (!strncmp(p, "line", 4))
1442 p += 4;
1443 ln = strtoul (p, &end, 10);
1444 if (ln > 1 && ln < INT_MAX
1445 && *remove_leading_whitespaces (end) == '"')
1446 lineno = ln - 1;
1447 }
1448 /* Ignore comments. */
1449 case '\0':
1450 continue;
1451 break;
1452 default:
1453 if (!marker)
1454 continue;
1455 break;
1456 }
1457
1458 last = p + strlen (p);
1459
1460 /* Find name. */
1461 name = next_field (p, ',', &str, last);
1462
1463 /* Get the slot in hash table. */
1464 hash_slot = (struct opcode_hash_entry **)
1465 htab_find_slot_with_hash (opcode_hash_table, name,
1466 htab_hash_string (name),
1467 INSERT);
1468
1469 if (*hash_slot == NULL)
1470 {
1471 /* It is the new one. Put it on opcode array. */
1472 if (i >= opcode_array_size)
1473 {
1474 /* Grow the opcode array when needed. */
1475 opcode_array_size += 1024;
1476 opcode_array = (struct opcode_hash_entry **)
1477 xrealloc (opcode_array,
1478 sizeof (*opcode_array) * opcode_array_size);
1479 }
1480
1481 opcode_array[i] = (struct opcode_hash_entry *)
1482 xmalloc (sizeof (struct opcode_hash_entry));
1483 opcode_array[i]->next = NULL;
1484 opcode_array[i]->name = xstrdup (name);
1485 opcode_array[i]->opcode = xstrdup (str);
1486 opcode_array[i]->lineno = lineno;
1487 *hash_slot = opcode_array[i];
1488 i++;
1489 }
1490 else
1491 {
1492 /* Append it to the existing one. */
1493 entry = hash_slot;
1494 while ((*entry) != NULL)
1495 entry = &(*entry)->next;
1496 *entry = (struct opcode_hash_entry *)
1497 xmalloc (sizeof (struct opcode_hash_entry));
1498 (*entry)->next = NULL;
1499 (*entry)->name = (*hash_slot)->name;
1500 (*entry)->opcode = xstrdup (str);
1501 (*entry)->lineno = lineno;
1502 }
1503 }
1504
1505 /* Process opcode array. */
1506 for (j = 0; j < i; j++)
1507 {
1508 for (next = opcode_array[j]; next; next = next->next)
1509 {
1510 name = next->name;
1511 str = next->opcode;
1512 lineno = next->lineno;
1513 last = str + strlen (str);
1514 output_i386_opcode (table, name, str, last, lineno);
1515 }
1516 }
1517
1518 fclose (fp);
1519
1520 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1521
1522 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1523
1524 process_i386_opcode_modifier (table, "0", NULL, -1);
1525
1526 fprintf (table, " { ");
1527 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1528 fprintf (table, " } }\n");
1529
1530 fprintf (table, "};\n");
1531 }
1532
1533 static void
1534 process_i386_registers (FILE *table)
1535 {
1536 FILE *fp;
1537 char buf[2048];
1538 char *str, *p, *last;
1539 char *reg_name, *reg_type, *reg_flags, *reg_num;
1540 char *dw2_32_num, *dw2_64_num;
1541 int lineno = 0;
1542
1543 filename = "i386-reg.tbl";
1544 fp = fopen (filename, "r");
1545 if (fp == NULL)
1546 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1547 xstrerror (errno));
1548
1549 fprintf (table, "\n/* i386 register table. */\n\n");
1550 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1551
1552 while (!feof (fp))
1553 {
1554 if (fgets (buf, sizeof (buf), fp) == NULL)
1555 break;
1556
1557 lineno++;
1558
1559 p = remove_leading_whitespaces (buf);
1560
1561 /* Skip comments. */
1562 str = strstr (p, "//");
1563 if (str != NULL)
1564 str[0] = '\0';
1565
1566 /* Remove trailing white spaces. */
1567 remove_trailing_whitespaces (p);
1568
1569 switch (p[0])
1570 {
1571 case '#':
1572 fprintf (table, "%s\n", p);
1573 case '\0':
1574 continue;
1575 break;
1576 default:
1577 break;
1578 }
1579
1580 last = p + strlen (p);
1581
1582 /* Find reg_name. */
1583 reg_name = next_field (p, ',', &str, last);
1584
1585 /* Find reg_type. */
1586 reg_type = next_field (str, ',', &str, last);
1587
1588 /* Find reg_flags. */
1589 reg_flags = next_field (str, ',', &str, last);
1590
1591 /* Find reg_num. */
1592 reg_num = next_field (str, ',', &str, last);
1593
1594 fprintf (table, " { \"%s\",\n ", reg_name);
1595
1596 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1597 lineno);
1598
1599 /* Find 32-bit Dwarf2 register number. */
1600 dw2_32_num = next_field (str, ',', &str, last);
1601
1602 /* Find 64-bit Dwarf2 register number. */
1603 dw2_64_num = next_field (str, ',', &str, last);
1604
1605 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1606 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1607 }
1608
1609 fclose (fp);
1610
1611 fprintf (table, "};\n");
1612
1613 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1614 }
1615
1616 static void
1617 process_i386_initializers (void)
1618 {
1619 unsigned int i;
1620 FILE *fp = fopen ("i386-init.h", "w");
1621 char *init;
1622
1623 if (fp == NULL)
1624 fail (_("can't create i386-init.h, errno = %s\n"),
1625 xstrerror (errno));
1626
1627 process_copyright (fp);
1628
1629 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1630 {
1631 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1632 init = xstrdup (cpu_flag_init[i].init);
1633 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1634 free (init);
1635 }
1636
1637 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1638 {
1639 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1640 init = xstrdup (operand_type_init[i].init);
1641 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1642 free (init);
1643 }
1644 fprintf (fp, "\n");
1645
1646 fclose (fp);
1647 }
1648
1649 /* Program options. */
1650 #define OPTION_SRCDIR 200
1651
1652 struct option long_options[] =
1653 {
1654 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1655 {"debug", no_argument, NULL, 'd'},
1656 {"version", no_argument, NULL, 'V'},
1657 {"help", no_argument, NULL, 'h'},
1658 {0, no_argument, NULL, 0}
1659 };
1660
1661 static void
1662 print_version (void)
1663 {
1664 printf ("%s: version 1.0\n", program_name);
1665 xexit (0);
1666 }
1667
1668 static void
1669 usage (FILE * stream, int status)
1670 {
1671 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1672 program_name);
1673 xexit (status);
1674 }
1675
1676 int
1677 main (int argc, char **argv)
1678 {
1679 extern int chdir (char *);
1680 char *srcdir = NULL;
1681 int c;
1682 unsigned int i, cpumax;
1683 FILE *table;
1684
1685 program_name = *argv;
1686 xmalloc_set_program_name (program_name);
1687
1688 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1689 switch (c)
1690 {
1691 case OPTION_SRCDIR:
1692 srcdir = optarg;
1693 break;
1694 case 'V':
1695 case 'v':
1696 print_version ();
1697 break;
1698 case 'd':
1699 debug = 1;
1700 break;
1701 case 'h':
1702 case '?':
1703 usage (stderr, 0);
1704 default:
1705 case 0:
1706 break;
1707 }
1708
1709 if (optind != argc)
1710 usage (stdout, 1);
1711
1712 if (srcdir != NULL)
1713 if (chdir (srcdir) != 0)
1714 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1715 srcdir, xstrerror (errno));
1716
1717 /* cpu_flags isn't sorted by position. */
1718 cpumax = 0;
1719 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1720 if (cpu_flags[i].position > cpumax)
1721 cpumax = cpu_flags[i].position;
1722
1723 /* Check the unused bitfield in i386_cpu_flags. */
1724 #ifdef CpuUnused
1725 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1726
1727 if ((cpumax - 1) != CpuMax)
1728 fail (_("CpuMax != %d!\n"), cpumax);
1729 #else
1730 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1731
1732 if (cpumax != CpuMax)
1733 fail (_("CpuMax != %d!\n"), cpumax);
1734
1735 c = CpuNumOfBits - CpuMax - 1;
1736 if (c)
1737 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1738 #endif
1739
1740 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1741
1742 /* Check the unused bitfield in i386_operand_type. */
1743 #ifdef OTUnused
1744 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1745 == OTNum + 1);
1746 #else
1747 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1748 == OTNum);
1749
1750 c = OTNumOfBits - OTMax - 1;
1751 if (c)
1752 fail (_("%d unused bits in i386_operand_type.\n"), c);
1753 #endif
1754
1755 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1756 compare);
1757
1758 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1759 sizeof (opcode_modifiers [0]), compare);
1760
1761 qsort (operand_types, ARRAY_SIZE (operand_types),
1762 sizeof (operand_types [0]), compare);
1763
1764 table = fopen ("i386-tbl.h", "w");
1765 if (table == NULL)
1766 fail (_("can't create i386-tbl.h, errno = %s\n"),
1767 xstrerror (errno));
1768
1769 process_copyright (table);
1770
1771 process_i386_opcodes (table);
1772 process_i386_registers (table);
1773 process_i386_initializers ();
1774
1775 fclose (table);
1776
1777 exit (0);
1778 }
This page took 0.065592 seconds and 5 git commands to generate.