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