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