or1k: Implement relocation R_OR1K_GOT_AHI16 for gotha()
[deliverable/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 void
1179 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1180 unsigned int prefix, char **opnd, int lineno)
1181 {
1182 char *str, *next, *last;
1183 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
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 val = adjust_broadcast_modifier (opnd);
1203
1204 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1205 lineno);
1206 if (strcasecmp(str, "IsString") == 0)
1207 active_isstring = 1;
1208
1209 if (strcasecmp(str, "W") == 0)
1210 have_w = 1;
1211
1212 if (strcasecmp(str, "No_bSuf") == 0)
1213 bwlq_suf &= ~1;
1214 if (strcasecmp(str, "No_wSuf") == 0)
1215 bwlq_suf &= ~2;
1216 if (strcasecmp(str, "No_lSuf") == 0)
1217 bwlq_suf &= ~4;
1218 if (strcasecmp(str, "No_qSuf") == 0)
1219 bwlq_suf &= ~8;
1220 }
1221 }
1222
1223 if (space)
1224 {
1225 if (!modifiers[OpcodeSpace].value)
1226 modifiers[OpcodeSpace].value = space;
1227 else if (modifiers[OpcodeSpace].value != space)
1228 fail (_("%s:%d: Conflicting opcode space specifications\n"),
1229 filename, lineno);
1230 else
1231 fprintf (stderr,
1232 _("%s:%d: Warning: redundant opcode space specification\n"),
1233 filename, lineno);
1234 }
1235
1236 if (prefix)
1237 {
1238 if (!modifiers[OpcodePrefix].value)
1239 modifiers[OpcodePrefix].value = prefix;
1240 else if (modifiers[OpcodePrefix].value != prefix)
1241 fail (_("%s:%d: Conflicting prefix specifications\n"),
1242 filename, lineno);
1243 else
1244 fprintf (stderr,
1245 _("%s:%d: Warning: redundant prefix specification\n"),
1246 filename, lineno);
1247 }
1248
1249 if (have_w && !bwlq_suf)
1250 fail ("%s: %d: stray W modifier\n", filename, lineno);
1251 if (have_w && !(bwlq_suf & 1))
1252 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1253 filename, lineno);
1254 if (have_w && !(bwlq_suf & ~1))
1255 fprintf (stderr,
1256 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1257 filename, lineno);
1258 }
1259 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1260 }
1261
1262 enum stage {
1263 stage_macros,
1264 stage_opcodes,
1265 stage_registers,
1266 };
1267
1268 static void
1269 output_operand_type (FILE *table, enum operand_class class,
1270 enum operand_instance instance,
1271 const bitfield *types, unsigned int size,
1272 enum stage stage, const char *indent)
1273 {
1274 unsigned int i;
1275
1276 fprintf (table, "{ { %d, %d, ", class, instance);
1277
1278 for (i = 0; i < size - 1; i++)
1279 {
1280 if (((i + 3) % 20) != 0)
1281 fprintf (table, "%d, ", types[i].value);
1282 else
1283 fprintf (table, "%d,", types[i].value);
1284 if (((i + 3) % 20) == 0)
1285 {
1286 /* We need \\ for macro. */
1287 if (stage == stage_macros)
1288 fprintf (table, " \\\n%s", indent);
1289 else
1290 fprintf (table, "\n%s", indent);
1291 }
1292 }
1293
1294 fprintf (table, "%d } }", types[i].value);
1295 }
1296
1297 static void
1298 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1299 const char *indent, int lineno)
1300 {
1301 char *str, *next, *last;
1302 enum operand_class class = ClassNone;
1303 enum operand_instance instance = InstanceNone;
1304 bitfield types [ARRAY_SIZE (operand_types)];
1305
1306 /* Copy the default operand type. */
1307 memcpy (types, operand_types, sizeof (types));
1308
1309 if (strcmp (op, "0"))
1310 {
1311 int baseindex = 0;
1312
1313 last = op + strlen (op);
1314 for (next = op; next && next < last; )
1315 {
1316 str = next_field (next, '|', &next, last);
1317 if (str)
1318 {
1319 unsigned int i;
1320
1321 if (!strncmp(str, "Class=", 6))
1322 {
1323 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1324 if (!strcmp(str + 6, operand_classes[i].name))
1325 {
1326 class = operand_classes[i].value;
1327 str = NULL;
1328 break;
1329 }
1330 }
1331
1332 if (str && !strncmp(str, "Instance=", 9))
1333 {
1334 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1335 if (!strcmp(str + 9, operand_instances[i].name))
1336 {
1337 instance = operand_instances[i].value;
1338 str = NULL;
1339 break;
1340 }
1341 }
1342 }
1343 if (str)
1344 {
1345 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1346 if (strcasecmp(str, "BaseIndex") == 0)
1347 baseindex = 1;
1348 }
1349 }
1350
1351 if (stage == stage_opcodes && baseindex && !active_isstring)
1352 {
1353 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1354 if (!active_cpu_flags.bitfield.cpu64
1355 && !active_cpu_flags.bitfield.cpumpx)
1356 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1357 if (!active_cpu_flags.bitfield.cpu64)
1358 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1359 if (!active_cpu_flags.bitfield.cpuno64)
1360 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1361 }
1362 }
1363 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1364 stage, indent);
1365 }
1366
1367 static void
1368 output_i386_opcode (FILE *table, const char *name, char *str,
1369 char *last, int lineno)
1370 {
1371 unsigned int i, length, prefix = 0, space = 0;
1372 char *base_opcode, *extension_opcode, *end;
1373 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1374 unsigned long long opcode;
1375
1376 /* Find base_opcode. */
1377 base_opcode = next_field (str, ',', &str, last);
1378
1379 /* Find extension_opcode. */
1380 extension_opcode = next_field (str, ',', &str, last);
1381
1382 /* Find cpu_flags. */
1383 cpu_flags = next_field (str, ',', &str, last);
1384
1385 /* Find opcode_modifier. */
1386 opcode_modifier = next_field (str, ',', &str, last);
1387
1388 /* Remove the first {. */
1389 str = remove_leading_whitespaces (str);
1390 if (*str != '{')
1391 abort ();
1392 str = remove_leading_whitespaces (str + 1);
1393 remove_trailing_whitespaces (str);
1394
1395 /* Remove } and trailing white space. */
1396 i = strlen (str);
1397 if (!i || str[i - 1] != '}')
1398 abort ();
1399 str[--i] = '\0';
1400 remove_trailing_whitespaces (str);
1401
1402 if (!*str)
1403 operand_types [i = 0] = NULL;
1404 else
1405 {
1406 last = str + strlen (str);
1407
1408 /* Find operand_types. */
1409 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1410 {
1411 if (str >= last)
1412 {
1413 operand_types [i] = NULL;
1414 break;
1415 }
1416
1417 operand_types [i] = next_field (str, ',', &str, last);
1418 }
1419 }
1420
1421 opcode = strtoull (base_opcode, &end, 0);
1422
1423 /* Determine opcode length. */
1424 for (length = 1; length < 8; ++length)
1425 if (!(opcode >> (8 * length)))
1426 break;
1427
1428 /* Transform prefixes encoded in the opcode into opcode modifier
1429 representation. */
1430 if (length > 1)
1431 {
1432 switch (opcode >> (8 * length - 8))
1433 {
1434 case 0x66: prefix = PREFIX_0X66; break;
1435 case 0xF3: prefix = PREFIX_0XF3; break;
1436 case 0xF2: prefix = PREFIX_0XF2; break;
1437 }
1438
1439 if (prefix)
1440 opcode &= (1ULL << (8 * --length)) - 1;
1441 }
1442
1443 /* Transform opcode space encoded in the opcode into opcode modifier
1444 representation. */
1445 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1446 {
1447 switch ((opcode >> (8 * length - 16)) & 0xff)
1448 {
1449 default: space = SPACE_0F; break;
1450 case 0x38: space = SPACE_0F38; break;
1451 case 0x3A: space = SPACE_0F3A; break;
1452 }
1453
1454 if (space != SPACE_0F && --length == 1)
1455 fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1456 filename, lineno, name);
1457 opcode &= (1ULL << (8 * --length)) - 1;
1458 }
1459
1460 if (length > 2)
1461 fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1462 filename, lineno, name, 2 * length, opcode);
1463
1464 fprintf (table, " { \"%s\", 0x%0*llx%s, %s, %lu,\n",
1465 name, 2 * (int)length, opcode, end, extension_opcode, i);
1466
1467 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
1468 operand_types, lineno);
1469
1470 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1471
1472 fprintf (table, " { ");
1473
1474 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1475 {
1476 if (!operand_types[i])
1477 {
1478 if (i == 0)
1479 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1480 lineno);
1481 break;
1482 }
1483
1484 if (i != 0)
1485 fprintf (table, ",\n ");
1486
1487 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1488 "\t ", lineno);
1489 }
1490 fprintf (table, " } },\n");
1491 }
1492
1493 struct opcode_hash_entry
1494 {
1495 struct opcode_hash_entry *next;
1496 char *name;
1497 char *opcode;
1498 int lineno;
1499 };
1500
1501 /* Calculate the hash value of an opcode hash entry P. */
1502
1503 static hashval_t
1504 opcode_hash_hash (const void *p)
1505 {
1506 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1507 return htab_hash_string (entry->name);
1508 }
1509
1510 /* Compare a string Q against an opcode hash entry P. */
1511
1512 static int
1513 opcode_hash_eq (const void *p, const void *q)
1514 {
1515 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1516 const char *name = (const char *) q;
1517 return strcmp (name, entry->name) == 0;
1518 }
1519
1520 static void
1521 parse_template (char *buf, int lineno)
1522 {
1523 char sep, *end, *name;
1524 struct template *tmpl = xmalloc (sizeof (*tmpl));
1525 struct template_instance *last_inst = NULL;
1526
1527 buf = remove_leading_whitespaces (buf + 1);
1528 end = strchr (buf, ':');
1529 if (end == NULL)
1530 fail ("%s: %d: missing ':'\n", filename, lineno);
1531 *end++ = '\0';
1532 remove_trailing_whitespaces (buf);
1533
1534 if (*buf == '\0')
1535 fail ("%s: %d: missing template identifier\n", filename, lineno);
1536 tmpl->name = xstrdup (buf);
1537
1538 tmpl->params = NULL;
1539 do {
1540 struct template_param *param;
1541
1542 buf = remove_leading_whitespaces (end);
1543 end = strpbrk (buf, ":,");
1544 if (end == NULL)
1545 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1546
1547 sep = *end;
1548 *end++ = '\0';
1549 remove_trailing_whitespaces (buf);
1550
1551 param = xmalloc (sizeof (*param));
1552 param->name = xstrdup (buf);
1553 param->next = tmpl->params;
1554 tmpl->params = param;
1555 } while (sep == ':');
1556
1557 tmpl->instances = NULL;
1558 do {
1559 struct template_instance *inst;
1560 char *cur, *next;
1561 const struct template_param *param;
1562
1563 buf = remove_leading_whitespaces (end);
1564 end = strpbrk (buf, ",>");
1565 if (end == NULL)
1566 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1567
1568 sep = *end;
1569 *end++ = '\0';
1570
1571 inst = xmalloc (sizeof (*inst));
1572 inst->next = NULL;
1573 inst->args = NULL;
1574
1575 cur = next_field (buf, ':', &next, end);
1576 inst->name = *cur != '$' ? xstrdup (cur) : "";
1577
1578 for (param = tmpl->params; param; param = param->next)
1579 {
1580 struct template_arg *arg = xmalloc (sizeof (*arg));
1581
1582 cur = next_field (next, ':', &next, end);
1583 if (next > end)
1584 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1585 arg->val = xstrdup (cur);
1586 arg->next = inst->args;
1587 inst->args = arg;
1588 }
1589
1590 if (tmpl->instances)
1591 last_inst->next = inst;
1592 else
1593 tmpl->instances = inst;
1594 last_inst = inst;
1595 } while (sep == ',');
1596
1597 buf = remove_leading_whitespaces (end);
1598 if (*buf)
1599 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1600 filename, lineno, buf);
1601
1602 tmpl->next = templates;
1603 templates = tmpl;
1604 }
1605
1606 static unsigned int
1607 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1608 struct opcode_hash_entry ***opcode_array_p, int lineno)
1609 {
1610 static unsigned int idx, opcode_array_size;
1611 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1612 struct opcode_hash_entry **hash_slot, **entry;
1613 char *ptr1 = strchr(name, '<'), *ptr2;
1614
1615 if (ptr1 == NULL)
1616 {
1617 /* Get the slot in hash table. */
1618 hash_slot = (struct opcode_hash_entry **)
1619 htab_find_slot_with_hash (opcode_hash_table, name,
1620 htab_hash_string (name),
1621 INSERT);
1622
1623 if (*hash_slot == NULL)
1624 {
1625 /* It is the new one. Put it on opcode array. */
1626 if (idx >= opcode_array_size)
1627 {
1628 /* Grow the opcode array when needed. */
1629 opcode_array_size += 1024;
1630 opcode_array = (struct opcode_hash_entry **)
1631 xrealloc (opcode_array,
1632 sizeof (*opcode_array) * opcode_array_size);
1633 *opcode_array_p = opcode_array;
1634 }
1635
1636 opcode_array[idx] = (struct opcode_hash_entry *)
1637 xmalloc (sizeof (struct opcode_hash_entry));
1638 opcode_array[idx]->next = NULL;
1639 opcode_array[idx]->name = xstrdup (name);
1640 opcode_array[idx]->opcode = xstrdup (str);
1641 opcode_array[idx]->lineno = lineno;
1642 *hash_slot = opcode_array[idx];
1643 idx++;
1644 }
1645 else
1646 {
1647 /* Append it to the existing one. */
1648 entry = hash_slot;
1649 while ((*entry) != NULL)
1650 entry = &(*entry)->next;
1651 *entry = (struct opcode_hash_entry *)
1652 xmalloc (sizeof (struct opcode_hash_entry));
1653 (*entry)->next = NULL;
1654 (*entry)->name = (*hash_slot)->name;
1655 (*entry)->opcode = xstrdup (str);
1656 (*entry)->lineno = lineno;
1657 }
1658 }
1659 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1660 fail ("%s: %d: missing '>'\n", filename, lineno);
1661 else
1662 {
1663 const struct template *tmpl;
1664 const struct template_instance *inst;
1665
1666 *ptr1 = '\0';
1667 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1668 remove_trailing_whitespaces (ptr1);
1669
1670 *ptr2++ = '\0';
1671
1672 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1673 if (!strcmp(ptr1, tmpl->name))
1674 break;
1675 if (!tmpl)
1676 fail ("reference to unknown template '%s'\n", ptr1);
1677
1678 for (inst = tmpl->instances; inst; inst = inst->next)
1679 {
1680 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1681 char *str2 = xmalloc(2 * strlen(str));
1682 const char *src;
1683
1684 strcpy (name2, name);
1685 strcat (name2, inst->name);
1686 strcat (name2, ptr2);
1687
1688 for (ptr1 = str2, src = str; *src; )
1689 {
1690 const char *ident = tmpl->name, *end;
1691 const struct template_param *param;
1692 const struct template_arg *arg;
1693
1694 if ((*ptr1 = *src++) != '<')
1695 {
1696 ++ptr1;
1697 continue;
1698 }
1699 while (ISSPACE(*src))
1700 ++src;
1701 while (*ident && *src == *ident)
1702 ++src, ++ident;
1703 while (ISSPACE(*src))
1704 ++src;
1705 if (*src != ':' || *ident != '\0')
1706 {
1707 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1708 ptr1 += ident - tmpl->name;
1709 continue;
1710 }
1711 while (ISSPACE(*++src))
1712 ;
1713
1714 end = src;
1715 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1716 ++end;
1717
1718 for (param = tmpl->params, arg = inst->args; param;
1719 param = param->next, arg = arg->next)
1720 {
1721 if (end - src == strlen (param->name)
1722 && !memcmp (src, param->name, end - src))
1723 {
1724 src = end;
1725 break;
1726 }
1727 }
1728
1729 if (param == NULL)
1730 fail ("template '%s' has no parameter '%.*s'\n",
1731 tmpl->name, (int)(end - src), src);
1732
1733 while (ISSPACE(*src))
1734 ++src;
1735 if (*src != '>')
1736 fail ("%s: %d: missing '>'\n", filename, lineno);
1737
1738 memcpy(ptr1, arg->val, strlen(arg->val));
1739 ptr1 += strlen(arg->val);
1740 ++src;
1741 }
1742
1743 *ptr1 = '\0';
1744
1745 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1746 lineno);
1747
1748 free (str2);
1749 free (name2);
1750 }
1751 }
1752
1753 return idx;
1754 }
1755
1756 static void
1757 process_i386_opcodes (FILE *table)
1758 {
1759 FILE *fp;
1760 char buf[2048];
1761 unsigned int i, j;
1762 char *str, *p, *last, *name;
1763 htab_t opcode_hash_table;
1764 struct opcode_hash_entry **opcode_array = NULL;
1765 int lineno = 0, marker = 0;
1766
1767 filename = "i386-opc.tbl";
1768 fp = stdin;
1769
1770 i = 0;
1771 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1772 opcode_hash_eq, NULL,
1773 xcalloc, free);
1774
1775 fprintf (table, "\n/* i386 opcode table. */\n\n");
1776 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1777
1778 /* Put everything on opcode array. */
1779 while (!feof (fp))
1780 {
1781 if (fgets (buf, sizeof (buf), fp) == NULL)
1782 break;
1783
1784 lineno++;
1785
1786 p = remove_leading_whitespaces (buf);
1787
1788 /* Skip comments. */
1789 str = strstr (p, "//");
1790 if (str != NULL)
1791 str[0] = '\0';
1792
1793 /* Remove trailing white spaces. */
1794 remove_trailing_whitespaces (p);
1795
1796 switch (p[0])
1797 {
1798 case '#':
1799 if (!strcmp("### MARKER ###", buf))
1800 marker = 1;
1801 else
1802 {
1803 /* Since we ignore all included files (we only care about their
1804 #define-s here), we don't need to monitor filenames. The final
1805 line number directive is going to refer to the main source file
1806 again. */
1807 char *end;
1808 unsigned long ln;
1809
1810 p = remove_leading_whitespaces (p + 1);
1811 if (!strncmp(p, "line", 4))
1812 p += 4;
1813 ln = strtoul (p, &end, 10);
1814 if (ln > 1 && ln < INT_MAX
1815 && *remove_leading_whitespaces (end) == '"')
1816 lineno = ln - 1;
1817 }
1818 /* Ignore comments. */
1819 case '\0':
1820 continue;
1821 break;
1822 case '<':
1823 parse_template (p, lineno);
1824 continue;
1825 default:
1826 if (!marker)
1827 continue;
1828 break;
1829 }
1830
1831 last = p + strlen (p);
1832
1833 /* Find name. */
1834 name = next_field (p, ',', &str, last);
1835
1836 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1837 lineno);
1838 }
1839
1840 /* Process opcode array. */
1841 for (j = 0; j < i; j++)
1842 {
1843 struct opcode_hash_entry *next;
1844
1845 for (next = opcode_array[j]; next; next = next->next)
1846 {
1847 name = next->name;
1848 str = next->opcode;
1849 lineno = next->lineno;
1850 last = str + strlen (str);
1851 output_i386_opcode (table, name, str, last, lineno);
1852 }
1853 }
1854
1855 fclose (fp);
1856
1857 fprintf (table, " { NULL, 0, 0, 0,\n");
1858
1859 process_i386_opcode_modifier (table, "0", 0, 0, NULL, -1);
1860
1861 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1862
1863 fprintf (table, " { ");
1864 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1865 fprintf (table, " } }\n");
1866
1867 fprintf (table, "};\n");
1868 }
1869
1870 static void
1871 process_i386_registers (FILE *table)
1872 {
1873 FILE *fp;
1874 char buf[2048];
1875 char *str, *p, *last;
1876 char *reg_name, *reg_type, *reg_flags, *reg_num;
1877 char *dw2_32_num, *dw2_64_num;
1878 int lineno = 0;
1879
1880 filename = "i386-reg.tbl";
1881 fp = fopen (filename, "r");
1882 if (fp == NULL)
1883 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1884 xstrerror (errno));
1885
1886 fprintf (table, "\n/* i386 register table. */\n\n");
1887 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1888
1889 while (!feof (fp))
1890 {
1891 if (fgets (buf, sizeof (buf), fp) == NULL)
1892 break;
1893
1894 lineno++;
1895
1896 p = remove_leading_whitespaces (buf);
1897
1898 /* Skip comments. */
1899 str = strstr (p, "//");
1900 if (str != NULL)
1901 str[0] = '\0';
1902
1903 /* Remove trailing white spaces. */
1904 remove_trailing_whitespaces (p);
1905
1906 switch (p[0])
1907 {
1908 case '#':
1909 fprintf (table, "%s\n", p);
1910 case '\0':
1911 continue;
1912 break;
1913 default:
1914 break;
1915 }
1916
1917 last = p + strlen (p);
1918
1919 /* Find reg_name. */
1920 reg_name = next_field (p, ',', &str, last);
1921
1922 /* Find reg_type. */
1923 reg_type = next_field (str, ',', &str, last);
1924
1925 /* Find reg_flags. */
1926 reg_flags = next_field (str, ',', &str, last);
1927
1928 /* Find reg_num. */
1929 reg_num = next_field (str, ',', &str, last);
1930
1931 fprintf (table, " { \"%s\",\n ", reg_name);
1932
1933 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1934 lineno);
1935
1936 /* Find 32-bit Dwarf2 register number. */
1937 dw2_32_num = next_field (str, ',', &str, last);
1938
1939 /* Find 64-bit Dwarf2 register number. */
1940 dw2_64_num = next_field (str, ',', &str, last);
1941
1942 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1943 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1944 }
1945
1946 fclose (fp);
1947
1948 fprintf (table, "};\n");
1949
1950 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1951 }
1952
1953 static void
1954 process_i386_initializers (void)
1955 {
1956 unsigned int i;
1957 FILE *fp = fopen ("i386-init.h", "w");
1958 char *init;
1959
1960 if (fp == NULL)
1961 fail (_("can't create i386-init.h, errno = %s\n"),
1962 xstrerror (errno));
1963
1964 process_copyright (fp);
1965
1966 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1967 {
1968 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1969 init = xstrdup (cpu_flag_init[i].init);
1970 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1971 free (init);
1972 }
1973
1974 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1975 {
1976 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1977 init = xstrdup (operand_type_init[i].init);
1978 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1979 free (init);
1980 }
1981 fprintf (fp, "\n");
1982
1983 fclose (fp);
1984 }
1985
1986 /* Program options. */
1987 #define OPTION_SRCDIR 200
1988
1989 struct option long_options[] =
1990 {
1991 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1992 {"debug", no_argument, NULL, 'd'},
1993 {"version", no_argument, NULL, 'V'},
1994 {"help", no_argument, NULL, 'h'},
1995 {0, no_argument, NULL, 0}
1996 };
1997
1998 static void
1999 print_version (void)
2000 {
2001 printf ("%s: version 1.0\n", program_name);
2002 xexit (0);
2003 }
2004
2005 static void
2006 usage (FILE * stream, int status)
2007 {
2008 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2009 program_name);
2010 xexit (status);
2011 }
2012
2013 int
2014 main (int argc, char **argv)
2015 {
2016 extern int chdir (char *);
2017 char *srcdir = NULL;
2018 int c;
2019 unsigned int i, cpumax;
2020 FILE *table;
2021
2022 program_name = *argv;
2023 xmalloc_set_program_name (program_name);
2024
2025 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2026 switch (c)
2027 {
2028 case OPTION_SRCDIR:
2029 srcdir = optarg;
2030 break;
2031 case 'V':
2032 case 'v':
2033 print_version ();
2034 break;
2035 case 'd':
2036 debug = 1;
2037 break;
2038 case 'h':
2039 case '?':
2040 usage (stderr, 0);
2041 default:
2042 case 0:
2043 break;
2044 }
2045
2046 if (optind != argc)
2047 usage (stdout, 1);
2048
2049 if (srcdir != NULL)
2050 if (chdir (srcdir) != 0)
2051 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2052 srcdir, xstrerror (errno));
2053
2054 /* cpu_flags isn't sorted by position. */
2055 cpumax = 0;
2056 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2057 if (cpu_flags[i].position > cpumax)
2058 cpumax = cpu_flags[i].position;
2059
2060 /* Check the unused bitfield in i386_cpu_flags. */
2061 #ifdef CpuUnused
2062 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2063
2064 if ((cpumax - 1) != CpuMax)
2065 fail (_("CpuMax != %d!\n"), cpumax);
2066 #else
2067 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2068
2069 if (cpumax != CpuMax)
2070 fail (_("CpuMax != %d!\n"), cpumax);
2071
2072 c = CpuNumOfBits - CpuMax - 1;
2073 if (c)
2074 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
2075 #endif
2076
2077 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2078
2079 /* Check the unused bitfield in i386_operand_type. */
2080 #ifdef OTUnused
2081 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2082 == OTNum + 1);
2083 #else
2084 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2085 == OTNum);
2086
2087 c = OTNumOfBits - OTNum;
2088 if (c)
2089 fail (_("%d unused bits in i386_operand_type.\n"), c);
2090 #endif
2091
2092 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2093 compare);
2094
2095 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2096 sizeof (opcode_modifiers [0]), compare);
2097
2098 qsort (operand_types, ARRAY_SIZE (operand_types),
2099 sizeof (operand_types [0]), compare);
2100
2101 table = fopen ("i386-tbl.h", "w");
2102 if (table == NULL)
2103 fail (_("can't create i386-tbl.h, errno = %s\n"),
2104 xstrerror (errno));
2105
2106 process_copyright (table);
2107
2108 process_i386_opcodes (table);
2109 process_i386_registers (table);
2110 process_i386_initializers ();
2111
2112 fclose (table);
2113
2114 exit (0);
2115 }
This page took 0.072294 seconds and 4 git commands to generate.