x86: drop sentinel from i386_optab[]
[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_ZNVER4_FLAGS",
109 "CPU_ZNVER3_FLAGS|CpuAVX512F|CpuAVX512DQ|CpuAVX512IFMA|CpuAVX512CD|CpuAVX512BW|CpuAVX512VL|CpuAVX512_BF16|CpuAVX512VBMI|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_VPOPCNTDQ|CpuGFNI|CpuRMPQUERY" },
110 { "CPU_BTVER1_FLAGS",
111 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuLZCNT|CpuPOPCNT|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME" },
112 { "CPU_BTVER2_FLAGS",
113 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
114 { "CPU_8087_FLAGS",
115 "Cpu8087" },
116 { "CPU_287_FLAGS",
117 "Cpu287" },
118 { "CPU_387_FLAGS",
119 "Cpu387" },
120 { "CPU_687_FLAGS",
121 "CPU_387_FLAGS|Cpu687" },
122 { "CPU_CMOV_FLAGS",
123 "CpuCMOV" },
124 { "CPU_FXSR_FLAGS",
125 "CpuFXSR" },
126 { "CPU_CLFLUSH_FLAGS",
127 "CpuClflush" },
128 { "CPU_NOP_FLAGS",
129 "CpuNop" },
130 { "CPU_SYSCALL_FLAGS",
131 "CpuSYSCALL" },
132 { "CPU_MMX_FLAGS",
133 "CpuMMX" },
134 { "CPU_SSE_FLAGS",
135 "CpuSSE" },
136 { "CPU_SSE2_FLAGS",
137 "CPU_SSE_FLAGS|CpuSSE2" },
138 { "CPU_SSE3_FLAGS",
139 "CPU_SSE2_FLAGS|CpuSSE3" },
140 { "CPU_SSSE3_FLAGS",
141 "CPU_SSE3_FLAGS|CpuSSSE3" },
142 { "CPU_SSE4_1_FLAGS",
143 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
144 { "CPU_SSE4_2_FLAGS",
145 "CPU_SSE4_1_FLAGS|CpuSSE4_2|CpuPOPCNT" },
146 { "CPU_VMX_FLAGS",
147 "CpuVMX" },
148 { "CPU_SMX_FLAGS",
149 "CpuSMX" },
150 { "CPU_XSAVE_FLAGS",
151 "CpuXsave" },
152 { "CPU_XSAVEOPT_FLAGS",
153 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
154 { "CPU_AES_FLAGS",
155 "CPU_SSE2_FLAGS|CpuAES" },
156 { "CPU_PCLMUL_FLAGS",
157 "CPU_SSE2_FLAGS|CpuPCLMUL" },
158 { "CPU_FMA_FLAGS",
159 "CPU_AVX_FLAGS|CpuFMA" },
160 { "CPU_FMA4_FLAGS",
161 "CPU_AVX_FLAGS|CpuFMA4" },
162 { "CPU_XOP_FLAGS",
163 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
164 { "CPU_LWP_FLAGS",
165 "CPU_XSAVE_FLAGS|CpuLWP" },
166 { "CPU_BMI_FLAGS",
167 "CpuBMI" },
168 { "CPU_TBM_FLAGS",
169 "CpuTBM" },
170 { "CPU_MOVBE_FLAGS",
171 "CpuMovbe" },
172 { "CPU_CX16_FLAGS",
173 "CpuCX16" },
174 { "CPU_RDTSCP_FLAGS",
175 "CpuRdtscp" },
176 { "CPU_EPT_FLAGS",
177 "CpuEPT" },
178 { "CPU_FSGSBASE_FLAGS",
179 "CpuFSGSBase" },
180 { "CPU_RDRND_FLAGS",
181 "CpuRdRnd" },
182 { "CPU_F16C_FLAGS",
183 "CPU_AVX_FLAGS|CpuF16C" },
184 { "CPU_BMI2_FLAGS",
185 "CpuBMI2" },
186 { "CPU_LZCNT_FLAGS",
187 "CpuLZCNT" },
188 { "CPU_POPCNT_FLAGS",
189 "CpuPOPCNT" },
190 { "CPU_HLE_FLAGS",
191 "CpuHLE" },
192 { "CPU_RTM_FLAGS",
193 "CpuRTM" },
194 { "CPU_INVPCID_FLAGS",
195 "CpuINVPCID" },
196 { "CPU_VMFUNC_FLAGS",
197 "CpuVMFUNC" },
198 { "CPU_3DNOW_FLAGS",
199 "CPU_MMX_FLAGS|Cpu3dnow" },
200 { "CPU_3DNOWA_FLAGS",
201 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
202 { "CPU_PADLOCK_FLAGS",
203 "CpuPadLock" },
204 { "CPU_SVME_FLAGS",
205 "CpuSVME" },
206 { "CPU_SSE4A_FLAGS",
207 "CPU_SSE3_FLAGS|CpuSSE4a" },
208 { "CPU_ABM_FLAGS",
209 "CpuLZCNT|CpuPOPCNT" },
210 { "CPU_AVX_FLAGS",
211 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
212 { "CPU_AVX2_FLAGS",
213 "CPU_AVX_FLAGS|CpuAVX2" },
214 { "CPU_AVX_VNNI_FLAGS",
215 "CPU_AVX2_FLAGS|CpuAVX_VNNI" },
216 { "CPU_AVX512F_FLAGS",
217 "CPU_AVX2_FLAGS|CpuAVX512F" },
218 { "CPU_AVX512CD_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
220 { "CPU_AVX512ER_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
222 { "CPU_AVX512PF_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
224 { "CPU_AVX512DQ_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
226 { "CPU_AVX512BW_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
228 { "CPU_AVX512VL_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
230 { "CPU_AVX512IFMA_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
232 { "CPU_AVX512VBMI_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
234 { "CPU_AVX512_4FMAPS_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
236 { "CPU_AVX512_4VNNIW_FLAGS",
237 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
238 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
239 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
240 { "CPU_AVX512_VBMI2_FLAGS",
241 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
242 { "CPU_AVX512_VNNI_FLAGS",
243 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
244 { "CPU_AVX512_BITALG_FLAGS",
245 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
246 { "CPU_AVX512_BF16_FLAGS",
247 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
248 { "CPU_AVX512_FP16_FLAGS",
249 "CPU_AVX512BW_FLAGS|CpuAVX512_FP16" },
250 { "CPU_PREFETCHI_FLAGS",
251 "CpuPREFETCHI"},
252 { "CPU_AVX_IFMA_FLAGS",
253 "CPU_AVX2_FLAGS|CpuAVX_IFMA" },
254 { "CPU_AVX_VNNI_INT8_FLAGS",
255 "CPU_AVX2_FLAGS|CpuAVX_VNNI_INT8" },
256 { "CPU_CMPCCXADD_FLAGS",
257 "CpuCMPCCXADD" },
258 { "CPU_WRMSRNS_FLAGS",
259 "CpuWRMSRNS" },
260 { "CPU_MSRLIST_FLAGS",
261 "CpuMSRLIST" },
262 { "CPU_AVX_NE_CONVERT_FLAGS",
263 "CPU_AVX2_FLAGS|CpuAVX_NE_CONVERT" },
264 { "CPU_RAO_INT_FLAGS",
265 "CpuRAO_INT" },
266 { "CPU_IAMCU_FLAGS",
267 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuIAMCU" },
268 { "CPU_ADX_FLAGS",
269 "CpuADX" },
270 { "CPU_RDSEED_FLAGS",
271 "CpuRdSeed" },
272 { "CPU_PRFCHW_FLAGS",
273 "CpuPRFCHW" },
274 { "CPU_SMAP_FLAGS",
275 "CpuSMAP" },
276 { "CPU_MPX_FLAGS",
277 "CPU_XSAVE_FLAGS|CpuMPX" },
278 { "CPU_SHA_FLAGS",
279 "CPU_SSE2_FLAGS|CpuSHA" },
280 { "CPU_CLFLUSHOPT_FLAGS",
281 "CpuClflushOpt" },
282 { "CPU_XSAVES_FLAGS",
283 "CPU_XSAVE_FLAGS|CpuXSAVES" },
284 { "CPU_XSAVEC_FLAGS",
285 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
286 { "CPU_PREFETCHWT1_FLAGS",
287 "CpuPREFETCHWT1" },
288 { "CPU_SE1_FLAGS",
289 "CpuSE1" },
290 { "CPU_CLWB_FLAGS",
291 "CpuCLWB" },
292 { "CPU_CLZERO_FLAGS",
293 "CpuCLZERO" },
294 { "CPU_MWAITX_FLAGS",
295 "CpuMWAITX" },
296 { "CPU_OSPKE_FLAGS",
297 "CPU_XSAVE_FLAGS|CpuOSPKE" },
298 { "CPU_RDPID_FLAGS",
299 "CpuRDPID" },
300 { "CPU_PTWRITE_FLAGS",
301 "CpuPTWRITE" },
302 { "CPU_IBT_FLAGS",
303 "CpuIBT" },
304 { "CPU_SHSTK_FLAGS",
305 "CpuSHSTK" },
306 { "CPU_GFNI_FLAGS",
307 "CpuGFNI" },
308 { "CPU_VAES_FLAGS",
309 "CpuVAES" },
310 { "CPU_VPCLMULQDQ_FLAGS",
311 "CpuVPCLMULQDQ" },
312 { "CPU_WBNOINVD_FLAGS",
313 "CpuWBNOINVD" },
314 { "CPU_PCONFIG_FLAGS",
315 "CpuPCONFIG" },
316 { "CPU_WAITPKG_FLAGS",
317 "CpuWAITPKG" },
318 { "CPU_UINTR_FLAGS",
319 "CpuUINTR" },
320 { "CPU_CLDEMOTE_FLAGS",
321 "CpuCLDEMOTE" },
322 { "CPU_AMX_INT8_FLAGS",
323 "CPU_AMX_TILE_FLAGS|CpuAMX_INT8" },
324 { "CPU_AMX_BF16_FLAGS",
325 "CPU_AMX_TILE_FLAGS|CpuAMX_BF16" },
326 { "CPU_AMX_FP16_FLAGS",
327 "CPU_AMX_TILE_FLAGS|CpuAMX_FP16" },
328 { "CPU_AMX_TILE_FLAGS",
329 "CpuAMX_TILE" },
330 { "CPU_MOVDIRI_FLAGS",
331 "CpuMOVDIRI" },
332 { "CPU_MOVDIR64B_FLAGS",
333 "CpuMOVDIR64B" },
334 { "CPU_ENQCMD_FLAGS",
335 "CpuENQCMD" },
336 { "CPU_SERIALIZE_FLAGS",
337 "CpuSERIALIZE" },
338 { "CPU_AVX512_VP2INTERSECT_FLAGS",
339 "CpuAVX512_VP2INTERSECT" },
340 { "CPU_TDX_FLAGS",
341 "CpuTDX" },
342 { "CPU_RDPRU_FLAGS",
343 "CpuRDPRU" },
344 { "CPU_MCOMMIT_FLAGS",
345 "CpuMCOMMIT" },
346 { "CPU_SEV_ES_FLAGS",
347 "CpuSEV_ES" },
348 { "CPU_TSXLDTRK_FLAGS",
349 "CpuTSXLDTRK"},
350 { "CPU_KL_FLAGS",
351 "CpuKL" },
352 { "CPU_WIDEKL_FLAGS",
353 "CpuWideKL" },
354 { "CPU_HRESET_FLAGS",
355 "CpuHRESET"},
356 { "CPU_INVLPGB_FLAGS",
357 "CpuINVLPGB" },
358 { "CPU_TLBSYNC_FLAGS",
359 "CpuTLBSYNC" },
360 { "CPU_SNP_FLAGS",
361 "CpuSNP" },
362 { "CPU_RMPQUERY_FLAGS",
363 "CpuRMPQUERY" },
364 { "CPU_ANY_X87_FLAGS",
365 "CPU_ANY_287_FLAGS|Cpu8087" },
366 { "CPU_ANY_287_FLAGS",
367 "CPU_ANY_387_FLAGS|Cpu287" },
368 { "CPU_ANY_387_FLAGS",
369 "CPU_ANY_687_FLAGS|Cpu387" },
370 { "CPU_ANY_687_FLAGS",
371 "Cpu687|CpuFISTTP" },
372 { "CPU_ANY_CMOV_FLAGS",
373 "CpuCMOV" },
374 { "CPU_ANY_FXSR_FLAGS",
375 "CpuFXSR" },
376 { "CPU_ANY_MMX_FLAGS",
377 "CPU_3DNOWA_FLAGS" },
378 { "CPU_ANY_SSE_FLAGS",
379 "CPU_ANY_SSE2_FLAGS|CpuSSE" },
380 { "CPU_ANY_SSE2_FLAGS",
381 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
382 { "CPU_ANY_SSE3_FLAGS",
383 "CPU_ANY_SSSE3_FLAGS|CpuSSE3|CpuSSE4a" },
384 { "CPU_ANY_SSSE3_FLAGS",
385 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
386 { "CPU_ANY_SSE4_1_FLAGS",
387 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
388 { "CPU_ANY_SSE4_2_FLAGS",
389 "CpuSSE4_2" },
390 { "CPU_ANY_SSE4A_FLAGS",
391 "CpuSSE4a" },
392 { "CPU_ANY_AVX_FLAGS",
393 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
394 { "CPU_ANY_AVX2_FLAGS",
395 "CPU_ANY_AVX512F_FLAGS|CpuAVX2|CpuAVX_VNNI|CpuAVX_IFMA|CpuAVX_VNNI_INT8|CpuAVX_NE_CONVERT" },
396 { "CPU_ANY_AVX512F_FLAGS",
397 "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" },
398 { "CPU_ANY_AVX512CD_FLAGS",
399 "CpuAVX512CD" },
400 { "CPU_ANY_AVX512ER_FLAGS",
401 "CpuAVX512ER" },
402 { "CPU_ANY_AVX512PF_FLAGS",
403 "CpuAVX512PF" },
404 { "CPU_ANY_AVX512DQ_FLAGS",
405 "CpuAVX512DQ" },
406 { "CPU_ANY_AVX512BW_FLAGS",
407 "CpuAVX512BW|CPU_ANY_AVX512_FP16_FLAGS" },
408 { "CPU_ANY_AVX512VL_FLAGS",
409 "CpuAVX512VL" },
410 { "CPU_ANY_AVX512IFMA_FLAGS",
411 "CpuAVX512IFMA" },
412 { "CPU_ANY_AVX512VBMI_FLAGS",
413 "CpuAVX512VBMI" },
414 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
415 "CpuAVX512_4FMAPS" },
416 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
417 "CpuAVX512_4VNNIW" },
418 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
419 "CpuAVX512_VPOPCNTDQ" },
420 { "CPU_ANY_IBT_FLAGS",
421 "CpuIBT" },
422 { "CPU_ANY_SHSTK_FLAGS",
423 "CpuSHSTK" },
424 { "CPU_ANY_AVX512_VBMI2_FLAGS",
425 "CpuAVX512_VBMI2" },
426 { "CPU_ANY_AVX512_VNNI_FLAGS",
427 "CpuAVX512_VNNI" },
428 { "CPU_ANY_AVX512_BITALG_FLAGS",
429 "CpuAVX512_BITALG" },
430 { "CPU_ANY_AVX512_BF16_FLAGS",
431 "CpuAVX512_BF16" },
432 { "CPU_ANY_AMX_INT8_FLAGS",
433 "CpuAMX_INT8" },
434 { "CPU_ANY_AMX_BF16_FLAGS",
435 "CpuAMX_BF16" },
436 { "CPU_ANY_AMX_TILE_FLAGS",
437 "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16|CpuAMX_FP16" },
438 { "CPU_ANY_AVX_VNNI_FLAGS",
439 "CpuAVX_VNNI" },
440 { "CPU_ANY_MOVDIRI_FLAGS",
441 "CpuMOVDIRI" },
442 { "CPU_ANY_UINTR_FLAGS",
443 "CpuUINTR" },
444 { "CPU_ANY_MOVDIR64B_FLAGS",
445 "CpuMOVDIR64B" },
446 { "CPU_ANY_ENQCMD_FLAGS",
447 "CpuENQCMD" },
448 { "CPU_ANY_SERIALIZE_FLAGS",
449 "CpuSERIALIZE" },
450 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
451 "CpuAVX512_VP2INTERSECT" },
452 { "CPU_ANY_TDX_FLAGS",
453 "CpuTDX" },
454 { "CPU_ANY_TSXLDTRK_FLAGS",
455 "CpuTSXLDTRK" },
456 { "CPU_ANY_KL_FLAGS",
457 "CpuKL|CpuWideKL" },
458 { "CPU_ANY_WIDEKL_FLAGS",
459 "CpuWideKL" },
460 { "CPU_ANY_HRESET_FLAGS",
461 "CpuHRESET" },
462 { "CPU_ANY_AVX512_FP16_FLAGS",
463 "CpuAVX512_FP16" },
464 { "CPU_ANY_AVX_IFMA_FLAGS",
465 "CpuAVX_IFMA" },
466 { "CPU_ANY_AVX_VNNI_INT8_FLAGS",
467 "CpuAVX_VNNI_INT8" },
468 { "CPU_ANY_CMPCCXADD_FLAGS",
469 "CpuCMPCCXADD" },
470 { "CPU_ANY_WRMSRNS_FLAGS",
471 "CpuWRMSRNS" },
472 { "CPU_ANY_MSRLIST_FLAGS",
473 "CpuMSRLIST" },
474 { "CPU_ANY_AVX_NE_CONVERT_FLAGS",
475 "CpuAVX_NE_CONVERT" },
476 { "CPU_ANY_RAO_INT_FLAGS",
477 "CpuRAO_INT"},
478 };
479
480 typedef struct bitfield
481 {
482 int position;
483 int value;
484 const char *name;
485 } bitfield;
486
487 #define BITFIELD(n) { n, 0, #n }
488
489 static bitfield cpu_flags[] =
490 {
491 BITFIELD (Cpu186),
492 BITFIELD (Cpu286),
493 BITFIELD (Cpu386),
494 BITFIELD (Cpu486),
495 BITFIELD (Cpu586),
496 BITFIELD (Cpu686),
497 BITFIELD (CpuCMOV),
498 BITFIELD (CpuFXSR),
499 BITFIELD (CpuClflush),
500 BITFIELD (CpuNop),
501 BITFIELD (CpuSYSCALL),
502 BITFIELD (Cpu8087),
503 BITFIELD (Cpu287),
504 BITFIELD (Cpu387),
505 BITFIELD (Cpu687),
506 BITFIELD (CpuFISTTP),
507 BITFIELD (CpuMMX),
508 BITFIELD (CpuSSE),
509 BITFIELD (CpuSSE2),
510 BITFIELD (CpuSSE3),
511 BITFIELD (CpuSSSE3),
512 BITFIELD (CpuSSE4_1),
513 BITFIELD (CpuSSE4_2),
514 BITFIELD (CpuAVX),
515 BITFIELD (CpuAVX2),
516 BITFIELD (CpuAVX512F),
517 BITFIELD (CpuAVX512CD),
518 BITFIELD (CpuAVX512ER),
519 BITFIELD (CpuAVX512PF),
520 BITFIELD (CpuAVX512VL),
521 BITFIELD (CpuAVX512DQ),
522 BITFIELD (CpuAVX512BW),
523 BITFIELD (CpuIAMCU),
524 BITFIELD (CpuSSE4a),
525 BITFIELD (Cpu3dnow),
526 BITFIELD (Cpu3dnowA),
527 BITFIELD (CpuPadLock),
528 BITFIELD (CpuSVME),
529 BITFIELD (CpuVMX),
530 BITFIELD (CpuSMX),
531 BITFIELD (CpuXsave),
532 BITFIELD (CpuXsaveopt),
533 BITFIELD (CpuAES),
534 BITFIELD (CpuPCLMUL),
535 BITFIELD (CpuFMA),
536 BITFIELD (CpuFMA4),
537 BITFIELD (CpuXOP),
538 BITFIELD (CpuLWP),
539 BITFIELD (CpuBMI),
540 BITFIELD (CpuTBM),
541 BITFIELD (CpuLM),
542 BITFIELD (CpuMovbe),
543 BITFIELD (CpuCX16),
544 BITFIELD (CpuEPT),
545 BITFIELD (CpuRdtscp),
546 BITFIELD (CpuFSGSBase),
547 BITFIELD (CpuRdRnd),
548 BITFIELD (CpuF16C),
549 BITFIELD (CpuBMI2),
550 BITFIELD (CpuLZCNT),
551 BITFIELD (CpuPOPCNT),
552 BITFIELD (CpuHLE),
553 BITFIELD (CpuRTM),
554 BITFIELD (CpuINVPCID),
555 BITFIELD (CpuVMFUNC),
556 BITFIELD (CpuRDSEED),
557 BITFIELD (CpuADX),
558 BITFIELD (CpuPRFCHW),
559 BITFIELD (CpuSMAP),
560 BITFIELD (CpuSHA),
561 BITFIELD (CpuClflushOpt),
562 BITFIELD (CpuXSAVES),
563 BITFIELD (CpuXSAVEC),
564 BITFIELD (CpuPREFETCHWT1),
565 BITFIELD (CpuSE1),
566 BITFIELD (CpuCLWB),
567 BITFIELD (CpuMPX),
568 BITFIELD (CpuAVX512IFMA),
569 BITFIELD (CpuAVX512VBMI),
570 BITFIELD (CpuAVX512_4FMAPS),
571 BITFIELD (CpuAVX512_4VNNIW),
572 BITFIELD (CpuAVX512_VPOPCNTDQ),
573 BITFIELD (CpuAVX512_VBMI2),
574 BITFIELD (CpuAVX512_VNNI),
575 BITFIELD (CpuAVX512_BITALG),
576 BITFIELD (CpuAVX512_BF16),
577 BITFIELD (CpuAVX512_VP2INTERSECT),
578 BITFIELD (CpuTDX),
579 BITFIELD (CpuAVX_VNNI),
580 BITFIELD (CpuAVX512_FP16),
581 BITFIELD (CpuPREFETCHI),
582 BITFIELD (CpuAVX_IFMA),
583 BITFIELD (CpuAVX_VNNI_INT8),
584 BITFIELD (CpuCMPCCXADD),
585 BITFIELD (CpuWRMSRNS),
586 BITFIELD (CpuMSRLIST),
587 BITFIELD (CpuAVX_NE_CONVERT),
588 BITFIELD (CpuRAO_INT),
589 BITFIELD (CpuMWAITX),
590 BITFIELD (CpuCLZERO),
591 BITFIELD (CpuOSPKE),
592 BITFIELD (CpuRDPID),
593 BITFIELD (CpuPTWRITE),
594 BITFIELD (CpuIBT),
595 BITFIELD (CpuSHSTK),
596 BITFIELD (CpuGFNI),
597 BITFIELD (CpuVAES),
598 BITFIELD (CpuVPCLMULQDQ),
599 BITFIELD (CpuWBNOINVD),
600 BITFIELD (CpuPCONFIG),
601 BITFIELD (CpuWAITPKG),
602 BITFIELD (CpuUINTR),
603 BITFIELD (CpuCLDEMOTE),
604 BITFIELD (CpuAMX_INT8),
605 BITFIELD (CpuAMX_BF16),
606 BITFIELD (CpuAMX_FP16),
607 BITFIELD (CpuAMX_TILE),
608 BITFIELD (CpuMOVDIRI),
609 BITFIELD (CpuMOVDIR64B),
610 BITFIELD (CpuENQCMD),
611 BITFIELD (CpuSERIALIZE),
612 BITFIELD (CpuRDPRU),
613 BITFIELD (CpuMCOMMIT),
614 BITFIELD (CpuSEV_ES),
615 BITFIELD (CpuTSXLDTRK),
616 BITFIELD (CpuKL),
617 BITFIELD (CpuWideKL),
618 BITFIELD (CpuHRESET),
619 BITFIELD (CpuINVLPGB),
620 BITFIELD (CpuTLBSYNC),
621 BITFIELD (CpuSNP),
622 BITFIELD (CpuRMPQUERY),
623 BITFIELD (Cpu64),
624 BITFIELD (CpuNo64),
625 #ifdef CpuUnused
626 BITFIELD (CpuUnused),
627 #endif
628 };
629
630 static bitfield opcode_modifiers[] =
631 {
632 BITFIELD (D),
633 BITFIELD (W),
634 BITFIELD (Load),
635 BITFIELD (Modrm),
636 BITFIELD (Jump),
637 BITFIELD (FloatMF),
638 BITFIELD (Size),
639 BITFIELD (CheckRegSize),
640 BITFIELD (OperandConstraint),
641 BITFIELD (MnemonicSize),
642 BITFIELD (No_bSuf),
643 BITFIELD (No_wSuf),
644 BITFIELD (No_lSuf),
645 BITFIELD (No_sSuf),
646 BITFIELD (No_qSuf),
647 BITFIELD (FWait),
648 BITFIELD (IsString),
649 BITFIELD (RegMem),
650 BITFIELD (BNDPrefixOk),
651 BITFIELD (PrefixOk),
652 BITFIELD (IsPrefix),
653 BITFIELD (ImmExt),
654 BITFIELD (NoRex64),
655 BITFIELD (Vex),
656 BITFIELD (VexVVVV),
657 BITFIELD (VexW),
658 BITFIELD (OpcodeSpace),
659 BITFIELD (OpcodePrefix),
660 BITFIELD (VexSources),
661 BITFIELD (SIB),
662 BITFIELD (SSE2AVX),
663 BITFIELD (EVex),
664 BITFIELD (Masking),
665 BITFIELD (Broadcast),
666 BITFIELD (StaticRounding),
667 BITFIELD (SAE),
668 BITFIELD (Disp8MemShift),
669 BITFIELD (Optimize),
670 BITFIELD (ATTMnemonic),
671 BITFIELD (ATTSyntax),
672 BITFIELD (IntelSyntax),
673 BITFIELD (ISA64),
674 };
675
676 #define CLASS(n) #n, n
677
678 static const struct {
679 const char *name;
680 enum operand_class value;
681 } operand_classes[] = {
682 CLASS (Reg),
683 CLASS (SReg),
684 CLASS (RegCR),
685 CLASS (RegDR),
686 CLASS (RegTR),
687 CLASS (RegMMX),
688 CLASS (RegSIMD),
689 CLASS (RegMask),
690 CLASS (RegBND),
691 };
692
693 #undef CLASS
694
695 #define INSTANCE(n) #n, n
696
697 static const struct {
698 const char *name;
699 enum operand_instance value;
700 } operand_instances[] = {
701 INSTANCE (Accum),
702 INSTANCE (RegC),
703 INSTANCE (RegD),
704 INSTANCE (RegB),
705 };
706
707 #undef INSTANCE
708
709 static bitfield operand_types[] =
710 {
711 BITFIELD (Imm1),
712 BITFIELD (Imm8),
713 BITFIELD (Imm8S),
714 BITFIELD (Imm16),
715 BITFIELD (Imm32),
716 BITFIELD (Imm32S),
717 BITFIELD (Imm64),
718 BITFIELD (BaseIndex),
719 BITFIELD (Disp8),
720 BITFIELD (Disp16),
721 BITFIELD (Disp32),
722 BITFIELD (Disp64),
723 BITFIELD (Byte),
724 BITFIELD (Word),
725 BITFIELD (Dword),
726 BITFIELD (Fword),
727 BITFIELD (Qword),
728 BITFIELD (Tbyte),
729 BITFIELD (Xmmword),
730 BITFIELD (Ymmword),
731 BITFIELD (Zmmword),
732 BITFIELD (Tmmword),
733 BITFIELD (Unspecified),
734 #ifdef OTUnused
735 BITFIELD (OTUnused),
736 #endif
737 };
738
739 static const char *filename;
740 static i386_cpu_flags active_cpu_flags;
741 static int active_isstring;
742
743 struct template_arg {
744 const struct template_arg *next;
745 const char *val;
746 };
747
748 struct template_instance {
749 const struct template_instance *next;
750 const char *name;
751 const struct template_arg *args;
752 };
753
754 struct template_param {
755 const struct template_param *next;
756 const char *name;
757 };
758
759 struct template {
760 struct template *next;
761 const char *name;
762 const struct template_instance *instances;
763 const struct template_param *params;
764 };
765
766 static struct template *templates;
767
768 static int
769 compare (const void *x, const void *y)
770 {
771 const bitfield *xp = (const bitfield *) x;
772 const bitfield *yp = (const bitfield *) y;
773 return xp->position - yp->position;
774 }
775
776 static void
777 fail (const char *message, ...)
778 {
779 va_list args;
780
781 va_start (args, message);
782 fprintf (stderr, _("%s: error: "), program_name);
783 vfprintf (stderr, message, args);
784 va_end (args);
785 xexit (1);
786 }
787
788 static void
789 process_copyright (FILE *fp)
790 {
791 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
792 /* Copyright (C) 2007-2022 Free Software Foundation, Inc.\n\
793 \n\
794 This file is part of the GNU opcodes library.\n\
795 \n\
796 This library is free software; you can redistribute it and/or modify\n\
797 it under the terms of the GNU General Public License as published by\n\
798 the Free Software Foundation; either version 3, or (at your option)\n\
799 any later version.\n\
800 \n\
801 It is distributed in the hope that it will be useful, but WITHOUT\n\
802 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
803 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
804 License for more details.\n\
805 \n\
806 You should have received a copy of the GNU General Public License\n\
807 along with this program; if not, write to the Free Software\n\
808 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
809 MA 02110-1301, USA. */\n");
810 }
811
812 /* Remove leading white spaces. */
813
814 static char *
815 remove_leading_whitespaces (char *str)
816 {
817 while (ISSPACE (*str))
818 str++;
819 return str;
820 }
821
822 /* Remove trailing white spaces. */
823
824 static void
825 remove_trailing_whitespaces (char *str)
826 {
827 size_t last = strlen (str);
828
829 if (last == 0)
830 return;
831
832 do
833 {
834 last--;
835 if (ISSPACE (str [last]))
836 str[last] = '\0';
837 else
838 break;
839 }
840 while (last != 0);
841 }
842
843 /* Find next field separated by SEP and terminate it. Return a
844 pointer to the one after it. */
845
846 static char *
847 next_field (char *str, char sep, char **next, char *last)
848 {
849 char *p;
850
851 p = remove_leading_whitespaces (str);
852 for (str = p; *str != sep && *str != '\0'; str++);
853
854 *str = '\0';
855 remove_trailing_whitespaces (p);
856
857 *next = str + 1;
858
859 if (p >= last)
860 abort ();
861
862 return p;
863 }
864
865 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
866
867 static int
868 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
869 int lineno)
870 {
871 char *str, *next, *last;
872 unsigned int i;
873
874 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
875 if (strcmp (cpu_flag_init[i].name, f) == 0)
876 {
877 /* Turn on selective bits. */
878 char *init = xstrdup (cpu_flag_init[i].init);
879 last = init + strlen (init);
880 for (next = init; next && next < last; )
881 {
882 str = next_field (next, '|', &next, last);
883 if (str)
884 set_bitfield (str, array, 1, size, lineno);
885 }
886 free (init);
887 return 0;
888 }
889
890 return -1;
891 }
892
893 static void
894 set_bitfield (char *f, bitfield *array, int value,
895 unsigned int size, int lineno)
896 {
897 unsigned int i;
898
899 /* Ignore empty fields; they may result from template expansions. */
900 if (*f == '\0')
901 return;
902
903 for (i = 0; i < size; i++)
904 if (strcasecmp (array[i].name, f) == 0)
905 {
906 array[i].value = value;
907 return;
908 }
909
910 if (value)
911 {
912 const char *v = strchr (f, '=');
913
914 if (v)
915 {
916 size_t n = v - f;
917 char *end;
918
919 for (i = 0; i < size; i++)
920 if (strncasecmp (array[i].name, f, n) == 0)
921 {
922 value = strtol (v + 1, &end, 0);
923 if (*end == '\0')
924 {
925 array[i].value = value;
926 return;
927 }
928 break;
929 }
930 }
931 }
932
933 /* Handle CPU_XXX_FLAGS. */
934 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
935 return;
936
937 if (lineno != -1)
938 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
939 else
940 fail (_("unknown bitfield: %s\n"), f);
941 }
942
943 static void
944 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
945 int macro, const char *comma, const char *indent)
946 {
947 unsigned int i;
948
949 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
950
951 fprintf (table, "%s{ { ", indent);
952
953 for (i = 0; i < size - 1; i++)
954 {
955 if (((i + 1) % 20) != 0)
956 fprintf (table, "%d, ", flags[i].value);
957 else
958 fprintf (table, "%d,", flags[i].value);
959 if (((i + 1) % 20) == 0)
960 {
961 /* We need \\ for macro. */
962 if (macro)
963 fprintf (table, " \\\n %s", indent);
964 else
965 fprintf (table, "\n %s", indent);
966 }
967 if (flags[i].value)
968 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
969 }
970
971 fprintf (table, "%d } }%s\n", flags[i].value, comma);
972 }
973
974 static void
975 process_i386_cpu_flag (FILE *table, char *flag, int macro,
976 const char *comma, const char *indent,
977 int lineno)
978 {
979 char *str, *next = flag, *last;
980 unsigned int i;
981 int value = 1;
982 bitfield flags [ARRAY_SIZE (cpu_flags)];
983
984 /* Copy the default cpu flags. */
985 memcpy (flags, cpu_flags, sizeof (cpu_flags));
986
987 if (flag[0] == '~')
988 {
989 last = flag + strlen (flag);
990
991 if (flag[1] == '(')
992 {
993 last -= 1;
994 next = flag + 2;
995 if (*last != ')')
996 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
997 lineno, flag);
998 *last = '\0';
999 }
1000 else
1001 next = flag + 1;
1002
1003 /* First we turn on everything except for cpu64, cpuno64, and - if
1004 present - the padding field. */
1005 for (i = 0; i < ARRAY_SIZE (flags); i++)
1006 if (flags[i].position < Cpu64)
1007 flags[i].value = 1;
1008
1009 /* Turn off selective bits. */
1010 value = 0;
1011 }
1012
1013 if (strcmp (flag, "0"))
1014 {
1015 /* Turn on/off selective bits. */
1016 last = flag + strlen (flag);
1017 for (; next && next < last; )
1018 {
1019 str = next_field (next, '|', &next, last);
1020 if (str)
1021 set_bitfield (str, flags, value, ARRAY_SIZE (flags), lineno);
1022 }
1023 }
1024
1025 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1026 comma, indent);
1027 }
1028
1029 static void
1030 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1031 {
1032 unsigned int i;
1033
1034 fprintf (table, " { ");
1035
1036 for (i = 0; i < size - 1; i++)
1037 {
1038 if (((i + 1) % 20) != 0)
1039 fprintf (table, "%d, ", modifier[i].value);
1040 else
1041 fprintf (table, "%d,", modifier[i].value);
1042 if (((i + 1) % 20) == 0)
1043 fprintf (table, "\n ");
1044 }
1045
1046 fprintf (table, "%d },\n", modifier[i].value);
1047 }
1048
1049 /* Returns LOG2 of element size. */
1050 static int
1051 get_element_size (char **opnd, int lineno)
1052 {
1053 char *str, *next, *last, *op;
1054 const char *full = opnd[0];
1055 int elem_size = INT_MAX;
1056
1057 /* Find the memory operand. */
1058 while (full != NULL && strstr(full, "BaseIndex") == NULL)
1059 full = *++opnd;
1060 if (full == NULL)
1061 fail (_("%s: %d: no memory operand\n"), filename, lineno);
1062
1063 op = xstrdup (full);
1064 last = op + strlen (op);
1065 for (next = op; next && next < last; )
1066 {
1067 str = next_field (next, '|', &next, last);
1068 if (str)
1069 {
1070 if (strcasecmp(str, "Byte") == 0)
1071 {
1072 /* The smallest element size, no need to check
1073 further. */
1074 elem_size = 0;
1075 break;
1076 }
1077 else if (strcasecmp(str, "Word") == 0)
1078 {
1079 if (elem_size > 1)
1080 elem_size = 1;
1081 }
1082 else if (strcasecmp(str, "Dword") == 0)
1083 {
1084 if (elem_size > 2)
1085 elem_size = 2;
1086 }
1087 else if (strcasecmp(str, "Qword") == 0)
1088 {
1089 if (elem_size > 3)
1090 elem_size = 3;
1091 }
1092 }
1093 }
1094 free (op);
1095
1096 if (elem_size == INT_MAX)
1097 fail (_("%s: %d: unknown element size: %s\n"), filename, lineno, full);
1098
1099 return elem_size;
1100 }
1101
1102 static void
1103 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1104 unsigned int prefix, char **opnd, int lineno)
1105 {
1106 char *str, *next, *last;
1107 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1108
1109 active_isstring = 0;
1110
1111 /* Copy the default opcode modifier. */
1112 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1113
1114 if (strcmp (mod, "0"))
1115 {
1116 unsigned int have_w = 0, bwlq_suf = 0xf;
1117
1118 last = mod + strlen (mod);
1119 for (next = mod; next && next < last; )
1120 {
1121 str = next_field (next, '|', &next, last);
1122 if (str)
1123 {
1124 int val = 1;
1125 if (strcasecmp(str, "Broadcast") == 0)
1126 val = get_element_size (opnd, lineno) + BYTE_BROADCAST;
1127 else if (strcasecmp(str, "Disp8MemShift") == 0)
1128 val = get_element_size (opnd, lineno);
1129
1130 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1131 lineno);
1132 if (strcasecmp(str, "IsString") == 0)
1133 active_isstring = 1;
1134
1135 if (strcasecmp(str, "W") == 0)
1136 have_w = 1;
1137
1138 if (strcasecmp(str, "No_bSuf") == 0)
1139 bwlq_suf &= ~1;
1140 if (strcasecmp(str, "No_wSuf") == 0)
1141 bwlq_suf &= ~2;
1142 if (strcasecmp(str, "No_lSuf") == 0)
1143 bwlq_suf &= ~4;
1144 if (strcasecmp(str, "No_qSuf") == 0)
1145 bwlq_suf &= ~8;
1146 }
1147 }
1148
1149 if (space)
1150 {
1151 if (!modifiers[OpcodeSpace].value)
1152 modifiers[OpcodeSpace].value = space;
1153 else if (modifiers[OpcodeSpace].value != space)
1154 fail (_("%s:%d: Conflicting opcode space specifications\n"),
1155 filename, lineno);
1156 else
1157 fprintf (stderr,
1158 _("%s:%d: Warning: redundant opcode space specification\n"),
1159 filename, lineno);
1160 }
1161
1162 if (prefix)
1163 {
1164 if (!modifiers[OpcodePrefix].value)
1165 modifiers[OpcodePrefix].value = prefix;
1166 else if (modifiers[OpcodePrefix].value != prefix)
1167 fail (_("%s:%d: Conflicting prefix specifications\n"),
1168 filename, lineno);
1169 else
1170 fprintf (stderr,
1171 _("%s:%d: Warning: redundant prefix specification\n"),
1172 filename, lineno);
1173 }
1174
1175 if (have_w && !bwlq_suf)
1176 fail ("%s: %d: stray W modifier\n", filename, lineno);
1177 if (have_w && !(bwlq_suf & 1))
1178 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1179 filename, lineno);
1180 if (have_w && !(bwlq_suf & ~1))
1181 fprintf (stderr,
1182 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1183 filename, lineno);
1184 }
1185 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1186 }
1187
1188 enum stage {
1189 stage_macros,
1190 stage_opcodes,
1191 stage_registers,
1192 };
1193
1194 static void
1195 output_operand_type (FILE *table, enum operand_class class,
1196 enum operand_instance instance,
1197 const bitfield *types, unsigned int size,
1198 enum stage stage, const char *indent)
1199 {
1200 unsigned int i;
1201
1202 fprintf (table, "{ { %d, %d, ", class, instance);
1203
1204 for (i = 0; i < size - 1; i++)
1205 {
1206 if (((i + 3) % 20) != 0)
1207 fprintf (table, "%d, ", types[i].value);
1208 else
1209 fprintf (table, "%d,", types[i].value);
1210 if (((i + 3) % 20) == 0)
1211 {
1212 /* We need \\ for macro. */
1213 if (stage == stage_macros)
1214 fprintf (table, " \\\n%s", indent);
1215 else
1216 fprintf (table, "\n%s", indent);
1217 }
1218 }
1219
1220 fprintf (table, "%d } }", types[i].value);
1221 }
1222
1223 static void
1224 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1225 const char *indent, int lineno)
1226 {
1227 char *str, *next, *last;
1228 enum operand_class class = ClassNone;
1229 enum operand_instance instance = InstanceNone;
1230 bitfield types [ARRAY_SIZE (operand_types)];
1231
1232 /* Copy the default operand type. */
1233 memcpy (types, operand_types, sizeof (types));
1234
1235 if (strcmp (op, "0"))
1236 {
1237 int baseindex = 0;
1238
1239 last = op + strlen (op);
1240 for (next = op; next && next < last; )
1241 {
1242 str = next_field (next, '|', &next, last);
1243 if (str)
1244 {
1245 unsigned int i;
1246
1247 if (!strncmp(str, "Class=", 6))
1248 {
1249 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1250 if (!strcmp(str + 6, operand_classes[i].name))
1251 {
1252 class = operand_classes[i].value;
1253 str = NULL;
1254 break;
1255 }
1256 }
1257
1258 if (str && !strncmp(str, "Instance=", 9))
1259 {
1260 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1261 if (!strcmp(str + 9, operand_instances[i].name))
1262 {
1263 instance = operand_instances[i].value;
1264 str = NULL;
1265 break;
1266 }
1267 }
1268 }
1269 if (str)
1270 {
1271 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1272 if (strcasecmp(str, "BaseIndex") == 0)
1273 baseindex = 1;
1274 }
1275 }
1276
1277 if (stage == stage_opcodes && baseindex && !active_isstring)
1278 {
1279 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1280 if (!active_cpu_flags.bitfield.cpu64
1281 && !active_cpu_flags.bitfield.cpumpx)
1282 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1283 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1284 }
1285 }
1286 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1287 stage, indent);
1288 }
1289
1290 static void
1291 output_i386_opcode (FILE *table, const char *name, char *str,
1292 char *last, int lineno)
1293 {
1294 unsigned int i, length, prefix = 0, space = 0;
1295 char *base_opcode, *extension_opcode, *end;
1296 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1297 unsigned long long opcode;
1298
1299 /* Find base_opcode. */
1300 base_opcode = next_field (str, ',', &str, last);
1301
1302 /* Find extension_opcode. */
1303 extension_opcode = next_field (str, ',', &str, last);
1304
1305 /* Find cpu_flags. */
1306 cpu_flags = next_field (str, ',', &str, last);
1307
1308 /* Find opcode_modifier. */
1309 opcode_modifier = next_field (str, ',', &str, last);
1310
1311 /* Remove the first {. */
1312 str = remove_leading_whitespaces (str);
1313 if (*str != '{')
1314 abort ();
1315 str = remove_leading_whitespaces (str + 1);
1316 remove_trailing_whitespaces (str);
1317
1318 /* Remove } and trailing white space. */
1319 i = strlen (str);
1320 if (!i || str[i - 1] != '}')
1321 abort ();
1322 str[--i] = '\0';
1323 remove_trailing_whitespaces (str);
1324
1325 if (!*str)
1326 operand_types [i = 0] = NULL;
1327 else
1328 {
1329 last = str + strlen (str);
1330
1331 /* Find operand_types. */
1332 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1333 {
1334 if (str >= last)
1335 {
1336 operand_types [i] = NULL;
1337 break;
1338 }
1339
1340 operand_types [i] = next_field (str, ',', &str, last);
1341 }
1342 }
1343
1344 opcode = strtoull (base_opcode, &end, 0);
1345
1346 /* Determine opcode length. */
1347 for (length = 1; length < 8; ++length)
1348 if (!(opcode >> (8 * length)))
1349 break;
1350
1351 /* Transform prefixes encoded in the opcode into opcode modifier
1352 representation. */
1353 if (length > 1)
1354 {
1355 switch (opcode >> (8 * length - 8))
1356 {
1357 case 0x66: prefix = PREFIX_0X66; break;
1358 case 0xF3: prefix = PREFIX_0XF3; break;
1359 case 0xF2: prefix = PREFIX_0XF2; break;
1360 }
1361
1362 if (prefix)
1363 opcode &= (1ULL << (8 * --length)) - 1;
1364 }
1365
1366 /* Transform opcode space encoded in the opcode into opcode modifier
1367 representation. */
1368 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1369 {
1370 switch ((opcode >> (8 * length - 16)) & 0xff)
1371 {
1372 default: space = SPACE_0F; break;
1373 case 0x38: space = SPACE_0F38; break;
1374 case 0x3A: space = SPACE_0F3A; break;
1375 }
1376
1377 if (space != SPACE_0F && --length == 1)
1378 fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1379 filename, lineno, name);
1380 opcode &= (1ULL << (8 * --length)) - 1;
1381 }
1382
1383 if (length > 2)
1384 fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1385 filename, lineno, name, 2 * length, opcode);
1386
1387 fprintf (table, " { \"%s\", 0x%0*llx%s, %lu, %s,\n",
1388 name, 2 * (int)length, opcode, end, i, extension_opcode);
1389
1390 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1391 operand_types, lineno);
1392
1393 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1394
1395 fprintf (table, " { ");
1396
1397 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1398 {
1399 if (!operand_types[i])
1400 {
1401 if (i == 0)
1402 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1403 lineno);
1404 break;
1405 }
1406
1407 if (i != 0)
1408 fprintf (table, ",\n ");
1409
1410 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1411 "\t ", lineno);
1412 }
1413 fprintf (table, " } },\n");
1414 }
1415
1416 struct opcode_hash_entry
1417 {
1418 struct opcode_hash_entry *next;
1419 char *name;
1420 char *opcode;
1421 int lineno;
1422 };
1423
1424 /* Calculate the hash value of an opcode hash entry P. */
1425
1426 static hashval_t
1427 opcode_hash_hash (const void *p)
1428 {
1429 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1430 return htab_hash_string (entry->name);
1431 }
1432
1433 /* Compare a string Q against an opcode hash entry P. */
1434
1435 static int
1436 opcode_hash_eq (const void *p, const void *q)
1437 {
1438 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1439 const char *name = (const char *) q;
1440 return strcmp (name, entry->name) == 0;
1441 }
1442
1443 static void
1444 parse_template (char *buf, int lineno)
1445 {
1446 char sep, *end, *name;
1447 struct template *tmpl;
1448 struct template_instance *last_inst = NULL;
1449
1450 buf = remove_leading_whitespaces (buf + 1);
1451 end = strchr (buf, ':');
1452 if (end == NULL)
1453 {
1454 struct template *prev = NULL;
1455
1456 end = strchr (buf, '>');
1457 if (end == NULL)
1458 fail ("%s: %d: missing ':' or '>'\n", filename, lineno);
1459 if (*remove_leading_whitespaces (end + 1))
1460 fail ("%s: %d: malformed template purge\n", filename, lineno);
1461 *end = '\0';
1462 remove_trailing_whitespaces (buf);
1463 /* Don't bother freeing the various structures. */
1464 for (tmpl = templates; tmpl != NULL; tmpl = (prev = tmpl)->next)
1465 if (!strcmp (buf, tmpl->name))
1466 break;
1467 if (tmpl == NULL)
1468 fail ("%s: %d: no template '%s'\n", filename, lineno, buf);
1469 if (prev)
1470 prev->next = tmpl->next;
1471 else
1472 templates = tmpl->next;
1473 return;
1474 }
1475 *end++ = '\0';
1476 remove_trailing_whitespaces (buf);
1477
1478 if (*buf == '\0')
1479 fail ("%s: %d: missing template identifier\n", filename, lineno);
1480 tmpl = xmalloc (sizeof (*tmpl));
1481 tmpl->name = xstrdup (buf);
1482
1483 tmpl->params = NULL;
1484 do {
1485 struct template_param *param;
1486
1487 buf = remove_leading_whitespaces (end);
1488 end = strpbrk (buf, ":,");
1489 if (end == NULL)
1490 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1491
1492 sep = *end;
1493 *end++ = '\0';
1494 remove_trailing_whitespaces (buf);
1495
1496 param = xmalloc (sizeof (*param));
1497 param->name = xstrdup (buf);
1498 param->next = tmpl->params;
1499 tmpl->params = param;
1500 } while (sep == ':');
1501
1502 tmpl->instances = NULL;
1503 do {
1504 struct template_instance *inst;
1505 char *cur, *next;
1506 const struct template_param *param;
1507
1508 buf = remove_leading_whitespaces (end);
1509 end = strpbrk (buf, ",>");
1510 if (end == NULL)
1511 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1512
1513 sep = *end;
1514 *end++ = '\0';
1515
1516 inst = xmalloc (sizeof (*inst));
1517 inst->next = NULL;
1518 inst->args = NULL;
1519
1520 cur = next_field (buf, ':', &next, end);
1521 inst->name = *cur != '$' ? xstrdup (cur) : "";
1522
1523 for (param = tmpl->params; param; param = param->next)
1524 {
1525 struct template_arg *arg = xmalloc (sizeof (*arg));
1526
1527 cur = next_field (next, ':', &next, end);
1528 if (next > end)
1529 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1530 arg->val = xstrdup (cur);
1531 arg->next = inst->args;
1532 inst->args = arg;
1533 }
1534
1535 if (tmpl->instances)
1536 last_inst->next = inst;
1537 else
1538 tmpl->instances = inst;
1539 last_inst = inst;
1540 } while (sep == ',');
1541
1542 buf = remove_leading_whitespaces (end);
1543 if (*buf)
1544 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1545 filename, lineno, buf);
1546
1547 tmpl->next = templates;
1548 templates = tmpl;
1549 }
1550
1551 static unsigned int
1552 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1553 struct opcode_hash_entry ***opcode_array_p, int lineno)
1554 {
1555 static unsigned int idx, opcode_array_size;
1556 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1557 struct opcode_hash_entry **hash_slot, **entry;
1558 char *ptr1 = strchr(name, '<'), *ptr2;
1559
1560 if (ptr1 == NULL)
1561 {
1562 /* Get the slot in hash table. */
1563 hash_slot = (struct opcode_hash_entry **)
1564 htab_find_slot_with_hash (opcode_hash_table, name,
1565 htab_hash_string (name),
1566 INSERT);
1567
1568 if (*hash_slot == NULL)
1569 {
1570 /* It is the new one. Put it on opcode array. */
1571 if (idx >= opcode_array_size)
1572 {
1573 /* Grow the opcode array when needed. */
1574 opcode_array_size += 1024;
1575 opcode_array = (struct opcode_hash_entry **)
1576 xrealloc (opcode_array,
1577 sizeof (*opcode_array) * opcode_array_size);
1578 *opcode_array_p = opcode_array;
1579 }
1580
1581 opcode_array[idx] = (struct opcode_hash_entry *)
1582 xmalloc (sizeof (struct opcode_hash_entry));
1583 opcode_array[idx]->next = NULL;
1584 opcode_array[idx]->name = xstrdup (name);
1585 opcode_array[idx]->opcode = xstrdup (str);
1586 opcode_array[idx]->lineno = lineno;
1587 *hash_slot = opcode_array[idx];
1588 idx++;
1589 }
1590 else
1591 {
1592 /* Append it to the existing one. */
1593 entry = hash_slot;
1594 while ((*entry) != NULL)
1595 entry = &(*entry)->next;
1596 *entry = (struct opcode_hash_entry *)
1597 xmalloc (sizeof (struct opcode_hash_entry));
1598 (*entry)->next = NULL;
1599 (*entry)->name = (*hash_slot)->name;
1600 (*entry)->opcode = xstrdup (str);
1601 (*entry)->lineno = lineno;
1602 }
1603 }
1604 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1605 fail ("%s: %d: missing '>'\n", filename, lineno);
1606 else
1607 {
1608 const struct template *tmpl;
1609 const struct template_instance *inst;
1610
1611 *ptr1 = '\0';
1612 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1613 remove_trailing_whitespaces (ptr1);
1614
1615 *ptr2++ = '\0';
1616
1617 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1618 if (!strcmp(ptr1, tmpl->name))
1619 break;
1620 if (!tmpl)
1621 fail ("reference to unknown template '%s'\n", ptr1);
1622
1623 for (inst = tmpl->instances; inst; inst = inst->next)
1624 {
1625 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1626 char *str2 = xmalloc(2 * strlen(str));
1627 const char *src;
1628
1629 strcpy (name2, name);
1630 strcat (name2, inst->name);
1631 strcat (name2, ptr2);
1632
1633 for (ptr1 = str2, src = str; *src; )
1634 {
1635 const char *ident = tmpl->name, *end;
1636 const struct template_param *param;
1637 const struct template_arg *arg;
1638
1639 if ((*ptr1 = *src++) != '<')
1640 {
1641 ++ptr1;
1642 continue;
1643 }
1644 while (ISSPACE(*src))
1645 ++src;
1646 while (*ident && *src == *ident)
1647 ++src, ++ident;
1648 while (ISSPACE(*src))
1649 ++src;
1650 if (*src != ':' || *ident != '\0')
1651 {
1652 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1653 ptr1 += ident - tmpl->name;
1654 continue;
1655 }
1656 while (ISSPACE(*++src))
1657 ;
1658
1659 end = src;
1660 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1661 ++end;
1662
1663 for (param = tmpl->params, arg = inst->args; param;
1664 param = param->next, arg = arg->next)
1665 {
1666 if (end - src == strlen (param->name)
1667 && !memcmp (src, param->name, end - src))
1668 {
1669 src = end;
1670 break;
1671 }
1672 }
1673
1674 if (param == NULL)
1675 fail ("template '%s' has no parameter '%.*s'\n",
1676 tmpl->name, (int)(end - src), src);
1677
1678 while (ISSPACE(*src))
1679 ++src;
1680 if (*src != '>')
1681 fail ("%s: %d: missing '>'\n", filename, lineno);
1682
1683 memcpy(ptr1, arg->val, strlen(arg->val));
1684 ptr1 += strlen(arg->val);
1685 ++src;
1686 }
1687
1688 *ptr1 = '\0';
1689
1690 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1691 lineno);
1692
1693 free (str2);
1694 free (name2);
1695 }
1696 }
1697
1698 return idx;
1699 }
1700
1701 static void
1702 process_i386_opcodes (FILE *table)
1703 {
1704 FILE *fp;
1705 char buf[2048];
1706 unsigned int i, j;
1707 char *str, *p, *last, *name;
1708 htab_t opcode_hash_table;
1709 struct opcode_hash_entry **opcode_array = NULL;
1710 int lineno = 0, marker = 0;
1711
1712 filename = "i386-opc.tbl";
1713 fp = stdin;
1714
1715 i = 0;
1716 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1717 opcode_hash_eq, NULL,
1718 xcalloc, free);
1719
1720 fprintf (table, "\n/* i386 opcode table. */\n\n");
1721 fprintf (table, "static const insn_template i386_optab[] =\n{\n");
1722
1723 /* Put everything on opcode array. */
1724 while (!feof (fp))
1725 {
1726 if (fgets (buf, sizeof (buf), fp) == NULL)
1727 break;
1728
1729 p = remove_leading_whitespaces (buf);
1730
1731 for ( ; ; )
1732 {
1733 lineno++;
1734
1735 /* Skip comments. */
1736 str = strstr (p, "//");
1737 if (str != NULL)
1738 {
1739 str[0] = '\0';
1740 remove_trailing_whitespaces (p);
1741 break;
1742 }
1743
1744 /* Look for line continuation character. */
1745 remove_trailing_whitespaces (p);
1746 j = strlen (buf);
1747 if (!j || buf[j - 1] != '+')
1748 break;
1749 if (j >= sizeof (buf) - 1)
1750 fail (_("%s: %d: (continued) line too long\n"), filename, lineno);
1751
1752 if (fgets (buf + j - 1, sizeof (buf) - j + 1, fp) == NULL)
1753 {
1754 fprintf (stderr, "%s: Line continuation on last line?\n",
1755 filename);
1756 break;
1757 }
1758 }
1759
1760 switch (p[0])
1761 {
1762 case '#':
1763 if (!strcmp("### MARKER ###", buf))
1764 marker = 1;
1765 else
1766 {
1767 /* Since we ignore all included files (we only care about their
1768 #define-s here), we don't need to monitor filenames. The final
1769 line number directive is going to refer to the main source file
1770 again. */
1771 char *end;
1772 unsigned long ln;
1773
1774 p = remove_leading_whitespaces (p + 1);
1775 if (!strncmp(p, "line", 4))
1776 p += 4;
1777 ln = strtoul (p, &end, 10);
1778 if (ln > 1 && ln < INT_MAX
1779 && *remove_leading_whitespaces (end) == '"')
1780 lineno = ln - 1;
1781 }
1782 /* Ignore comments. */
1783 case '\0':
1784 continue;
1785 break;
1786 case '<':
1787 parse_template (p, lineno);
1788 continue;
1789 default:
1790 if (!marker)
1791 continue;
1792 break;
1793 }
1794
1795 last = p + strlen (p);
1796
1797 /* Find name. */
1798 name = next_field (p, ',', &str, last);
1799
1800 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1801 lineno);
1802 }
1803
1804 /* Process opcode array. */
1805 for (j = 0; j < i; j++)
1806 {
1807 struct opcode_hash_entry *next;
1808
1809 for (next = opcode_array[j]; next; next = next->next)
1810 {
1811 name = next->name;
1812 str = next->opcode;
1813 lineno = next->lineno;
1814 last = str + strlen (str);
1815 output_i386_opcode (table, name, str, last, lineno);
1816 }
1817 }
1818
1819 fclose (fp);
1820
1821 fprintf (table, "};\n");
1822 }
1823
1824 static void
1825 process_i386_registers (FILE *table)
1826 {
1827 FILE *fp;
1828 char buf[2048];
1829 char *str, *p, *last;
1830 char *reg_name, *reg_type, *reg_flags, *reg_num;
1831 char *dw2_32_num, *dw2_64_num;
1832 int lineno = 0;
1833
1834 filename = "i386-reg.tbl";
1835 fp = fopen (filename, "r");
1836 if (fp == NULL)
1837 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1838 xstrerror (errno));
1839
1840 fprintf (table, "\n/* i386 register table. */\n\n");
1841 fprintf (table, "static const reg_entry i386_regtab[] =\n{\n");
1842
1843 while (!feof (fp))
1844 {
1845 if (fgets (buf, sizeof (buf), fp) == NULL)
1846 break;
1847
1848 lineno++;
1849
1850 p = remove_leading_whitespaces (buf);
1851
1852 /* Skip comments. */
1853 str = strstr (p, "//");
1854 if (str != NULL)
1855 str[0] = '\0';
1856
1857 /* Remove trailing white spaces. */
1858 remove_trailing_whitespaces (p);
1859
1860 switch (p[0])
1861 {
1862 case '#':
1863 fprintf (table, "%s\n", p);
1864 case '\0':
1865 continue;
1866 break;
1867 default:
1868 break;
1869 }
1870
1871 last = p + strlen (p);
1872
1873 /* Find reg_name. */
1874 reg_name = next_field (p, ',', &str, last);
1875
1876 /* Find reg_type. */
1877 reg_type = next_field (str, ',', &str, last);
1878
1879 /* Find reg_flags. */
1880 reg_flags = next_field (str, ',', &str, last);
1881
1882 /* Find reg_num. */
1883 reg_num = next_field (str, ',', &str, last);
1884
1885 fprintf (table, " { \"%s\",\n ", reg_name);
1886
1887 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1888 lineno);
1889
1890 /* Find 32-bit Dwarf2 register number. */
1891 dw2_32_num = next_field (str, ',', &str, last);
1892
1893 /* Find 64-bit Dwarf2 register number. */
1894 dw2_64_num = next_field (str, ',', &str, last);
1895
1896 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1897 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1898 }
1899
1900 fclose (fp);
1901
1902 fprintf (table, "};\n");
1903
1904 fprintf (table, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1905 }
1906
1907 static void
1908 process_i386_initializers (void)
1909 {
1910 unsigned int i;
1911 FILE *fp = fopen ("i386-init.h", "w");
1912 char *init;
1913
1914 if (fp == NULL)
1915 fail (_("can't create i386-init.h, errno = %s\n"),
1916 xstrerror (errno));
1917
1918 process_copyright (fp);
1919
1920 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1921 {
1922 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1923 init = xstrdup (cpu_flag_init[i].init);
1924 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1925 free (init);
1926 }
1927
1928 fprintf (fp, "\n");
1929
1930 fclose (fp);
1931 }
1932
1933 /* Program options. */
1934 #define OPTION_SRCDIR 200
1935
1936 struct option long_options[] =
1937 {
1938 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1939 {"debug", no_argument, NULL, 'd'},
1940 {"version", no_argument, NULL, 'V'},
1941 {"help", no_argument, NULL, 'h'},
1942 {0, no_argument, NULL, 0}
1943 };
1944
1945 static void
1946 print_version (void)
1947 {
1948 printf ("%s: version 1.0\n", program_name);
1949 xexit (0);
1950 }
1951
1952 static void
1953 usage (FILE * stream, int status)
1954 {
1955 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1956 program_name);
1957 xexit (status);
1958 }
1959
1960 int
1961 main (int argc, char **argv)
1962 {
1963 extern int chdir (char *);
1964 char *srcdir = NULL;
1965 int c;
1966 unsigned int i, cpumax;
1967 FILE *table;
1968
1969 program_name = *argv;
1970 xmalloc_set_program_name (program_name);
1971
1972 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1973 switch (c)
1974 {
1975 case OPTION_SRCDIR:
1976 srcdir = optarg;
1977 break;
1978 case 'V':
1979 case 'v':
1980 print_version ();
1981 break;
1982 case 'd':
1983 debug = 1;
1984 break;
1985 case 'h':
1986 case '?':
1987 usage (stderr, 0);
1988 default:
1989 case 0:
1990 break;
1991 }
1992
1993 if (optind != argc)
1994 usage (stdout, 1);
1995
1996 if (srcdir != NULL)
1997 if (chdir (srcdir) != 0)
1998 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1999 srcdir, xstrerror (errno));
2000
2001 /* cpu_flags isn't sorted by position. */
2002 cpumax = 0;
2003 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2004 if (cpu_flags[i].position > cpumax)
2005 cpumax = cpu_flags[i].position;
2006
2007 /* Check the unused bitfield in i386_cpu_flags. */
2008 #ifdef CpuUnused
2009 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2010
2011 if ((cpumax - 1) != CpuMax)
2012 fail (_("CpuMax != %d!\n"), cpumax);
2013 #else
2014 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2015
2016 if (cpumax != CpuMax)
2017 fail (_("CpuMax != %d!\n"), cpumax);
2018
2019 c = CpuNumOfBits - CpuMax - 1;
2020 if (c)
2021 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
2022 #endif
2023
2024 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2025
2026 /* Check the unused bitfield in i386_operand_type. */
2027 #ifdef OTUnused
2028 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2029 == OTNum + 1);
2030 #else
2031 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2032 == OTNum);
2033
2034 c = OTNumOfBits - OTNum;
2035 if (c)
2036 fail (_("%d unused bits in i386_operand_type.\n"), c);
2037 #endif
2038
2039 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2040 compare);
2041
2042 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2043 sizeof (opcode_modifiers [0]), compare);
2044
2045 qsort (operand_types, ARRAY_SIZE (operand_types),
2046 sizeof (operand_types [0]), compare);
2047
2048 table = fopen ("i386-tbl.h", "w");
2049 if (table == NULL)
2050 fail (_("can't create i386-tbl.h, errno = %s\n"),
2051 xstrerror (errno));
2052
2053 process_copyright (table);
2054
2055 process_i386_opcodes (table);
2056 process_i386_registers (table);
2057 process_i386_initializers ();
2058
2059 fclose (table);
2060
2061 exit (0);
2062 }