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