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