Automatic date update in version.in
[binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
2
3 This file is part of the GNU opcodes library.
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
19
20 #include "sysdep.h"
21 #include <stdio.h>
22 #include <errno.h>
23 #include "getopt.h"
24 #include "libiberty.h"
25 #include "hashtab.h"
26 #include "safe-ctype.h"
27
28 #include "i386-opc.h"
29
30 #include <libintl.h>
31 #define _(String) gettext (String)
32
33 /* Build-time checks are preferrable over runtime ones. Use this construct
34 in preference where possible. */
35 #define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
36
37 static const char *program_name = NULL;
38 static int debug = 0;
39
40 typedef struct initializer
41 {
42 const char *name;
43 const char *init;
44 } initializer;
45
46 static initializer cpu_flag_init[] =
47 {
48 { "CPU_UNKNOWN_FLAGS",
49 "~CpuIAMCU" },
50 { "CPU_GENERIC32_FLAGS",
51 "Cpu186|Cpu286|Cpu386" },
52 { "CPU_GENERIC64_FLAGS",
53 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
54 { "CPU_NONE_FLAGS",
55 "0" },
56 { "CPU_I186_FLAGS",
57 "Cpu186" },
58 { "CPU_I286_FLAGS",
59 "CPU_I186_FLAGS|Cpu286" },
60 { "CPU_I386_FLAGS",
61 "CPU_I286_FLAGS|Cpu386" },
62 { "CPU_I486_FLAGS",
63 "CPU_I386_FLAGS|Cpu486" },
64 { "CPU_I586_FLAGS",
65 "CPU_I486_FLAGS|Cpu387|Cpu586" },
66 { "CPU_I686_FLAGS",
67 "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" },
68 { "CPU_PENTIUMPRO_FLAGS",
69 "CPU_I686_FLAGS|CpuNop" },
70 { "CPU_P2_FLAGS",
71 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
72 { "CPU_P3_FLAGS",
73 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
74 { "CPU_P4_FLAGS",
75 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
76 { "CPU_NOCONA_FLAGS",
77 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
78 { "CPU_CORE_FLAGS",
79 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
80 { "CPU_CORE2_FLAGS",
81 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
82 { "CPU_COREI7_FLAGS",
83 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
84 { "CPU_K6_FLAGS",
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
86 { "CPU_K6_2_FLAGS",
87 "CPU_K6_FLAGS|Cpu3dnow" },
88 { "CPU_ATHLON_FLAGS",
89 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
90 { "CPU_K8_FLAGS",
91 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
92 { "CPU_AMDFAM10_FLAGS",
93 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuLZCNT|CpuPOPCNT" },
94 { "CPU_BDVER1_FLAGS",
95 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuLZCNT|CpuPOPCNT|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuPRFCHW" },
96 { "CPU_BDVER2_FLAGS",
97 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
98 { "CPU_BDVER3_FLAGS",
99 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
100 { "CPU_BDVER4_FLAGS",
101 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
102 { "CPU_ZNVER1_FLAGS",
103 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuSVME|CpuAES|CpuPCLMUL|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
104 { "CPU_ZNVER2_FLAGS",
105 "CPU_ZNVER1_FLAGS|CpuCLWB|CpuRDPID|CpuRDPRU|CpuMCOMMIT|CpuWBNOINVD" },
106 { "CPU_ZNVER3_FLAGS",
107 "CPU_ZNVER2_FLAGS|CpuINVLPGB|CpuTLBSYNC|CpuVAES|CpuVPCLMULQDQ|CpuINVPCID|CpuSNP|CpuOSPKE" },
108 { "CPU_BTVER1_FLAGS",
109 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME" },
110 { "CPU_BTVER2_FLAGS",
111 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
112 { "CPU_8087_FLAGS",
113 "Cpu8087" },
114 { "CPU_287_FLAGS",
115 "Cpu287" },
116 { "CPU_387_FLAGS",
117 "Cpu387" },
118 { "CPU_687_FLAGS",
119 "CPU_387_FLAGS|Cpu687" },
120 { "CPU_CMOV_FLAGS",
121 "CpuCMOV" },
122 { "CPU_FXSR_FLAGS",
123 "CpuFXSR" },
124 { "CPU_CLFLUSH_FLAGS",
125 "CpuClflush" },
126 { "CPU_NOP_FLAGS",
127 "CpuNop" },
128 { "CPU_SYSCALL_FLAGS",
129 "CpuSYSCALL" },
130 { "CPU_MMX_FLAGS",
131 "CpuMMX" },
132 { "CPU_SSE_FLAGS",
133 "CpuSSE" },
134 { "CPU_SSE2_FLAGS",
135 "CPU_SSE_FLAGS|CpuSSE2" },
136 { "CPU_SSE3_FLAGS",
137 "CPU_SSE2_FLAGS|CpuSSE3" },
138 { "CPU_SSSE3_FLAGS",
139 "CPU_SSE3_FLAGS|CpuSSSE3" },
140 { "CPU_SSE4_1_FLAGS",
141 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
142 { "CPU_SSE4_2_FLAGS",
143 "CPU_SSE4_1_FLAGS|CpuSSE4_2|CpuPOPCNT" },
144 { "CPU_VMX_FLAGS",
145 "CpuVMX" },
146 { "CPU_SMX_FLAGS",
147 "CpuSMX" },
148 { "CPU_XSAVE_FLAGS",
149 "CpuXsave" },
150 { "CPU_XSAVEOPT_FLAGS",
151 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
152 { "CPU_AES_FLAGS",
153 "CPU_SSE2_FLAGS|CpuAES" },
154 { "CPU_PCLMUL_FLAGS",
155 "CPU_SSE2_FLAGS|CpuPCLMUL" },
156 { "CPU_FMA_FLAGS",
157 "CPU_AVX_FLAGS|CpuFMA" },
158 { "CPU_FMA4_FLAGS",
159 "CPU_AVX_FLAGS|CpuFMA4" },
160 { "CPU_XOP_FLAGS",
161 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
162 { "CPU_LWP_FLAGS",
163 "CPU_XSAVE_FLAGS|CpuLWP" },
164 { "CPU_BMI_FLAGS",
165 "CpuBMI" },
166 { "CPU_TBM_FLAGS",
167 "CpuTBM" },
168 { "CPU_MOVBE_FLAGS",
169 "CpuMovbe" },
170 { "CPU_CX16_FLAGS",
171 "CpuCX16" },
172 { "CPU_RDTSCP_FLAGS",
173 "CpuRdtscp" },
174 { "CPU_EPT_FLAGS",
175 "CpuEPT" },
176 { "CPU_FSGSBASE_FLAGS",
177 "CpuFSGSBase" },
178 { "CPU_RDRND_FLAGS",
179 "CpuRdRnd" },
180 { "CPU_F16C_FLAGS",
181 "CPU_AVX_FLAGS|CpuF16C" },
182 { "CPU_BMI2_FLAGS",
183 "CpuBMI2" },
184 { "CPU_LZCNT_FLAGS",
185 "CpuLZCNT" },
186 { "CPU_POPCNT_FLAGS",
187 "CpuPOPCNT" },
188 { "CPU_HLE_FLAGS",
189 "CpuHLE" },
190 { "CPU_RTM_FLAGS",
191 "CpuRTM" },
192 { "CPU_INVPCID_FLAGS",
193 "CpuINVPCID" },
194 { "CPU_VMFUNC_FLAGS",
195 "CpuVMFUNC" },
196 { "CPU_3DNOW_FLAGS",
197 "CPU_MMX_FLAGS|Cpu3dnow" },
198 { "CPU_3DNOWA_FLAGS",
199 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
200 { "CPU_PADLOCK_FLAGS",
201 "CpuPadLock" },
202 { "CPU_SVME_FLAGS",
203 "CpuSVME" },
204 { "CPU_SSE4A_FLAGS",
205 "CPU_SSE3_FLAGS|CpuSSE4a" },
206 { "CPU_ABM_FLAGS",
207 "CpuLZCNT|CpuPOPCNT" },
208 { "CPU_AVX_FLAGS",
209 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
210 { "CPU_AVX2_FLAGS",
211 "CPU_AVX_FLAGS|CpuAVX2" },
212 { "CPU_AVX_VNNI_FLAGS",
213 "CPU_AVX2_FLAGS|CpuAVX_VNNI" },
214 { "CPU_AVX512F_FLAGS",
215 "CPU_AVX2_FLAGS|CpuAVX512F" },
216 { "CPU_AVX512CD_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
218 { "CPU_AVX512ER_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
220 { "CPU_AVX512PF_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
222 { "CPU_AVX512DQ_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
224 { "CPU_AVX512BW_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
226 { "CPU_AVX512VL_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
228 { "CPU_AVX512IFMA_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
230 { "CPU_AVX512VBMI_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
232 { "CPU_AVX512_4FMAPS_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
234 { "CPU_AVX512_4VNNIW_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
236 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
237 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
238 { "CPU_AVX512_VBMI2_FLAGS",
239 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
240 { "CPU_AVX512_VNNI_FLAGS",
241 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
242 { "CPU_AVX512_BITALG_FLAGS",
243 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
244 { "CPU_AVX512_BF16_FLAGS",
245 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
246 { "CPU_AVX512_FP16_FLAGS",
247 "CPU_AVX512BW_FLAGS|CpuAVX512_FP16" },
248 { "CPU_IAMCU_FLAGS",
249 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuIAMCU" },
250 { "CPU_ADX_FLAGS",
251 "CpuADX" },
252 { "CPU_RDSEED_FLAGS",
253 "CpuRdSeed" },
254 { "CPU_PRFCHW_FLAGS",
255 "CpuPRFCHW" },
256 { "CPU_SMAP_FLAGS",
257 "CpuSMAP" },
258 { "CPU_MPX_FLAGS",
259 "CPU_XSAVE_FLAGS|CpuMPX" },
260 { "CPU_SHA_FLAGS",
261 "CPU_SSE2_FLAGS|CpuSHA" },
262 { "CPU_CLFLUSHOPT_FLAGS",
263 "CpuClflushOpt" },
264 { "CPU_XSAVES_FLAGS",
265 "CPU_XSAVE_FLAGS|CpuXSAVES" },
266 { "CPU_XSAVEC_FLAGS",
267 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
268 { "CPU_PREFETCHWT1_FLAGS",
269 "CpuPREFETCHWT1" },
270 { "CPU_SE1_FLAGS",
271 "CpuSE1" },
272 { "CPU_CLWB_FLAGS",
273 "CpuCLWB" },
274 { "CPU_CLZERO_FLAGS",
275 "CpuCLZERO" },
276 { "CPU_MWAITX_FLAGS",
277 "CpuMWAITX" },
278 { "CPU_OSPKE_FLAGS",
279 "CPU_XSAVE_FLAGS|CpuOSPKE" },
280 { "CPU_RDPID_FLAGS",
281 "CpuRDPID" },
282 { "CPU_PTWRITE_FLAGS",
283 "CpuPTWRITE" },
284 { "CPU_IBT_FLAGS",
285 "CpuIBT" },
286 { "CPU_SHSTK_FLAGS",
287 "CpuSHSTK" },
288 { "CPU_GFNI_FLAGS",
289 "CpuGFNI" },
290 { "CPU_VAES_FLAGS",
291 "CpuVAES" },
292 { "CPU_VPCLMULQDQ_FLAGS",
293 "CpuVPCLMULQDQ" },
294 { "CPU_WBNOINVD_FLAGS",
295 "CpuWBNOINVD" },
296 { "CPU_PCONFIG_FLAGS",
297 "CpuPCONFIG" },
298 { "CPU_WAITPKG_FLAGS",
299 "CpuWAITPKG" },
300 { "CPU_UINTR_FLAGS",
301 "CpuUINTR" },
302 { "CPU_CLDEMOTE_FLAGS",
303 "CpuCLDEMOTE" },
304 { "CPU_AMX_INT8_FLAGS",
305 "CpuAMX_INT8" },
306 { "CPU_AMX_BF16_FLAGS",
307 "CpuAMX_BF16" },
308 { "CPU_AMX_TILE_FLAGS",
309 "CpuAMX_TILE" },
310 { "CPU_MOVDIRI_FLAGS",
311 "CpuMOVDIRI" },
312 { "CPU_MOVDIR64B_FLAGS",
313 "CpuMOVDIR64B" },
314 { "CPU_ENQCMD_FLAGS",
315 "CpuENQCMD" },
316 { "CPU_SERIALIZE_FLAGS",
317 "CpuSERIALIZE" },
318 { "CPU_AVX512_VP2INTERSECT_FLAGS",
319 "CpuAVX512_VP2INTERSECT" },
320 { "CPU_TDX_FLAGS",
321 "CpuTDX" },
322 { "CPU_RDPRU_FLAGS",
323 "CpuRDPRU" },
324 { "CPU_MCOMMIT_FLAGS",
325 "CpuMCOMMIT" },
326 { "CPU_SEV_ES_FLAGS",
327 "CpuSEV_ES" },
328 { "CPU_TSXLDTRK_FLAGS",
329 "CpuTSXLDTRK"},
330 { "CPU_KL_FLAGS",
331 "CpuKL" },
332 { "CPU_WIDEKL_FLAGS",
333 "CpuWideKL" },
334 { "CPU_HRESET_FLAGS",
335 "CpuHRESET"},
336 { "CPU_INVLPGB_FLAGS",
337 "CpuINVLPGB" },
338 { "CPU_TLBSYNC_FLAGS",
339 "CpuTLBSYNC" },
340 { "CPU_SNP_FLAGS",
341 "CpuSNP" },
342 { "CPU_ANY_X87_FLAGS",
343 "CPU_ANY_287_FLAGS|Cpu8087" },
344 { "CPU_ANY_287_FLAGS",
345 "CPU_ANY_387_FLAGS|Cpu287" },
346 { "CPU_ANY_387_FLAGS",
347 "CPU_ANY_687_FLAGS|Cpu387" },
348 { "CPU_ANY_687_FLAGS",
349 "Cpu687|CpuFISTTP" },
350 { "CPU_ANY_CMOV_FLAGS",
351 "CpuCMOV" },
352 { "CPU_ANY_FXSR_FLAGS",
353 "CpuFXSR" },
354 { "CPU_ANY_MMX_FLAGS",
355 "CPU_3DNOWA_FLAGS" },
356 { "CPU_ANY_SSE_FLAGS",
357 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
358 { "CPU_ANY_SSE2_FLAGS",
359 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
360 { "CPU_ANY_SSE3_FLAGS",
361 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
362 { "CPU_ANY_SSSE3_FLAGS",
363 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
364 { "CPU_ANY_SSE4_1_FLAGS",
365 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
366 { "CPU_ANY_SSE4_2_FLAGS",
367 "CpuSSE4_2" },
368 { "CPU_ANY_SSE4A_FLAGS",
369 "CpuSSE4a" },
370 { "CPU_ANY_AVX_FLAGS",
371 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
372 { "CPU_ANY_AVX2_FLAGS",
373 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
374 { "CPU_ANY_AVX512F_FLAGS",
375 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CPU_ANY_AVX512BW_FLAGS|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
376 { "CPU_ANY_AVX512CD_FLAGS",
377 "CpuAVX512CD" },
378 { "CPU_ANY_AVX512ER_FLAGS",
379 "CpuAVX512ER" },
380 { "CPU_ANY_AVX512PF_FLAGS",
381 "CpuAVX512PF" },
382 { "CPU_ANY_AVX512DQ_FLAGS",
383 "CpuAVX512DQ" },
384 { "CPU_ANY_AVX512BW_FLAGS",
385 "CpuAVX512BW|CPU_ANY_AVX512_FP16_FLAGS" },
386 { "CPU_ANY_AVX512VL_FLAGS",
387 "CpuAVX512VL" },
388 { "CPU_ANY_AVX512IFMA_FLAGS",
389 "CpuAVX512IFMA" },
390 { "CPU_ANY_AVX512VBMI_FLAGS",
391 "CpuAVX512VBMI" },
392 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
393 "CpuAVX512_4FMAPS" },
394 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
395 "CpuAVX512_4VNNIW" },
396 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
397 "CpuAVX512_VPOPCNTDQ" },
398 { "CPU_ANY_IBT_FLAGS",
399 "CpuIBT" },
400 { "CPU_ANY_SHSTK_FLAGS",
401 "CpuSHSTK" },
402 { "CPU_ANY_AVX512_VBMI2_FLAGS",
403 "CpuAVX512_VBMI2" },
404 { "CPU_ANY_AVX512_VNNI_FLAGS",
405 "CpuAVX512_VNNI" },
406 { "CPU_ANY_AVX512_BITALG_FLAGS",
407 "CpuAVX512_BITALG" },
408 { "CPU_ANY_AVX512_BF16_FLAGS",
409 "CpuAVX512_BF16" },
410 { "CPU_ANY_AMX_INT8_FLAGS",
411 "CpuAMX_INT8" },
412 { "CPU_ANY_AMX_BF16_FLAGS",
413 "CpuAMX_BF16" },
414 { "CPU_ANY_AMX_TILE_FLAGS",
415 "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16" },
416 { "CPU_ANY_AVX_VNNI_FLAGS",
417 "CpuAVX_VNNI" },
418 { "CPU_ANY_MOVDIRI_FLAGS",
419 "CpuMOVDIRI" },
420 { "CPU_ANY_UINTR_FLAGS",
421 "CpuUINTR" },
422 { "CPU_ANY_MOVDIR64B_FLAGS",
423 "CpuMOVDIR64B" },
424 { "CPU_ANY_ENQCMD_FLAGS",
425 "CpuENQCMD" },
426 { "CPU_ANY_SERIALIZE_FLAGS",
427 "CpuSERIALIZE" },
428 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
429 "CpuAVX512_VP2INTERSECT" },
430 { "CPU_ANY_TDX_FLAGS",
431 "CpuTDX" },
432 { "CPU_ANY_TSXLDTRK_FLAGS",
433 "CpuTSXLDTRK" },
434 { "CPU_ANY_KL_FLAGS",
435 "CpuKL|CpuWideKL" },
436 { "CPU_ANY_WIDEKL_FLAGS",
437 "CpuWideKL" },
438 { "CPU_ANY_HRESET_FLAGS",
439 "CpuHRESET" },
440 { "CPU_ANY_AVX512_FP16_FLAGS",
441 "CpuAVX512_FP16" },
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 (CpuIAMCU),
588 BITFIELD (CpuSSE4a),
589 BITFIELD (Cpu3dnow),
590 BITFIELD (Cpu3dnowA),
591 BITFIELD (CpuPadLock),
592 BITFIELD (CpuSVME),
593 BITFIELD (CpuVMX),
594 BITFIELD (CpuSMX),
595 BITFIELD (CpuXsave),
596 BITFIELD (CpuXsaveopt),
597 BITFIELD (CpuAES),
598 BITFIELD (CpuPCLMUL),
599 BITFIELD (CpuFMA),
600 BITFIELD (CpuFMA4),
601 BITFIELD (CpuXOP),
602 BITFIELD (CpuLWP),
603 BITFIELD (CpuBMI),
604 BITFIELD (CpuTBM),
605 BITFIELD (CpuLM),
606 BITFIELD (CpuMovbe),
607 BITFIELD (CpuCX16),
608 BITFIELD (CpuEPT),
609 BITFIELD (CpuRdtscp),
610 BITFIELD (CpuFSGSBase),
611 BITFIELD (CpuRdRnd),
612 BITFIELD (CpuF16C),
613 BITFIELD (CpuBMI2),
614 BITFIELD (CpuLZCNT),
615 BITFIELD (CpuPOPCNT),
616 BITFIELD (CpuHLE),
617 BITFIELD (CpuRTM),
618 BITFIELD (CpuINVPCID),
619 BITFIELD (CpuVMFUNC),
620 BITFIELD (CpuRDSEED),
621 BITFIELD (CpuADX),
622 BITFIELD (CpuPRFCHW),
623 BITFIELD (CpuSMAP),
624 BITFIELD (CpuSHA),
625 BITFIELD (CpuClflushOpt),
626 BITFIELD (CpuXSAVES),
627 BITFIELD (CpuXSAVEC),
628 BITFIELD (CpuPREFETCHWT1),
629 BITFIELD (CpuSE1),
630 BITFIELD (CpuCLWB),
631 BITFIELD (CpuMPX),
632 BITFIELD (CpuAVX512IFMA),
633 BITFIELD (CpuAVX512VBMI),
634 BITFIELD (CpuAVX512_4FMAPS),
635 BITFIELD (CpuAVX512_4VNNIW),
636 BITFIELD (CpuAVX512_VPOPCNTDQ),
637 BITFIELD (CpuAVX512_VBMI2),
638 BITFIELD (CpuAVX512_VNNI),
639 BITFIELD (CpuAVX512_BITALG),
640 BITFIELD (CpuAVX512_BF16),
641 BITFIELD (CpuAVX512_VP2INTERSECT),
642 BITFIELD (CpuTDX),
643 BITFIELD (CpuAVX_VNNI),
644 BITFIELD (CpuAVX512_FP16),
645 BITFIELD (CpuMWAITX),
646 BITFIELD (CpuCLZERO),
647 BITFIELD (CpuOSPKE),
648 BITFIELD (CpuRDPID),
649 BITFIELD (CpuPTWRITE),
650 BITFIELD (CpuIBT),
651 BITFIELD (CpuSHSTK),
652 BITFIELD (CpuGFNI),
653 BITFIELD (CpuVAES),
654 BITFIELD (CpuVPCLMULQDQ),
655 BITFIELD (CpuWBNOINVD),
656 BITFIELD (CpuPCONFIG),
657 BITFIELD (CpuWAITPKG),
658 BITFIELD (CpuUINTR),
659 BITFIELD (CpuCLDEMOTE),
660 BITFIELD (CpuAMX_INT8),
661 BITFIELD (CpuAMX_BF16),
662 BITFIELD (CpuAMX_TILE),
663 BITFIELD (CpuMOVDIRI),
664 BITFIELD (CpuMOVDIR64B),
665 BITFIELD (CpuENQCMD),
666 BITFIELD (CpuSERIALIZE),
667 BITFIELD (CpuRDPRU),
668 BITFIELD (CpuMCOMMIT),
669 BITFIELD (CpuSEV_ES),
670 BITFIELD (CpuTSXLDTRK),
671 BITFIELD (CpuKL),
672 BITFIELD (CpuWideKL),
673 BITFIELD (CpuHRESET),
674 BITFIELD (CpuINVLPGB),
675 BITFIELD (CpuTLBSYNC),
676 BITFIELD (CpuSNP),
677 BITFIELD (Cpu64),
678 BITFIELD (CpuNo64),
679 #ifdef CpuUnused
680 BITFIELD (CpuUnused),
681 #endif
682 };
683
684 static bitfield opcode_modifiers[] =
685 {
686 BITFIELD (D),
687 BITFIELD (W),
688 BITFIELD (Load),
689 BITFIELD (Modrm),
690 BITFIELD (Jump),
691 BITFIELD (FloatMF),
692 BITFIELD (FloatR),
693 BITFIELD (Size),
694 BITFIELD (CheckRegSize),
695 BITFIELD (DistinctDest),
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 (OpcodeSpace),
723 BITFIELD (OpcodePrefix),
724 BITFIELD (VexSources),
725 BITFIELD (SIB),
726 BITFIELD (SSE2AVX),
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-2022 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 = flag, *last;
1048 unsigned int i;
1049 int value = 1;
1050 bitfield flags [ARRAY_SIZE (cpu_flags)];
1051
1052 /* Copy the default cpu flags. */
1053 memcpy (flags, cpu_flags, sizeof (cpu_flags));
1054
1055 if (flag[0] == '~')
1056 {
1057 last = flag + strlen (flag);
1058
1059 if (flag[1] == '(')
1060 {
1061 last -= 1;
1062 next = flag + 2;
1063 if (*last != ')')
1064 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
1065 lineno, flag);
1066 *last = '\0';
1067 }
1068 else
1069 next = flag + 1;
1070
1071 /* First we turn on everything except for cpu64, cpuno64, and - if
1072 present - the padding field. */
1073 for (i = 0; i < ARRAY_SIZE (flags); i++)
1074 if (flags[i].position < Cpu64)
1075 flags[i].value = 1;
1076
1077 /* Turn off selective bits. */
1078 value = 0;
1079 }
1080
1081 if (strcmp (flag, "0"))
1082 {
1083 /* Turn on/off selective bits. */
1084 last = flag + strlen (flag);
1085 for (; next && next < last; )
1086 {
1087 str = next_field (next, '|', &next, last);
1088 if (str)
1089 set_bitfield (str, flags, value, ARRAY_SIZE (flags), lineno);
1090 }
1091 }
1092
1093 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1094 comma, indent);
1095 }
1096
1097 static void
1098 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1099 {
1100 unsigned int i;
1101
1102 fprintf (table, " { ");
1103
1104 for (i = 0; i < size - 1; i++)
1105 {
1106 if (((i + 1) % 20) != 0)
1107 fprintf (table, "%d, ", modifier[i].value);
1108 else
1109 fprintf (table, "%d,", modifier[i].value);
1110 if (((i + 1) % 20) == 0)
1111 fprintf (table, "\n ");
1112 }
1113
1114 fprintf (table, "%d },\n", modifier[i].value);
1115 }
1116
1117 static int
1118 adjust_broadcast_modifier (char **opnd)
1119 {
1120 char *str, *next, *last, *op;
1121 int bcst_type = INT_MAX;
1122
1123 /* Skip the immediate operand. */
1124 op = opnd[0];
1125 if (strcasecmp(op, "Imm8") == 0)
1126 op = opnd[1];
1127
1128 op = xstrdup (op);
1129 last = op + strlen (op);
1130 for (next = op; next && next < last; )
1131 {
1132 str = next_field (next, '|', &next, last);
1133 if (str)
1134 {
1135 if (strcasecmp(str, "Byte") == 0)
1136 {
1137 /* The smalest broadcast type, no need to check
1138 further. */
1139 bcst_type = BYTE_BROADCAST;
1140 break;
1141 }
1142 else if (strcasecmp(str, "Word") == 0)
1143 {
1144 if (bcst_type > WORD_BROADCAST)
1145 bcst_type = WORD_BROADCAST;
1146 }
1147 else if (strcasecmp(str, "Dword") == 0)
1148 {
1149 if (bcst_type > DWORD_BROADCAST)
1150 bcst_type = DWORD_BROADCAST;
1151 }
1152 else if (strcasecmp(str, "Qword") == 0)
1153 {
1154 if (bcst_type > QWORD_BROADCAST)
1155 bcst_type = QWORD_BROADCAST;
1156 }
1157 }
1158 }
1159 free (op);
1160
1161 if (bcst_type == INT_MAX)
1162 fail (_("unknown broadcast operand: %s\n"), op);
1163
1164 return bcst_type;
1165 }
1166
1167 static void
1168 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1169 unsigned int prefix, char **opnd, int lineno)
1170 {
1171 char *str, *next, *last;
1172 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1173
1174 active_isstring = 0;
1175
1176 /* Copy the default opcode modifier. */
1177 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1178
1179 if (strcmp (mod, "0"))
1180 {
1181 unsigned int have_w = 0, bwlq_suf = 0xf;
1182
1183 last = mod + strlen (mod);
1184 for (next = mod; next && next < last; )
1185 {
1186 str = next_field (next, '|', &next, last);
1187 if (str)
1188 {
1189 int val = 1;
1190 if (strcasecmp(str, "Broadcast") == 0)
1191 val = adjust_broadcast_modifier (opnd);
1192
1193 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1194 lineno);
1195 if (strcasecmp(str, "IsString") == 0)
1196 active_isstring = 1;
1197
1198 if (strcasecmp(str, "W") == 0)
1199 have_w = 1;
1200
1201 if (strcasecmp(str, "No_bSuf") == 0)
1202 bwlq_suf &= ~1;
1203 if (strcasecmp(str, "No_wSuf") == 0)
1204 bwlq_suf &= ~2;
1205 if (strcasecmp(str, "No_lSuf") == 0)
1206 bwlq_suf &= ~4;
1207 if (strcasecmp(str, "No_qSuf") == 0)
1208 bwlq_suf &= ~8;
1209 }
1210 }
1211
1212 if (space)
1213 {
1214 if (!modifiers[OpcodeSpace].value)
1215 modifiers[OpcodeSpace].value = space;
1216 else if (modifiers[OpcodeSpace].value != space)
1217 fail (_("%s:%d: Conflicting opcode space specifications\n"),
1218 filename, lineno);
1219 else
1220 fprintf (stderr,
1221 _("%s:%d: Warning: redundant opcode space specification\n"),
1222 filename, lineno);
1223 }
1224
1225 if (prefix)
1226 {
1227 if (!modifiers[OpcodePrefix].value)
1228 modifiers[OpcodePrefix].value = prefix;
1229 else if (modifiers[OpcodePrefix].value != prefix)
1230 fail (_("%s:%d: Conflicting prefix specifications\n"),
1231 filename, lineno);
1232 else
1233 fprintf (stderr,
1234 _("%s:%d: Warning: redundant prefix specification\n"),
1235 filename, lineno);
1236 }
1237
1238 if (have_w && !bwlq_suf)
1239 fail ("%s: %d: stray W modifier\n", filename, lineno);
1240 if (have_w && !(bwlq_suf & 1))
1241 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1242 filename, lineno);
1243 if (have_w && !(bwlq_suf & ~1))
1244 fprintf (stderr,
1245 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1246 filename, lineno);
1247 }
1248 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1249 }
1250
1251 enum stage {
1252 stage_macros,
1253 stage_opcodes,
1254 stage_registers,
1255 };
1256
1257 static void
1258 output_operand_type (FILE *table, enum operand_class class,
1259 enum operand_instance instance,
1260 const bitfield *types, unsigned int size,
1261 enum stage stage, const char *indent)
1262 {
1263 unsigned int i;
1264
1265 fprintf (table, "{ { %d, %d, ", class, instance);
1266
1267 for (i = 0; i < size - 1; i++)
1268 {
1269 if (((i + 3) % 20) != 0)
1270 fprintf (table, "%d, ", types[i].value);
1271 else
1272 fprintf (table, "%d,", types[i].value);
1273 if (((i + 3) % 20) == 0)
1274 {
1275 /* We need \\ for macro. */
1276 if (stage == stage_macros)
1277 fprintf (table, " \\\n%s", indent);
1278 else
1279 fprintf (table, "\n%s", indent);
1280 }
1281 }
1282
1283 fprintf (table, "%d } }", types[i].value);
1284 }
1285
1286 static void
1287 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1288 const char *indent, int lineno)
1289 {
1290 char *str, *next, *last;
1291 enum operand_class class = ClassNone;
1292 enum operand_instance instance = InstanceNone;
1293 bitfield types [ARRAY_SIZE (operand_types)];
1294
1295 /* Copy the default operand type. */
1296 memcpy (types, operand_types, sizeof (types));
1297
1298 if (strcmp (op, "0"))
1299 {
1300 int baseindex = 0;
1301
1302 last = op + strlen (op);
1303 for (next = op; next && next < last; )
1304 {
1305 str = next_field (next, '|', &next, last);
1306 if (str)
1307 {
1308 unsigned int i;
1309
1310 if (!strncmp(str, "Class=", 6))
1311 {
1312 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1313 if (!strcmp(str + 6, operand_classes[i].name))
1314 {
1315 class = operand_classes[i].value;
1316 str = NULL;
1317 break;
1318 }
1319 }
1320
1321 if (str && !strncmp(str, "Instance=", 9))
1322 {
1323 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1324 if (!strcmp(str + 9, operand_instances[i].name))
1325 {
1326 instance = operand_instances[i].value;
1327 str = NULL;
1328 break;
1329 }
1330 }
1331 }
1332 if (str)
1333 {
1334 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1335 if (strcasecmp(str, "BaseIndex") == 0)
1336 baseindex = 1;
1337 }
1338 }
1339
1340 if (stage == stage_opcodes && baseindex && !active_isstring)
1341 {
1342 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1343 if (!active_cpu_flags.bitfield.cpu64
1344 && !active_cpu_flags.bitfield.cpumpx)
1345 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1346 if (!active_cpu_flags.bitfield.cpu64)
1347 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1348 if (!active_cpu_flags.bitfield.cpuno64)
1349 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1350 }
1351 }
1352 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1353 stage, indent);
1354 }
1355
1356 static void
1357 output_i386_opcode (FILE *table, const char *name, char *str,
1358 char *last, int lineno)
1359 {
1360 unsigned int i, length, prefix = 0, space = 0;
1361 char *base_opcode, *extension_opcode, *end;
1362 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1363 unsigned long long opcode;
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 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 opcode = strtoull (base_opcode, &end, 0);
1411
1412 /* Determine opcode length. */
1413 for (length = 1; length < 8; ++length)
1414 if (!(opcode >> (8 * length)))
1415 break;
1416
1417 /* Transform prefixes encoded in the opcode into opcode modifier
1418 representation. */
1419 if (length > 1)
1420 {
1421 switch (opcode >> (8 * length - 8))
1422 {
1423 case 0x66: prefix = PREFIX_0X66; break;
1424 case 0xF3: prefix = PREFIX_0XF3; break;
1425 case 0xF2: prefix = PREFIX_0XF2; break;
1426 }
1427
1428 if (prefix)
1429 opcode &= (1ULL << (8 * --length)) - 1;
1430 }
1431
1432 /* Transform opcode space encoded in the opcode into opcode modifier
1433 representation. */
1434 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1435 {
1436 switch ((opcode >> (8 * length - 16)) & 0xff)
1437 {
1438 default: space = SPACE_0F; break;
1439 case 0x38: space = SPACE_0F38; break;
1440 case 0x3A: space = SPACE_0F3A; break;
1441 }
1442
1443 if (space != SPACE_0F && --length == 1)
1444 fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1445 filename, lineno, name);
1446 opcode &= (1ULL << (8 * --length)) - 1;
1447 }
1448
1449 if (length > 2)
1450 fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1451 filename, lineno, name, 2 * length, opcode);
1452
1453 fprintf (table, " { \"%s\", 0x%0*llx%s, %s, %lu,\n",
1454 name, 2 * (int)length, opcode, end, extension_opcode, i);
1455
1456 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1457 operand_types, lineno);
1458
1459 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1460
1461 fprintf (table, " { ");
1462
1463 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1464 {
1465 if (!operand_types[i])
1466 {
1467 if (i == 0)
1468 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1469 lineno);
1470 break;
1471 }
1472
1473 if (i != 0)
1474 fprintf (table, ",\n ");
1475
1476 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1477 "\t ", lineno);
1478 }
1479 fprintf (table, " } },\n");
1480 }
1481
1482 struct opcode_hash_entry
1483 {
1484 struct opcode_hash_entry *next;
1485 char *name;
1486 char *opcode;
1487 int lineno;
1488 };
1489
1490 /* Calculate the hash value of an opcode hash entry P. */
1491
1492 static hashval_t
1493 opcode_hash_hash (const void *p)
1494 {
1495 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1496 return htab_hash_string (entry->name);
1497 }
1498
1499 /* Compare a string Q against an opcode hash entry P. */
1500
1501 static int
1502 opcode_hash_eq (const void *p, const void *q)
1503 {
1504 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1505 const char *name = (const char *) q;
1506 return strcmp (name, entry->name) == 0;
1507 }
1508
1509 static void
1510 parse_template (char *buf, int lineno)
1511 {
1512 char sep, *end, *name;
1513 struct template *tmpl = xmalloc (sizeof (*tmpl));
1514 struct template_instance *last_inst = NULL;
1515
1516 buf = remove_leading_whitespaces (buf + 1);
1517 end = strchr (buf, ':');
1518 if (end == NULL)
1519 fail ("%s: %d: missing ':'\n", filename, lineno);
1520 *end++ = '\0';
1521 remove_trailing_whitespaces (buf);
1522
1523 if (*buf == '\0')
1524 fail ("%s: %d: missing template identifier\n", filename, lineno);
1525 tmpl->name = xstrdup (buf);
1526
1527 tmpl->params = NULL;
1528 do {
1529 struct template_param *param;
1530
1531 buf = remove_leading_whitespaces (end);
1532 end = strpbrk (buf, ":,");
1533 if (end == NULL)
1534 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1535
1536 sep = *end;
1537 *end++ = '\0';
1538 remove_trailing_whitespaces (buf);
1539
1540 param = xmalloc (sizeof (*param));
1541 param->name = xstrdup (buf);
1542 param->next = tmpl->params;
1543 tmpl->params = param;
1544 } while (sep == ':');
1545
1546 tmpl->instances = NULL;
1547 do {
1548 struct template_instance *inst;
1549 char *cur, *next;
1550 const struct template_param *param;
1551
1552 buf = remove_leading_whitespaces (end);
1553 end = strpbrk (buf, ",>");
1554 if (end == NULL)
1555 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1556
1557 sep = *end;
1558 *end++ = '\0';
1559
1560 inst = xmalloc (sizeof (*inst));
1561 inst->next = NULL;
1562 inst->args = NULL;
1563
1564 cur = next_field (buf, ':', &next, end);
1565 inst->name = *cur != '$' ? xstrdup (cur) : "";
1566
1567 for (param = tmpl->params; param; param = param->next)
1568 {
1569 struct template_arg *arg = xmalloc (sizeof (*arg));
1570
1571 cur = next_field (next, ':', &next, end);
1572 if (next > end)
1573 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1574 arg->val = xstrdup (cur);
1575 arg->next = inst->args;
1576 inst->args = arg;
1577 }
1578
1579 if (tmpl->instances)
1580 last_inst->next = inst;
1581 else
1582 tmpl->instances = inst;
1583 last_inst = inst;
1584 } while (sep == ',');
1585
1586 buf = remove_leading_whitespaces (end);
1587 if (*buf)
1588 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1589 filename, lineno, buf);
1590
1591 tmpl->next = templates;
1592 templates = tmpl;
1593 }
1594
1595 static unsigned int
1596 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1597 struct opcode_hash_entry ***opcode_array_p, int lineno)
1598 {
1599 static unsigned int idx, opcode_array_size;
1600 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1601 struct opcode_hash_entry **hash_slot, **entry;
1602 char *ptr1 = strchr(name, '<'), *ptr2;
1603
1604 if (ptr1 == NULL)
1605 {
1606 /* Get the slot in hash table. */
1607 hash_slot = (struct opcode_hash_entry **)
1608 htab_find_slot_with_hash (opcode_hash_table, name,
1609 htab_hash_string (name),
1610 INSERT);
1611
1612 if (*hash_slot == NULL)
1613 {
1614 /* It is the new one. Put it on opcode array. */
1615 if (idx >= opcode_array_size)
1616 {
1617 /* Grow the opcode array when needed. */
1618 opcode_array_size += 1024;
1619 opcode_array = (struct opcode_hash_entry **)
1620 xrealloc (opcode_array,
1621 sizeof (*opcode_array) * opcode_array_size);
1622 *opcode_array_p = opcode_array;
1623 }
1624
1625 opcode_array[idx] = (struct opcode_hash_entry *)
1626 xmalloc (sizeof (struct opcode_hash_entry));
1627 opcode_array[idx]->next = NULL;
1628 opcode_array[idx]->name = xstrdup (name);
1629 opcode_array[idx]->opcode = xstrdup (str);
1630 opcode_array[idx]->lineno = lineno;
1631 *hash_slot = opcode_array[idx];
1632 idx++;
1633 }
1634 else
1635 {
1636 /* Append it to the existing one. */
1637 entry = hash_slot;
1638 while ((*entry) != NULL)
1639 entry = &(*entry)->next;
1640 *entry = (struct opcode_hash_entry *)
1641 xmalloc (sizeof (struct opcode_hash_entry));
1642 (*entry)->next = NULL;
1643 (*entry)->name = (*hash_slot)->name;
1644 (*entry)->opcode = xstrdup (str);
1645 (*entry)->lineno = lineno;
1646 }
1647 }
1648 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1649 fail ("%s: %d: missing '>'\n", filename, lineno);
1650 else
1651 {
1652 const struct template *tmpl;
1653 const struct template_instance *inst;
1654
1655 *ptr1 = '\0';
1656 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1657 remove_trailing_whitespaces (ptr1);
1658
1659 *ptr2++ = '\0';
1660
1661 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1662 if (!strcmp(ptr1, tmpl->name))
1663 break;
1664 if (!tmpl)
1665 fail ("reference to unknown template '%s'\n", ptr1);
1666
1667 for (inst = tmpl->instances; inst; inst = inst->next)
1668 {
1669 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1670 char *str2 = xmalloc(2 * strlen(str));
1671 const char *src;
1672
1673 strcpy (name2, name);
1674 strcat (name2, inst->name);
1675 strcat (name2, ptr2);
1676
1677 for (ptr1 = str2, src = str; *src; )
1678 {
1679 const char *ident = tmpl->name, *end;
1680 const struct template_param *param;
1681 const struct template_arg *arg;
1682
1683 if ((*ptr1 = *src++) != '<')
1684 {
1685 ++ptr1;
1686 continue;
1687 }
1688 while (ISSPACE(*src))
1689 ++src;
1690 while (*ident && *src == *ident)
1691 ++src, ++ident;
1692 while (ISSPACE(*src))
1693 ++src;
1694 if (*src != ':' || *ident != '\0')
1695 {
1696 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1697 ptr1 += ident - tmpl->name;
1698 continue;
1699 }
1700 while (ISSPACE(*++src))
1701 ;
1702
1703 end = src;
1704 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1705 ++end;
1706
1707 for (param = tmpl->params, arg = inst->args; param;
1708 param = param->next, arg = arg->next)
1709 {
1710 if (end - src == strlen (param->name)
1711 && !memcmp (src, param->name, end - src))
1712 {
1713 src = end;
1714 break;
1715 }
1716 }
1717
1718 if (param == NULL)
1719 fail ("template '%s' has no parameter '%.*s'\n",
1720 tmpl->name, (int)(end - src), src);
1721
1722 while (ISSPACE(*src))
1723 ++src;
1724 if (*src != '>')
1725 fail ("%s: %d: missing '>'\n", filename, lineno);
1726
1727 memcpy(ptr1, arg->val, strlen(arg->val));
1728 ptr1 += strlen(arg->val);
1729 ++src;
1730 }
1731
1732 *ptr1 = '\0';
1733
1734 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1735 lineno);
1736
1737 free (str2);
1738 free (name2);
1739 }
1740 }
1741
1742 return idx;
1743 }
1744
1745 static void
1746 process_i386_opcodes (FILE *table)
1747 {
1748 FILE *fp;
1749 char buf[2048];
1750 unsigned int i, j;
1751 char *str, *p, *last, *name;
1752 htab_t opcode_hash_table;
1753 struct opcode_hash_entry **opcode_array = NULL;
1754 int lineno = 0, marker = 0;
1755
1756 filename = "i386-opc.tbl";
1757 fp = stdin;
1758
1759 i = 0;
1760 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1761 opcode_hash_eq, NULL,
1762 xcalloc, free);
1763
1764 fprintf (table, "\n/* i386 opcode table. */\n\n");
1765 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1766
1767 /* Put everything on opcode array. */
1768 while (!feof (fp))
1769 {
1770 if (fgets (buf, sizeof (buf), fp) == NULL)
1771 break;
1772
1773 lineno++;
1774
1775 p = remove_leading_whitespaces (buf);
1776
1777 /* Skip comments. */
1778 str = strstr (p, "//");
1779 if (str != NULL)
1780 str[0] = '\0';
1781
1782 /* Remove trailing white spaces. */
1783 remove_trailing_whitespaces (p);
1784
1785 switch (p[0])
1786 {
1787 case '#':
1788 if (!strcmp("### MARKER ###", buf))
1789 marker = 1;
1790 else
1791 {
1792 /* Since we ignore all included files (we only care about their
1793 #define-s here), we don't need to monitor filenames. The final
1794 line number directive is going to refer to the main source file
1795 again. */
1796 char *end;
1797 unsigned long ln;
1798
1799 p = remove_leading_whitespaces (p + 1);
1800 if (!strncmp(p, "line", 4))
1801 p += 4;
1802 ln = strtoul (p, &end, 10);
1803 if (ln > 1 && ln < INT_MAX
1804 && *remove_leading_whitespaces (end) == '"')
1805 lineno = ln - 1;
1806 }
1807 /* Ignore comments. */
1808 case '\0':
1809 continue;
1810 break;
1811 case '<':
1812 parse_template (p, lineno);
1813 continue;
1814 default:
1815 if (!marker)
1816 continue;
1817 break;
1818 }
1819
1820 last = p + strlen (p);
1821
1822 /* Find name. */
1823 name = next_field (p, ',', &str, last);
1824
1825 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1826 lineno);
1827 }
1828
1829 /* Process opcode array. */
1830 for (j = 0; j < i; j++)
1831 {
1832 struct opcode_hash_entry *next;
1833
1834 for (next = opcode_array[j]; next; next = next->next)
1835 {
1836 name = next->name;
1837 str = next->opcode;
1838 lineno = next->lineno;
1839 last = str + strlen (str);
1840 output_i386_opcode (table, name, str, last, lineno);
1841 }
1842 }
1843
1844 fclose (fp);
1845
1846 fprintf (table, " { NULL, 0, 0, 0,\n");
1847
1848 process_i386_opcode_modifier (table, "0", 0, 0, NULL, -1);
1849
1850 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1851
1852 fprintf (table, " { ");
1853 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1854 fprintf (table, " } }\n");
1855
1856 fprintf (table, "};\n");
1857 }
1858
1859 static void
1860 process_i386_registers (FILE *table)
1861 {
1862 FILE *fp;
1863 char buf[2048];
1864 char *str, *p, *last;
1865 char *reg_name, *reg_type, *reg_flags, *reg_num;
1866 char *dw2_32_num, *dw2_64_num;
1867 int lineno = 0;
1868
1869 filename = "i386-reg.tbl";
1870 fp = fopen (filename, "r");
1871 if (fp == NULL)
1872 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1873 xstrerror (errno));
1874
1875 fprintf (table, "\n/* i386 register table. */\n\n");
1876 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1877
1878 while (!feof (fp))
1879 {
1880 if (fgets (buf, sizeof (buf), fp) == NULL)
1881 break;
1882
1883 lineno++;
1884
1885 p = remove_leading_whitespaces (buf);
1886
1887 /* Skip comments. */
1888 str = strstr (p, "//");
1889 if (str != NULL)
1890 str[0] = '\0';
1891
1892 /* Remove trailing white spaces. */
1893 remove_trailing_whitespaces (p);
1894
1895 switch (p[0])
1896 {
1897 case '#':
1898 fprintf (table, "%s\n", p);
1899 case '\0':
1900 continue;
1901 break;
1902 default:
1903 break;
1904 }
1905
1906 last = p + strlen (p);
1907
1908 /* Find reg_name. */
1909 reg_name = next_field (p, ',', &str, last);
1910
1911 /* Find reg_type. */
1912 reg_type = next_field (str, ',', &str, last);
1913
1914 /* Find reg_flags. */
1915 reg_flags = next_field (str, ',', &str, last);
1916
1917 /* Find reg_num. */
1918 reg_num = next_field (str, ',', &str, last);
1919
1920 fprintf (table, " { \"%s\",\n ", reg_name);
1921
1922 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1923 lineno);
1924
1925 /* Find 32-bit Dwarf2 register number. */
1926 dw2_32_num = next_field (str, ',', &str, last);
1927
1928 /* Find 64-bit Dwarf2 register number. */
1929 dw2_64_num = next_field (str, ',', &str, last);
1930
1931 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1932 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1933 }
1934
1935 fclose (fp);
1936
1937 fprintf (table, "};\n");
1938
1939 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1940 }
1941
1942 static void
1943 process_i386_initializers (void)
1944 {
1945 unsigned int i;
1946 FILE *fp = fopen ("i386-init.h", "w");
1947 char *init;
1948
1949 if (fp == NULL)
1950 fail (_("can't create i386-init.h, errno = %s\n"),
1951 xstrerror (errno));
1952
1953 process_copyright (fp);
1954
1955 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1956 {
1957 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1958 init = xstrdup (cpu_flag_init[i].init);
1959 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1960 free (init);
1961 }
1962
1963 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1964 {
1965 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1966 init = xstrdup (operand_type_init[i].init);
1967 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1968 free (init);
1969 }
1970 fprintf (fp, "\n");
1971
1972 fclose (fp);
1973 }
1974
1975 /* Program options. */
1976 #define OPTION_SRCDIR 200
1977
1978 struct option long_options[] =
1979 {
1980 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1981 {"debug", no_argument, NULL, 'd'},
1982 {"version", no_argument, NULL, 'V'},
1983 {"help", no_argument, NULL, 'h'},
1984 {0, no_argument, NULL, 0}
1985 };
1986
1987 static void
1988 print_version (void)
1989 {
1990 printf ("%s: version 1.0\n", program_name);
1991 xexit (0);
1992 }
1993
1994 static void
1995 usage (FILE * stream, int status)
1996 {
1997 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1998 program_name);
1999 xexit (status);
2000 }
2001
2002 int
2003 main (int argc, char **argv)
2004 {
2005 extern int chdir (char *);
2006 char *srcdir = NULL;
2007 int c;
2008 unsigned int i, cpumax;
2009 FILE *table;
2010
2011 program_name = *argv;
2012 xmalloc_set_program_name (program_name);
2013
2014 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2015 switch (c)
2016 {
2017 case OPTION_SRCDIR:
2018 srcdir = optarg;
2019 break;
2020 case 'V':
2021 case 'v':
2022 print_version ();
2023 break;
2024 case 'd':
2025 debug = 1;
2026 break;
2027 case 'h':
2028 case '?':
2029 usage (stderr, 0);
2030 default:
2031 case 0:
2032 break;
2033 }
2034
2035 if (optind != argc)
2036 usage (stdout, 1);
2037
2038 if (srcdir != NULL)
2039 if (chdir (srcdir) != 0)
2040 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2041 srcdir, xstrerror (errno));
2042
2043 /* cpu_flags isn't sorted by position. */
2044 cpumax = 0;
2045 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2046 if (cpu_flags[i].position > cpumax)
2047 cpumax = cpu_flags[i].position;
2048
2049 /* Check the unused bitfield in i386_cpu_flags. */
2050 #ifdef CpuUnused
2051 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2052
2053 if ((cpumax - 1) != CpuMax)
2054 fail (_("CpuMax != %d!\n"), cpumax);
2055 #else
2056 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2057
2058 if (cpumax != CpuMax)
2059 fail (_("CpuMax != %d!\n"), cpumax);
2060
2061 c = CpuNumOfBits - CpuMax - 1;
2062 if (c)
2063 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
2064 #endif
2065
2066 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2067
2068 /* Check the unused bitfield in i386_operand_type. */
2069 #ifdef OTUnused
2070 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2071 == OTNum + 1);
2072 #else
2073 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2074 == OTNum);
2075
2076 c = OTNumOfBits - OTNum;
2077 if (c)
2078 fail (_("%d unused bits in i386_operand_type.\n"), c);
2079 #endif
2080
2081 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2082 compare);
2083
2084 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2085 sizeof (opcode_modifiers [0]), compare);
2086
2087 qsort (operand_types, ARRAY_SIZE (operand_types),
2088 sizeof (operand_types [0]), compare);
2089
2090 table = fopen ("i386-tbl.h", "w");
2091 if (table == NULL)
2092 fail (_("can't create i386-tbl.h, errno = %s\n"),
2093 xstrerror (errno));
2094
2095 process_copyright (table);
2096
2097 process_i386_opcodes (table);
2098 process_i386_registers (table);
2099 process_i386_initializers ();
2100
2101 fclose (table);
2102
2103 exit (0);
2104 }