x86: introduce operand type "instance"
[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 };
708
709 #undef INSTANCE
710
711 static bitfield operand_types[] =
712 {
713 BITFIELD (Imm1),
714 BITFIELD (Imm8),
715 BITFIELD (Imm8S),
716 BITFIELD (Imm16),
717 BITFIELD (Imm32),
718 BITFIELD (Imm32S),
719 BITFIELD (Imm64),
720 BITFIELD (BaseIndex),
721 BITFIELD (Disp8),
722 BITFIELD (Disp16),
723 BITFIELD (Disp32),
724 BITFIELD (Disp32S),
725 BITFIELD (Disp64),
726 BITFIELD (JumpAbsolute),
727 BITFIELD (EsSeg),
728 BITFIELD (Byte),
729 BITFIELD (Word),
730 BITFIELD (Dword),
731 BITFIELD (Fword),
732 BITFIELD (Qword),
733 BITFIELD (Tbyte),
734 BITFIELD (Xmmword),
735 BITFIELD (Ymmword),
736 BITFIELD (Zmmword),
737 BITFIELD (Unspecified),
738 BITFIELD (Anysize),
739 #ifdef OTUnused
740 BITFIELD (OTUnused),
741 #endif
742 };
743
744 static const char *filename;
745 static i386_cpu_flags active_cpu_flags;
746 static int active_isstring;
747
748 static int
749 compare (const void *x, const void *y)
750 {
751 const bitfield *xp = (const bitfield *) x;
752 const bitfield *yp = (const bitfield *) y;
753 return xp->position - yp->position;
754 }
755
756 static void
757 fail (const char *message, ...)
758 {
759 va_list args;
760
761 va_start (args, message);
762 fprintf (stderr, _("%s: error: "), program_name);
763 vfprintf (stderr, message, args);
764 va_end (args);
765 xexit (1);
766 }
767
768 static void
769 process_copyright (FILE *fp)
770 {
771 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
772 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
773 \n\
774 This file is part of the GNU opcodes library.\n\
775 \n\
776 This library is free software; you can redistribute it and/or modify\n\
777 it under the terms of the GNU General Public License as published by\n\
778 the Free Software Foundation; either version 3, or (at your option)\n\
779 any later version.\n\
780 \n\
781 It is distributed in the hope that it will be useful, but WITHOUT\n\
782 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
783 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
784 License for more details.\n\
785 \n\
786 You should have received a copy of the GNU General Public License\n\
787 along with this program; if not, write to the Free Software\n\
788 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
789 MA 02110-1301, USA. */\n");
790 }
791
792 /* Remove leading white spaces. */
793
794 static char *
795 remove_leading_whitespaces (char *str)
796 {
797 while (ISSPACE (*str))
798 str++;
799 return str;
800 }
801
802 /* Remove trailing white spaces. */
803
804 static void
805 remove_trailing_whitespaces (char *str)
806 {
807 size_t last = strlen (str);
808
809 if (last == 0)
810 return;
811
812 do
813 {
814 last--;
815 if (ISSPACE (str [last]))
816 str[last] = '\0';
817 else
818 break;
819 }
820 while (last != 0);
821 }
822
823 /* Find next field separated by SEP and terminate it. Return a
824 pointer to the one after it. */
825
826 static char *
827 next_field (char *str, char sep, char **next, char *last)
828 {
829 char *p;
830
831 p = remove_leading_whitespaces (str);
832 for (str = p; *str != sep && *str != '\0'; str++);
833
834 *str = '\0';
835 remove_trailing_whitespaces (p);
836
837 *next = str + 1;
838
839 if (p >= last)
840 abort ();
841
842 return p;
843 }
844
845 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
846
847 static int
848 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
849 int lineno)
850 {
851 char *str, *next, *last;
852 unsigned int i;
853
854 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
855 if (strcmp (cpu_flag_init[i].name, f) == 0)
856 {
857 /* Turn on selective bits. */
858 char *init = xstrdup (cpu_flag_init[i].init);
859 last = init + strlen (init);
860 for (next = init; next && next < last; )
861 {
862 str = next_field (next, '|', &next, last);
863 if (str)
864 set_bitfield (str, array, 1, size, lineno);
865 }
866 free (init);
867 return 0;
868 }
869
870 return -1;
871 }
872
873 static void
874 set_bitfield (char *f, bitfield *array, int value,
875 unsigned int size, int lineno)
876 {
877 unsigned int i;
878
879 if (strcmp (f, "CpuFP") == 0)
880 {
881 set_bitfield("Cpu387", array, value, size, lineno);
882 set_bitfield("Cpu287", array, value, size, lineno);
883 f = "Cpu8087";
884 }
885 else if (strcmp (f, "Mmword") == 0)
886 f= "Qword";
887 else if (strcmp (f, "Oword") == 0)
888 f= "Xmmword";
889
890 for (i = 0; i < size; i++)
891 if (strcasecmp (array[i].name, f) == 0)
892 {
893 array[i].value = value;
894 return;
895 }
896
897 if (value)
898 {
899 const char *v = strchr (f, '=');
900
901 if (v)
902 {
903 size_t n = v - f;
904 char *end;
905
906 for (i = 0; i < size; i++)
907 if (strncasecmp (array[i].name, f, n) == 0)
908 {
909 value = strtol (v + 1, &end, 0);
910 if (*end == '\0')
911 {
912 array[i].value = value;
913 return;
914 }
915 break;
916 }
917 }
918 }
919
920 /* Handle CPU_XXX_FLAGS. */
921 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
922 return;
923
924 if (lineno != -1)
925 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
926 else
927 fail (_("unknown bitfield: %s\n"), f);
928 }
929
930 static void
931 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
932 int macro, const char *comma, const char *indent)
933 {
934 unsigned int i;
935
936 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
937
938 fprintf (table, "%s{ { ", indent);
939
940 for (i = 0; i < size - 1; i++)
941 {
942 if (((i + 1) % 20) != 0)
943 fprintf (table, "%d, ", flags[i].value);
944 else
945 fprintf (table, "%d,", flags[i].value);
946 if (((i + 1) % 20) == 0)
947 {
948 /* We need \\ for macro. */
949 if (macro)
950 fprintf (table, " \\\n %s", indent);
951 else
952 fprintf (table, "\n %s", indent);
953 }
954 if (flags[i].value)
955 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
956 }
957
958 fprintf (table, "%d } }%s\n", flags[i].value, comma);
959 }
960
961 static void
962 process_i386_cpu_flag (FILE *table, char *flag, int macro,
963 const char *comma, const char *indent,
964 int lineno)
965 {
966 char *str, *next, *last;
967 unsigned int i;
968 bitfield flags [ARRAY_SIZE (cpu_flags)];
969
970 /* Copy the default cpu flags. */
971 memcpy (flags, cpu_flags, sizeof (cpu_flags));
972
973 if (strcasecmp (flag, "unknown") == 0)
974 {
975 /* We turn on everything except for cpu64 in case of
976 CPU_UNKNOWN_FLAGS. */
977 for (i = 0; i < ARRAY_SIZE (flags); i++)
978 if (flags[i].position != Cpu64)
979 flags[i].value = 1;
980 }
981 else if (flag[0] == '~')
982 {
983 last = flag + strlen (flag);
984
985 if (flag[1] == '(')
986 {
987 last -= 1;
988 next = flag + 2;
989 if (*last != ')')
990 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
991 lineno, flag);
992 *last = '\0';
993 }
994 else
995 next = flag + 1;
996
997 /* First we turn on everything except for cpu64. */
998 for (i = 0; i < ARRAY_SIZE (flags); i++)
999 if (flags[i].position != Cpu64)
1000 flags[i].value = 1;
1001
1002 /* Turn off selective bits. */
1003 for (; next && next < last; )
1004 {
1005 str = next_field (next, '|', &next, last);
1006 if (str)
1007 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1008 }
1009 }
1010 else if (strcmp (flag, "0"))
1011 {
1012 /* Turn on selective bits. */
1013 last = flag + strlen (flag);
1014 for (next = flag; next && next < last; )
1015 {
1016 str = next_field (next, '|', &next, last);
1017 if (str)
1018 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1019 }
1020 }
1021
1022 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1023 comma, indent);
1024 }
1025
1026 static void
1027 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1028 {
1029 unsigned int i;
1030
1031 fprintf (table, " { ");
1032
1033 for (i = 0; i < size - 1; i++)
1034 {
1035 if (((i + 1) % 20) != 0)
1036 fprintf (table, "%d, ", modifier[i].value);
1037 else
1038 fprintf (table, "%d,", modifier[i].value);
1039 if (((i + 1) % 20) == 0)
1040 fprintf (table, "\n ");
1041 }
1042
1043 fprintf (table, "%d },\n", modifier[i].value);
1044 }
1045
1046 static int
1047 adjust_broadcast_modifier (char **opnd)
1048 {
1049 char *str, *next, *last, *op;
1050 int bcst_type = INT_MAX;
1051
1052 /* Skip the immediate operand. */
1053 op = opnd[0];
1054 if (strcasecmp(op, "Imm8") == 0)
1055 op = opnd[1];
1056
1057 op = xstrdup (op);
1058 last = op + strlen (op);
1059 for (next = op; next && next < last; )
1060 {
1061 str = next_field (next, '|', &next, last);
1062 if (str)
1063 {
1064 if (strcasecmp(str, "Byte") == 0)
1065 {
1066 /* The smalest broadcast type, no need to check
1067 further. */
1068 bcst_type = BYTE_BROADCAST;
1069 break;
1070 }
1071 else if (strcasecmp(str, "Word") == 0)
1072 {
1073 if (bcst_type > WORD_BROADCAST)
1074 bcst_type = WORD_BROADCAST;
1075 }
1076 else if (strcasecmp(str, "Dword") == 0)
1077 {
1078 if (bcst_type > DWORD_BROADCAST)
1079 bcst_type = DWORD_BROADCAST;
1080 }
1081 else if (strcasecmp(str, "Qword") == 0)
1082 {
1083 if (bcst_type > QWORD_BROADCAST)
1084 bcst_type = QWORD_BROADCAST;
1085 }
1086 }
1087 }
1088 free (op);
1089
1090 if (bcst_type == INT_MAX)
1091 fail (_("unknown broadcast operand: %s\n"), op);
1092
1093 return bcst_type;
1094 }
1095
1096 static void
1097 process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
1098 {
1099 char *str, *next, *last;
1100 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1101
1102 active_isstring = 0;
1103
1104 /* Copy the default opcode modifier. */
1105 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1106
1107 if (strcmp (mod, "0"))
1108 {
1109 unsigned int have_w = 0, bwlq_suf = 0xf;
1110
1111 last = mod + strlen (mod);
1112 for (next = mod; next && next < last; )
1113 {
1114 str = next_field (next, '|', &next, last);
1115 if (str)
1116 {
1117 int val = 1;
1118 if (strcasecmp(str, "Broadcast") == 0)
1119 val = adjust_broadcast_modifier (opnd);
1120 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1121 lineno);
1122 if (strcasecmp(str, "IsString") == 0)
1123 active_isstring = 1;
1124
1125 if (strcasecmp(str, "W") == 0)
1126 have_w = 1;
1127
1128 if (strcasecmp(str, "No_bSuf") == 0)
1129 bwlq_suf &= ~1;
1130 if (strcasecmp(str, "No_wSuf") == 0)
1131 bwlq_suf &= ~2;
1132 if (strcasecmp(str, "No_lSuf") == 0)
1133 bwlq_suf &= ~4;
1134 if (strcasecmp(str, "No_qSuf") == 0)
1135 bwlq_suf &= ~8;
1136 }
1137 }
1138
1139 if (have_w && !bwlq_suf)
1140 fail ("%s: %d: stray W modifier\n", filename, lineno);
1141 if (have_w && !(bwlq_suf & 1))
1142 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1143 filename, lineno);
1144 if (have_w && !(bwlq_suf & ~1))
1145 fprintf (stderr,
1146 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1147 filename, lineno);
1148 }
1149 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1150 }
1151
1152 enum stage {
1153 stage_macros,
1154 stage_opcodes,
1155 stage_registers,
1156 };
1157
1158 static void
1159 output_operand_type (FILE *table, enum operand_class class,
1160 enum operand_instance instance,
1161 const bitfield *types, unsigned int size,
1162 enum stage stage, const char *indent)
1163 {
1164 unsigned int i;
1165
1166 fprintf (table, "{ { %d, %d, ", class, instance);
1167
1168 for (i = 0; i < size - 1; i++)
1169 {
1170 if (((i + 3) % 20) != 0)
1171 fprintf (table, "%d, ", types[i].value);
1172 else
1173 fprintf (table, "%d,", types[i].value);
1174 if (((i + 3) % 20) == 0)
1175 {
1176 /* We need \\ for macro. */
1177 if (stage == stage_macros)
1178 fprintf (table, " \\\n%s", indent);
1179 else
1180 fprintf (table, "\n%s", indent);
1181 }
1182 }
1183
1184 fprintf (table, "%d } }", types[i].value);
1185 }
1186
1187 static void
1188 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1189 const char *indent, int lineno)
1190 {
1191 char *str, *next, *last;
1192 enum operand_class class = ClassNone;
1193 enum operand_instance instance = InstanceNone;
1194 bitfield types [ARRAY_SIZE (operand_types)];
1195
1196 /* Copy the default operand type. */
1197 memcpy (types, operand_types, sizeof (types));
1198
1199 if (strcmp (op, "0"))
1200 {
1201 int baseindex = 0;
1202
1203 last = op + strlen (op);
1204 for (next = op; next && next < last; )
1205 {
1206 str = next_field (next, '|', &next, last);
1207 if (str)
1208 {
1209 unsigned int i;
1210
1211 if (!strncmp(str, "Class=", 6))
1212 {
1213 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1214 if (!strcmp(str + 6, operand_classes[i].name))
1215 {
1216 class = operand_classes[i].value;
1217 str = NULL;
1218 break;
1219 }
1220 }
1221
1222 if (str && !strncmp(str, "Instance=", 9))
1223 {
1224 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1225 if (!strcmp(str + 9, operand_instances[i].name))
1226 {
1227 instance = operand_instances[i].value;
1228 str = NULL;
1229 break;
1230 }
1231 }
1232 }
1233 if (str)
1234 {
1235 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1236 if (strcasecmp(str, "BaseIndex") == 0)
1237 baseindex = 1;
1238 }
1239 }
1240
1241 if (stage == stage_opcodes && baseindex && !active_isstring)
1242 {
1243 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1244 if (!active_cpu_flags.bitfield.cpu64
1245 && !active_cpu_flags.bitfield.cpumpx)
1246 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1247 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1248 if (!active_cpu_flags.bitfield.cpuno64)
1249 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1250 }
1251 }
1252 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1253 stage, indent);
1254 }
1255
1256 static void
1257 output_i386_opcode (FILE *table, const char *name, char *str,
1258 char *last, int lineno)
1259 {
1260 unsigned int i;
1261 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1262 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1263
1264 /* Find number of operands. */
1265 operands = next_field (str, ',', &str, last);
1266
1267 /* Find base_opcode. */
1268 base_opcode = next_field (str, ',', &str, last);
1269
1270 /* Find extension_opcode. */
1271 extension_opcode = next_field (str, ',', &str, last);
1272
1273 /* Find opcode_length. */
1274 opcode_length = next_field (str, ',', &str, last);
1275
1276 /* Find cpu_flags. */
1277 cpu_flags = next_field (str, ',', &str, last);
1278
1279 /* Find opcode_modifier. */
1280 opcode_modifier = next_field (str, ',', &str, last);
1281
1282 /* Remove the first {. */
1283 str = remove_leading_whitespaces (str);
1284 if (*str != '{')
1285 abort ();
1286 str = remove_leading_whitespaces (str + 1);
1287
1288 i = strlen (str);
1289
1290 /* There are at least "X}". */
1291 if (i < 2)
1292 abort ();
1293
1294 /* Remove trailing white spaces and }. */
1295 do
1296 {
1297 i--;
1298 if (ISSPACE (str[i]) || str[i] == '}')
1299 str[i] = '\0';
1300 else
1301 break;
1302 }
1303 while (i != 0);
1304
1305 last = str + i;
1306
1307 /* Find operand_types. */
1308 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1309 {
1310 if (str >= last)
1311 {
1312 operand_types [i] = NULL;
1313 break;
1314 }
1315
1316 operand_types [i] = next_field (str, ',', &str, last);
1317 if (*operand_types[i] == '0')
1318 {
1319 if (i != 0)
1320 operand_types[i] = NULL;
1321 break;
1322 }
1323 }
1324
1325 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1326 name, base_opcode, extension_opcode, opcode_length, operands);
1327
1328 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1329
1330 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
1331
1332 fprintf (table, " { ");
1333
1334 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1335 {
1336 if (operand_types[i] == NULL || *operand_types[i] == '0')
1337 {
1338 if (i == 0)
1339 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1340 lineno);
1341 break;
1342 }
1343
1344 if (i != 0)
1345 fprintf (table, ",\n ");
1346
1347 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1348 "\t ", lineno);
1349 }
1350 fprintf (table, " } },\n");
1351 }
1352
1353 struct opcode_hash_entry
1354 {
1355 struct opcode_hash_entry *next;
1356 char *name;
1357 char *opcode;
1358 int lineno;
1359 };
1360
1361 /* Calculate the hash value of an opcode hash entry P. */
1362
1363 static hashval_t
1364 opcode_hash_hash (const void *p)
1365 {
1366 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1367 return htab_hash_string (entry->name);
1368 }
1369
1370 /* Compare a string Q against an opcode hash entry P. */
1371
1372 static int
1373 opcode_hash_eq (const void *p, const void *q)
1374 {
1375 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1376 const char *name = (const char *) q;
1377 return strcmp (name, entry->name) == 0;
1378 }
1379
1380 static void
1381 process_i386_opcodes (FILE *table)
1382 {
1383 FILE *fp;
1384 char buf[2048];
1385 unsigned int i, j;
1386 char *str, *p, *last, *name;
1387 struct opcode_hash_entry **hash_slot, **entry, *next;
1388 htab_t opcode_hash_table;
1389 struct opcode_hash_entry **opcode_array;
1390 unsigned int opcode_array_size = 1024;
1391 int lineno = 0, marker = 0;
1392
1393 filename = "i386-opc.tbl";
1394 fp = stdin;
1395
1396 i = 0;
1397 opcode_array = (struct opcode_hash_entry **)
1398 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1399
1400 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1401 opcode_hash_eq, NULL,
1402 xcalloc, free);
1403
1404 fprintf (table, "\n/* i386 opcode table. */\n\n");
1405 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1406
1407 /* Put everything on opcode array. */
1408 while (!feof (fp))
1409 {
1410 if (fgets (buf, sizeof (buf), fp) == NULL)
1411 break;
1412
1413 lineno++;
1414
1415 p = remove_leading_whitespaces (buf);
1416
1417 /* Skip comments. */
1418 str = strstr (p, "//");
1419 if (str != NULL)
1420 str[0] = '\0';
1421
1422 /* Remove trailing white spaces. */
1423 remove_trailing_whitespaces (p);
1424
1425 switch (p[0])
1426 {
1427 case '#':
1428 if (!strcmp("### MARKER ###", buf))
1429 marker = 1;
1430 else
1431 {
1432 /* Since we ignore all included files (we only care about their
1433 #define-s here), we don't need to monitor filenames. The final
1434 line number directive is going to refer to the main source file
1435 again. */
1436 char *end;
1437 unsigned long ln;
1438
1439 p = remove_leading_whitespaces (p + 1);
1440 if (!strncmp(p, "line", 4))
1441 p += 4;
1442 ln = strtoul (p, &end, 10);
1443 if (ln > 1 && ln < INT_MAX
1444 && *remove_leading_whitespaces (end) == '"')
1445 lineno = ln - 1;
1446 }
1447 /* Ignore comments. */
1448 case '\0':
1449 continue;
1450 break;
1451 default:
1452 if (!marker)
1453 continue;
1454 break;
1455 }
1456
1457 last = p + strlen (p);
1458
1459 /* Find name. */
1460 name = next_field (p, ',', &str, last);
1461
1462 /* Get the slot in hash table. */
1463 hash_slot = (struct opcode_hash_entry **)
1464 htab_find_slot_with_hash (opcode_hash_table, name,
1465 htab_hash_string (name),
1466 INSERT);
1467
1468 if (*hash_slot == NULL)
1469 {
1470 /* It is the new one. Put it on opcode array. */
1471 if (i >= opcode_array_size)
1472 {
1473 /* Grow the opcode array when needed. */
1474 opcode_array_size += 1024;
1475 opcode_array = (struct opcode_hash_entry **)
1476 xrealloc (opcode_array,
1477 sizeof (*opcode_array) * opcode_array_size);
1478 }
1479
1480 opcode_array[i] = (struct opcode_hash_entry *)
1481 xmalloc (sizeof (struct opcode_hash_entry));
1482 opcode_array[i]->next = NULL;
1483 opcode_array[i]->name = xstrdup (name);
1484 opcode_array[i]->opcode = xstrdup (str);
1485 opcode_array[i]->lineno = lineno;
1486 *hash_slot = opcode_array[i];
1487 i++;
1488 }
1489 else
1490 {
1491 /* Append it to the existing one. */
1492 entry = hash_slot;
1493 while ((*entry) != NULL)
1494 entry = &(*entry)->next;
1495 *entry = (struct opcode_hash_entry *)
1496 xmalloc (sizeof (struct opcode_hash_entry));
1497 (*entry)->next = NULL;
1498 (*entry)->name = (*hash_slot)->name;
1499 (*entry)->opcode = xstrdup (str);
1500 (*entry)->lineno = lineno;
1501 }
1502 }
1503
1504 /* Process opcode array. */
1505 for (j = 0; j < i; j++)
1506 {
1507 for (next = opcode_array[j]; next; next = next->next)
1508 {
1509 name = next->name;
1510 str = next->opcode;
1511 lineno = next->lineno;
1512 last = str + strlen (str);
1513 output_i386_opcode (table, name, str, last, lineno);
1514 }
1515 }
1516
1517 fclose (fp);
1518
1519 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1520
1521 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1522
1523 process_i386_opcode_modifier (table, "0", NULL, -1);
1524
1525 fprintf (table, " { ");
1526 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1527 fprintf (table, " } }\n");
1528
1529 fprintf (table, "};\n");
1530 }
1531
1532 static void
1533 process_i386_registers (FILE *table)
1534 {
1535 FILE *fp;
1536 char buf[2048];
1537 char *str, *p, *last;
1538 char *reg_name, *reg_type, *reg_flags, *reg_num;
1539 char *dw2_32_num, *dw2_64_num;
1540 int lineno = 0;
1541
1542 filename = "i386-reg.tbl";
1543 fp = fopen (filename, "r");
1544 if (fp == NULL)
1545 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1546 xstrerror (errno));
1547
1548 fprintf (table, "\n/* i386 register table. */\n\n");
1549 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1550
1551 while (!feof (fp))
1552 {
1553 if (fgets (buf, sizeof (buf), fp) == NULL)
1554 break;
1555
1556 lineno++;
1557
1558 p = remove_leading_whitespaces (buf);
1559
1560 /* Skip comments. */
1561 str = strstr (p, "//");
1562 if (str != NULL)
1563 str[0] = '\0';
1564
1565 /* Remove trailing white spaces. */
1566 remove_trailing_whitespaces (p);
1567
1568 switch (p[0])
1569 {
1570 case '#':
1571 fprintf (table, "%s\n", p);
1572 case '\0':
1573 continue;
1574 break;
1575 default:
1576 break;
1577 }
1578
1579 last = p + strlen (p);
1580
1581 /* Find reg_name. */
1582 reg_name = next_field (p, ',', &str, last);
1583
1584 /* Find reg_type. */
1585 reg_type = next_field (str, ',', &str, last);
1586
1587 /* Find reg_flags. */
1588 reg_flags = next_field (str, ',', &str, last);
1589
1590 /* Find reg_num. */
1591 reg_num = next_field (str, ',', &str, last);
1592
1593 fprintf (table, " { \"%s\",\n ", reg_name);
1594
1595 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1596 lineno);
1597
1598 /* Find 32-bit Dwarf2 register number. */
1599 dw2_32_num = next_field (str, ',', &str, last);
1600
1601 /* Find 64-bit Dwarf2 register number. */
1602 dw2_64_num = next_field (str, ',', &str, last);
1603
1604 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1605 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1606 }
1607
1608 fclose (fp);
1609
1610 fprintf (table, "};\n");
1611
1612 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1613 }
1614
1615 static void
1616 process_i386_initializers (void)
1617 {
1618 unsigned int i;
1619 FILE *fp = fopen ("i386-init.h", "w");
1620 char *init;
1621
1622 if (fp == NULL)
1623 fail (_("can't create i386-init.h, errno = %s\n"),
1624 xstrerror (errno));
1625
1626 process_copyright (fp);
1627
1628 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1629 {
1630 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1631 init = xstrdup (cpu_flag_init[i].init);
1632 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1633 free (init);
1634 }
1635
1636 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1637 {
1638 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1639 init = xstrdup (operand_type_init[i].init);
1640 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1641 free (init);
1642 }
1643 fprintf (fp, "\n");
1644
1645 fclose (fp);
1646 }
1647
1648 /* Program options. */
1649 #define OPTION_SRCDIR 200
1650
1651 struct option long_options[] =
1652 {
1653 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1654 {"debug", no_argument, NULL, 'd'},
1655 {"version", no_argument, NULL, 'V'},
1656 {"help", no_argument, NULL, 'h'},
1657 {0, no_argument, NULL, 0}
1658 };
1659
1660 static void
1661 print_version (void)
1662 {
1663 printf ("%s: version 1.0\n", program_name);
1664 xexit (0);
1665 }
1666
1667 static void
1668 usage (FILE * stream, int status)
1669 {
1670 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1671 program_name);
1672 xexit (status);
1673 }
1674
1675 int
1676 main (int argc, char **argv)
1677 {
1678 extern int chdir (char *);
1679 char *srcdir = NULL;
1680 int c;
1681 unsigned int i, cpumax;
1682 FILE *table;
1683
1684 program_name = *argv;
1685 xmalloc_set_program_name (program_name);
1686
1687 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1688 switch (c)
1689 {
1690 case OPTION_SRCDIR:
1691 srcdir = optarg;
1692 break;
1693 case 'V':
1694 case 'v':
1695 print_version ();
1696 break;
1697 case 'd':
1698 debug = 1;
1699 break;
1700 case 'h':
1701 case '?':
1702 usage (stderr, 0);
1703 default:
1704 case 0:
1705 break;
1706 }
1707
1708 if (optind != argc)
1709 usage (stdout, 1);
1710
1711 if (srcdir != NULL)
1712 if (chdir (srcdir) != 0)
1713 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1714 srcdir, xstrerror (errno));
1715
1716 /* cpu_flags isn't sorted by position. */
1717 cpumax = 0;
1718 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1719 if (cpu_flags[i].position > cpumax)
1720 cpumax = cpu_flags[i].position;
1721
1722 /* Check the unused bitfield in i386_cpu_flags. */
1723 #ifdef CpuUnused
1724 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1725
1726 if ((cpumax - 1) != CpuMax)
1727 fail (_("CpuMax != %d!\n"), cpumax);
1728 #else
1729 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1730
1731 if (cpumax != CpuMax)
1732 fail (_("CpuMax != %d!\n"), cpumax);
1733
1734 c = CpuNumOfBits - CpuMax - 1;
1735 if (c)
1736 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1737 #endif
1738
1739 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1740
1741 /* Check the unused bitfield in i386_operand_type. */
1742 #ifdef OTUnused
1743 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1744 == OTNum + 1);
1745 #else
1746 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1747 == OTNum);
1748
1749 c = OTNumOfBits - OTMax - 1;
1750 if (c)
1751 fail (_("%d unused bits in i386_operand_type.\n"), c);
1752 #endif
1753
1754 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1755 compare);
1756
1757 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1758 sizeof (opcode_modifiers [0]), compare);
1759
1760 qsort (operand_types, ARRAY_SIZE (operand_types),
1761 sizeof (operand_types [0]), compare);
1762
1763 table = fopen ("i386-tbl.h", "w");
1764 if (table == NULL)
1765 fail (_("can't create i386-tbl.h, errno = %s\n"),
1766 xstrerror (errno));
1767
1768 process_copyright (table);
1769
1770 process_i386_opcodes (table);
1771 process_i386_registers (table);
1772 process_i386_initializers ();
1773
1774 fclose (table);
1775
1776 exit (0);
1777 }
This page took 0.071725 seconds and 5 git commands to generate.