]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/i386-gen.c
Fix printf formatting errors where "0x" is used as a prefix for a decimal number.
[thirdparty/binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.
2
3 This file is part of the GNU opcodes library.
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
19
20 #include "sysdep.h"
21 #include <stdio.h>
22 #include <errno.h>
23 #include "getopt.h"
24 #include "libiberty.h"
25 #include "hashtab.h"
26 #include "safe-ctype.h"
27
28 #include "i386-opc.h"
29
30 #include <libintl.h>
31 #define _(String) gettext (String)
32
33 /* Build-time checks are preferrable over runtime ones. Use this construct
34 in preference where possible. */
35 #define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
36
37 static const char *program_name = NULL;
38 static int debug = 0;
39
40 typedef struct initializer
41 {
42 const char *name;
43 const char *init;
44 } initializer;
45
46 static initializer cpu_flag_init[] =
47 {
48 { "CPU_UNKNOWN_FLAGS",
49 "~(CpuL1OM|CpuK1OM)" },
50 { "CPU_GENERIC32_FLAGS",
51 "Cpu186|Cpu286|Cpu386" },
52 { "CPU_GENERIC64_FLAGS",
53 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
54 { "CPU_NONE_FLAGS",
55 "0" },
56 { "CPU_I186_FLAGS",
57 "Cpu186" },
58 { "CPU_I286_FLAGS",
59 "CPU_I186_FLAGS|Cpu286" },
60 { "CPU_I386_FLAGS",
61 "CPU_I286_FLAGS|Cpu386" },
62 { "CPU_I486_FLAGS",
63 "CPU_I386_FLAGS|Cpu486" },
64 { "CPU_I586_FLAGS",
65 "CPU_I486_FLAGS|Cpu387|Cpu586" },
66 { "CPU_I686_FLAGS",
67 "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" },
68 { "CPU_PENTIUMPRO_FLAGS",
69 "CPU_I686_FLAGS|CpuNop" },
70 { "CPU_P2_FLAGS",
71 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
72 { "CPU_P3_FLAGS",
73 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
74 { "CPU_P4_FLAGS",
75 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
76 { "CPU_NOCONA_FLAGS",
77 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
78 { "CPU_CORE_FLAGS",
79 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
80 { "CPU_CORE2_FLAGS",
81 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
82 { "CPU_COREI7_FLAGS",
83 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
84 { "CPU_K6_FLAGS",
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
86 { "CPU_K6_2_FLAGS",
87 "CPU_K6_FLAGS|Cpu3dnow" },
88 { "CPU_ATHLON_FLAGS",
89 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
90 { "CPU_K8_FLAGS",
91 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
92 { "CPU_AMDFAM10_FLAGS",
93 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuLZCNT|CpuPOPCNT" },
94 { "CPU_BDVER1_FLAGS",
95 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuLZCNT|CpuPOPCNT|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuPRFCHW" },
96 { "CPU_BDVER2_FLAGS",
97 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
98 { "CPU_BDVER3_FLAGS",
99 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
100 { "CPU_BDVER4_FLAGS",
101 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
102 { "CPU_ZNVER1_FLAGS",
103 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuSVME|CpuAES|CpuPCLMUL|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
104 { "CPU_ZNVER2_FLAGS",
105 "CPU_ZNVER1_FLAGS|CpuCLWB|CpuRDPID|CpuRDPRU|CpuMCOMMIT|CpuWBNOINVD" },
106 { "CPU_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_L1OM_FLAGS",
247 "unknown" },
248 { "CPU_K1OM_FLAGS",
249 "unknown" },
250 { "CPU_IAMCU_FLAGS",
251 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
252 { "CPU_ADX_FLAGS",
253 "CpuADX" },
254 { "CPU_RDSEED_FLAGS",
255 "CpuRdSeed" },
256 { "CPU_PRFCHW_FLAGS",
257 "CpuPRFCHW" },
258 { "CPU_SMAP_FLAGS",
259 "CpuSMAP" },
260 { "CPU_MPX_FLAGS",
261 "CPU_XSAVE_FLAGS|CpuMPX" },
262 { "CPU_SHA_FLAGS",
263 "CPU_SSE2_FLAGS|CpuSHA" },
264 { "CPU_CLFLUSHOPT_FLAGS",
265 "CpuClflushOpt" },
266 { "CPU_XSAVES_FLAGS",
267 "CPU_XSAVE_FLAGS|CpuXSAVES" },
268 { "CPU_XSAVEC_FLAGS",
269 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
270 { "CPU_PREFETCHWT1_FLAGS",
271 "CpuPREFETCHWT1" },
272 { "CPU_SE1_FLAGS",
273 "CpuSE1" },
274 { "CPU_CLWB_FLAGS",
275 "CpuCLWB" },
276 { "CPU_CLZERO_FLAGS",
277 "CpuCLZERO" },
278 { "CPU_MWAITX_FLAGS",
279 "CpuMWAITX" },
280 { "CPU_OSPKE_FLAGS",
281 "CPU_XSAVE_FLAGS|CpuOSPKE" },
282 { "CPU_RDPID_FLAGS",
283 "CpuRDPID" },
284 { "CPU_PTWRITE_FLAGS",
285 "CpuPTWRITE" },
286 { "CPU_IBT_FLAGS",
287 "CpuIBT" },
288 { "CPU_SHSTK_FLAGS",
289 "CpuSHSTK" },
290 { "CPU_GFNI_FLAGS",
291 "CpuGFNI" },
292 { "CPU_VAES_FLAGS",
293 "CpuVAES" },
294 { "CPU_VPCLMULQDQ_FLAGS",
295 "CpuVPCLMULQDQ" },
296 { "CPU_WBNOINVD_FLAGS",
297 "CpuWBNOINVD" },
298 { "CPU_PCONFIG_FLAGS",
299 "CpuPCONFIG" },
300 { "CPU_WAITPKG_FLAGS",
301 "CpuWAITPKG" },
302 { "CPU_UINTR_FLAGS",
303 "CpuUINTR" },
304 { "CPU_CLDEMOTE_FLAGS",
305 "CpuCLDEMOTE" },
306 { "CPU_AMX_INT8_FLAGS",
307 "CpuAMX_INT8" },
308 { "CPU_AMX_BF16_FLAGS",
309 "CpuAMX_BF16" },
310 { "CPU_AMX_TILE_FLAGS",
311 "CpuAMX_TILE" },
312 { "CPU_MOVDIRI_FLAGS",
313 "CpuMOVDIRI" },
314 { "CPU_MOVDIR64B_FLAGS",
315 "CpuMOVDIR64B" },
316 { "CPU_ENQCMD_FLAGS",
317 "CpuENQCMD" },
318 { "CPU_SERIALIZE_FLAGS",
319 "CpuSERIALIZE" },
320 { "CPU_AVX512_VP2INTERSECT_FLAGS",
321 "CpuAVX512_VP2INTERSECT" },
322 { "CPU_TDX_FLAGS",
323 "CpuTDX" },
324 { "CPU_RDPRU_FLAGS",
325 "CpuRDPRU" },
326 { "CPU_MCOMMIT_FLAGS",
327 "CpuMCOMMIT" },
328 { "CPU_SEV_ES_FLAGS",
329 "CpuSEV_ES" },
330 { "CPU_TSXLDTRK_FLAGS",
331 "CpuTSXLDTRK"},
332 { "CPU_KL_FLAGS",
333 "CpuKL" },
334 { "CPU_WIDEKL_FLAGS",
335 "CpuWideKL" },
336 { "CPU_HRESET_FLAGS",
337 "CpuHRESET"},
338 { "CPU_INVLPGB_FLAGS",
339 "CpuINVLPGB" },
340 { "CPU_TLBSYNC_FLAGS",
341 "CpuTLBSYNC" },
342 { "CPU_SNP_FLAGS",
343 "CpuSNP" },
344 { "CPU_ANY_X87_FLAGS",
345 "CPU_ANY_287_FLAGS|Cpu8087" },
346 { "CPU_ANY_287_FLAGS",
347 "CPU_ANY_387_FLAGS|Cpu287" },
348 { "CPU_ANY_387_FLAGS",
349 "CPU_ANY_687_FLAGS|Cpu387" },
350 { "CPU_ANY_687_FLAGS",
351 "Cpu687|CpuFISTTP" },
352 { "CPU_ANY_CMOV_FLAGS",
353 "CpuCMOV" },
354 { "CPU_ANY_FXSR_FLAGS",
355 "CpuFXSR" },
356 { "CPU_ANY_MMX_FLAGS",
357 "CPU_3DNOWA_FLAGS" },
358 { "CPU_ANY_SSE_FLAGS",
359 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
360 { "CPU_ANY_SSE2_FLAGS",
361 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
362 { "CPU_ANY_SSE3_FLAGS",
363 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
364 { "CPU_ANY_SSSE3_FLAGS",
365 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
366 { "CPU_ANY_SSE4_1_FLAGS",
367 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
368 { "CPU_ANY_SSE4_2_FLAGS",
369 "CpuSSE4_2" },
370 { "CPU_ANY_SSE4A_FLAGS",
371 "CpuSSE4a" },
372 { "CPU_ANY_AVX_FLAGS",
373 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
374 { "CPU_ANY_AVX2_FLAGS",
375 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
376 { "CPU_ANY_AVX512F_FLAGS",
377 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
378 { "CPU_ANY_AVX512CD_FLAGS",
379 "CpuAVX512CD" },
380 { "CPU_ANY_AVX512ER_FLAGS",
381 "CpuAVX512ER" },
382 { "CPU_ANY_AVX512PF_FLAGS",
383 "CpuAVX512PF" },
384 { "CPU_ANY_AVX512DQ_FLAGS",
385 "CpuAVX512DQ" },
386 { "CPU_ANY_AVX512BW_FLAGS",
387 "CpuAVX512BW" },
388 { "CPU_ANY_AVX512VL_FLAGS",
389 "CpuAVX512VL" },
390 { "CPU_ANY_AVX512IFMA_FLAGS",
391 "CpuAVX512IFMA" },
392 { "CPU_ANY_AVX512VBMI_FLAGS",
393 "CpuAVX512VBMI" },
394 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
395 "CpuAVX512_4FMAPS" },
396 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
397 "CpuAVX512_4VNNIW" },
398 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
399 "CpuAVX512_VPOPCNTDQ" },
400 { "CPU_ANY_IBT_FLAGS",
401 "CpuIBT" },
402 { "CPU_ANY_SHSTK_FLAGS",
403 "CpuSHSTK" },
404 { "CPU_ANY_AVX512_VBMI2_FLAGS",
405 "CpuAVX512_VBMI2" },
406 { "CPU_ANY_AVX512_VNNI_FLAGS",
407 "CpuAVX512_VNNI" },
408 { "CPU_ANY_AVX512_BITALG_FLAGS",
409 "CpuAVX512_BITALG" },
410 { "CPU_ANY_AVX512_BF16_FLAGS",
411 "CpuAVX512_BF16" },
412 { "CPU_ANY_AMX_INT8_FLAGS",
413 "CpuAMX_INT8" },
414 { "CPU_ANY_AMX_BF16_FLAGS",
415 "CpuAMX_BF16" },
416 { "CPU_ANY_AMX_TILE_FLAGS",
417 "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16" },
418 { "CPU_ANY_AVX_VNNI_FLAGS",
419 "CpuAVX_VNNI" },
420 { "CPU_ANY_MOVDIRI_FLAGS",
421 "CpuMOVDIRI" },
422 { "CPU_ANY_UINTR_FLAGS",
423 "CpuUINTR" },
424 { "CPU_ANY_MOVDIR64B_FLAGS",
425 "CpuMOVDIR64B" },
426 { "CPU_ANY_ENQCMD_FLAGS",
427 "CpuENQCMD" },
428 { "CPU_ANY_SERIALIZE_FLAGS",
429 "CpuSERIALIZE" },
430 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
431 "CpuAVX512_VP2INTERSECT" },
432 { "CPU_ANY_TDX_FLAGS",
433 "CpuTDX" },
434 { "CPU_ANY_TSXLDTRK_FLAGS",
435 "CpuTSXLDTRK" },
436 { "CPU_ANY_KL_FLAGS",
437 "CpuKL|CpuWideKL" },
438 { "CPU_ANY_WIDEKL_FLAGS",
439 "CpuWideKL" },
440 { "CPU_ANY_HRESET_FLAGS",
441 "CpuHRESET" },
442 };
443
444 static initializer operand_type_init[] =
445 {
446 { "OPERAND_TYPE_NONE",
447 "0" },
448 { "OPERAND_TYPE_REG8",
449 "Class=Reg|Byte" },
450 { "OPERAND_TYPE_REG16",
451 "Class=Reg|Word" },
452 { "OPERAND_TYPE_REG32",
453 "Class=Reg|Dword" },
454 { "OPERAND_TYPE_REG64",
455 "Class=Reg|Qword" },
456 { "OPERAND_TYPE_IMM1",
457 "Imm1" },
458 { "OPERAND_TYPE_IMM8",
459 "Imm8" },
460 { "OPERAND_TYPE_IMM8S",
461 "Imm8S" },
462 { "OPERAND_TYPE_IMM16",
463 "Imm16" },
464 { "OPERAND_TYPE_IMM32",
465 "Imm32" },
466 { "OPERAND_TYPE_IMM32S",
467 "Imm32S" },
468 { "OPERAND_TYPE_IMM64",
469 "Imm64" },
470 { "OPERAND_TYPE_BASEINDEX",
471 "BaseIndex" },
472 { "OPERAND_TYPE_DISP8",
473 "Disp8" },
474 { "OPERAND_TYPE_DISP16",
475 "Disp16" },
476 { "OPERAND_TYPE_DISP32",
477 "Disp32" },
478 { "OPERAND_TYPE_DISP32S",
479 "Disp32S" },
480 { "OPERAND_TYPE_DISP64",
481 "Disp64" },
482 { "OPERAND_TYPE_INOUTPORTREG",
483 "Instance=RegD|Word" },
484 { "OPERAND_TYPE_SHIFTCOUNT",
485 "Instance=RegC|Byte" },
486 { "OPERAND_TYPE_CONTROL",
487 "Class=RegCR" },
488 { "OPERAND_TYPE_TEST",
489 "Class=RegTR" },
490 { "OPERAND_TYPE_DEBUG",
491 "Class=RegDR" },
492 { "OPERAND_TYPE_FLOATREG",
493 "Class=Reg|Tbyte" },
494 { "OPERAND_TYPE_FLOATACC",
495 "Instance=Accum|Tbyte" },
496 { "OPERAND_TYPE_SREG",
497 "Class=SReg" },
498 { "OPERAND_TYPE_REGMMX",
499 "Class=RegMMX" },
500 { "OPERAND_TYPE_REGXMM",
501 "Class=RegSIMD|Xmmword" },
502 { "OPERAND_TYPE_REGYMM",
503 "Class=RegSIMD|Ymmword" },
504 { "OPERAND_TYPE_REGZMM",
505 "Class=RegSIMD|Zmmword" },
506 { "OPERAND_TYPE_REGTMM",
507 "Class=RegSIMD|Tmmword" },
508 { "OPERAND_TYPE_REGMASK",
509 "Class=RegMask" },
510 { "OPERAND_TYPE_REGBND",
511 "Class=RegBND" },
512 { "OPERAND_TYPE_ACC8",
513 "Instance=Accum|Byte" },
514 { "OPERAND_TYPE_ACC16",
515 "Instance=Accum|Word" },
516 { "OPERAND_TYPE_ACC32",
517 "Instance=Accum|Dword" },
518 { "OPERAND_TYPE_ACC64",
519 "Instance=Accum|Qword" },
520 { "OPERAND_TYPE_DISP16_32",
521 "Disp16|Disp32" },
522 { "OPERAND_TYPE_ANYDISP",
523 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
524 { "OPERAND_TYPE_IMM16_32",
525 "Imm16|Imm32" },
526 { "OPERAND_TYPE_IMM16_32S",
527 "Imm16|Imm32S" },
528 { "OPERAND_TYPE_IMM16_32_32S",
529 "Imm16|Imm32|Imm32S" },
530 { "OPERAND_TYPE_IMM32_64",
531 "Imm32|Imm64" },
532 { "OPERAND_TYPE_IMM32_32S_DISP32",
533 "Imm32|Imm32S|Disp32" },
534 { "OPERAND_TYPE_IMM64_DISP64",
535 "Imm64|Disp64" },
536 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
537 "Imm32|Imm32S|Imm64|Disp32" },
538 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
539 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
540 { "OPERAND_TYPE_ANYIMM",
541 "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
542 };
543
544 typedef struct bitfield
545 {
546 int position;
547 int value;
548 const char *name;
549 } bitfield;
550
551 #define BITFIELD(n) { n, 0, #n }
552
553 static bitfield cpu_flags[] =
554 {
555 BITFIELD (Cpu186),
556 BITFIELD (Cpu286),
557 BITFIELD (Cpu386),
558 BITFIELD (Cpu486),
559 BITFIELD (Cpu586),
560 BITFIELD (Cpu686),
561 BITFIELD (CpuCMOV),
562 BITFIELD (CpuFXSR),
563 BITFIELD (CpuClflush),
564 BITFIELD (CpuNop),
565 BITFIELD (CpuSYSCALL),
566 BITFIELD (Cpu8087),
567 BITFIELD (Cpu287),
568 BITFIELD (Cpu387),
569 BITFIELD (Cpu687),
570 BITFIELD (CpuFISTTP),
571 BITFIELD (CpuMMX),
572 BITFIELD (CpuSSE),
573 BITFIELD (CpuSSE2),
574 BITFIELD (CpuSSE3),
575 BITFIELD (CpuSSSE3),
576 BITFIELD (CpuSSE4_1),
577 BITFIELD (CpuSSE4_2),
578 BITFIELD (CpuAVX),
579 BITFIELD (CpuAVX2),
580 BITFIELD (CpuAVX512F),
581 BITFIELD (CpuAVX512CD),
582 BITFIELD (CpuAVX512ER),
583 BITFIELD (CpuAVX512PF),
584 BITFIELD (CpuAVX512VL),
585 BITFIELD (CpuAVX512DQ),
586 BITFIELD (CpuAVX512BW),
587 BITFIELD (CpuL1OM),
588 BITFIELD (CpuK1OM),
589 BITFIELD (CpuIAMCU),
590 BITFIELD (CpuSSE4a),
591 BITFIELD (Cpu3dnow),
592 BITFIELD (Cpu3dnowA),
593 BITFIELD (CpuPadLock),
594 BITFIELD (CpuSVME),
595 BITFIELD (CpuVMX),
596 BITFIELD (CpuSMX),
597 BITFIELD (CpuXsave),
598 BITFIELD (CpuXsaveopt),
599 BITFIELD (CpuAES),
600 BITFIELD (CpuPCLMUL),
601 BITFIELD (CpuFMA),
602 BITFIELD (CpuFMA4),
603 BITFIELD (CpuXOP),
604 BITFIELD (CpuLWP),
605 BITFIELD (CpuBMI),
606 BITFIELD (CpuTBM),
607 BITFIELD (CpuLM),
608 BITFIELD (CpuMovbe),
609 BITFIELD (CpuCX16),
610 BITFIELD (CpuEPT),
611 BITFIELD (CpuRdtscp),
612 BITFIELD (CpuFSGSBase),
613 BITFIELD (CpuRdRnd),
614 BITFIELD (CpuF16C),
615 BITFIELD (CpuBMI2),
616 BITFIELD (CpuLZCNT),
617 BITFIELD (CpuPOPCNT),
618 BITFIELD (CpuHLE),
619 BITFIELD (CpuRTM),
620 BITFIELD (CpuINVPCID),
621 BITFIELD (CpuVMFUNC),
622 BITFIELD (CpuRDSEED),
623 BITFIELD (CpuADX),
624 BITFIELD (CpuPRFCHW),
625 BITFIELD (CpuSMAP),
626 BITFIELD (CpuSHA),
627 BITFIELD (CpuClflushOpt),
628 BITFIELD (CpuXSAVES),
629 BITFIELD (CpuXSAVEC),
630 BITFIELD (CpuPREFETCHWT1),
631 BITFIELD (CpuSE1),
632 BITFIELD (CpuCLWB),
633 BITFIELD (Cpu64),
634 BITFIELD (CpuNo64),
635 BITFIELD (CpuMPX),
636 BITFIELD (CpuAVX512IFMA),
637 BITFIELD (CpuAVX512VBMI),
638 BITFIELD (CpuAVX512_4FMAPS),
639 BITFIELD (CpuAVX512_4VNNIW),
640 BITFIELD (CpuAVX512_VPOPCNTDQ),
641 BITFIELD (CpuAVX512_VBMI2),
642 BITFIELD (CpuAVX512_VNNI),
643 BITFIELD (CpuAVX512_BITALG),
644 BITFIELD (CpuAVX512_BF16),
645 BITFIELD (CpuAVX512_VP2INTERSECT),
646 BITFIELD (CpuTDX),
647 BITFIELD (CpuAVX_VNNI),
648 BITFIELD (CpuMWAITX),
649 BITFIELD (CpuCLZERO),
650 BITFIELD (CpuOSPKE),
651 BITFIELD (CpuRDPID),
652 BITFIELD (CpuPTWRITE),
653 BITFIELD (CpuIBT),
654 BITFIELD (CpuSHSTK),
655 BITFIELD (CpuGFNI),
656 BITFIELD (CpuVAES),
657 BITFIELD (CpuVPCLMULQDQ),
658 BITFIELD (CpuWBNOINVD),
659 BITFIELD (CpuPCONFIG),
660 BITFIELD (CpuWAITPKG),
661 BITFIELD (CpuUINTR),
662 BITFIELD (CpuCLDEMOTE),
663 BITFIELD (CpuAMX_INT8),
664 BITFIELD (CpuAMX_BF16),
665 BITFIELD (CpuAMX_TILE),
666 BITFIELD (CpuMOVDIRI),
667 BITFIELD (CpuMOVDIR64B),
668 BITFIELD (CpuENQCMD),
669 BITFIELD (CpuSERIALIZE),
670 BITFIELD (CpuRDPRU),
671 BITFIELD (CpuMCOMMIT),
672 BITFIELD (CpuSEV_ES),
673 BITFIELD (CpuTSXLDTRK),
674 BITFIELD (CpuKL),
675 BITFIELD (CpuWideKL),
676 BITFIELD (CpuHRESET),
677 BITFIELD (CpuINVLPGB),
678 BITFIELD (CpuTLBSYNC),
679 BITFIELD (CpuSNP),
680 #ifdef CpuUnused
681 BITFIELD (CpuUnused),
682 #endif
683 };
684
685 static bitfield opcode_modifiers[] =
686 {
687 BITFIELD (D),
688 BITFIELD (W),
689 BITFIELD (Load),
690 BITFIELD (Modrm),
691 BITFIELD (Jump),
692 BITFIELD (FloatMF),
693 BITFIELD (FloatR),
694 BITFIELD (Size),
695 BITFIELD (CheckRegSize),
696 BITFIELD (MnemonicSize),
697 BITFIELD (Anysize),
698 BITFIELD (No_bSuf),
699 BITFIELD (No_wSuf),
700 BITFIELD (No_lSuf),
701 BITFIELD (No_sSuf),
702 BITFIELD (No_qSuf),
703 BITFIELD (No_ldSuf),
704 BITFIELD (FWait),
705 BITFIELD (IsString),
706 BITFIELD (RegMem),
707 BITFIELD (BNDPrefixOk),
708 BITFIELD (NoTrackPrefixOk),
709 BITFIELD (IsLockable),
710 BITFIELD (RegKludge),
711 BITFIELD (Implicit1stXmm0),
712 BITFIELD (RepPrefixOk),
713 BITFIELD (HLEPrefixOk),
714 BITFIELD (ToDword),
715 BITFIELD (ToQword),
716 BITFIELD (AddrPrefixOpReg),
717 BITFIELD (IsPrefix),
718 BITFIELD (ImmExt),
719 BITFIELD (NoRex64),
720 BITFIELD (Ugh),
721 BITFIELD (PseudoVexPrefix),
722 BITFIELD (Vex),
723 BITFIELD (VexVVVV),
724 BITFIELD (VexW),
725 BITFIELD (OpcodePrefix),
726 BITFIELD (VexSources),
727 BITFIELD (SIB),
728 BITFIELD (SSE2AVX),
729 BITFIELD (NoAVX),
730 BITFIELD (EVex),
731 BITFIELD (Masking),
732 BITFIELD (Broadcast),
733 BITFIELD (StaticRounding),
734 BITFIELD (SAE),
735 BITFIELD (Disp8MemShift),
736 BITFIELD (NoDefMask),
737 BITFIELD (ImplicitQuadGroup),
738 BITFIELD (SwapSources),
739 BITFIELD (Optimize),
740 BITFIELD (ATTMnemonic),
741 BITFIELD (ATTSyntax),
742 BITFIELD (IntelSyntax),
743 BITFIELD (ISA64),
744 };
745
746 #define CLASS(n) #n, n
747
748 static const struct {
749 const char *name;
750 enum operand_class value;
751 } operand_classes[] = {
752 CLASS (Reg),
753 CLASS (SReg),
754 CLASS (RegCR),
755 CLASS (RegDR),
756 CLASS (RegTR),
757 CLASS (RegMMX),
758 CLASS (RegSIMD),
759 CLASS (RegMask),
760 CLASS (RegBND),
761 };
762
763 #undef CLASS
764
765 #define INSTANCE(n) #n, n
766
767 static const struct {
768 const char *name;
769 enum operand_instance value;
770 } operand_instances[] = {
771 INSTANCE (Accum),
772 INSTANCE (RegC),
773 INSTANCE (RegD),
774 INSTANCE (RegB),
775 };
776
777 #undef INSTANCE
778
779 static bitfield operand_types[] =
780 {
781 BITFIELD (Imm1),
782 BITFIELD (Imm8),
783 BITFIELD (Imm8S),
784 BITFIELD (Imm16),
785 BITFIELD (Imm32),
786 BITFIELD (Imm32S),
787 BITFIELD (Imm64),
788 BITFIELD (BaseIndex),
789 BITFIELD (Disp8),
790 BITFIELD (Disp16),
791 BITFIELD (Disp32),
792 BITFIELD (Disp32S),
793 BITFIELD (Disp64),
794 BITFIELD (Byte),
795 BITFIELD (Word),
796 BITFIELD (Dword),
797 BITFIELD (Fword),
798 BITFIELD (Qword),
799 BITFIELD (Tbyte),
800 BITFIELD (Xmmword),
801 BITFIELD (Ymmword),
802 BITFIELD (Zmmword),
803 BITFIELD (Tmmword),
804 BITFIELD (Unspecified),
805 #ifdef OTUnused
806 BITFIELD (OTUnused),
807 #endif
808 };
809
810 static const char *filename;
811 static i386_cpu_flags active_cpu_flags;
812 static int active_isstring;
813
814 struct template_arg {
815 const struct template_arg *next;
816 const char *val;
817 };
818
819 struct template_instance {
820 const struct template_instance *next;
821 const char *name;
822 const struct template_arg *args;
823 };
824
825 struct template_param {
826 const struct template_param *next;
827 const char *name;
828 };
829
830 struct template {
831 const struct template *next;
832 const char *name;
833 const struct template_instance *instances;
834 const struct template_param *params;
835 };
836
837 static const struct template *templates;
838
839 static int
840 compare (const void *x, const void *y)
841 {
842 const bitfield *xp = (const bitfield *) x;
843 const bitfield *yp = (const bitfield *) y;
844 return xp->position - yp->position;
845 }
846
847 static void
848 fail (const char *message, ...)
849 {
850 va_list args;
851
852 va_start (args, message);
853 fprintf (stderr, _("%s: error: "), program_name);
854 vfprintf (stderr, message, args);
855 va_end (args);
856 xexit (1);
857 }
858
859 static void
860 process_copyright (FILE *fp)
861 {
862 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
863 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
864 \n\
865 This file is part of the GNU opcodes library.\n\
866 \n\
867 This library is free software; you can redistribute it and/or modify\n\
868 it under the terms of the GNU General Public License as published by\n\
869 the Free Software Foundation; either version 3, or (at your option)\n\
870 any later version.\n\
871 \n\
872 It is distributed in the hope that it will be useful, but WITHOUT\n\
873 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
874 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
875 License for more details.\n\
876 \n\
877 You should have received a copy of the GNU General Public License\n\
878 along with this program; if not, write to the Free Software\n\
879 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
880 MA 02110-1301, USA. */\n");
881 }
882
883 /* Remove leading white spaces. */
884
885 static char *
886 remove_leading_whitespaces (char *str)
887 {
888 while (ISSPACE (*str))
889 str++;
890 return str;
891 }
892
893 /* Remove trailing white spaces. */
894
895 static void
896 remove_trailing_whitespaces (char *str)
897 {
898 size_t last = strlen (str);
899
900 if (last == 0)
901 return;
902
903 do
904 {
905 last--;
906 if (ISSPACE (str [last]))
907 str[last] = '\0';
908 else
909 break;
910 }
911 while (last != 0);
912 }
913
914 /* Find next field separated by SEP and terminate it. Return a
915 pointer to the one after it. */
916
917 static char *
918 next_field (char *str, char sep, char **next, char *last)
919 {
920 char *p;
921
922 p = remove_leading_whitespaces (str);
923 for (str = p; *str != sep && *str != '\0'; str++);
924
925 *str = '\0';
926 remove_trailing_whitespaces (p);
927
928 *next = str + 1;
929
930 if (p >= last)
931 abort ();
932
933 return p;
934 }
935
936 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
937
938 static int
939 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
940 int lineno)
941 {
942 char *str, *next, *last;
943 unsigned int i;
944
945 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
946 if (strcmp (cpu_flag_init[i].name, f) == 0)
947 {
948 /* Turn on selective bits. */
949 char *init = xstrdup (cpu_flag_init[i].init);
950 last = init + strlen (init);
951 for (next = init; next && next < last; )
952 {
953 str = next_field (next, '|', &next, last);
954 if (str)
955 set_bitfield (str, array, 1, size, lineno);
956 }
957 free (init);
958 return 0;
959 }
960
961 return -1;
962 }
963
964 static void
965 set_bitfield (char *f, bitfield *array, int value,
966 unsigned int size, int lineno)
967 {
968 unsigned int i;
969
970 /* Ignore empty fields; they may result from template expansions. */
971 if (*f == '\0')
972 return;
973
974 if (strcmp (f, "CpuFP") == 0)
975 {
976 set_bitfield("Cpu387", array, value, size, lineno);
977 set_bitfield("Cpu287", array, value, size, lineno);
978 f = "Cpu8087";
979 }
980 else if (strcmp (f, "Mmword") == 0)
981 f= "Qword";
982 else if (strcmp (f, "Oword") == 0)
983 f= "Xmmword";
984
985 for (i = 0; i < size; i++)
986 if (strcasecmp (array[i].name, f) == 0)
987 {
988 array[i].value = value;
989 return;
990 }
991
992 if (value)
993 {
994 const char *v = strchr (f, '=');
995
996 if (v)
997 {
998 size_t n = v - f;
999 char *end;
1000
1001 for (i = 0; i < size; i++)
1002 if (strncasecmp (array[i].name, f, n) == 0)
1003 {
1004 value = strtol (v + 1, &end, 0);
1005 if (*end == '\0')
1006 {
1007 array[i].value = value;
1008 return;
1009 }
1010 break;
1011 }
1012 }
1013 }
1014
1015 /* Handle CPU_XXX_FLAGS. */
1016 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1017 return;
1018
1019 if (lineno != -1)
1020 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
1021 else
1022 fail (_("unknown bitfield: %s\n"), f);
1023 }
1024
1025 static void
1026 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
1027 int macro, const char *comma, const char *indent)
1028 {
1029 unsigned int i;
1030
1031 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
1032
1033 fprintf (table, "%s{ { ", indent);
1034
1035 for (i = 0; i < size - 1; i++)
1036 {
1037 if (((i + 1) % 20) != 0)
1038 fprintf (table, "%d, ", flags[i].value);
1039 else
1040 fprintf (table, "%d,", flags[i].value);
1041 if (((i + 1) % 20) == 0)
1042 {
1043 /* We need \\ for macro. */
1044 if (macro)
1045 fprintf (table, " \\\n %s", indent);
1046 else
1047 fprintf (table, "\n %s", indent);
1048 }
1049 if (flags[i].value)
1050 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
1051 }
1052
1053 fprintf (table, "%d } }%s\n", flags[i].value, comma);
1054 }
1055
1056 static void
1057 process_i386_cpu_flag (FILE *table, char *flag, int macro,
1058 const char *comma, const char *indent,
1059 int lineno)
1060 {
1061 char *str, *next, *last;
1062 unsigned int i;
1063 bitfield flags [ARRAY_SIZE (cpu_flags)];
1064
1065 /* Copy the default cpu flags. */
1066 memcpy (flags, cpu_flags, sizeof (cpu_flags));
1067
1068 if (strcasecmp (flag, "unknown") == 0)
1069 {
1070 /* We turn on everything except for cpu64 in case of
1071 CPU_UNKNOWN_FLAGS. */
1072 for (i = 0; i < ARRAY_SIZE (flags); i++)
1073 if (flags[i].position != Cpu64)
1074 flags[i].value = 1;
1075 }
1076 else if (flag[0] == '~')
1077 {
1078 last = flag + strlen (flag);
1079
1080 if (flag[1] == '(')
1081 {
1082 last -= 1;
1083 next = flag + 2;
1084 if (*last != ')')
1085 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
1086 lineno, flag);
1087 *last = '\0';
1088 }
1089 else
1090 next = flag + 1;
1091
1092 /* First we turn on everything except for cpu64. */
1093 for (i = 0; i < ARRAY_SIZE (flags); i++)
1094 if (flags[i].position != Cpu64)
1095 flags[i].value = 1;
1096
1097 /* Turn off selective bits. */
1098 for (; next && next < last; )
1099 {
1100 str = next_field (next, '|', &next, last);
1101 if (str)
1102 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1103 }
1104 }
1105 else if (strcmp (flag, "0"))
1106 {
1107 /* Turn on selective bits. */
1108 last = flag + strlen (flag);
1109 for (next = flag; next && next < last; )
1110 {
1111 str = next_field (next, '|', &next, last);
1112 if (str)
1113 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1114 }
1115 }
1116
1117 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1118 comma, indent);
1119 }
1120
1121 static void
1122 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1123 {
1124 unsigned int i;
1125
1126 fprintf (table, " { ");
1127
1128 for (i = 0; i < size - 1; i++)
1129 {
1130 if (((i + 1) % 20) != 0)
1131 fprintf (table, "%d, ", modifier[i].value);
1132 else
1133 fprintf (table, "%d,", modifier[i].value);
1134 if (((i + 1) % 20) == 0)
1135 fprintf (table, "\n ");
1136 }
1137
1138 fprintf (table, "%d },\n", modifier[i].value);
1139 }
1140
1141 static int
1142 adjust_broadcast_modifier (char **opnd)
1143 {
1144 char *str, *next, *last, *op;
1145 int bcst_type = INT_MAX;
1146
1147 /* Skip the immediate operand. */
1148 op = opnd[0];
1149 if (strcasecmp(op, "Imm8") == 0)
1150 op = opnd[1];
1151
1152 op = xstrdup (op);
1153 last = op + strlen (op);
1154 for (next = op; next && next < last; )
1155 {
1156 str = next_field (next, '|', &next, last);
1157 if (str)
1158 {
1159 if (strcasecmp(str, "Byte") == 0)
1160 {
1161 /* The smalest broadcast type, no need to check
1162 further. */
1163 bcst_type = BYTE_BROADCAST;
1164 break;
1165 }
1166 else if (strcasecmp(str, "Word") == 0)
1167 {
1168 if (bcst_type > WORD_BROADCAST)
1169 bcst_type = WORD_BROADCAST;
1170 }
1171 else if (strcasecmp(str, "Dword") == 0)
1172 {
1173 if (bcst_type > DWORD_BROADCAST)
1174 bcst_type = DWORD_BROADCAST;
1175 }
1176 else if (strcasecmp(str, "Qword") == 0)
1177 {
1178 if (bcst_type > QWORD_BROADCAST)
1179 bcst_type = QWORD_BROADCAST;
1180 }
1181 }
1182 }
1183 free (op);
1184
1185 if (bcst_type == INT_MAX)
1186 fail (_("unknown broadcast operand: %s\n"), op);
1187
1188 return bcst_type;
1189 }
1190
1191 static int
1192 process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
1193 {
1194 char *str, *next, *last;
1195 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1196 unsigned int regular_encoding = 1;
1197
1198 active_isstring = 0;
1199
1200 /* Copy the default opcode modifier. */
1201 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1202
1203 if (strcmp (mod, "0"))
1204 {
1205 unsigned int have_w = 0, bwlq_suf = 0xf;
1206
1207 last = mod + strlen (mod);
1208 for (next = mod; next && next < last; )
1209 {
1210 str = next_field (next, '|', &next, last);
1211 if (str)
1212 {
1213 int val = 1;
1214 if (strcasecmp(str, "Broadcast") == 0)
1215 {
1216 val = adjust_broadcast_modifier (opnd);
1217 regular_encoding = 0;
1218 }
1219 else if (strcasecmp(str, "Vex") == 0
1220 || strncasecmp(str, "Vex=", 4) == 0
1221 || strcasecmp(str, "EVex") == 0
1222 || strncasecmp(str, "EVex=", 5) == 0
1223 || strncasecmp(str, "Disp8MemShift=", 14) == 0
1224 || strncasecmp(str, "Masking=", 8) == 0
1225 || strcasecmp(str, "SAE") == 0
1226 || strcasecmp(str, "IsPrefix") == 0)
1227 regular_encoding = 0;
1228
1229 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1230 lineno);
1231 if (strcasecmp(str, "IsString") == 0)
1232 active_isstring = 1;
1233
1234 if (strcasecmp(str, "W") == 0)
1235 have_w = 1;
1236
1237 if (strcasecmp(str, "No_bSuf") == 0)
1238 bwlq_suf &= ~1;
1239 if (strcasecmp(str, "No_wSuf") == 0)
1240 bwlq_suf &= ~2;
1241 if (strcasecmp(str, "No_lSuf") == 0)
1242 bwlq_suf &= ~4;
1243 if (strcasecmp(str, "No_qSuf") == 0)
1244 bwlq_suf &= ~8;
1245 }
1246 }
1247
1248 if (have_w && !bwlq_suf)
1249 fail ("%s: %d: stray W modifier\n", filename, lineno);
1250 if (have_w && !(bwlq_suf & 1))
1251 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1252 filename, lineno);
1253 if (have_w && !(bwlq_suf & ~1))
1254 fprintf (stderr,
1255 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1256 filename, lineno);
1257 }
1258 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1259
1260 return regular_encoding;
1261 }
1262
1263 enum stage {
1264 stage_macros,
1265 stage_opcodes,
1266 stage_registers,
1267 };
1268
1269 static void
1270 output_operand_type (FILE *table, enum operand_class class,
1271 enum operand_instance instance,
1272 const bitfield *types, unsigned int size,
1273 enum stage stage, const char *indent)
1274 {
1275 unsigned int i;
1276
1277 fprintf (table, "{ { %d, %d, ", class, instance);
1278
1279 for (i = 0; i < size - 1; i++)
1280 {
1281 if (((i + 3) % 20) != 0)
1282 fprintf (table, "%d, ", types[i].value);
1283 else
1284 fprintf (table, "%d,", types[i].value);
1285 if (((i + 3) % 20) == 0)
1286 {
1287 /* We need \\ for macro. */
1288 if (stage == stage_macros)
1289 fprintf (table, " \\\n%s", indent);
1290 else
1291 fprintf (table, "\n%s", indent);
1292 }
1293 }
1294
1295 fprintf (table, "%d } }", types[i].value);
1296 }
1297
1298 static void
1299 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1300 const char *indent, int lineno)
1301 {
1302 char *str, *next, *last;
1303 enum operand_class class = ClassNone;
1304 enum operand_instance instance = InstanceNone;
1305 bitfield types [ARRAY_SIZE (operand_types)];
1306
1307 /* Copy the default operand type. */
1308 memcpy (types, operand_types, sizeof (types));
1309
1310 if (strcmp (op, "0"))
1311 {
1312 int baseindex = 0;
1313
1314 last = op + strlen (op);
1315 for (next = op; next && next < last; )
1316 {
1317 str = next_field (next, '|', &next, last);
1318 if (str)
1319 {
1320 unsigned int i;
1321
1322 if (!strncmp(str, "Class=", 6))
1323 {
1324 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1325 if (!strcmp(str + 6, operand_classes[i].name))
1326 {
1327 class = operand_classes[i].value;
1328 str = NULL;
1329 break;
1330 }
1331 }
1332
1333 if (str && !strncmp(str, "Instance=", 9))
1334 {
1335 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1336 if (!strcmp(str + 9, operand_instances[i].name))
1337 {
1338 instance = operand_instances[i].value;
1339 str = NULL;
1340 break;
1341 }
1342 }
1343 }
1344 if (str)
1345 {
1346 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1347 if (strcasecmp(str, "BaseIndex") == 0)
1348 baseindex = 1;
1349 }
1350 }
1351
1352 if (stage == stage_opcodes && baseindex && !active_isstring)
1353 {
1354 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1355 if (!active_cpu_flags.bitfield.cpu64
1356 && !active_cpu_flags.bitfield.cpumpx)
1357 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1358 if (!active_cpu_flags.bitfield.cpu64)
1359 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1360 if (!active_cpu_flags.bitfield.cpuno64)
1361 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1362 }
1363 }
1364 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1365 stage, indent);
1366 }
1367
1368 static void
1369 output_i386_opcode (FILE *table, const char *name, char *str,
1370 char *last, int lineno)
1371 {
1372 unsigned int i;
1373 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1374 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1375
1376 /* Find number of operands. */
1377 operands = next_field (str, ',', &str, last);
1378
1379 /* Find base_opcode. */
1380 base_opcode = next_field (str, ',', &str, last);
1381
1382 /* Find extension_opcode. */
1383 extension_opcode = next_field (str, ',', &str, last);
1384
1385 /* Find opcode_length. */
1386 opcode_length = 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
1400 i = strlen (str);
1401
1402 /* There are at least "X}". */
1403 if (i < 2)
1404 abort ();
1405
1406 /* Remove trailing white spaces and }. */
1407 do
1408 {
1409 i--;
1410 if (ISSPACE (str[i]) || str[i] == '}')
1411 str[i] = '\0';
1412 else
1413 break;
1414 }
1415 while (i != 0);
1416
1417 last = str + i;
1418
1419 /* Find operand_types. */
1420 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1421 {
1422 if (str >= last)
1423 {
1424 operand_types [i] = NULL;
1425 break;
1426 }
1427
1428 operand_types [i] = next_field (str, ',', &str, last);
1429 if (*operand_types[i] == '0')
1430 {
1431 if (i != 0)
1432 operand_types[i] = NULL;
1433 break;
1434 }
1435 }
1436
1437 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1438 name, base_opcode, extension_opcode, opcode_length, operands);
1439
1440 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1441
1442 if (process_i386_opcode_modifier (table, opcode_modifier,
1443 operand_types, lineno))
1444 {
1445 char *end;
1446 unsigned long int length = strtoul (opcode_length, &end, 0);
1447 unsigned long int opcode = strtoul (base_opcode, &end, 0);
1448 switch (length)
1449 {
1450 case 4:
1451 break;
1452 case 3:
1453 if ((opcode >> 24) != 0)
1454 fail (_("%s: %s: (base_opcode >> 24) != 0: %s\n"),
1455 filename, name, base_opcode);
1456 break;
1457 case 2:
1458 if ((opcode >> 16) != 0)
1459 fail (_("%s: %s: (base_opcode >> 16) != 0: %s\n"),
1460 filename, name, base_opcode);
1461 break;
1462 case 1:
1463 if ((opcode >> 8) != 0)
1464 fail (_("%s: %s: (base_opcode >> 8) != 0: %s\n"),
1465 filename, name, base_opcode);
1466 break;
1467 case 0:
1468 if (opcode != 0)
1469 fail (_("%s: %s: base_opcode != 0: %s\n"),
1470 filename, name, base_opcode);
1471 break;
1472 default:
1473 fail (_("%s: %s: invalid opcode length: %s\n"),
1474 filename, name, opcode_length);
1475 break;
1476 }
1477 }
1478
1479 fprintf (table, " { ");
1480
1481 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1482 {
1483 if (operand_types[i] == NULL || *operand_types[i] == '0')
1484 {
1485 if (i == 0)
1486 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1487 lineno);
1488 break;
1489 }
1490
1491 if (i != 0)
1492 fprintf (table, ",\n ");
1493
1494 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1495 "\t ", lineno);
1496 }
1497 fprintf (table, " } },\n");
1498 }
1499
1500 struct opcode_hash_entry
1501 {
1502 struct opcode_hash_entry *next;
1503 char *name;
1504 char *opcode;
1505 int lineno;
1506 };
1507
1508 /* Calculate the hash value of an opcode hash entry P. */
1509
1510 static hashval_t
1511 opcode_hash_hash (const void *p)
1512 {
1513 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1514 return htab_hash_string (entry->name);
1515 }
1516
1517 /* Compare a string Q against an opcode hash entry P. */
1518
1519 static int
1520 opcode_hash_eq (const void *p, const void *q)
1521 {
1522 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1523 const char *name = (const char *) q;
1524 return strcmp (name, entry->name) == 0;
1525 }
1526
1527 static void
1528 parse_template (char *buf, int lineno)
1529 {
1530 char sep, *end, *name;
1531 struct template *tmpl = xmalloc (sizeof (*tmpl));
1532 struct template_instance *last_inst = NULL;
1533
1534 buf = remove_leading_whitespaces (buf + 1);
1535 end = strchr (buf, ':');
1536 if (end == NULL)
1537 fail ("%s: %d: missing ':'\n", filename, lineno);
1538 *end++ = '\0';
1539 remove_trailing_whitespaces (buf);
1540
1541 if (*buf == '\0')
1542 fail ("%s: %d: missing template identifier\n", filename, lineno);
1543 tmpl->name = xstrdup (buf);
1544
1545 tmpl->params = NULL;
1546 do {
1547 struct template_param *param;
1548
1549 buf = remove_leading_whitespaces (end);
1550 end = strpbrk (buf, ":,");
1551 if (end == NULL)
1552 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1553
1554 sep = *end;
1555 *end++ = '\0';
1556 remove_trailing_whitespaces (buf);
1557
1558 param = xmalloc (sizeof (*param));
1559 param->name = xstrdup (buf);
1560 param->next = tmpl->params;
1561 tmpl->params = param;
1562 } while (sep == ':');
1563
1564 tmpl->instances = NULL;
1565 do {
1566 struct template_instance *inst;
1567 char *cur, *next;
1568 const struct template_param *param;
1569
1570 buf = remove_leading_whitespaces (end);
1571 end = strpbrk (buf, ",>");
1572 if (end == NULL)
1573 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1574
1575 sep = *end;
1576 *end++ = '\0';
1577
1578 inst = xmalloc (sizeof (*inst));
1579
1580 cur = next_field (buf, ':', &next, end);
1581 inst->name = 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, 0,\n");
1863
1864 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1865
1866 process_i386_opcode_modifier (table, "0", NULL, -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 }