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