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