Automatic date update in version.in
[binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright (C) 2007-2021 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 (NoAVX),
734 BITFIELD (EVex),
735 BITFIELD (Masking),
736 BITFIELD (Broadcast),
737 BITFIELD (StaticRounding),
738 BITFIELD (SAE),
739 BITFIELD (Disp8MemShift),
740 BITFIELD (NoDefMask),
741 BITFIELD (ImplicitQuadGroup),
742 BITFIELD (SwapSources),
743 BITFIELD (Optimize),
744 BITFIELD (ATTMnemonic),
745 BITFIELD (ATTSyntax),
746 BITFIELD (IntelSyntax),
747 BITFIELD (ISA64),
748 };
749
750 #define CLASS(n) #n, n
751
752 static const struct {
753 const char *name;
754 enum operand_class value;
755 } operand_classes[] = {
756 CLASS (Reg),
757 CLASS (SReg),
758 CLASS (RegCR),
759 CLASS (RegDR),
760 CLASS (RegTR),
761 CLASS (RegMMX),
762 CLASS (RegSIMD),
763 CLASS (RegMask),
764 CLASS (RegBND),
765 };
766
767 #undef CLASS
768
769 #define INSTANCE(n) #n, n
770
771 static const struct {
772 const char *name;
773 enum operand_instance value;
774 } operand_instances[] = {
775 INSTANCE (Accum),
776 INSTANCE (RegC),
777 INSTANCE (RegD),
778 INSTANCE (RegB),
779 };
780
781 #undef INSTANCE
782
783 static bitfield operand_types[] =
784 {
785 BITFIELD (Imm1),
786 BITFIELD (Imm8),
787 BITFIELD (Imm8S),
788 BITFIELD (Imm16),
789 BITFIELD (Imm32),
790 BITFIELD (Imm32S),
791 BITFIELD (Imm64),
792 BITFIELD (BaseIndex),
793 BITFIELD (Disp8),
794 BITFIELD (Disp16),
795 BITFIELD (Disp32),
796 BITFIELD (Disp32S),
797 BITFIELD (Disp64),
798 BITFIELD (Byte),
799 BITFIELD (Word),
800 BITFIELD (Dword),
801 BITFIELD (Fword),
802 BITFIELD (Qword),
803 BITFIELD (Tbyte),
804 BITFIELD (Xmmword),
805 BITFIELD (Ymmword),
806 BITFIELD (Zmmword),
807 BITFIELD (Tmmword),
808 BITFIELD (Unspecified),
809 #ifdef OTUnused
810 BITFIELD (OTUnused),
811 #endif
812 };
813
814 static const char *filename;
815 static i386_cpu_flags active_cpu_flags;
816 static int active_isstring;
817
818 struct template_arg {
819 const struct template_arg *next;
820 const char *val;
821 };
822
823 struct template_instance {
824 const struct template_instance *next;
825 const char *name;
826 const struct template_arg *args;
827 };
828
829 struct template_param {
830 const struct template_param *next;
831 const char *name;
832 };
833
834 struct template {
835 const struct template *next;
836 const char *name;
837 const struct template_instance *instances;
838 const struct template_param *params;
839 };
840
841 static const struct template *templates;
842
843 static int
844 compare (const void *x, const void *y)
845 {
846 const bitfield *xp = (const bitfield *) x;
847 const bitfield *yp = (const bitfield *) y;
848 return xp->position - yp->position;
849 }
850
851 static void
852 fail (const char *message, ...)
853 {
854 va_list args;
855
856 va_start (args, message);
857 fprintf (stderr, _("%s: error: "), program_name);
858 vfprintf (stderr, message, args);
859 va_end (args);
860 xexit (1);
861 }
862
863 static void
864 process_copyright (FILE *fp)
865 {
866 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
867 /* Copyright (C) 2007-2021 Free Software Foundation, Inc.\n\
868 \n\
869 This file is part of the GNU opcodes library.\n\
870 \n\
871 This library is free software; you can redistribute it and/or modify\n\
872 it under the terms of the GNU General Public License as published by\n\
873 the Free Software Foundation; either version 3, or (at your option)\n\
874 any later version.\n\
875 \n\
876 It is distributed in the hope that it will be useful, but WITHOUT\n\
877 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
878 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
879 License for more details.\n\
880 \n\
881 You should have received a copy of the GNU General Public License\n\
882 along with this program; if not, write to the Free Software\n\
883 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
884 MA 02110-1301, USA. */\n");
885 }
886
887 /* Remove leading white spaces. */
888
889 static char *
890 remove_leading_whitespaces (char *str)
891 {
892 while (ISSPACE (*str))
893 str++;
894 return str;
895 }
896
897 /* Remove trailing white spaces. */
898
899 static void
900 remove_trailing_whitespaces (char *str)
901 {
902 size_t last = strlen (str);
903
904 if (last == 0)
905 return;
906
907 do
908 {
909 last--;
910 if (ISSPACE (str [last]))
911 str[last] = '\0';
912 else
913 break;
914 }
915 while (last != 0);
916 }
917
918 /* Find next field separated by SEP and terminate it. Return a
919 pointer to the one after it. */
920
921 static char *
922 next_field (char *str, char sep, char **next, char *last)
923 {
924 char *p;
925
926 p = remove_leading_whitespaces (str);
927 for (str = p; *str != sep && *str != '\0'; str++);
928
929 *str = '\0';
930 remove_trailing_whitespaces (p);
931
932 *next = str + 1;
933
934 if (p >= last)
935 abort ();
936
937 return p;
938 }
939
940 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
941
942 static int
943 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
944 int lineno)
945 {
946 char *str, *next, *last;
947 unsigned int i;
948
949 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
950 if (strcmp (cpu_flag_init[i].name, f) == 0)
951 {
952 /* Turn on selective bits. */
953 char *init = xstrdup (cpu_flag_init[i].init);
954 last = init + strlen (init);
955 for (next = init; next && next < last; )
956 {
957 str = next_field (next, '|', &next, last);
958 if (str)
959 set_bitfield (str, array, 1, size, lineno);
960 }
961 free (init);
962 return 0;
963 }
964
965 return -1;
966 }
967
968 static void
969 set_bitfield (char *f, bitfield *array, int value,
970 unsigned int size, int lineno)
971 {
972 unsigned int i;
973
974 /* Ignore empty fields; they may result from template expansions. */
975 if (*f == '\0')
976 return;
977
978 for (i = 0; i < size; i++)
979 if (strcasecmp (array[i].name, f) == 0)
980 {
981 array[i].value = value;
982 return;
983 }
984
985 if (value)
986 {
987 const char *v = strchr (f, '=');
988
989 if (v)
990 {
991 size_t n = v - f;
992 char *end;
993
994 for (i = 0; i < size; i++)
995 if (strncasecmp (array[i].name, f, n) == 0)
996 {
997 value = strtol (v + 1, &end, 0);
998 if (*end == '\0')
999 {
1000 array[i].value = value;
1001 return;
1002 }
1003 break;
1004 }
1005 }
1006 }
1007
1008 /* Handle CPU_XXX_FLAGS. */
1009 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1010 return;
1011
1012 if (lineno != -1)
1013 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
1014 else
1015 fail (_("unknown bitfield: %s\n"), f);
1016 }
1017
1018 static void
1019 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
1020 int macro, const char *comma, const char *indent)
1021 {
1022 unsigned int i;
1023
1024 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
1025
1026 fprintf (table, "%s{ { ", indent);
1027
1028 for (i = 0; i < size - 1; i++)
1029 {
1030 if (((i + 1) % 20) != 0)
1031 fprintf (table, "%d, ", flags[i].value);
1032 else
1033 fprintf (table, "%d,", flags[i].value);
1034 if (((i + 1) % 20) == 0)
1035 {
1036 /* We need \\ for macro. */
1037 if (macro)
1038 fprintf (table, " \\\n %s", indent);
1039 else
1040 fprintf (table, "\n %s", indent);
1041 }
1042 if (flags[i].value)
1043 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
1044 }
1045
1046 fprintf (table, "%d } }%s\n", flags[i].value, comma);
1047 }
1048
1049 static void
1050 process_i386_cpu_flag (FILE *table, char *flag, int macro,
1051 const char *comma, const char *indent,
1052 int lineno)
1053 {
1054 char *str, *next, *last;
1055 unsigned int i;
1056 bitfield flags [ARRAY_SIZE (cpu_flags)];
1057
1058 /* Copy the default cpu flags. */
1059 memcpy (flags, cpu_flags, sizeof (cpu_flags));
1060
1061 if (strcasecmp (flag, "unknown") == 0)
1062 {
1063 /* We turn on everything except for cpu64 in case of
1064 CPU_UNKNOWN_FLAGS. */
1065 for (i = 0; i < ARRAY_SIZE (flags); i++)
1066 if (flags[i].position != Cpu64)
1067 flags[i].value = 1;
1068 }
1069 else if (flag[0] == '~')
1070 {
1071 last = flag + strlen (flag);
1072
1073 if (flag[1] == '(')
1074 {
1075 last -= 1;
1076 next = flag + 2;
1077 if (*last != ')')
1078 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
1079 lineno, flag);
1080 *last = '\0';
1081 }
1082 else
1083 next = flag + 1;
1084
1085 /* First we turn on everything except for cpu64. */
1086 for (i = 0; i < ARRAY_SIZE (flags); i++)
1087 if (flags[i].position != Cpu64)
1088 flags[i].value = 1;
1089
1090 /* Turn off selective bits. */
1091 for (; next && next < last; )
1092 {
1093 str = next_field (next, '|', &next, last);
1094 if (str)
1095 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1096 }
1097 }
1098 else if (strcmp (flag, "0"))
1099 {
1100 /* Turn on selective bits. */
1101 last = flag + strlen (flag);
1102 for (next = flag; next && next < last; )
1103 {
1104 str = next_field (next, '|', &next, last);
1105 if (str)
1106 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1107 }
1108 }
1109
1110 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1111 comma, indent);
1112 }
1113
1114 static void
1115 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1116 {
1117 unsigned int i;
1118
1119 fprintf (table, " { ");
1120
1121 for (i = 0; i < size - 1; i++)
1122 {
1123 if (((i + 1) % 20) != 0)
1124 fprintf (table, "%d, ", modifier[i].value);
1125 else
1126 fprintf (table, "%d,", modifier[i].value);
1127 if (((i + 1) % 20) == 0)
1128 fprintf (table, "\n ");
1129 }
1130
1131 fprintf (table, "%d },\n", modifier[i].value);
1132 }
1133
1134 static int
1135 adjust_broadcast_modifier (char **opnd)
1136 {
1137 char *str, *next, *last, *op;
1138 int bcst_type = INT_MAX;
1139
1140 /* Skip the immediate operand. */
1141 op = opnd[0];
1142 if (strcasecmp(op, "Imm8") == 0)
1143 op = opnd[1];
1144
1145 op = xstrdup (op);
1146 last = op + strlen (op);
1147 for (next = op; next && next < last; )
1148 {
1149 str = next_field (next, '|', &next, last);
1150 if (str)
1151 {
1152 if (strcasecmp(str, "Byte") == 0)
1153 {
1154 /* The smalest broadcast type, no need to check
1155 further. */
1156 bcst_type = BYTE_BROADCAST;
1157 break;
1158 }
1159 else if (strcasecmp(str, "Word") == 0)
1160 {
1161 if (bcst_type > WORD_BROADCAST)
1162 bcst_type = WORD_BROADCAST;
1163 }
1164 else if (strcasecmp(str, "Dword") == 0)
1165 {
1166 if (bcst_type > DWORD_BROADCAST)
1167 bcst_type = DWORD_BROADCAST;
1168 }
1169 else if (strcasecmp(str, "Qword") == 0)
1170 {
1171 if (bcst_type > QWORD_BROADCAST)
1172 bcst_type = QWORD_BROADCAST;
1173 }
1174 }
1175 }
1176 free (op);
1177
1178 if (bcst_type == INT_MAX)
1179 fail (_("unknown broadcast operand: %s\n"), op);
1180
1181 return bcst_type;
1182 }
1183
1184 static void
1185 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1186 unsigned int prefix, char **opnd, int lineno)
1187 {
1188 char *str, *next, *last;
1189 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1190
1191 active_isstring = 0;
1192
1193 /* Copy the default opcode modifier. */
1194 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1195
1196 if (strcmp (mod, "0"))
1197 {
1198 unsigned int have_w = 0, bwlq_suf = 0xf;
1199
1200 last = mod + strlen (mod);
1201 for (next = mod; next && next < last; )
1202 {
1203 str = next_field (next, '|', &next, last);
1204 if (str)
1205 {
1206 int val = 1;
1207 if (strcasecmp(str, "Broadcast") == 0)
1208 val = adjust_broadcast_modifier (opnd);
1209
1210 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1211 lineno);
1212 if (strcasecmp(str, "IsString") == 0)
1213 active_isstring = 1;
1214
1215 if (strcasecmp(str, "W") == 0)
1216 have_w = 1;
1217
1218 if (strcasecmp(str, "No_bSuf") == 0)
1219 bwlq_suf &= ~1;
1220 if (strcasecmp(str, "No_wSuf") == 0)
1221 bwlq_suf &= ~2;
1222 if (strcasecmp(str, "No_lSuf") == 0)
1223 bwlq_suf &= ~4;
1224 if (strcasecmp(str, "No_qSuf") == 0)
1225 bwlq_suf &= ~8;
1226 }
1227 }
1228
1229 if (space)
1230 {
1231 if (!modifiers[OpcodeSpace].value)
1232 modifiers[OpcodeSpace].value = space;
1233 else if (modifiers[OpcodeSpace].value != space)
1234 fail (_("%s:%d: Conflicting opcode space specifications\n"),
1235 filename, lineno);
1236 else
1237 fprintf (stderr,
1238 _("%s:%d: Warning: redundant opcode space specification\n"),
1239 filename, lineno);
1240 }
1241
1242 if (prefix)
1243 {
1244 if (!modifiers[OpcodePrefix].value)
1245 modifiers[OpcodePrefix].value = prefix;
1246 else if (modifiers[OpcodePrefix].value != prefix)
1247 fail (_("%s:%d: Conflicting prefix specifications\n"),
1248 filename, lineno);
1249 else
1250 fprintf (stderr,
1251 _("%s:%d: Warning: redundant prefix specification\n"),
1252 filename, lineno);
1253 }
1254
1255 if (have_w && !bwlq_suf)
1256 fail ("%s: %d: stray W modifier\n", filename, lineno);
1257 if (have_w && !(bwlq_suf & 1))
1258 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1259 filename, lineno);
1260 if (have_w && !(bwlq_suf & ~1))
1261 fprintf (stderr,
1262 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1263 filename, lineno);
1264 }
1265 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1266 }
1267
1268 enum stage {
1269 stage_macros,
1270 stage_opcodes,
1271 stage_registers,
1272 };
1273
1274 static void
1275 output_operand_type (FILE *table, enum operand_class class,
1276 enum operand_instance instance,
1277 const bitfield *types, unsigned int size,
1278 enum stage stage, const char *indent)
1279 {
1280 unsigned int i;
1281
1282 fprintf (table, "{ { %d, %d, ", class, instance);
1283
1284 for (i = 0; i < size - 1; i++)
1285 {
1286 if (((i + 3) % 20) != 0)
1287 fprintf (table, "%d, ", types[i].value);
1288 else
1289 fprintf (table, "%d,", types[i].value);
1290 if (((i + 3) % 20) == 0)
1291 {
1292 /* We need \\ for macro. */
1293 if (stage == stage_macros)
1294 fprintf (table, " \\\n%s", indent);
1295 else
1296 fprintf (table, "\n%s", indent);
1297 }
1298 }
1299
1300 fprintf (table, "%d } }", types[i].value);
1301 }
1302
1303 static void
1304 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1305 const char *indent, int lineno)
1306 {
1307 char *str, *next, *last;
1308 enum operand_class class = ClassNone;
1309 enum operand_instance instance = InstanceNone;
1310 bitfield types [ARRAY_SIZE (operand_types)];
1311
1312 /* Copy the default operand type. */
1313 memcpy (types, operand_types, sizeof (types));
1314
1315 if (strcmp (op, "0"))
1316 {
1317 int baseindex = 0;
1318
1319 last = op + strlen (op);
1320 for (next = op; next && next < last; )
1321 {
1322 str = next_field (next, '|', &next, last);
1323 if (str)
1324 {
1325 unsigned int i;
1326
1327 if (!strncmp(str, "Class=", 6))
1328 {
1329 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1330 if (!strcmp(str + 6, operand_classes[i].name))
1331 {
1332 class = operand_classes[i].value;
1333 str = NULL;
1334 break;
1335 }
1336 }
1337
1338 if (str && !strncmp(str, "Instance=", 9))
1339 {
1340 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1341 if (!strcmp(str + 9, operand_instances[i].name))
1342 {
1343 instance = operand_instances[i].value;
1344 str = NULL;
1345 break;
1346 }
1347 }
1348 }
1349 if (str)
1350 {
1351 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1352 if (strcasecmp(str, "BaseIndex") == 0)
1353 baseindex = 1;
1354 }
1355 }
1356
1357 if (stage == stage_opcodes && baseindex && !active_isstring)
1358 {
1359 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1360 if (!active_cpu_flags.bitfield.cpu64
1361 && !active_cpu_flags.bitfield.cpumpx)
1362 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1363 if (!active_cpu_flags.bitfield.cpu64)
1364 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1365 if (!active_cpu_flags.bitfield.cpuno64)
1366 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1367 }
1368 }
1369 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1370 stage, indent);
1371 }
1372
1373 static void
1374 output_i386_opcode (FILE *table, const char *name, char *str,
1375 char *last, int lineno)
1376 {
1377 unsigned int i, length, prefix = 0, space = 0;
1378 char *base_opcode, *extension_opcode, *end;
1379 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1380 unsigned long long opcode;
1381
1382 /* Find base_opcode. */
1383 base_opcode = next_field (str, ',', &str, last);
1384
1385 /* Find extension_opcode. */
1386 extension_opcode = next_field (str, ',', &str, last);
1387
1388 /* Find cpu_flags. */
1389 cpu_flags = next_field (str, ',', &str, last);
1390
1391 /* Find opcode_modifier. */
1392 opcode_modifier = next_field (str, ',', &str, last);
1393
1394 /* Remove the first {. */
1395 str = remove_leading_whitespaces (str);
1396 if (*str != '{')
1397 abort ();
1398 str = remove_leading_whitespaces (str + 1);
1399 remove_trailing_whitespaces (str);
1400
1401 /* Remove } and trailing white space. */
1402 i = strlen (str);
1403 if (!i || str[i - 1] != '}')
1404 abort ();
1405 str[--i] = '\0';
1406 remove_trailing_whitespaces (str);
1407
1408 if (!*str)
1409 operand_types [i = 0] = NULL;
1410 else
1411 {
1412 last = str + strlen (str);
1413
1414 /* Find operand_types. */
1415 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1416 {
1417 if (str >= last)
1418 {
1419 operand_types [i] = NULL;
1420 break;
1421 }
1422
1423 operand_types [i] = next_field (str, ',', &str, last);
1424 }
1425 }
1426
1427 opcode = strtoull (base_opcode, &end, 0);
1428
1429 /* Determine opcode length. */
1430 for (length = 1; length < 8; ++length)
1431 if (!(opcode >> (8 * length)))
1432 break;
1433
1434 /* Transform prefixes encoded in the opcode into opcode modifier
1435 representation. */
1436 if (length > 1)
1437 {
1438 switch (opcode >> (8 * length - 8))
1439 {
1440 case 0x66: prefix = PREFIX_0X66; break;
1441 case 0xF3: prefix = PREFIX_0XF3; break;
1442 case 0xF2: prefix = PREFIX_0XF2; break;
1443 }
1444
1445 if (prefix)
1446 opcode &= (1ULL << (8 * --length)) - 1;
1447 }
1448
1449 /* Transform opcode space encoded in the opcode into opcode modifier
1450 representation. */
1451 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1452 {
1453 switch ((opcode >> (8 * length - 16)) & 0xff)
1454 {
1455 default: space = SPACE_0F; break;
1456 case 0x38: space = SPACE_0F38; break;
1457 case 0x3A: space = SPACE_0F3A; break;
1458 }
1459
1460 if (space != SPACE_0F && --length == 1)
1461 fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1462 filename, lineno, name);
1463 opcode &= (1ULL << (8 * --length)) - 1;
1464 }
1465
1466 if (length > 2)
1467 fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1468 filename, lineno, name, 2 * length, opcode);
1469
1470 fprintf (table, " { \"%s\", 0x%0*llx%s, %s, %lu,\n",
1471 name, 2 * (int)length, opcode, end, extension_opcode, i);
1472
1473 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1474 operand_types, lineno);
1475
1476 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1477
1478 fprintf (table, " { ");
1479
1480 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1481 {
1482 if (!operand_types[i])
1483 {
1484 if (i == 0)
1485 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1486 lineno);
1487 break;
1488 }
1489
1490 if (i != 0)
1491 fprintf (table, ",\n ");
1492
1493 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1494 "\t ", lineno);
1495 }
1496 fprintf (table, " } },\n");
1497 }
1498
1499 struct opcode_hash_entry
1500 {
1501 struct opcode_hash_entry *next;
1502 char *name;
1503 char *opcode;
1504 int lineno;
1505 };
1506
1507 /* Calculate the hash value of an opcode hash entry P. */
1508
1509 static hashval_t
1510 opcode_hash_hash (const void *p)
1511 {
1512 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1513 return htab_hash_string (entry->name);
1514 }
1515
1516 /* Compare a string Q against an opcode hash entry P. */
1517
1518 static int
1519 opcode_hash_eq (const void *p, const void *q)
1520 {
1521 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1522 const char *name = (const char *) q;
1523 return strcmp (name, entry->name) == 0;
1524 }
1525
1526 static void
1527 parse_template (char *buf, int lineno)
1528 {
1529 char sep, *end, *name;
1530 struct template *tmpl = xmalloc (sizeof (*tmpl));
1531 struct template_instance *last_inst = NULL;
1532
1533 buf = remove_leading_whitespaces (buf + 1);
1534 end = strchr (buf, ':');
1535 if (end == NULL)
1536 fail ("%s: %d: missing ':'\n", filename, lineno);
1537 *end++ = '\0';
1538 remove_trailing_whitespaces (buf);
1539
1540 if (*buf == '\0')
1541 fail ("%s: %d: missing template identifier\n", filename, lineno);
1542 tmpl->name = xstrdup (buf);
1543
1544 tmpl->params = NULL;
1545 do {
1546 struct template_param *param;
1547
1548 buf = remove_leading_whitespaces (end);
1549 end = strpbrk (buf, ":,");
1550 if (end == NULL)
1551 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1552
1553 sep = *end;
1554 *end++ = '\0';
1555 remove_trailing_whitespaces (buf);
1556
1557 param = xmalloc (sizeof (*param));
1558 param->name = xstrdup (buf);
1559 param->next = tmpl->params;
1560 tmpl->params = param;
1561 } while (sep == ':');
1562
1563 tmpl->instances = NULL;
1564 do {
1565 struct template_instance *inst;
1566 char *cur, *next;
1567 const struct template_param *param;
1568
1569 buf = remove_leading_whitespaces (end);
1570 end = strpbrk (buf, ",>");
1571 if (end == NULL)
1572 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1573
1574 sep = *end;
1575 *end++ = '\0';
1576
1577 inst = xmalloc (sizeof (*inst));
1578 inst->next = NULL;
1579 inst->args = NULL;
1580
1581 cur = next_field (buf, ':', &next, end);
1582 inst->name = *cur != '$' ? xstrdup (cur) : "";
1583
1584 for (param = tmpl->params; param; param = param->next)
1585 {
1586 struct template_arg *arg = xmalloc (sizeof (*arg));
1587
1588 cur = next_field (next, ':', &next, end);
1589 if (next > end)
1590 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1591 arg->val = xstrdup (cur);
1592 arg->next = inst->args;
1593 inst->args = arg;
1594 }
1595
1596 if (tmpl->instances)
1597 last_inst->next = inst;
1598 else
1599 tmpl->instances = inst;
1600 last_inst = inst;
1601 } while (sep == ',');
1602
1603 buf = remove_leading_whitespaces (end);
1604 if (*buf)
1605 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1606 filename, lineno, buf);
1607
1608 tmpl->next = templates;
1609 templates = tmpl;
1610 }
1611
1612 static unsigned int
1613 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1614 struct opcode_hash_entry ***opcode_array_p, int lineno)
1615 {
1616 static unsigned int idx, opcode_array_size;
1617 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1618 struct opcode_hash_entry **hash_slot, **entry;
1619 char *ptr1 = strchr(name, '<'), *ptr2;
1620
1621 if (ptr1 == NULL)
1622 {
1623 /* Get the slot in hash table. */
1624 hash_slot = (struct opcode_hash_entry **)
1625 htab_find_slot_with_hash (opcode_hash_table, name,
1626 htab_hash_string (name),
1627 INSERT);
1628
1629 if (*hash_slot == NULL)
1630 {
1631 /* It is the new one. Put it on opcode array. */
1632 if (idx >= opcode_array_size)
1633 {
1634 /* Grow the opcode array when needed. */
1635 opcode_array_size += 1024;
1636 opcode_array = (struct opcode_hash_entry **)
1637 xrealloc (opcode_array,
1638 sizeof (*opcode_array) * opcode_array_size);
1639 *opcode_array_p = opcode_array;
1640 }
1641
1642 opcode_array[idx] = (struct opcode_hash_entry *)
1643 xmalloc (sizeof (struct opcode_hash_entry));
1644 opcode_array[idx]->next = NULL;
1645 opcode_array[idx]->name = xstrdup (name);
1646 opcode_array[idx]->opcode = xstrdup (str);
1647 opcode_array[idx]->lineno = lineno;
1648 *hash_slot = opcode_array[idx];
1649 idx++;
1650 }
1651 else
1652 {
1653 /* Append it to the existing one. */
1654 entry = hash_slot;
1655 while ((*entry) != NULL)
1656 entry = &(*entry)->next;
1657 *entry = (struct opcode_hash_entry *)
1658 xmalloc (sizeof (struct opcode_hash_entry));
1659 (*entry)->next = NULL;
1660 (*entry)->name = (*hash_slot)->name;
1661 (*entry)->opcode = xstrdup (str);
1662 (*entry)->lineno = lineno;
1663 }
1664 }
1665 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1666 fail ("%s: %d: missing '>'\n", filename, lineno);
1667 else
1668 {
1669 const struct template *tmpl;
1670 const struct template_instance *inst;
1671
1672 *ptr1 = '\0';
1673 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1674 remove_trailing_whitespaces (ptr1);
1675
1676 *ptr2++ = '\0';
1677
1678 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1679 if (!strcmp(ptr1, tmpl->name))
1680 break;
1681 if (!tmpl)
1682 fail ("reference to unknown template '%s'\n", ptr1);
1683
1684 for (inst = tmpl->instances; inst; inst = inst->next)
1685 {
1686 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1687 char *str2 = xmalloc(2 * strlen(str));
1688 const char *src;
1689
1690 strcpy (name2, name);
1691 strcat (name2, inst->name);
1692 strcat (name2, ptr2);
1693
1694 for (ptr1 = str2, src = str; *src; )
1695 {
1696 const char *ident = tmpl->name, *end;
1697 const struct template_param *param;
1698 const struct template_arg *arg;
1699
1700 if ((*ptr1 = *src++) != '<')
1701 {
1702 ++ptr1;
1703 continue;
1704 }
1705 while (ISSPACE(*src))
1706 ++src;
1707 while (*ident && *src == *ident)
1708 ++src, ++ident;
1709 while (ISSPACE(*src))
1710 ++src;
1711 if (*src != ':' || *ident != '\0')
1712 {
1713 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1714 ptr1 += ident - tmpl->name;
1715 continue;
1716 }
1717 while (ISSPACE(*++src))
1718 ;
1719
1720 end = src;
1721 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1722 ++end;
1723
1724 for (param = tmpl->params, arg = inst->args; param;
1725 param = param->next, arg = arg->next)
1726 {
1727 if (end - src == strlen (param->name)
1728 && !memcmp (src, param->name, end - src))
1729 {
1730 src = end;
1731 break;
1732 }
1733 }
1734
1735 if (param == NULL)
1736 fail ("template '%s' has no parameter '%.*s'\n",
1737 tmpl->name, (int)(end - src), src);
1738
1739 while (ISSPACE(*src))
1740 ++src;
1741 if (*src != '>')
1742 fail ("%s: %d: missing '>'\n", filename, lineno);
1743
1744 memcpy(ptr1, arg->val, strlen(arg->val));
1745 ptr1 += strlen(arg->val);
1746 ++src;
1747 }
1748
1749 *ptr1 = '\0';
1750
1751 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1752 lineno);
1753
1754 free (str2);
1755 free (name2);
1756 }
1757 }
1758
1759 return idx;
1760 }
1761
1762 static void
1763 process_i386_opcodes (FILE *table)
1764 {
1765 FILE *fp;
1766 char buf[2048];
1767 unsigned int i, j;
1768 char *str, *p, *last, *name;
1769 htab_t opcode_hash_table;
1770 struct opcode_hash_entry **opcode_array = NULL;
1771 int lineno = 0, marker = 0;
1772
1773 filename = "i386-opc.tbl";
1774 fp = stdin;
1775
1776 i = 0;
1777 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1778 opcode_hash_eq, NULL,
1779 xcalloc, free);
1780
1781 fprintf (table, "\n/* i386 opcode table. */\n\n");
1782 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1783
1784 /* Put everything on opcode array. */
1785 while (!feof (fp))
1786 {
1787 if (fgets (buf, sizeof (buf), fp) == NULL)
1788 break;
1789
1790 lineno++;
1791
1792 p = remove_leading_whitespaces (buf);
1793
1794 /* Skip comments. */
1795 str = strstr (p, "//");
1796 if (str != NULL)
1797 str[0] = '\0';
1798
1799 /* Remove trailing white spaces. */
1800 remove_trailing_whitespaces (p);
1801
1802 switch (p[0])
1803 {
1804 case '#':
1805 if (!strcmp("### MARKER ###", buf))
1806 marker = 1;
1807 else
1808 {
1809 /* Since we ignore all included files (we only care about their
1810 #define-s here), we don't need to monitor filenames. The final
1811 line number directive is going to refer to the main source file
1812 again. */
1813 char *end;
1814 unsigned long ln;
1815
1816 p = remove_leading_whitespaces (p + 1);
1817 if (!strncmp(p, "line", 4))
1818 p += 4;
1819 ln = strtoul (p, &end, 10);
1820 if (ln > 1 && ln < INT_MAX
1821 && *remove_leading_whitespaces (end) == '"')
1822 lineno = ln - 1;
1823 }
1824 /* Ignore comments. */
1825 case '\0':
1826 continue;
1827 break;
1828 case '<':
1829 parse_template (p, lineno);
1830 continue;
1831 default:
1832 if (!marker)
1833 continue;
1834 break;
1835 }
1836
1837 last = p + strlen (p);
1838
1839 /* Find name. */
1840 name = next_field (p, ',', &str, last);
1841
1842 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1843 lineno);
1844 }
1845
1846 /* Process opcode array. */
1847 for (j = 0; j < i; j++)
1848 {
1849 struct opcode_hash_entry *next;
1850
1851 for (next = opcode_array[j]; next; next = next->next)
1852 {
1853 name = next->name;
1854 str = next->opcode;
1855 lineno = next->lineno;
1856 last = str + strlen (str);
1857 output_i386_opcode (table, name, str, last, lineno);
1858 }
1859 }
1860
1861 fclose (fp);
1862
1863 fprintf (table, " { NULL, 0, 0, 0,\n");
1864
1865 process_i386_opcode_modifier (table, "0", 0, 0, NULL, -1);
1866
1867 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1868
1869 fprintf (table, " { ");
1870 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1871 fprintf (table, " } }\n");
1872
1873 fprintf (table, "};\n");
1874 }
1875
1876 static void
1877 process_i386_registers (FILE *table)
1878 {
1879 FILE *fp;
1880 char buf[2048];
1881 char *str, *p, *last;
1882 char *reg_name, *reg_type, *reg_flags, *reg_num;
1883 char *dw2_32_num, *dw2_64_num;
1884 int lineno = 0;
1885
1886 filename = "i386-reg.tbl";
1887 fp = fopen (filename, "r");
1888 if (fp == NULL)
1889 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1890 xstrerror (errno));
1891
1892 fprintf (table, "\n/* i386 register table. */\n\n");
1893 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1894
1895 while (!feof (fp))
1896 {
1897 if (fgets (buf, sizeof (buf), fp) == NULL)
1898 break;
1899
1900 lineno++;
1901
1902 p = remove_leading_whitespaces (buf);
1903
1904 /* Skip comments. */
1905 str = strstr (p, "//");
1906 if (str != NULL)
1907 str[0] = '\0';
1908
1909 /* Remove trailing white spaces. */
1910 remove_trailing_whitespaces (p);
1911
1912 switch (p[0])
1913 {
1914 case '#':
1915 fprintf (table, "%s\n", p);
1916 case '\0':
1917 continue;
1918 break;
1919 default:
1920 break;
1921 }
1922
1923 last = p + strlen (p);
1924
1925 /* Find reg_name. */
1926 reg_name = next_field (p, ',', &str, last);
1927
1928 /* Find reg_type. */
1929 reg_type = next_field (str, ',', &str, last);
1930
1931 /* Find reg_flags. */
1932 reg_flags = next_field (str, ',', &str, last);
1933
1934 /* Find reg_num. */
1935 reg_num = next_field (str, ',', &str, last);
1936
1937 fprintf (table, " { \"%s\",\n ", reg_name);
1938
1939 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1940 lineno);
1941
1942 /* Find 32-bit Dwarf2 register number. */
1943 dw2_32_num = next_field (str, ',', &str, last);
1944
1945 /* Find 64-bit Dwarf2 register number. */
1946 dw2_64_num = next_field (str, ',', &str, last);
1947
1948 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1949 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1950 }
1951
1952 fclose (fp);
1953
1954 fprintf (table, "};\n");
1955
1956 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1957 }
1958
1959 static void
1960 process_i386_initializers (void)
1961 {
1962 unsigned int i;
1963 FILE *fp = fopen ("i386-init.h", "w");
1964 char *init;
1965
1966 if (fp == NULL)
1967 fail (_("can't create i386-init.h, errno = %s\n"),
1968 xstrerror (errno));
1969
1970 process_copyright (fp);
1971
1972 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1973 {
1974 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1975 init = xstrdup (cpu_flag_init[i].init);
1976 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1977 free (init);
1978 }
1979
1980 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1981 {
1982 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1983 init = xstrdup (operand_type_init[i].init);
1984 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1985 free (init);
1986 }
1987 fprintf (fp, "\n");
1988
1989 fclose (fp);
1990 }
1991
1992 /* Program options. */
1993 #define OPTION_SRCDIR 200
1994
1995 struct option long_options[] =
1996 {
1997 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1998 {"debug", no_argument, NULL, 'd'},
1999 {"version", no_argument, NULL, 'V'},
2000 {"help", no_argument, NULL, 'h'},
2001 {0, no_argument, NULL, 0}
2002 };
2003
2004 static void
2005 print_version (void)
2006 {
2007 printf ("%s: version 1.0\n", program_name);
2008 xexit (0);
2009 }
2010
2011 static void
2012 usage (FILE * stream, int status)
2013 {
2014 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2015 program_name);
2016 xexit (status);
2017 }
2018
2019 int
2020 main (int argc, char **argv)
2021 {
2022 extern int chdir (char *);
2023 char *srcdir = NULL;
2024 int c;
2025 unsigned int i, cpumax;
2026 FILE *table;
2027
2028 program_name = *argv;
2029 xmalloc_set_program_name (program_name);
2030
2031 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2032 switch (c)
2033 {
2034 case OPTION_SRCDIR:
2035 srcdir = optarg;
2036 break;
2037 case 'V':
2038 case 'v':
2039 print_version ();
2040 break;
2041 case 'd':
2042 debug = 1;
2043 break;
2044 case 'h':
2045 case '?':
2046 usage (stderr, 0);
2047 default:
2048 case 0:
2049 break;
2050 }
2051
2052 if (optind != argc)
2053 usage (stdout, 1);
2054
2055 if (srcdir != NULL)
2056 if (chdir (srcdir) != 0)
2057 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2058 srcdir, xstrerror (errno));
2059
2060 /* cpu_flags isn't sorted by position. */
2061 cpumax = 0;
2062 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2063 if (cpu_flags[i].position > cpumax)
2064 cpumax = cpu_flags[i].position;
2065
2066 /* Check the unused bitfield in i386_cpu_flags. */
2067 #ifdef CpuUnused
2068 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2069
2070 if ((cpumax - 1) != CpuMax)
2071 fail (_("CpuMax != %d!\n"), cpumax);
2072 #else
2073 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2074
2075 if (cpumax != CpuMax)
2076 fail (_("CpuMax != %d!\n"), cpumax);
2077
2078 c = CpuNumOfBits - CpuMax - 1;
2079 if (c)
2080 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
2081 #endif
2082
2083 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2084
2085 /* Check the unused bitfield in i386_operand_type. */
2086 #ifdef OTUnused
2087 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2088 == OTNum + 1);
2089 #else
2090 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2091 == OTNum);
2092
2093 c = OTNumOfBits - OTNum;
2094 if (c)
2095 fail (_("%d unused bits in i386_operand_type.\n"), c);
2096 #endif
2097
2098 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2099 compare);
2100
2101 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2102 sizeof (opcode_modifiers [0]), compare);
2103
2104 qsort (operand_types, ARRAY_SIZE (operand_types),
2105 sizeof (operand_types [0]), compare);
2106
2107 table = fopen ("i386-tbl.h", "w");
2108 if (table == NULL)
2109 fail (_("can't create i386-tbl.h, errno = %s\n"),
2110 xstrerror (errno));
2111
2112 process_copyright (table);
2113
2114 process_i386_opcodes (table);
2115 process_i386_registers (table);
2116 process_i386_initializers ();
2117
2118 fclose (table);
2119
2120 exit (0);
2121 }