Update gdb/NEWS after GDB 13 branch creation.
[binutils-gdb.git] / opcodes / i386-gen.c
blob101f6860ce275c5e904b9231012051a5263b819b
1 /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
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.
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.
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. */
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"
28 #include "i386-opc.h"
30 #include <libintl.h>
31 #define _(String) gettext (String)
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); }))
37 static const char *program_name = NULL;
38 static int debug = 0;
40 typedef struct initializer
42 const char *name;
43 const char *init;
44 } initializer;
46 static initializer cpu_flag_init[] =
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"},
480 typedef struct bitfield
482 int position;
483 int value;
484 const char *name;
485 } bitfield;
487 #define BITFIELD(n) { n, 0, #n }
489 static bitfield cpu_flags[] =
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
630 static bitfield opcode_modifiers[] =
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),
676 #define CLASS(n) #n, n
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),
693 #undef CLASS
695 #define INSTANCE(n) #n, n
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),
707 #undef INSTANCE
709 static bitfield operand_types[] =
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
739 static const char *filename;
740 static i386_cpu_flags active_cpu_flags;
741 static int active_isstring;
743 struct template_arg {
744 const struct template_arg *next;
745 const char *val;
748 struct template_instance {
749 const struct template_instance *next;
750 const char *name;
751 const struct template_arg *args;
754 struct template_param {
755 const struct template_param *next;
756 const char *name;
759 struct template {
760 struct template *next;
761 const char *name;
762 const struct template_instance *instances;
763 const struct template_param *params;
766 static struct template *templates;
768 static int
769 compare (const void *x, const void *y)
771 const bitfield *xp = (const bitfield *) x;
772 const bitfield *yp = (const bitfield *) y;
773 return xp->position - yp->position;
776 static void
777 fail (const char *message, ...)
779 va_list args;
781 va_start (args, message);
782 fprintf (stderr, _("%s: error: "), program_name);
783 vfprintf (stderr, message, args);
784 va_end (args);
785 xexit (1);
788 static void
789 process_copyright (FILE *fp)
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\
794 This file is part of the GNU opcodes library.\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\
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\
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");
812 /* Remove leading white spaces. */
814 static char *
815 remove_leading_whitespaces (char *str)
817 while (ISSPACE (*str))
818 str++;
819 return str;
822 /* Remove trailing white spaces. */
824 static void
825 remove_trailing_whitespaces (char *str)
827 size_t last = strlen (str);
829 if (last == 0)
830 return;
834 last--;
835 if (ISSPACE (str [last]))
836 str[last] = '\0';
837 else
838 break;
840 while (last != 0);
843 /* Find next field separated by SEP and terminate it. Return a
844 pointer to the one after it. */
846 static char *
847 next_field (char *str, char sep, char **next, char *last)
849 char *p;
851 p = remove_leading_whitespaces (str);
852 for (str = p; *str != sep && *str != '\0'; str++);
854 *str = '\0';
855 remove_trailing_whitespaces (p);
857 *next = str + 1;
859 if (p >= last)
860 abort ();
862 return p;
865 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
867 static int
868 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
869 int lineno)
871 char *str, *next, *last;
872 unsigned int i;
874 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
875 if (strcmp (cpu_flag_init[i].name, f) == 0)
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; )
882 str = next_field (next, '|', &next, last);
883 if (str)
884 set_bitfield (str, array, 1, size, lineno);
886 free (init);
887 return 0;
890 return -1;
893 static void
894 set_bitfield (char *f, bitfield *array, int value,
895 unsigned int size, int lineno)
897 unsigned int i;
899 /* Ignore empty fields; they may result from template expansions. */
900 if (*f == '\0')
901 return;
903 for (i = 0; i < size; i++)
904 if (strcasecmp (array[i].name, f) == 0)
906 array[i].value = value;
907 return;
910 if (value)
912 const char *v = strchr (f, '=');
914 if (v)
916 size_t n = v - f;
917 char *end;
919 for (i = 0; i < size; i++)
920 if (strncasecmp (array[i].name, f, n) == 0)
922 value = strtol (v + 1, &end, 0);
923 if (*end == '\0')
925 array[i].value = value;
926 return;
928 break;
933 /* Handle CPU_XXX_FLAGS. */
934 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
935 return;
937 if (lineno != -1)
938 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
939 else
940 fail (_("unknown bitfield: %s\n"), f);
943 static void
944 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
945 int macro, const char *comma, const char *indent)
947 unsigned int i;
949 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
951 fprintf (table, "%s{ { ", indent);
953 for (i = 0; i < size - 1; i++)
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)
961 /* We need \\ for macro. */
962 if (macro)
963 fprintf (table, " \\\n %s", indent);
964 else
965 fprintf (table, "\n %s", indent);
967 if (flags[i].value)
968 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
971 fprintf (table, "%d } }%s\n", flags[i].value, comma);
974 static void
975 process_i386_cpu_flag (FILE *table, char *flag, int macro,
976 const char *comma, const char *indent,
977 int lineno)
979 char *str, *next = flag, *last;
980 unsigned int i;
981 int value = 1;
982 bitfield flags [ARRAY_SIZE (cpu_flags)];
984 /* Copy the default cpu flags. */
985 memcpy (flags, cpu_flags, sizeof (cpu_flags));
987 if (flag[0] == '~')
989 last = flag + strlen (flag);
991 if (flag[1] == '(')
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';
1000 else
1001 next = flag + 1;
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;
1009 /* Turn off selective bits. */
1010 value = 0;
1013 if (strcmp (flag, "0"))
1015 /* Turn on/off selective bits. */
1016 last = flag + strlen (flag);
1017 for (; next && next < last; )
1019 str = next_field (next, '|', &next, last);
1020 if (str)
1021 set_bitfield (str, flags, value, ARRAY_SIZE (flags), lineno);
1025 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1026 comma, indent);
1029 static void
1030 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1032 unsigned int i;
1034 fprintf (table, " { ");
1036 for (i = 0; i < size - 1; i++)
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 ");
1046 fprintf (table, "%d },\n", modifier[i].value);
1049 /* Returns LOG2 of element size. */
1050 static int
1051 get_element_size (char **opnd, int lineno)
1053 char *str, *next, *last, *op;
1054 const char *full = opnd[0];
1055 int elem_size = INT_MAX;
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);
1063 op = xstrdup (full);
1064 last = op + strlen (op);
1065 for (next = op; next && next < last; )
1067 str = next_field (next, '|', &next, last);
1068 if (str)
1070 if (strcasecmp(str, "Byte") == 0)
1072 /* The smallest element size, no need to check
1073 further. */
1074 elem_size = 0;
1075 break;
1077 else if (strcasecmp(str, "Word") == 0)
1079 if (elem_size > 1)
1080 elem_size = 1;
1082 else if (strcasecmp(str, "Dword") == 0)
1084 if (elem_size > 2)
1085 elem_size = 2;
1087 else if (strcasecmp(str, "Qword") == 0)
1089 if (elem_size > 3)
1090 elem_size = 3;
1094 free (op);
1096 if (elem_size == INT_MAX)
1097 fail (_("%s: %d: unknown element size: %s\n"), filename, lineno, full);
1099 return elem_size;
1102 static void
1103 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1104 unsigned int prefix, char **opnd, int lineno)
1106 char *str, *next, *last;
1107 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1109 active_isstring = 0;
1111 /* Copy the default opcode modifier. */
1112 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1114 if (strcmp (mod, "0"))
1116 unsigned int have_w = 0, bwlq_suf = 0xf;
1118 last = mod + strlen (mod);
1119 for (next = mod; next && next < last; )
1121 str = next_field (next, '|', &next, last);
1122 if (str)
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);
1130 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1131 lineno);
1132 if (strcasecmp(str, "IsString") == 0)
1133 active_isstring = 1;
1135 if (strcasecmp(str, "W") == 0)
1136 have_w = 1;
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;
1149 if (space)
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);
1162 if (prefix)
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);
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);
1185 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1188 enum stage {
1189 stage_macros,
1190 stage_opcodes,
1191 stage_registers,
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)
1200 unsigned int i;
1202 fprintf (table, "{ { %d, %d, ", class, instance);
1204 for (i = 0; i < size - 1; i++)
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)
1212 /* We need \\ for macro. */
1213 if (stage == stage_macros)
1214 fprintf (table, " \\\n%s", indent);
1215 else
1216 fprintf (table, "\n%s", indent);
1220 fprintf (table, "%d } }", types[i].value);
1223 static void
1224 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1225 const char *indent, int lineno)
1227 char *str, *next, *last;
1228 enum operand_class class = ClassNone;
1229 enum operand_instance instance = InstanceNone;
1230 bitfield types [ARRAY_SIZE (operand_types)];
1232 /* Copy the default operand type. */
1233 memcpy (types, operand_types, sizeof (types));
1235 if (strcmp (op, "0"))
1237 int baseindex = 0;
1239 last = op + strlen (op);
1240 for (next = op; next && next < last; )
1242 str = next_field (next, '|', &next, last);
1243 if (str)
1245 unsigned int i;
1247 if (!strncmp(str, "Class=", 6))
1249 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1250 if (!strcmp(str + 6, operand_classes[i].name))
1252 class = operand_classes[i].value;
1253 str = NULL;
1254 break;
1258 if (str && !strncmp(str, "Instance=", 9))
1260 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1261 if (!strcmp(str + 9, operand_instances[i].name))
1263 instance = operand_instances[i].value;
1264 str = NULL;
1265 break;
1269 if (str)
1271 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1272 if (strcasecmp(str, "BaseIndex") == 0)
1273 baseindex = 1;
1277 if (stage == stage_opcodes && baseindex && !active_isstring)
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);
1286 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1287 stage, indent);
1290 static void
1291 output_i386_opcode (FILE *table, const char *name, char *str,
1292 char *last, int lineno)
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;
1299 /* Find base_opcode. */
1300 base_opcode = next_field (str, ',', &str, last);
1302 /* Find extension_opcode, if any. */
1303 extension_opcode = strchr (base_opcode, '/');
1304 if (extension_opcode)
1305 *extension_opcode++ = '\0';
1307 /* Find cpu_flags. */
1308 cpu_flags = next_field (str, ',', &str, last);
1310 /* Find opcode_modifier. */
1311 opcode_modifier = next_field (str, ',', &str, last);
1313 /* Remove the first {. */
1314 str = remove_leading_whitespaces (str);
1315 if (*str != '{')
1316 abort ();
1317 str = remove_leading_whitespaces (str + 1);
1318 remove_trailing_whitespaces (str);
1320 /* Remove } and trailing white space. */
1321 i = strlen (str);
1322 if (!i || str[i - 1] != '}')
1323 abort ();
1324 str[--i] = '\0';
1325 remove_trailing_whitespaces (str);
1327 if (!*str)
1328 operand_types [i = 0] = NULL;
1329 else
1331 last = str + strlen (str);
1333 /* Find operand_types. */
1334 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1336 if (str >= last)
1338 operand_types [i] = NULL;
1339 break;
1342 operand_types [i] = next_field (str, ',', &str, last);
1346 opcode = strtoull (base_opcode, &end, 0);
1348 /* Determine opcode length. */
1349 for (length = 1; length < 8; ++length)
1350 if (!(opcode >> (8 * length)))
1351 break;
1353 /* Transform prefixes encoded in the opcode into opcode modifier
1354 representation. */
1355 if (length > 1)
1357 switch (opcode >> (8 * length - 8))
1359 case 0x66: prefix = PREFIX_0X66; break;
1360 case 0xF3: prefix = PREFIX_0XF3; break;
1361 case 0xF2: prefix = PREFIX_0XF2; break;
1364 if (prefix)
1365 opcode &= (1ULL << (8 * --length)) - 1;
1368 /* Transform opcode space encoded in the opcode into opcode modifier
1369 representation. */
1370 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1372 switch ((opcode >> (8 * length - 16)) & 0xff)
1374 default: space = SPACE_0F; break;
1375 case 0x38: space = SPACE_0F38; break;
1376 case 0x3A: space = SPACE_0F3A; break;
1379 if (space != SPACE_0F && --length == 1)
1380 fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1381 filename, lineno, name);
1382 opcode &= (1ULL << (8 * --length)) - 1;
1385 if (length > 2)
1386 fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1387 filename, lineno, name, 2 * length, opcode);
1389 fprintf (table, " { \"%s\", 0x%0*llx%s, %lu, %s,\n",
1390 name, 2 * (int)length, opcode, end, i,
1391 extension_opcode ? extension_opcode : "None");
1393 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1394 operand_types, lineno);
1396 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1398 fprintf (table, " { ");
1400 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1402 if (!operand_types[i])
1404 if (i == 0)
1405 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1406 lineno);
1407 break;
1410 if (i != 0)
1411 fprintf (table, ",\n ");
1413 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1414 "\t ", lineno);
1416 fprintf (table, " } },\n");
1419 struct opcode_hash_entry
1421 struct opcode_hash_entry *next;
1422 char *name;
1423 char *opcode;
1424 int lineno;
1427 /* Calculate the hash value of an opcode hash entry P. */
1429 static hashval_t
1430 opcode_hash_hash (const void *p)
1432 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1433 return htab_hash_string (entry->name);
1436 /* Compare a string Q against an opcode hash entry P. */
1438 static int
1439 opcode_hash_eq (const void *p, const void *q)
1441 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1442 const char *name = (const char *) q;
1443 return strcmp (name, entry->name) == 0;
1446 static void
1447 parse_template (char *buf, int lineno)
1449 char sep, *end, *name;
1450 struct template *tmpl;
1451 struct template_instance *last_inst = NULL;
1453 buf = remove_leading_whitespaces (buf + 1);
1454 end = strchr (buf, ':');
1455 if (end == NULL)
1457 struct template *prev = NULL;
1459 end = strchr (buf, '>');
1460 if (end == NULL)
1461 fail ("%s: %d: missing ':' or '>'\n", filename, lineno);
1462 if (*remove_leading_whitespaces (end + 1))
1463 fail ("%s: %d: malformed template purge\n", filename, lineno);
1464 *end = '\0';
1465 remove_trailing_whitespaces (buf);
1466 /* Don't bother freeing the various structures. */
1467 for (tmpl = templates; tmpl != NULL; tmpl = (prev = tmpl)->next)
1468 if (!strcmp (buf, tmpl->name))
1469 break;
1470 if (tmpl == NULL)
1471 fail ("%s: %d: no template '%s'\n", filename, lineno, buf);
1472 if (prev)
1473 prev->next = tmpl->next;
1474 else
1475 templates = tmpl->next;
1476 return;
1478 *end++ = '\0';
1479 remove_trailing_whitespaces (buf);
1481 if (*buf == '\0')
1482 fail ("%s: %d: missing template identifier\n", filename, lineno);
1483 tmpl = xmalloc (sizeof (*tmpl));
1484 tmpl->name = xstrdup (buf);
1486 tmpl->params = NULL;
1487 do {
1488 struct template_param *param;
1490 buf = remove_leading_whitespaces (end);
1491 end = strpbrk (buf, ":,");
1492 if (end == NULL)
1493 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1495 sep = *end;
1496 *end++ = '\0';
1497 remove_trailing_whitespaces (buf);
1499 param = xmalloc (sizeof (*param));
1500 param->name = xstrdup (buf);
1501 param->next = tmpl->params;
1502 tmpl->params = param;
1503 } while (sep == ':');
1505 tmpl->instances = NULL;
1506 do {
1507 struct template_instance *inst;
1508 char *cur, *next;
1509 const struct template_param *param;
1511 buf = remove_leading_whitespaces (end);
1512 end = strpbrk (buf, ",>");
1513 if (end == NULL)
1514 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1516 sep = *end;
1517 *end++ = '\0';
1519 inst = xmalloc (sizeof (*inst));
1520 inst->next = NULL;
1521 inst->args = NULL;
1523 cur = next_field (buf, ':', &next, end);
1524 inst->name = *cur != '$' ? xstrdup (cur) : "";
1526 for (param = tmpl->params; param; param = param->next)
1528 struct template_arg *arg = xmalloc (sizeof (*arg));
1530 cur = next_field (next, ':', &next, end);
1531 if (next > end)
1532 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1533 arg->val = xstrdup (cur);
1534 arg->next = inst->args;
1535 inst->args = arg;
1538 if (tmpl->instances)
1539 last_inst->next = inst;
1540 else
1541 tmpl->instances = inst;
1542 last_inst = inst;
1543 } while (sep == ',');
1545 buf = remove_leading_whitespaces (end);
1546 if (*buf)
1547 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1548 filename, lineno, buf);
1550 tmpl->next = templates;
1551 templates = tmpl;
1554 static unsigned int
1555 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1556 struct opcode_hash_entry ***opcode_array_p, int lineno)
1558 static unsigned int idx, opcode_array_size;
1559 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1560 struct opcode_hash_entry **hash_slot, **entry;
1561 char *ptr1 = strchr(name, '<'), *ptr2;
1563 if (ptr1 == NULL)
1565 /* Get the slot in hash table. */
1566 hash_slot = (struct opcode_hash_entry **)
1567 htab_find_slot_with_hash (opcode_hash_table, name,
1568 htab_hash_string (name),
1569 INSERT);
1571 if (*hash_slot == NULL)
1573 /* It is the new one. Put it on opcode array. */
1574 if (idx >= opcode_array_size)
1576 /* Grow the opcode array when needed. */
1577 opcode_array_size += 1024;
1578 opcode_array = (struct opcode_hash_entry **)
1579 xrealloc (opcode_array,
1580 sizeof (*opcode_array) * opcode_array_size);
1581 *opcode_array_p = opcode_array;
1584 opcode_array[idx] = (struct opcode_hash_entry *)
1585 xmalloc (sizeof (struct opcode_hash_entry));
1586 opcode_array[idx]->next = NULL;
1587 opcode_array[idx]->name = xstrdup (name);
1588 opcode_array[idx]->opcode = xstrdup (str);
1589 opcode_array[idx]->lineno = lineno;
1590 *hash_slot = opcode_array[idx];
1591 idx++;
1593 else
1595 /* Append it to the existing one. */
1596 entry = hash_slot;
1597 while ((*entry) != NULL)
1598 entry = &(*entry)->next;
1599 *entry = (struct opcode_hash_entry *)
1600 xmalloc (sizeof (struct opcode_hash_entry));
1601 (*entry)->next = NULL;
1602 (*entry)->name = (*hash_slot)->name;
1603 (*entry)->opcode = xstrdup (str);
1604 (*entry)->lineno = lineno;
1607 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1608 fail ("%s: %d: missing '>'\n", filename, lineno);
1609 else
1611 const struct template *tmpl;
1612 const struct template_instance *inst;
1614 *ptr1 = '\0';
1615 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1616 remove_trailing_whitespaces (ptr1);
1618 *ptr2++ = '\0';
1620 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1621 if (!strcmp(ptr1, tmpl->name))
1622 break;
1623 if (!tmpl)
1624 fail ("reference to unknown template '%s'\n", ptr1);
1626 for (inst = tmpl->instances; inst; inst = inst->next)
1628 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1629 char *str2 = xmalloc(2 * strlen(str));
1630 const char *src;
1632 strcpy (name2, name);
1633 strcat (name2, inst->name);
1634 strcat (name2, ptr2);
1636 for (ptr1 = str2, src = str; *src; )
1638 const char *ident = tmpl->name, *end;
1639 const struct template_param *param;
1640 const struct template_arg *arg;
1642 if ((*ptr1 = *src++) != '<')
1644 ++ptr1;
1645 continue;
1647 while (ISSPACE(*src))
1648 ++src;
1649 while (*ident && *src == *ident)
1650 ++src, ++ident;
1651 while (ISSPACE(*src))
1652 ++src;
1653 if (*src != ':' || *ident != '\0')
1655 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1656 ptr1 += ident - tmpl->name;
1657 continue;
1659 while (ISSPACE(*++src))
1662 end = src;
1663 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1664 ++end;
1666 for (param = tmpl->params, arg = inst->args; param;
1667 param = param->next, arg = arg->next)
1669 if (end - src == strlen (param->name)
1670 && !memcmp (src, param->name, end - src))
1672 src = end;
1673 break;
1677 if (param == NULL)
1678 fail ("template '%s' has no parameter '%.*s'\n",
1679 tmpl->name, (int)(end - src), src);
1681 while (ISSPACE(*src))
1682 ++src;
1683 if (*src != '>')
1684 fail ("%s: %d: missing '>'\n", filename, lineno);
1686 memcpy(ptr1, arg->val, strlen(arg->val));
1687 ptr1 += strlen(arg->val);
1688 ++src;
1691 *ptr1 = '\0';
1693 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1694 lineno);
1696 free (str2);
1697 free (name2);
1701 return idx;
1704 static void
1705 process_i386_opcodes (FILE *table)
1707 FILE *fp;
1708 char buf[2048];
1709 unsigned int i, j, nr;
1710 char *str, *p, *last, *name;
1711 htab_t opcode_hash_table;
1712 struct opcode_hash_entry **opcode_array = NULL;
1713 int lineno = 0, marker = 0;
1715 filename = "i386-opc.tbl";
1716 fp = stdin;
1718 i = 0;
1719 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1720 opcode_hash_eq, NULL,
1721 xcalloc, free);
1723 fprintf (table, "\n/* i386 opcode table. */\n\n");
1724 fprintf (table, "static const insn_template i386_optab[] =\n{\n");
1726 /* Put everything on opcode array. */
1727 while (!feof (fp))
1729 if (fgets (buf, sizeof (buf), fp) == NULL)
1730 break;
1732 p = remove_leading_whitespaces (buf);
1734 for ( ; ; )
1736 lineno++;
1738 /* Skip comments. */
1739 str = strstr (p, "//");
1740 if (str != NULL)
1742 str[0] = '\0';
1743 remove_trailing_whitespaces (p);
1744 break;
1747 /* Look for line continuation character. */
1748 remove_trailing_whitespaces (p);
1749 j = strlen (buf);
1750 if (!j || buf[j - 1] != '+')
1751 break;
1752 if (j >= sizeof (buf) - 1)
1753 fail (_("%s: %d: (continued) line too long\n"), filename, lineno);
1755 if (fgets (buf + j - 1, sizeof (buf) - j + 1, fp) == NULL)
1757 fprintf (stderr, "%s: Line continuation on last line?\n",
1758 filename);
1759 break;
1763 switch (p[0])
1765 case '#':
1766 if (!strcmp("### MARKER ###", buf))
1767 marker = 1;
1768 else
1770 /* Since we ignore all included files (we only care about their
1771 #define-s here), we don't need to monitor filenames. The final
1772 line number directive is going to refer to the main source file
1773 again. */
1774 char *end;
1775 unsigned long ln;
1777 p = remove_leading_whitespaces (p + 1);
1778 if (!strncmp(p, "line", 4))
1779 p += 4;
1780 ln = strtoul (p, &end, 10);
1781 if (ln > 1 && ln < INT_MAX
1782 && *remove_leading_whitespaces (end) == '"')
1783 lineno = ln - 1;
1785 /* Ignore comments. */
1786 case '\0':
1787 continue;
1788 break;
1789 case '<':
1790 parse_template (p, lineno);
1791 continue;
1792 default:
1793 if (!marker)
1794 continue;
1795 break;
1798 last = p + strlen (p);
1800 /* Find name. */
1801 name = next_field (p, ',', &str, last);
1803 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1804 lineno);
1807 /* Process opcode array. */
1808 for (j = 0; j < i; j++)
1810 struct opcode_hash_entry *next;
1812 for (next = opcode_array[j]; next; next = next->next)
1814 name = next->name;
1815 str = next->opcode;
1816 lineno = next->lineno;
1817 last = str + strlen (str);
1818 output_i386_opcode (table, name, str, last, lineno);
1822 fclose (fp);
1824 fprintf (table, "};\n");
1826 /* Generate opcode sets array. */
1827 fprintf (table, "\n/* i386 opcode sets table. */\n\n");
1828 fprintf (table, "static const insn_template *const i386_op_sets[] =\n{\n");
1829 fprintf (table, " i386_optab,\n");
1831 for (nr = j = 0; j < i; j++)
1833 struct opcode_hash_entry *next = opcode_array[j];
1837 ++nr;
1838 next = next->next;
1840 while (next);
1841 fprintf (table, " i386_optab + %u,\n", nr);
1844 fprintf (table, "};\n");
1847 static void
1848 process_i386_registers (FILE *table)
1850 FILE *fp;
1851 char buf[2048];
1852 char *str, *p, *last;
1853 char *reg_name, *reg_type, *reg_flags, *reg_num;
1854 char *dw2_32_num, *dw2_64_num;
1855 int lineno = 0;
1857 filename = "i386-reg.tbl";
1858 fp = fopen (filename, "r");
1859 if (fp == NULL)
1860 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1861 xstrerror (errno));
1863 fprintf (table, "\n/* i386 register table. */\n\n");
1864 fprintf (table, "static const reg_entry i386_regtab[] =\n{\n");
1866 while (!feof (fp))
1868 if (fgets (buf, sizeof (buf), fp) == NULL)
1869 break;
1871 lineno++;
1873 p = remove_leading_whitespaces (buf);
1875 /* Skip comments. */
1876 str = strstr (p, "//");
1877 if (str != NULL)
1878 str[0] = '\0';
1880 /* Remove trailing white spaces. */
1881 remove_trailing_whitespaces (p);
1883 switch (p[0])
1885 case '#':
1886 fprintf (table, "%s\n", p);
1887 case '\0':
1888 continue;
1889 break;
1890 default:
1891 break;
1894 last = p + strlen (p);
1896 /* Find reg_name. */
1897 reg_name = next_field (p, ',', &str, last);
1899 /* Find reg_type. */
1900 reg_type = next_field (str, ',', &str, last);
1902 /* Find reg_flags. */
1903 reg_flags = next_field (str, ',', &str, last);
1905 /* Find reg_num. */
1906 reg_num = next_field (str, ',', &str, last);
1908 fprintf (table, " { \"%s\",\n ", reg_name);
1910 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1911 lineno);
1913 /* Find 32-bit Dwarf2 register number. */
1914 dw2_32_num = next_field (str, ',', &str, last);
1916 /* Find 64-bit Dwarf2 register number. */
1917 dw2_64_num = next_field (str, ',', &str, last);
1919 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1920 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1923 fclose (fp);
1925 fprintf (table, "};\n");
1927 fprintf (table, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1930 static void
1931 process_i386_initializers (void)
1933 unsigned int i;
1934 FILE *fp = fopen ("i386-init.h", "w");
1935 char *init;
1937 if (fp == NULL)
1938 fail (_("can't create i386-init.h, errno = %s\n"),
1939 xstrerror (errno));
1941 process_copyright (fp);
1943 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1945 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1946 init = xstrdup (cpu_flag_init[i].init);
1947 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1948 free (init);
1951 fprintf (fp, "\n");
1953 fclose (fp);
1956 /* Program options. */
1957 #define OPTION_SRCDIR 200
1959 struct option long_options[] =
1961 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1962 {"debug", no_argument, NULL, 'd'},
1963 {"version", no_argument, NULL, 'V'},
1964 {"help", no_argument, NULL, 'h'},
1965 {0, no_argument, NULL, 0}
1968 static void
1969 print_version (void)
1971 printf ("%s: version 1.0\n", program_name);
1972 xexit (0);
1975 static void
1976 usage (FILE * stream, int status)
1978 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1979 program_name);
1980 xexit (status);
1984 main (int argc, char **argv)
1986 extern int chdir (char *);
1987 char *srcdir = NULL;
1988 int c;
1989 unsigned int i, cpumax;
1990 FILE *table;
1992 program_name = *argv;
1993 xmalloc_set_program_name (program_name);
1995 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1996 switch (c)
1998 case OPTION_SRCDIR:
1999 srcdir = optarg;
2000 break;
2001 case 'V':
2002 case 'v':
2003 print_version ();
2004 break;
2005 case 'd':
2006 debug = 1;
2007 break;
2008 case 'h':
2009 case '?':
2010 usage (stderr, 0);
2011 default:
2012 case 0:
2013 break;
2016 if (optind != argc)
2017 usage (stdout, 1);
2019 if (srcdir != NULL)
2020 if (chdir (srcdir) != 0)
2021 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2022 srcdir, xstrerror (errno));
2024 /* cpu_flags isn't sorted by position. */
2025 cpumax = 0;
2026 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2027 if (cpu_flags[i].position > cpumax)
2028 cpumax = cpu_flags[i].position;
2030 /* Check the unused bitfield in i386_cpu_flags. */
2031 #ifdef CpuUnused
2032 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2034 if ((cpumax - 1) != CpuMax)
2035 fail (_("CpuMax != %d!\n"), cpumax);
2036 #else
2037 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2039 if (cpumax != CpuMax)
2040 fail (_("CpuMax != %d!\n"), cpumax);
2042 c = CpuNumOfBits - CpuMax - 1;
2043 if (c)
2044 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
2045 #endif
2047 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2049 /* Check the unused bitfield in i386_operand_type. */
2050 #ifdef OTUnused
2051 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2052 == OTNum + 1);
2053 #else
2054 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2055 == OTNum);
2057 c = OTNumOfBits - OTNum;
2058 if (c)
2059 fail (_("%d unused bits in i386_operand_type.\n"), c);
2060 #endif
2062 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2063 compare);
2065 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2066 sizeof (opcode_modifiers [0]), compare);
2068 qsort (operand_types, ARRAY_SIZE (operand_types),
2069 sizeof (operand_types [0]), compare);
2071 table = fopen ("i386-tbl.h", "w");
2072 if (table == NULL)
2073 fail (_("can't create i386-tbl.h, errno = %s\n"),
2074 xstrerror (errno));
2076 process_copyright (table);
2078 process_i386_opcodes (table);
2079 process_i386_registers (table);
2080 process_i386_initializers ();
2082 fclose (table);
2084 exit (0);