x86: infer operand count of templates
[deliverable/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 (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-2021 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 for (i = 0; i < size; i++)
975 if (strcasecmp (array[i].name, f) == 0)
976 {
977 array[i].value = value;
978 return;
979 }
980
981 if (value)
982 {
983 const char *v = strchr (f, '=');
984
985 if (v)
986 {
987 size_t n = v - f;
988 char *end;
989
990 for (i = 0; i < size; i++)
991 if (strncasecmp (array[i].name, f, n) == 0)
992 {
993 value = strtol (v + 1, &end, 0);
994 if (*end == '\0')
995 {
996 array[i].value = value;
997 return;
998 }
999 break;
1000 }
1001 }
1002 }
1003
1004 /* Handle CPU_XXX_FLAGS. */
1005 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1006 return;
1007
1008 if (lineno != -1)
1009 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
1010 else
1011 fail (_("unknown bitfield: %s\n"), f);
1012 }
1013
1014 static void
1015 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
1016 int macro, const char *comma, const char *indent)
1017 {
1018 unsigned int i;
1019
1020 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
1021
1022 fprintf (table, "%s{ { ", indent);
1023
1024 for (i = 0; i < size - 1; i++)
1025 {
1026 if (((i + 1) % 20) != 0)
1027 fprintf (table, "%d, ", flags[i].value);
1028 else
1029 fprintf (table, "%d,", flags[i].value);
1030 if (((i + 1) % 20) == 0)
1031 {
1032 /* We need \\ for macro. */
1033 if (macro)
1034 fprintf (table, " \\\n %s", indent);
1035 else
1036 fprintf (table, "\n %s", indent);
1037 }
1038 if (flags[i].value)
1039 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
1040 }
1041
1042 fprintf (table, "%d } }%s\n", flags[i].value, comma);
1043 }
1044
1045 static void
1046 process_i386_cpu_flag (FILE *table, char *flag, int macro,
1047 const char *comma, const char *indent,
1048 int lineno)
1049 {
1050 char *str, *next, *last;
1051 unsigned int i;
1052 bitfield flags [ARRAY_SIZE (cpu_flags)];
1053
1054 /* Copy the default cpu flags. */
1055 memcpy (flags, cpu_flags, sizeof (cpu_flags));
1056
1057 if (strcasecmp (flag, "unknown") == 0)
1058 {
1059 /* We turn on everything except for cpu64 in case of
1060 CPU_UNKNOWN_FLAGS. */
1061 for (i = 0; i < ARRAY_SIZE (flags); i++)
1062 if (flags[i].position != Cpu64)
1063 flags[i].value = 1;
1064 }
1065 else if (flag[0] == '~')
1066 {
1067 last = flag + strlen (flag);
1068
1069 if (flag[1] == '(')
1070 {
1071 last -= 1;
1072 next = flag + 2;
1073 if (*last != ')')
1074 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
1075 lineno, flag);
1076 *last = '\0';
1077 }
1078 else
1079 next = flag + 1;
1080
1081 /* First we turn on everything except for cpu64. */
1082 for (i = 0; i < ARRAY_SIZE (flags); i++)
1083 if (flags[i].position != Cpu64)
1084 flags[i].value = 1;
1085
1086 /* Turn off selective bits. */
1087 for (; next && next < last; )
1088 {
1089 str = next_field (next, '|', &next, last);
1090 if (str)
1091 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1092 }
1093 }
1094 else if (strcmp (flag, "0"))
1095 {
1096 /* Turn on selective bits. */
1097 last = flag + strlen (flag);
1098 for (next = flag; next && next < last; )
1099 {
1100 str = next_field (next, '|', &next, last);
1101 if (str)
1102 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1103 }
1104 }
1105
1106 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1107 comma, indent);
1108 }
1109
1110 static void
1111 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1112 {
1113 unsigned int i;
1114
1115 fprintf (table, " { ");
1116
1117 for (i = 0; i < size - 1; i++)
1118 {
1119 if (((i + 1) % 20) != 0)
1120 fprintf (table, "%d, ", modifier[i].value);
1121 else
1122 fprintf (table, "%d,", modifier[i].value);
1123 if (((i + 1) % 20) == 0)
1124 fprintf (table, "\n ");
1125 }
1126
1127 fprintf (table, "%d },\n", modifier[i].value);
1128 }
1129
1130 static int
1131 adjust_broadcast_modifier (char **opnd)
1132 {
1133 char *str, *next, *last, *op;
1134 int bcst_type = INT_MAX;
1135
1136 /* Skip the immediate operand. */
1137 op = opnd[0];
1138 if (strcasecmp(op, "Imm8") == 0)
1139 op = opnd[1];
1140
1141 op = xstrdup (op);
1142 last = op + strlen (op);
1143 for (next = op; next && next < last; )
1144 {
1145 str = next_field (next, '|', &next, last);
1146 if (str)
1147 {
1148 if (strcasecmp(str, "Byte") == 0)
1149 {
1150 /* The smalest broadcast type, no need to check
1151 further. */
1152 bcst_type = BYTE_BROADCAST;
1153 break;
1154 }
1155 else if (strcasecmp(str, "Word") == 0)
1156 {
1157 if (bcst_type > WORD_BROADCAST)
1158 bcst_type = WORD_BROADCAST;
1159 }
1160 else if (strcasecmp(str, "Dword") == 0)
1161 {
1162 if (bcst_type > DWORD_BROADCAST)
1163 bcst_type = DWORD_BROADCAST;
1164 }
1165 else if (strcasecmp(str, "Qword") == 0)
1166 {
1167 if (bcst_type > QWORD_BROADCAST)
1168 bcst_type = QWORD_BROADCAST;
1169 }
1170 }
1171 }
1172 free (op);
1173
1174 if (bcst_type == INT_MAX)
1175 fail (_("unknown broadcast operand: %s\n"), op);
1176
1177 return bcst_type;
1178 }
1179
1180 static int
1181 process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
1182 {
1183 char *str, *next, *last;
1184 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1185 unsigned int regular_encoding = 1;
1186
1187 active_isstring = 0;
1188
1189 /* Copy the default opcode modifier. */
1190 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1191
1192 if (strcmp (mod, "0"))
1193 {
1194 unsigned int have_w = 0, bwlq_suf = 0xf;
1195
1196 last = mod + strlen (mod);
1197 for (next = mod; next && next < last; )
1198 {
1199 str = next_field (next, '|', &next, last);
1200 if (str)
1201 {
1202 int val = 1;
1203 if (strcasecmp(str, "Broadcast") == 0)
1204 {
1205 val = adjust_broadcast_modifier (opnd);
1206 regular_encoding = 0;
1207 }
1208 else if (strcasecmp(str, "Vex") == 0
1209 || strncasecmp(str, "Vex=", 4) == 0
1210 || strcasecmp(str, "EVex") == 0
1211 || strncasecmp(str, "EVex=", 5) == 0
1212 || strncasecmp(str, "Disp8MemShift=", 14) == 0
1213 || strncasecmp(str, "Masking=", 8) == 0
1214 || strcasecmp(str, "SAE") == 0
1215 || strcasecmp(str, "IsPrefix") == 0)
1216 regular_encoding = 0;
1217
1218 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1219 lineno);
1220 if (strcasecmp(str, "IsString") == 0)
1221 active_isstring = 1;
1222
1223 if (strcasecmp(str, "W") == 0)
1224 have_w = 1;
1225
1226 if (strcasecmp(str, "No_bSuf") == 0)
1227 bwlq_suf &= ~1;
1228 if (strcasecmp(str, "No_wSuf") == 0)
1229 bwlq_suf &= ~2;
1230 if (strcasecmp(str, "No_lSuf") == 0)
1231 bwlq_suf &= ~4;
1232 if (strcasecmp(str, "No_qSuf") == 0)
1233 bwlq_suf &= ~8;
1234 }
1235 }
1236
1237 if (have_w && !bwlq_suf)
1238 fail ("%s: %d: stray W modifier\n", filename, lineno);
1239 if (have_w && !(bwlq_suf & 1))
1240 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1241 filename, lineno);
1242 if (have_w && !(bwlq_suf & ~1))
1243 fprintf (stderr,
1244 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1245 filename, lineno);
1246 }
1247 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1248
1249 return regular_encoding;
1250 }
1251
1252 enum stage {
1253 stage_macros,
1254 stage_opcodes,
1255 stage_registers,
1256 };
1257
1258 static void
1259 output_operand_type (FILE *table, enum operand_class class,
1260 enum operand_instance instance,
1261 const bitfield *types, unsigned int size,
1262 enum stage stage, const char *indent)
1263 {
1264 unsigned int i;
1265
1266 fprintf (table, "{ { %d, %d, ", class, instance);
1267
1268 for (i = 0; i < size - 1; i++)
1269 {
1270 if (((i + 3) % 20) != 0)
1271 fprintf (table, "%d, ", types[i].value);
1272 else
1273 fprintf (table, "%d,", types[i].value);
1274 if (((i + 3) % 20) == 0)
1275 {
1276 /* We need \\ for macro. */
1277 if (stage == stage_macros)
1278 fprintf (table, " \\\n%s", indent);
1279 else
1280 fprintf (table, "\n%s", indent);
1281 }
1282 }
1283
1284 fprintf (table, "%d } }", types[i].value);
1285 }
1286
1287 static void
1288 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1289 const char *indent, int lineno)
1290 {
1291 char *str, *next, *last;
1292 enum operand_class class = ClassNone;
1293 enum operand_instance instance = InstanceNone;
1294 bitfield types [ARRAY_SIZE (operand_types)];
1295
1296 /* Copy the default operand type. */
1297 memcpy (types, operand_types, sizeof (types));
1298
1299 if (strcmp (op, "0"))
1300 {
1301 int baseindex = 0;
1302
1303 last = op + strlen (op);
1304 for (next = op; next && next < last; )
1305 {
1306 str = next_field (next, '|', &next, last);
1307 if (str)
1308 {
1309 unsigned int i;
1310
1311 if (!strncmp(str, "Class=", 6))
1312 {
1313 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1314 if (!strcmp(str + 6, operand_classes[i].name))
1315 {
1316 class = operand_classes[i].value;
1317 str = NULL;
1318 break;
1319 }
1320 }
1321
1322 if (str && !strncmp(str, "Instance=", 9))
1323 {
1324 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1325 if (!strcmp(str + 9, operand_instances[i].name))
1326 {
1327 instance = operand_instances[i].value;
1328 str = NULL;
1329 break;
1330 }
1331 }
1332 }
1333 if (str)
1334 {
1335 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1336 if (strcasecmp(str, "BaseIndex") == 0)
1337 baseindex = 1;
1338 }
1339 }
1340
1341 if (stage == stage_opcodes && baseindex && !active_isstring)
1342 {
1343 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1344 if (!active_cpu_flags.bitfield.cpu64
1345 && !active_cpu_flags.bitfield.cpumpx)
1346 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1347 if (!active_cpu_flags.bitfield.cpu64)
1348 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1349 if (!active_cpu_flags.bitfield.cpuno64)
1350 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1351 }
1352 }
1353 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1354 stage, indent);
1355 }
1356
1357 static void
1358 output_i386_opcode (FILE *table, const char *name, char *str,
1359 char *last, int lineno)
1360 {
1361 unsigned int i;
1362 char *base_opcode, *extension_opcode, *opcode_length;
1363 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1364
1365 /* Find base_opcode. */
1366 base_opcode = next_field (str, ',', &str, last);
1367
1368 /* Find extension_opcode. */
1369 extension_opcode = next_field (str, ',', &str, last);
1370
1371 /* Find opcode_length. */
1372 opcode_length = next_field (str, ',', &str, last);
1373
1374 /* Find cpu_flags. */
1375 cpu_flags = next_field (str, ',', &str, last);
1376
1377 /* Find opcode_modifier. */
1378 opcode_modifier = next_field (str, ',', &str, last);
1379
1380 /* Remove the first {. */
1381 str = remove_leading_whitespaces (str);
1382 if (*str != '{')
1383 abort ();
1384 str = remove_leading_whitespaces (str + 1);
1385 remove_trailing_whitespaces (str);
1386
1387 /* Remove } and trailing white space. */
1388 i = strlen (str);
1389 if (!i || str[i - 1] != '}')
1390 abort ();
1391 str[--i] = '\0';
1392 remove_trailing_whitespaces (str);
1393
1394 if (!*str)
1395 operand_types [i = 0] = NULL;
1396 else
1397 {
1398 last = str + strlen (str);
1399
1400 /* Find operand_types. */
1401 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1402 {
1403 if (str >= last)
1404 {
1405 operand_types [i] = NULL;
1406 break;
1407 }
1408
1409 operand_types [i] = next_field (str, ',', &str, last);
1410 }
1411 }
1412
1413 fprintf (table, " { \"%s\", %s, %s, %s, %u,\n",
1414 name, base_opcode, extension_opcode, opcode_length, i);
1415
1416 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1417
1418 if (process_i386_opcode_modifier (table, opcode_modifier,
1419 operand_types, lineno))
1420 {
1421 char *end;
1422 unsigned long int length = strtoul (opcode_length, &end, 0);
1423 unsigned long int opcode = strtoul (base_opcode, &end, 0);
1424 switch (length)
1425 {
1426 case 4:
1427 break;
1428 case 3:
1429 if ((opcode >> 24) != 0)
1430 fail (_("%s: %s: (base_opcode >> 24) != 0: %s\n"),
1431 filename, name, base_opcode);
1432 break;
1433 case 2:
1434 if ((opcode >> 16) != 0)
1435 fail (_("%s: %s: (base_opcode >> 16) != 0: %s\n"),
1436 filename, name, base_opcode);
1437 break;
1438 case 1:
1439 if ((opcode >> 8) != 0)
1440 fail (_("%s: %s: (base_opcode >> 8) != 0: %s\n"),
1441 filename, name, base_opcode);
1442 break;
1443 case 0:
1444 if (opcode != 0)
1445 fail (_("%s: %s: base_opcode != 0: %s\n"),
1446 filename, name, base_opcode);
1447 break;
1448 default:
1449 fail (_("%s: %s: invalid opcode length: %s\n"),
1450 filename, name, opcode_length);
1451 break;
1452 }
1453 }
1454
1455 fprintf (table, " { ");
1456
1457 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1458 {
1459 if (!operand_types[i])
1460 {
1461 if (i == 0)
1462 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1463 lineno);
1464 break;
1465 }
1466
1467 if (i != 0)
1468 fprintf (table, ",\n ");
1469
1470 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1471 "\t ", lineno);
1472 }
1473 fprintf (table, " } },\n");
1474 }
1475
1476 struct opcode_hash_entry
1477 {
1478 struct opcode_hash_entry *next;
1479 char *name;
1480 char *opcode;
1481 int lineno;
1482 };
1483
1484 /* Calculate the hash value of an opcode hash entry P. */
1485
1486 static hashval_t
1487 opcode_hash_hash (const void *p)
1488 {
1489 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1490 return htab_hash_string (entry->name);
1491 }
1492
1493 /* Compare a string Q against an opcode hash entry P. */
1494
1495 static int
1496 opcode_hash_eq (const void *p, const void *q)
1497 {
1498 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1499 const char *name = (const char *) q;
1500 return strcmp (name, entry->name) == 0;
1501 }
1502
1503 static void
1504 parse_template (char *buf, int lineno)
1505 {
1506 char sep, *end, *name;
1507 struct template *tmpl = xmalloc (sizeof (*tmpl));
1508 struct template_instance *last_inst = NULL;
1509
1510 buf = remove_leading_whitespaces (buf + 1);
1511 end = strchr (buf, ':');
1512 if (end == NULL)
1513 fail ("%s: %d: missing ':'\n", filename, lineno);
1514 *end++ = '\0';
1515 remove_trailing_whitespaces (buf);
1516
1517 if (*buf == '\0')
1518 fail ("%s: %d: missing template identifier\n", filename, lineno);
1519 tmpl->name = xstrdup (buf);
1520
1521 tmpl->params = NULL;
1522 do {
1523 struct template_param *param;
1524
1525 buf = remove_leading_whitespaces (end);
1526 end = strpbrk (buf, ":,");
1527 if (end == NULL)
1528 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1529
1530 sep = *end;
1531 *end++ = '\0';
1532 remove_trailing_whitespaces (buf);
1533
1534 param = xmalloc (sizeof (*param));
1535 param->name = xstrdup (buf);
1536 param->next = tmpl->params;
1537 tmpl->params = param;
1538 } while (sep == ':');
1539
1540 tmpl->instances = NULL;
1541 do {
1542 struct template_instance *inst;
1543 char *cur, *next;
1544 const struct template_param *param;
1545
1546 buf = remove_leading_whitespaces (end);
1547 end = strpbrk (buf, ",>");
1548 if (end == NULL)
1549 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1550
1551 sep = *end;
1552 *end++ = '\0';
1553
1554 inst = xmalloc (sizeof (*inst));
1555 inst->next = NULL;
1556 inst->args = NULL;
1557
1558 cur = next_field (buf, ':', &next, end);
1559 inst->name = xstrdup (cur);
1560
1561 for (param = tmpl->params; param; param = param->next)
1562 {
1563 struct template_arg *arg = xmalloc (sizeof (*arg));
1564
1565 cur = next_field (next, ':', &next, end);
1566 if (next > end)
1567 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1568 arg->val = xstrdup (cur);
1569 arg->next = inst->args;
1570 inst->args = arg;
1571 }
1572
1573 if (tmpl->instances)
1574 last_inst->next = inst;
1575 else
1576 tmpl->instances = inst;
1577 last_inst = inst;
1578 } while (sep == ',');
1579
1580 buf = remove_leading_whitespaces (end);
1581 if (*buf)
1582 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1583 filename, lineno, buf);
1584
1585 tmpl->next = templates;
1586 templates = tmpl;
1587 }
1588
1589 static unsigned int
1590 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1591 struct opcode_hash_entry ***opcode_array_p, int lineno)
1592 {
1593 static unsigned int idx, opcode_array_size;
1594 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1595 struct opcode_hash_entry **hash_slot, **entry;
1596 char *ptr1 = strchr(name, '<'), *ptr2;
1597
1598 if (ptr1 == NULL)
1599 {
1600 /* Get the slot in hash table. */
1601 hash_slot = (struct opcode_hash_entry **)
1602 htab_find_slot_with_hash (opcode_hash_table, name,
1603 htab_hash_string (name),
1604 INSERT);
1605
1606 if (*hash_slot == NULL)
1607 {
1608 /* It is the new one. Put it on opcode array. */
1609 if (idx >= opcode_array_size)
1610 {
1611 /* Grow the opcode array when needed. */
1612 opcode_array_size += 1024;
1613 opcode_array = (struct opcode_hash_entry **)
1614 xrealloc (opcode_array,
1615 sizeof (*opcode_array) * opcode_array_size);
1616 *opcode_array_p = opcode_array;
1617 }
1618
1619 opcode_array[idx] = (struct opcode_hash_entry *)
1620 xmalloc (sizeof (struct opcode_hash_entry));
1621 opcode_array[idx]->next = NULL;
1622 opcode_array[idx]->name = xstrdup (name);
1623 opcode_array[idx]->opcode = xstrdup (str);
1624 opcode_array[idx]->lineno = lineno;
1625 *hash_slot = opcode_array[idx];
1626 idx++;
1627 }
1628 else
1629 {
1630 /* Append it to the existing one. */
1631 entry = hash_slot;
1632 while ((*entry) != NULL)
1633 entry = &(*entry)->next;
1634 *entry = (struct opcode_hash_entry *)
1635 xmalloc (sizeof (struct opcode_hash_entry));
1636 (*entry)->next = NULL;
1637 (*entry)->name = (*hash_slot)->name;
1638 (*entry)->opcode = xstrdup (str);
1639 (*entry)->lineno = lineno;
1640 }
1641 }
1642 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1643 fail ("%s: %d: missing '>'\n", filename, lineno);
1644 else
1645 {
1646 const struct template *tmpl;
1647 const struct template_instance *inst;
1648
1649 *ptr1 = '\0';
1650 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1651 remove_trailing_whitespaces (ptr1);
1652
1653 *ptr2++ = '\0';
1654
1655 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1656 if (!strcmp(ptr1, tmpl->name))
1657 break;
1658 if (!tmpl)
1659 fail ("reference to unknown template '%s'\n", ptr1);
1660
1661 for (inst = tmpl->instances; inst; inst = inst->next)
1662 {
1663 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1664 char *str2 = xmalloc(2 * strlen(str));
1665 const char *src;
1666
1667 strcpy (name2, name);
1668 strcat (name2, inst->name);
1669 strcat (name2, ptr2);
1670
1671 for (ptr1 = str2, src = str; *src; )
1672 {
1673 const char *ident = tmpl->name, *end;
1674 const struct template_param *param;
1675 const struct template_arg *arg;
1676
1677 if ((*ptr1 = *src++) != '<')
1678 {
1679 ++ptr1;
1680 continue;
1681 }
1682 while (ISSPACE(*src))
1683 ++src;
1684 while (*ident && *src == *ident)
1685 ++src, ++ident;
1686 while (ISSPACE(*src))
1687 ++src;
1688 if (*src != ':' || *ident != '\0')
1689 {
1690 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1691 ptr1 += ident - tmpl->name;
1692 continue;
1693 }
1694 while (ISSPACE(*++src))
1695 ;
1696
1697 end = src;
1698 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1699 ++end;
1700
1701 for (param = tmpl->params, arg = inst->args; param;
1702 param = param->next, arg = arg->next)
1703 {
1704 if (end - src == strlen (param->name)
1705 && !memcmp (src, param->name, end - src))
1706 {
1707 src = end;
1708 break;
1709 }
1710 }
1711
1712 if (param == NULL)
1713 fail ("template '%s' has no parameter '%.*s'\n",
1714 tmpl->name, (int)(end - src), src);
1715
1716 while (ISSPACE(*src))
1717 ++src;
1718 if (*src != '>')
1719 fail ("%s: %d: missing '>'\n", filename, lineno);
1720
1721 memcpy(ptr1, arg->val, strlen(arg->val));
1722 ptr1 += strlen(arg->val);
1723 ++src;
1724 }
1725
1726 *ptr1 = '\0';
1727
1728 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1729 lineno);
1730
1731 free (str2);
1732 free (name2);
1733 }
1734 }
1735
1736 return idx;
1737 }
1738
1739 static void
1740 process_i386_opcodes (FILE *table)
1741 {
1742 FILE *fp;
1743 char buf[2048];
1744 unsigned int i, j;
1745 char *str, *p, *last, *name;
1746 htab_t opcode_hash_table;
1747 struct opcode_hash_entry **opcode_array = NULL;
1748 int lineno = 0, marker = 0;
1749
1750 filename = "i386-opc.tbl";
1751 fp = stdin;
1752
1753 i = 0;
1754 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1755 opcode_hash_eq, NULL,
1756 xcalloc, free);
1757
1758 fprintf (table, "\n/* i386 opcode table. */\n\n");
1759 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1760
1761 /* Put everything on opcode array. */
1762 while (!feof (fp))
1763 {
1764 if (fgets (buf, sizeof (buf), fp) == NULL)
1765 break;
1766
1767 lineno++;
1768
1769 p = remove_leading_whitespaces (buf);
1770
1771 /* Skip comments. */
1772 str = strstr (p, "//");
1773 if (str != NULL)
1774 str[0] = '\0';
1775
1776 /* Remove trailing white spaces. */
1777 remove_trailing_whitespaces (p);
1778
1779 switch (p[0])
1780 {
1781 case '#':
1782 if (!strcmp("### MARKER ###", buf))
1783 marker = 1;
1784 else
1785 {
1786 /* Since we ignore all included files (we only care about their
1787 #define-s here), we don't need to monitor filenames. The final
1788 line number directive is going to refer to the main source file
1789 again. */
1790 char *end;
1791 unsigned long ln;
1792
1793 p = remove_leading_whitespaces (p + 1);
1794 if (!strncmp(p, "line", 4))
1795 p += 4;
1796 ln = strtoul (p, &end, 10);
1797 if (ln > 1 && ln < INT_MAX
1798 && *remove_leading_whitespaces (end) == '"')
1799 lineno = ln - 1;
1800 }
1801 /* Ignore comments. */
1802 case '\0':
1803 continue;
1804 break;
1805 case '<':
1806 parse_template (p, lineno);
1807 continue;
1808 default:
1809 if (!marker)
1810 continue;
1811 break;
1812 }
1813
1814 last = p + strlen (p);
1815
1816 /* Find name. */
1817 name = next_field (p, ',', &str, last);
1818
1819 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1820 lineno);
1821 }
1822
1823 /* Process opcode array. */
1824 for (j = 0; j < i; j++)
1825 {
1826 struct opcode_hash_entry *next;
1827
1828 for (next = opcode_array[j]; next; next = next->next)
1829 {
1830 name = next->name;
1831 str = next->opcode;
1832 lineno = next->lineno;
1833 last = str + strlen (str);
1834 output_i386_opcode (table, name, str, last, lineno);
1835 }
1836 }
1837
1838 fclose (fp);
1839
1840 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1841
1842 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1843
1844 process_i386_opcode_modifier (table, "0", NULL, -1);
1845
1846 fprintf (table, " { ");
1847 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1848 fprintf (table, " } }\n");
1849
1850 fprintf (table, "};\n");
1851 }
1852
1853 static void
1854 process_i386_registers (FILE *table)
1855 {
1856 FILE *fp;
1857 char buf[2048];
1858 char *str, *p, *last;
1859 char *reg_name, *reg_type, *reg_flags, *reg_num;
1860 char *dw2_32_num, *dw2_64_num;
1861 int lineno = 0;
1862
1863 filename = "i386-reg.tbl";
1864 fp = fopen (filename, "r");
1865 if (fp == NULL)
1866 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1867 xstrerror (errno));
1868
1869 fprintf (table, "\n/* i386 register table. */\n\n");
1870 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1871
1872 while (!feof (fp))
1873 {
1874 if (fgets (buf, sizeof (buf), fp) == NULL)
1875 break;
1876
1877 lineno++;
1878
1879 p = remove_leading_whitespaces (buf);
1880
1881 /* Skip comments. */
1882 str = strstr (p, "//");
1883 if (str != NULL)
1884 str[0] = '\0';
1885
1886 /* Remove trailing white spaces. */
1887 remove_trailing_whitespaces (p);
1888
1889 switch (p[0])
1890 {
1891 case '#':
1892 fprintf (table, "%s\n", p);
1893 case '\0':
1894 continue;
1895 break;
1896 default:
1897 break;
1898 }
1899
1900 last = p + strlen (p);
1901
1902 /* Find reg_name. */
1903 reg_name = next_field (p, ',', &str, last);
1904
1905 /* Find reg_type. */
1906 reg_type = next_field (str, ',', &str, last);
1907
1908 /* Find reg_flags. */
1909 reg_flags = next_field (str, ',', &str, last);
1910
1911 /* Find reg_num. */
1912 reg_num = next_field (str, ',', &str, last);
1913
1914 fprintf (table, " { \"%s\",\n ", reg_name);
1915
1916 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1917 lineno);
1918
1919 /* Find 32-bit Dwarf2 register number. */
1920 dw2_32_num = next_field (str, ',', &str, last);
1921
1922 /* Find 64-bit Dwarf2 register number. */
1923 dw2_64_num = next_field (str, ',', &str, last);
1924
1925 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1926 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1927 }
1928
1929 fclose (fp);
1930
1931 fprintf (table, "};\n");
1932
1933 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1934 }
1935
1936 static void
1937 process_i386_initializers (void)
1938 {
1939 unsigned int i;
1940 FILE *fp = fopen ("i386-init.h", "w");
1941 char *init;
1942
1943 if (fp == NULL)
1944 fail (_("can't create i386-init.h, errno = %s\n"),
1945 xstrerror (errno));
1946
1947 process_copyright (fp);
1948
1949 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1950 {
1951 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1952 init = xstrdup (cpu_flag_init[i].init);
1953 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1954 free (init);
1955 }
1956
1957 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1958 {
1959 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1960 init = xstrdup (operand_type_init[i].init);
1961 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1962 free (init);
1963 }
1964 fprintf (fp, "\n");
1965
1966 fclose (fp);
1967 }
1968
1969 /* Program options. */
1970 #define OPTION_SRCDIR 200
1971
1972 struct option long_options[] =
1973 {
1974 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1975 {"debug", no_argument, NULL, 'd'},
1976 {"version", no_argument, NULL, 'V'},
1977 {"help", no_argument, NULL, 'h'},
1978 {0, no_argument, NULL, 0}
1979 };
1980
1981 static void
1982 print_version (void)
1983 {
1984 printf ("%s: version 1.0\n", program_name);
1985 xexit (0);
1986 }
1987
1988 static void
1989 usage (FILE * stream, int status)
1990 {
1991 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1992 program_name);
1993 xexit (status);
1994 }
1995
1996 int
1997 main (int argc, char **argv)
1998 {
1999 extern int chdir (char *);
2000 char *srcdir = NULL;
2001 int c;
2002 unsigned int i, cpumax;
2003 FILE *table;
2004
2005 program_name = *argv;
2006 xmalloc_set_program_name (program_name);
2007
2008 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2009 switch (c)
2010 {
2011 case OPTION_SRCDIR:
2012 srcdir = optarg;
2013 break;
2014 case 'V':
2015 case 'v':
2016 print_version ();
2017 break;
2018 case 'd':
2019 debug = 1;
2020 break;
2021 case 'h':
2022 case '?':
2023 usage (stderr, 0);
2024 default:
2025 case 0:
2026 break;
2027 }
2028
2029 if (optind != argc)
2030 usage (stdout, 1);
2031
2032 if (srcdir != NULL)
2033 if (chdir (srcdir) != 0)
2034 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2035 srcdir, xstrerror (errno));
2036
2037 /* cpu_flags isn't sorted by position. */
2038 cpumax = 0;
2039 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2040 if (cpu_flags[i].position > cpumax)
2041 cpumax = cpu_flags[i].position;
2042
2043 /* Check the unused bitfield in i386_cpu_flags. */
2044 #ifdef CpuUnused
2045 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2046
2047 if ((cpumax - 1) != CpuMax)
2048 fail (_("CpuMax != %d!\n"), cpumax);
2049 #else
2050 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2051
2052 if (cpumax != CpuMax)
2053 fail (_("CpuMax != %d!\n"), cpumax);
2054
2055 c = CpuNumOfBits - CpuMax - 1;
2056 if (c)
2057 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
2058 #endif
2059
2060 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2061
2062 /* Check the unused bitfield in i386_operand_type. */
2063 #ifdef OTUnused
2064 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2065 == OTNum + 1);
2066 #else
2067 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2068 == OTNum);
2069
2070 c = OTNumOfBits - OTNum;
2071 if (c)
2072 fail (_("%d unused bits in i386_operand_type.\n"), c);
2073 #endif
2074
2075 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2076 compare);
2077
2078 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2079 sizeof (opcode_modifiers [0]), compare);
2080
2081 qsort (operand_types, ARRAY_SIZE (operand_types),
2082 sizeof (operand_types [0]), compare);
2083
2084 table = fopen ("i386-tbl.h", "w");
2085 if (table == NULL)
2086 fail (_("can't create i386-tbl.h, errno = %s\n"),
2087 xstrerror (errno));
2088
2089 process_copyright (table);
2090
2091 process_i386_opcodes (table);
2092 process_i386_registers (table);
2093 process_i386_initializers ();
2094
2095 fclose (table);
2096
2097 exit (0);
2098 }
This page took 0.07304 seconds and 4 git commands to generate.