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