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