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