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