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