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