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