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