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