0c5a392a2ae76f55265b294bf981c5918e703a9a
[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 if (strcmp (f, "CpuFP") == 0)
900 {
901 set_bitfield("Cpu387", array, value, size, lineno);
902 set_bitfield("Cpu287", array, value, size, lineno);
903 f = "Cpu8087";
904 }
905 else if (strcmp (f, "Mmword") == 0)
906 f= "Qword";
907 else if (strcmp (f, "Oword") == 0)
908 f= "Xmmword";
909
910 for (i = 0; i < size; i++)
911 if (strcasecmp (array[i].name, f) == 0)
912 {
913 array[i].value = value;
914 return;
915 }
916
917 if (value)
918 {
919 const char *v = strchr (f, '=');
920
921 if (v)
922 {
923 size_t n = v - f;
924 char *end;
925
926 for (i = 0; i < size; i++)
927 if (strncasecmp (array[i].name, f, n) == 0)
928 {
929 value = strtol (v + 1, &end, 0);
930 if (*end == '\0')
931 {
932 array[i].value = value;
933 return;
934 }
935 break;
936 }
937 }
938 }
939
940 /* Handle CPU_XXX_FLAGS. */
941 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
942 return;
943
944 if (lineno != -1)
945 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
946 else
947 fail (_("unknown bitfield: %s\n"), f);
948 }
949
950 static void
951 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
952 int macro, const char *comma, const char *indent)
953 {
954 unsigned int i;
955
956 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
957
958 fprintf (table, "%s{ { ", indent);
959
960 for (i = 0; i < size - 1; i++)
961 {
962 if (((i + 1) % 20) != 0)
963 fprintf (table, "%d, ", flags[i].value);
964 else
965 fprintf (table, "%d,", flags[i].value);
966 if (((i + 1) % 20) == 0)
967 {
968 /* We need \\ for macro. */
969 if (macro)
970 fprintf (table, " \\\n %s", indent);
971 else
972 fprintf (table, "\n %s", indent);
973 }
974 if (flags[i].value)
975 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
976 }
977
978 fprintf (table, "%d } }%s\n", flags[i].value, comma);
979 }
980
981 static void
982 process_i386_cpu_flag (FILE *table, char *flag, int macro,
983 const char *comma, const char *indent,
984 int lineno)
985 {
986 char *str, *next, *last;
987 unsigned int i;
988 bitfield flags [ARRAY_SIZE (cpu_flags)];
989
990 /* Copy the default cpu flags. */
991 memcpy (flags, cpu_flags, sizeof (cpu_flags));
992
993 if (strcasecmp (flag, "unknown") == 0)
994 {
995 /* We turn on everything except for cpu64 in case of
996 CPU_UNKNOWN_FLAGS. */
997 for (i = 0; i < ARRAY_SIZE (flags); i++)
998 if (flags[i].position != Cpu64)
999 flags[i].value = 1;
1000 }
1001 else if (flag[0] == '~')
1002 {
1003 last = flag + strlen (flag);
1004
1005 if (flag[1] == '(')
1006 {
1007 last -= 1;
1008 next = flag + 2;
1009 if (*last != ')')
1010 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
1011 lineno, flag);
1012 *last = '\0';
1013 }
1014 else
1015 next = flag + 1;
1016
1017 /* First we turn on everything except for cpu64. */
1018 for (i = 0; i < ARRAY_SIZE (flags); i++)
1019 if (flags[i].position != Cpu64)
1020 flags[i].value = 1;
1021
1022 /* Turn off selective bits. */
1023 for (; next && next < last; )
1024 {
1025 str = next_field (next, '|', &next, last);
1026 if (str)
1027 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
1028 }
1029 }
1030 else if (strcmp (flag, "0"))
1031 {
1032 /* Turn on selective bits. */
1033 last = flag + strlen (flag);
1034 for (next = flag; next && next < last; )
1035 {
1036 str = next_field (next, '|', &next, last);
1037 if (str)
1038 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1039 }
1040 }
1041
1042 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1043 comma, indent);
1044 }
1045
1046 static void
1047 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1048 {
1049 unsigned int i;
1050
1051 fprintf (table, " { ");
1052
1053 for (i = 0; i < size - 1; i++)
1054 {
1055 if (((i + 1) % 20) != 0)
1056 fprintf (table, "%d, ", modifier[i].value);
1057 else
1058 fprintf (table, "%d,", modifier[i].value);
1059 if (((i + 1) % 20) == 0)
1060 fprintf (table, "\n ");
1061 }
1062
1063 fprintf (table, "%d },\n", modifier[i].value);
1064 }
1065
1066 static int
1067 adjust_broadcast_modifier (char **opnd)
1068 {
1069 char *str, *next, *last, *op;
1070 int bcst_type = INT_MAX;
1071
1072 /* Skip the immediate operand. */
1073 op = opnd[0];
1074 if (strcasecmp(op, "Imm8") == 0)
1075 op = opnd[1];
1076
1077 op = xstrdup (op);
1078 last = op + strlen (op);
1079 for (next = op; next && next < last; )
1080 {
1081 str = next_field (next, '|', &next, last);
1082 if (str)
1083 {
1084 if (strcasecmp(str, "Byte") == 0)
1085 {
1086 /* The smalest broadcast type, no need to check
1087 further. */
1088 bcst_type = BYTE_BROADCAST;
1089 break;
1090 }
1091 else if (strcasecmp(str, "Word") == 0)
1092 {
1093 if (bcst_type > WORD_BROADCAST)
1094 bcst_type = WORD_BROADCAST;
1095 }
1096 else if (strcasecmp(str, "Dword") == 0)
1097 {
1098 if (bcst_type > DWORD_BROADCAST)
1099 bcst_type = DWORD_BROADCAST;
1100 }
1101 else if (strcasecmp(str, "Qword") == 0)
1102 {
1103 if (bcst_type > QWORD_BROADCAST)
1104 bcst_type = QWORD_BROADCAST;
1105 }
1106 }
1107 }
1108 free (op);
1109
1110 if (bcst_type == INT_MAX)
1111 fail (_("unknown broadcast operand: %s\n"), op);
1112
1113 return bcst_type;
1114 }
1115
1116 static void
1117 process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
1118 {
1119 char *str, *next, *last;
1120 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1121
1122 active_isstring = 0;
1123
1124 /* Copy the default opcode modifier. */
1125 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1126
1127 if (strcmp (mod, "0"))
1128 {
1129 unsigned int have_w = 0, bwlq_suf = 0xf;
1130
1131 last = mod + strlen (mod);
1132 for (next = mod; next && next < last; )
1133 {
1134 str = next_field (next, '|', &next, last);
1135 if (str)
1136 {
1137 int val = 1;
1138 if (strcasecmp(str, "Broadcast") == 0)
1139 val = adjust_broadcast_modifier (opnd);
1140 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1141 lineno);
1142 if (strcasecmp(str, "IsString") == 0)
1143 active_isstring = 1;
1144
1145 if (strcasecmp(str, "W") == 0)
1146 have_w = 1;
1147
1148 if (strcasecmp(str, "No_bSuf") == 0)
1149 bwlq_suf &= ~1;
1150 if (strcasecmp(str, "No_wSuf") == 0)
1151 bwlq_suf &= ~2;
1152 if (strcasecmp(str, "No_lSuf") == 0)
1153 bwlq_suf &= ~4;
1154 if (strcasecmp(str, "No_qSuf") == 0)
1155 bwlq_suf &= ~8;
1156 }
1157 }
1158
1159 if (have_w && !bwlq_suf)
1160 fail ("%s: %d: stray W modifier\n", filename, lineno);
1161 if (have_w && !(bwlq_suf & 1))
1162 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1163 filename, lineno);
1164 if (have_w && !(bwlq_suf & ~1))
1165 fprintf (stderr,
1166 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1167 filename, lineno);
1168 }
1169 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1170 }
1171
1172 enum stage {
1173 stage_macros,
1174 stage_opcodes,
1175 stage_registers,
1176 };
1177
1178 static void
1179 output_operand_type (FILE *table, enum operand_class class,
1180 enum operand_instance instance,
1181 const bitfield *types, unsigned int size,
1182 enum stage stage, const char *indent)
1183 {
1184 unsigned int i;
1185
1186 fprintf (table, "{ { %d, %d, ", class, instance);
1187
1188 for (i = 0; i < size - 1; i++)
1189 {
1190 if (((i + 3) % 20) != 0)
1191 fprintf (table, "%d, ", types[i].value);
1192 else
1193 fprintf (table, "%d,", types[i].value);
1194 if (((i + 3) % 20) == 0)
1195 {
1196 /* We need \\ for macro. */
1197 if (stage == stage_macros)
1198 fprintf (table, " \\\n%s", indent);
1199 else
1200 fprintf (table, "\n%s", indent);
1201 }
1202 }
1203
1204 fprintf (table, "%d } }", types[i].value);
1205 }
1206
1207 static void
1208 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1209 const char *indent, int lineno)
1210 {
1211 char *str, *next, *last;
1212 enum operand_class class = ClassNone;
1213 enum operand_instance instance = InstanceNone;
1214 bitfield types [ARRAY_SIZE (operand_types)];
1215
1216 /* Copy the default operand type. */
1217 memcpy (types, operand_types, sizeof (types));
1218
1219 if (strcmp (op, "0"))
1220 {
1221 int baseindex = 0;
1222
1223 last = op + strlen (op);
1224 for (next = op; next && next < last; )
1225 {
1226 str = next_field (next, '|', &next, last);
1227 if (str)
1228 {
1229 unsigned int i;
1230
1231 if (!strncmp(str, "Class=", 6))
1232 {
1233 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1234 if (!strcmp(str + 6, operand_classes[i].name))
1235 {
1236 class = operand_classes[i].value;
1237 str = NULL;
1238 break;
1239 }
1240 }
1241
1242 if (str && !strncmp(str, "Instance=", 9))
1243 {
1244 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1245 if (!strcmp(str + 9, operand_instances[i].name))
1246 {
1247 instance = operand_instances[i].value;
1248 str = NULL;
1249 break;
1250 }
1251 }
1252 }
1253 if (str)
1254 {
1255 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1256 if (strcasecmp(str, "BaseIndex") == 0)
1257 baseindex = 1;
1258 }
1259 }
1260
1261 if (stage == stage_opcodes && baseindex && !active_isstring)
1262 {
1263 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1264 if (!active_cpu_flags.bitfield.cpu64
1265 && !active_cpu_flags.bitfield.cpumpx)
1266 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1267 if (!active_cpu_flags.bitfield.cpu64)
1268 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1269 if (!active_cpu_flags.bitfield.cpuno64)
1270 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1271 }
1272 }
1273 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1274 stage, indent);
1275 }
1276
1277 static void
1278 output_i386_opcode (FILE *table, const char *name, char *str,
1279 char *last, int lineno)
1280 {
1281 unsigned int i;
1282 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1283 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1284
1285 /* Find number of operands. */
1286 operands = next_field (str, ',', &str, last);
1287
1288 /* Find base_opcode. */
1289 base_opcode = next_field (str, ',', &str, last);
1290
1291 /* Find extension_opcode. */
1292 extension_opcode = next_field (str, ',', &str, last);
1293
1294 /* Find opcode_length. */
1295 opcode_length = next_field (str, ',', &str, last);
1296
1297 /* Find cpu_flags. */
1298 cpu_flags = next_field (str, ',', &str, last);
1299
1300 /* Find opcode_modifier. */
1301 opcode_modifier = next_field (str, ',', &str, last);
1302
1303 /* Remove the first {. */
1304 str = remove_leading_whitespaces (str);
1305 if (*str != '{')
1306 abort ();
1307 str = remove_leading_whitespaces (str + 1);
1308
1309 i = strlen (str);
1310
1311 /* There are at least "X}". */
1312 if (i < 2)
1313 abort ();
1314
1315 /* Remove trailing white spaces and }. */
1316 do
1317 {
1318 i--;
1319 if (ISSPACE (str[i]) || str[i] == '}')
1320 str[i] = '\0';
1321 else
1322 break;
1323 }
1324 while (i != 0);
1325
1326 last = str + i;
1327
1328 /* Find operand_types. */
1329 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1330 {
1331 if (str >= last)
1332 {
1333 operand_types [i] = NULL;
1334 break;
1335 }
1336
1337 operand_types [i] = next_field (str, ',', &str, last);
1338 if (*operand_types[i] == '0')
1339 {
1340 if (i != 0)
1341 operand_types[i] = NULL;
1342 break;
1343 }
1344 }
1345
1346 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1347 name, base_opcode, extension_opcode, opcode_length, operands);
1348
1349 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1350
1351 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
1352
1353 fprintf (table, " { ");
1354
1355 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1356 {
1357 if (operand_types[i] == NULL || *operand_types[i] == '0')
1358 {
1359 if (i == 0)
1360 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1361 lineno);
1362 break;
1363 }
1364
1365 if (i != 0)
1366 fprintf (table, ",\n ");
1367
1368 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1369 "\t ", lineno);
1370 }
1371 fprintf (table, " } },\n");
1372 }
1373
1374 struct opcode_hash_entry
1375 {
1376 struct opcode_hash_entry *next;
1377 char *name;
1378 char *opcode;
1379 int lineno;
1380 };
1381
1382 /* Calculate the hash value of an opcode hash entry P. */
1383
1384 static hashval_t
1385 opcode_hash_hash (const void *p)
1386 {
1387 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1388 return htab_hash_string (entry->name);
1389 }
1390
1391 /* Compare a string Q against an opcode hash entry P. */
1392
1393 static int
1394 opcode_hash_eq (const void *p, const void *q)
1395 {
1396 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1397 const char *name = (const char *) q;
1398 return strcmp (name, entry->name) == 0;
1399 }
1400
1401 static void
1402 parse_template (char *buf, int lineno)
1403 {
1404 char sep, *end, *name;
1405 struct template *tmpl = xmalloc (sizeof (*tmpl));
1406 struct template_instance *last_inst = NULL;
1407
1408 buf = remove_leading_whitespaces (buf + 1);
1409 end = strchr (buf, ':');
1410 if (end == NULL)
1411 fail ("%s: %d: missing ':'\n", filename, lineno);
1412 *end++ = '\0';
1413 remove_trailing_whitespaces (buf);
1414
1415 if (*buf == '\0')
1416 fail ("%s: %d: missing template identifier\n", filename, lineno);
1417 tmpl->name = xstrdup (buf);
1418
1419 tmpl->params = NULL;
1420 do {
1421 struct template_param *param;
1422
1423 buf = remove_leading_whitespaces (end);
1424 end = strpbrk (buf, ":,");
1425 if (end == NULL)
1426 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1427
1428 sep = *end;
1429 *end++ = '\0';
1430 remove_trailing_whitespaces (buf);
1431
1432 param = xmalloc (sizeof (*param));
1433 param->name = xstrdup (buf);
1434 param->next = tmpl->params;
1435 tmpl->params = param;
1436 } while (sep == ':');
1437
1438 tmpl->instances = NULL;
1439 do {
1440 struct template_instance *inst;
1441 char *cur, *next;
1442 const struct template_param *param;
1443
1444 buf = remove_leading_whitespaces (end);
1445 end = strpbrk (buf, ",>");
1446 if (end == NULL)
1447 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1448
1449 sep = *end;
1450 *end++ = '\0';
1451
1452 inst = xmalloc (sizeof (*inst));
1453
1454 cur = next_field (buf, ':', &next, end);
1455 inst->name = xstrdup (cur);
1456
1457 for (param = tmpl->params; param; param = param->next)
1458 {
1459 struct template_arg *arg = xmalloc (sizeof (*arg));
1460
1461 cur = next_field (next, ':', &next, end);
1462 if (next > end)
1463 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1464 arg->val = xstrdup (cur);
1465 arg->next = inst->args;
1466 inst->args = arg;
1467 }
1468
1469 if (tmpl->instances)
1470 last_inst->next = inst;
1471 else
1472 tmpl->instances = inst;
1473 last_inst = inst;
1474 } while (sep == ',');
1475
1476 buf = remove_leading_whitespaces (end);
1477 if (*buf)
1478 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1479 filename, lineno, buf);
1480
1481 tmpl->next = templates;
1482 templates = tmpl;
1483 }
1484
1485 static unsigned int
1486 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1487 struct opcode_hash_entry ***opcode_array_p, int lineno)
1488 {
1489 static unsigned int idx, opcode_array_size;
1490 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1491 struct opcode_hash_entry **hash_slot, **entry;
1492 char *ptr1 = strchr(name, '<'), *ptr2;
1493
1494 if (ptr1 == NULL)
1495 {
1496 /* Get the slot in hash table. */
1497 hash_slot = (struct opcode_hash_entry **)
1498 htab_find_slot_with_hash (opcode_hash_table, name,
1499 htab_hash_string (name),
1500 INSERT);
1501
1502 if (*hash_slot == NULL)
1503 {
1504 /* It is the new one. Put it on opcode array. */
1505 if (idx >= opcode_array_size)
1506 {
1507 /* Grow the opcode array when needed. */
1508 opcode_array_size += 1024;
1509 opcode_array = (struct opcode_hash_entry **)
1510 xrealloc (opcode_array,
1511 sizeof (*opcode_array) * opcode_array_size);
1512 *opcode_array_p = opcode_array;
1513 }
1514
1515 opcode_array[idx] = (struct opcode_hash_entry *)
1516 xmalloc (sizeof (struct opcode_hash_entry));
1517 opcode_array[idx]->next = NULL;
1518 opcode_array[idx]->name = xstrdup (name);
1519 opcode_array[idx]->opcode = xstrdup (str);
1520 opcode_array[idx]->lineno = lineno;
1521 *hash_slot = opcode_array[idx];
1522 idx++;
1523 }
1524 else
1525 {
1526 /* Append it to the existing one. */
1527 entry = hash_slot;
1528 while ((*entry) != NULL)
1529 entry = &(*entry)->next;
1530 *entry = (struct opcode_hash_entry *)
1531 xmalloc (sizeof (struct opcode_hash_entry));
1532 (*entry)->next = NULL;
1533 (*entry)->name = (*hash_slot)->name;
1534 (*entry)->opcode = xstrdup (str);
1535 (*entry)->lineno = lineno;
1536 }
1537 }
1538 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1539 fail ("%s: %d: missing '>'\n", filename, lineno);
1540 else
1541 {
1542 const struct template *tmpl;
1543 const struct template_instance *inst;
1544
1545 *ptr1 = '\0';
1546 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1547 remove_trailing_whitespaces (ptr1);
1548
1549 *ptr2++ = '\0';
1550
1551 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1552 if (!strcmp(ptr1, tmpl->name))
1553 break;
1554 if (!tmpl)
1555 fail ("reference to unknown template '%s'\n", ptr1);
1556
1557 for (inst = tmpl->instances; inst; inst = inst->next)
1558 {
1559 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1560 char *str2 = xmalloc(2 * strlen(str));
1561 const char *src;
1562
1563 strcpy (name2, name);
1564 strcat (name2, inst->name);
1565 strcat (name2, ptr2);
1566
1567 for (ptr1 = str2, src = str; *src; )
1568 {
1569 const char *ident = tmpl->name, *end;
1570 const struct template_param *param;
1571 const struct template_arg *arg;
1572
1573 if ((*ptr1 = *src++) != '<')
1574 {
1575 ++ptr1;
1576 continue;
1577 }
1578 while (ISSPACE(*src))
1579 ++src;
1580 while (*ident && *src == *ident)
1581 ++src, ++ident;
1582 while (ISSPACE(*src))
1583 ++src;
1584 if (*src != ':' || *ident != '\0')
1585 {
1586 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1587 ptr1 += ident - tmpl->name;
1588 continue;
1589 }
1590 while (ISSPACE(*++src))
1591 ;
1592
1593 end = src;
1594 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1595 ++end;
1596
1597 for (param = tmpl->params, arg = inst->args; param;
1598 param = param->next, arg = arg->next)
1599 {
1600 if (end - src == strlen (param->name)
1601 && !memcmp (src, param->name, end - src))
1602 {
1603 src = end;
1604 break;
1605 }
1606 }
1607
1608 if (param == NULL)
1609 fail ("template '%s' has no parameter '%.*s'\n",
1610 tmpl->name, (int)(end - src), src);
1611
1612 while (ISSPACE(*src))
1613 ++src;
1614 if (*src != '>')
1615 fail ("%s: %d: missing '>'\n", filename, lineno);
1616
1617 memcpy(ptr1, arg->val, strlen(arg->val));
1618 ptr1 += strlen(arg->val);
1619 ++src;
1620 }
1621
1622 *ptr1 = '\0';
1623
1624 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1625 lineno);
1626
1627 free (str2);
1628 free (name2);
1629 }
1630 }
1631
1632 return idx;
1633 }
1634
1635 static void
1636 process_i386_opcodes (FILE *table)
1637 {
1638 FILE *fp;
1639 char buf[2048];
1640 unsigned int i, j;
1641 char *str, *p, *last, *name;
1642 htab_t opcode_hash_table;
1643 struct opcode_hash_entry **opcode_array = NULL;
1644 int lineno = 0, marker = 0;
1645
1646 filename = "i386-opc.tbl";
1647 fp = stdin;
1648
1649 i = 0;
1650 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1651 opcode_hash_eq, NULL,
1652 xcalloc, free);
1653
1654 fprintf (table, "\n/* i386 opcode table. */\n\n");
1655 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1656
1657 /* Put everything on opcode array. */
1658 while (!feof (fp))
1659 {
1660 if (fgets (buf, sizeof (buf), fp) == NULL)
1661 break;
1662
1663 lineno++;
1664
1665 p = remove_leading_whitespaces (buf);
1666
1667 /* Skip comments. */
1668 str = strstr (p, "//");
1669 if (str != NULL)
1670 str[0] = '\0';
1671
1672 /* Remove trailing white spaces. */
1673 remove_trailing_whitespaces (p);
1674
1675 switch (p[0])
1676 {
1677 case '#':
1678 if (!strcmp("### MARKER ###", buf))
1679 marker = 1;
1680 else
1681 {
1682 /* Since we ignore all included files (we only care about their
1683 #define-s here), we don't need to monitor filenames. The final
1684 line number directive is going to refer to the main source file
1685 again. */
1686 char *end;
1687 unsigned long ln;
1688
1689 p = remove_leading_whitespaces (p + 1);
1690 if (!strncmp(p, "line", 4))
1691 p += 4;
1692 ln = strtoul (p, &end, 10);
1693 if (ln > 1 && ln < INT_MAX
1694 && *remove_leading_whitespaces (end) == '"')
1695 lineno = ln - 1;
1696 }
1697 /* Ignore comments. */
1698 case '\0':
1699 continue;
1700 break;
1701 case '<':
1702 parse_template (p, lineno);
1703 continue;
1704 default:
1705 if (!marker)
1706 continue;
1707 break;
1708 }
1709
1710 last = p + strlen (p);
1711
1712 /* Find name. */
1713 name = next_field (p, ',', &str, last);
1714
1715 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1716 lineno);
1717 }
1718
1719 /* Process opcode array. */
1720 for (j = 0; j < i; j++)
1721 {
1722 struct opcode_hash_entry *next;
1723
1724 for (next = opcode_array[j]; next; next = next->next)
1725 {
1726 name = next->name;
1727 str = next->opcode;
1728 lineno = next->lineno;
1729 last = str + strlen (str);
1730 output_i386_opcode (table, name, str, last, lineno);
1731 }
1732 }
1733
1734 fclose (fp);
1735
1736 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1737
1738 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1739
1740 process_i386_opcode_modifier (table, "0", NULL, -1);
1741
1742 fprintf (table, " { ");
1743 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1744 fprintf (table, " } }\n");
1745
1746 fprintf (table, "};\n");
1747 }
1748
1749 static void
1750 process_i386_registers (FILE *table)
1751 {
1752 FILE *fp;
1753 char buf[2048];
1754 char *str, *p, *last;
1755 char *reg_name, *reg_type, *reg_flags, *reg_num;
1756 char *dw2_32_num, *dw2_64_num;
1757 int lineno = 0;
1758
1759 filename = "i386-reg.tbl";
1760 fp = fopen (filename, "r");
1761 if (fp == NULL)
1762 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1763 xstrerror (errno));
1764
1765 fprintf (table, "\n/* i386 register table. */\n\n");
1766 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1767
1768 while (!feof (fp))
1769 {
1770 if (fgets (buf, sizeof (buf), fp) == NULL)
1771 break;
1772
1773 lineno++;
1774
1775 p = remove_leading_whitespaces (buf);
1776
1777 /* Skip comments. */
1778 str = strstr (p, "//");
1779 if (str != NULL)
1780 str[0] = '\0';
1781
1782 /* Remove trailing white spaces. */
1783 remove_trailing_whitespaces (p);
1784
1785 switch (p[0])
1786 {
1787 case '#':
1788 fprintf (table, "%s\n", p);
1789 case '\0':
1790 continue;
1791 break;
1792 default:
1793 break;
1794 }
1795
1796 last = p + strlen (p);
1797
1798 /* Find reg_name. */
1799 reg_name = next_field (p, ',', &str, last);
1800
1801 /* Find reg_type. */
1802 reg_type = next_field (str, ',', &str, last);
1803
1804 /* Find reg_flags. */
1805 reg_flags = next_field (str, ',', &str, last);
1806
1807 /* Find reg_num. */
1808 reg_num = next_field (str, ',', &str, last);
1809
1810 fprintf (table, " { \"%s\",\n ", reg_name);
1811
1812 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1813 lineno);
1814
1815 /* Find 32-bit Dwarf2 register number. */
1816 dw2_32_num = next_field (str, ',', &str, last);
1817
1818 /* Find 64-bit Dwarf2 register number. */
1819 dw2_64_num = next_field (str, ',', &str, last);
1820
1821 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1822 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1823 }
1824
1825 fclose (fp);
1826
1827 fprintf (table, "};\n");
1828
1829 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1830 }
1831
1832 static void
1833 process_i386_initializers (void)
1834 {
1835 unsigned int i;
1836 FILE *fp = fopen ("i386-init.h", "w");
1837 char *init;
1838
1839 if (fp == NULL)
1840 fail (_("can't create i386-init.h, errno = %s\n"),
1841 xstrerror (errno));
1842
1843 process_copyright (fp);
1844
1845 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1846 {
1847 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1848 init = xstrdup (cpu_flag_init[i].init);
1849 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1850 free (init);
1851 }
1852
1853 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1854 {
1855 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1856 init = xstrdup (operand_type_init[i].init);
1857 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1858 free (init);
1859 }
1860 fprintf (fp, "\n");
1861
1862 fclose (fp);
1863 }
1864
1865 /* Program options. */
1866 #define OPTION_SRCDIR 200
1867
1868 struct option long_options[] =
1869 {
1870 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1871 {"debug", no_argument, NULL, 'd'},
1872 {"version", no_argument, NULL, 'V'},
1873 {"help", no_argument, NULL, 'h'},
1874 {0, no_argument, NULL, 0}
1875 };
1876
1877 static void
1878 print_version (void)
1879 {
1880 printf ("%s: version 1.0\n", program_name);
1881 xexit (0);
1882 }
1883
1884 static void
1885 usage (FILE * stream, int status)
1886 {
1887 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1888 program_name);
1889 xexit (status);
1890 }
1891
1892 int
1893 main (int argc, char **argv)
1894 {
1895 extern int chdir (char *);
1896 char *srcdir = NULL;
1897 int c;
1898 unsigned int i, cpumax;
1899 FILE *table;
1900
1901 program_name = *argv;
1902 xmalloc_set_program_name (program_name);
1903
1904 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1905 switch (c)
1906 {
1907 case OPTION_SRCDIR:
1908 srcdir = optarg;
1909 break;
1910 case 'V':
1911 case 'v':
1912 print_version ();
1913 break;
1914 case 'd':
1915 debug = 1;
1916 break;
1917 case 'h':
1918 case '?':
1919 usage (stderr, 0);
1920 default:
1921 case 0:
1922 break;
1923 }
1924
1925 if (optind != argc)
1926 usage (stdout, 1);
1927
1928 if (srcdir != NULL)
1929 if (chdir (srcdir) != 0)
1930 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1931 srcdir, xstrerror (errno));
1932
1933 /* cpu_flags isn't sorted by position. */
1934 cpumax = 0;
1935 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1936 if (cpu_flags[i].position > cpumax)
1937 cpumax = cpu_flags[i].position;
1938
1939 /* Check the unused bitfield in i386_cpu_flags. */
1940 #ifdef CpuUnused
1941 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1942
1943 if ((cpumax - 1) != CpuMax)
1944 fail (_("CpuMax != %d!\n"), cpumax);
1945 #else
1946 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1947
1948 if (cpumax != CpuMax)
1949 fail (_("CpuMax != %d!\n"), cpumax);
1950
1951 c = CpuNumOfBits - CpuMax - 1;
1952 if (c)
1953 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1954 #endif
1955
1956 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1957
1958 /* Check the unused bitfield in i386_operand_type. */
1959 #ifdef OTUnused
1960 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1961 == OTNum + 1);
1962 #else
1963 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
1964 == OTNum);
1965
1966 c = OTNumOfBits - OTNum;
1967 if (c)
1968 fail (_("%d unused bits in i386_operand_type.\n"), c);
1969 #endif
1970
1971 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1972 compare);
1973
1974 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1975 sizeof (opcode_modifiers [0]), compare);
1976
1977 qsort (operand_types, ARRAY_SIZE (operand_types),
1978 sizeof (operand_types [0]), compare);
1979
1980 table = fopen ("i386-tbl.h", "w");
1981 if (table == NULL)
1982 fail (_("can't create i386-tbl.h, errno = %s\n"),
1983 xstrerror (errno));
1984
1985 process_copyright (table);
1986
1987 process_i386_opcodes (table);
1988 process_i386_registers (table);
1989 process_i386_initializers ();
1990
1991 fclose (table);
1992
1993 exit (0);
1994 }
This page took 0.072941 seconds and 4 git commands to generate.