x86: re-do "shorthand" handling
[deliverable/binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright (C) 2007-2019 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|CpuABM" },
94 { "CPU_BDVER1_FLAGS",
95 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|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|CpuABM|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|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|CpuRDPID|CpuWBNOINVD|CpuCLWB" },
106 { "CPU_BTVER1_FLAGS",
107 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
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" },
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_HLE_FLAGS",
185 "CpuHLE" },
186 { "CPU_RTM_FLAGS",
187 "CpuRTM" },
188 { "CPU_INVPCID_FLAGS",
189 "CpuINVPCID" },
190 { "CPU_VMFUNC_FLAGS",
191 "CpuVMFUNC" },
192 { "CPU_3DNOW_FLAGS",
193 "CPU_MMX_FLAGS|Cpu3dnow" },
194 { "CPU_3DNOWA_FLAGS",
195 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
196 { "CPU_PADLOCK_FLAGS",
197 "CpuPadLock" },
198 { "CPU_SVME_FLAGS",
199 "CpuSVME" },
200 { "CPU_SSE4A_FLAGS",
201 "CPU_SSE3_FLAGS|CpuSSE4a" },
202 { "CPU_ABM_FLAGS",
203 "CpuABM" },
204 { "CPU_AVX_FLAGS",
205 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
206 { "CPU_AVX2_FLAGS",
207 "CPU_AVX_FLAGS|CpuAVX2" },
208 { "CPU_AVX512F_FLAGS",
209 "CPU_AVX2_FLAGS|CpuAVX512F" },
210 { "CPU_AVX512CD_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
212 { "CPU_AVX512ER_FLAGS",
213 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
214 { "CPU_AVX512PF_FLAGS",
215 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
216 { "CPU_AVX512DQ_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
218 { "CPU_AVX512BW_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
220 { "CPU_AVX512VL_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512VL" },
222 { "CPU_AVX512IFMA_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
224 { "CPU_AVX512VBMI_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
226 { "CPU_AVX512_4FMAPS_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
228 { "CPU_AVX512_4VNNIW_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
230 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
232 { "CPU_AVX512_VBMI2_FLAGS",
233 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
234 { "CPU_AVX512_VNNI_FLAGS",
235 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
236 { "CPU_AVX512_BITALG_FLAGS",
237 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
238 { "CPU_AVX512_BF16_FLAGS",
239 "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
240 { "CPU_L1OM_FLAGS",
241 "unknown" },
242 { "CPU_K1OM_FLAGS",
243 "unknown" },
244 { "CPU_IAMCU_FLAGS",
245 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
246 { "CPU_ADX_FLAGS",
247 "CpuADX" },
248 { "CPU_RDSEED_FLAGS",
249 "CpuRdSeed" },
250 { "CPU_PRFCHW_FLAGS",
251 "CpuPRFCHW" },
252 { "CPU_SMAP_FLAGS",
253 "CpuSMAP" },
254 { "CPU_MPX_FLAGS",
255 "CPU_XSAVE_FLAGS|CpuMPX" },
256 { "CPU_SHA_FLAGS",
257 "CPU_SSE2_FLAGS|CpuSHA" },
258 { "CPU_CLFLUSHOPT_FLAGS",
259 "CpuClflushOpt" },
260 { "CPU_XSAVES_FLAGS",
261 "CPU_XSAVE_FLAGS|CpuXSAVES" },
262 { "CPU_XSAVEC_FLAGS",
263 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
264 { "CPU_PREFETCHWT1_FLAGS",
265 "CpuPREFETCHWT1" },
266 { "CPU_SE1_FLAGS",
267 "CpuSE1" },
268 { "CPU_CLWB_FLAGS",
269 "CpuCLWB" },
270 { "CPU_CLZERO_FLAGS",
271 "CpuCLZERO" },
272 { "CPU_MWAITX_FLAGS",
273 "CpuMWAITX" },
274 { "CPU_OSPKE_FLAGS",
275 "CPU_XSAVE_FLAGS|CpuOSPKE" },
276 { "CPU_RDPID_FLAGS",
277 "CpuRDPID" },
278 { "CPU_PTWRITE_FLAGS",
279 "CpuPTWRITE" },
280 { "CPU_IBT_FLAGS",
281 "CpuIBT" },
282 { "CPU_SHSTK_FLAGS",
283 "CpuSHSTK" },
284 { "CPU_GFNI_FLAGS",
285 "CpuGFNI" },
286 { "CPU_VAES_FLAGS",
287 "CpuVAES" },
288 { "CPU_VPCLMULQDQ_FLAGS",
289 "CpuVPCLMULQDQ" },
290 { "CPU_WBNOINVD_FLAGS",
291 "CpuWBNOINVD" },
292 { "CPU_PCONFIG_FLAGS",
293 "CpuPCONFIG" },
294 { "CPU_WAITPKG_FLAGS",
295 "CpuWAITPKG" },
296 { "CPU_CLDEMOTE_FLAGS",
297 "CpuCLDEMOTE" },
298 { "CPU_MOVDIRI_FLAGS",
299 "CpuMOVDIRI" },
300 { "CPU_MOVDIR64B_FLAGS",
301 "CpuMOVDIR64B" },
302 { "CPU_ENQCMD_FLAGS",
303 "CpuENQCMD" },
304 { "CPU_AVX512_VP2INTERSECT_FLAGS",
305 "CpuAVX512_VP2INTERSECT" },
306 { "CPU_ANY_X87_FLAGS",
307 "CPU_ANY_287_FLAGS|Cpu8087" },
308 { "CPU_ANY_287_FLAGS",
309 "CPU_ANY_387_FLAGS|Cpu287" },
310 { "CPU_ANY_387_FLAGS",
311 "CPU_ANY_687_FLAGS|Cpu387" },
312 { "CPU_ANY_687_FLAGS",
313 "Cpu687|CpuFISTTP" },
314 { "CPU_ANY_CMOV_FLAGS",
315 "CpuCMOV" },
316 { "CPU_ANY_FXSR_FLAGS",
317 "CpuFXSR" },
318 { "CPU_ANY_MMX_FLAGS",
319 "CPU_3DNOWA_FLAGS" },
320 { "CPU_ANY_SSE_FLAGS",
321 "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
322 { "CPU_ANY_SSE2_FLAGS",
323 "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
324 { "CPU_ANY_SSE3_FLAGS",
325 "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
326 { "CPU_ANY_SSSE3_FLAGS",
327 "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
328 { "CPU_ANY_SSE4_1_FLAGS",
329 "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
330 { "CPU_ANY_SSE4_2_FLAGS",
331 "CpuSSE4_2" },
332 { "CPU_ANY_AVX_FLAGS",
333 "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
334 { "CPU_ANY_AVX2_FLAGS",
335 "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
336 { "CPU_ANY_AVX512F_FLAGS",
337 "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" },
338 { "CPU_ANY_AVX512CD_FLAGS",
339 "CpuAVX512CD" },
340 { "CPU_ANY_AVX512ER_FLAGS",
341 "CpuAVX512ER" },
342 { "CPU_ANY_AVX512PF_FLAGS",
343 "CpuAVX512PF" },
344 { "CPU_ANY_AVX512DQ_FLAGS",
345 "CpuAVX512DQ" },
346 { "CPU_ANY_AVX512BW_FLAGS",
347 "CpuAVX512BW" },
348 { "CPU_ANY_AVX512VL_FLAGS",
349 "CpuAVX512VL" },
350 { "CPU_ANY_AVX512IFMA_FLAGS",
351 "CpuAVX512IFMA" },
352 { "CPU_ANY_AVX512VBMI_FLAGS",
353 "CpuAVX512VBMI" },
354 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
355 "CpuAVX512_4FMAPS" },
356 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
357 "CpuAVX512_4VNNIW" },
358 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
359 "CpuAVX512_VPOPCNTDQ" },
360 { "CPU_ANY_IBT_FLAGS",
361 "CpuIBT" },
362 { "CPU_ANY_SHSTK_FLAGS",
363 "CpuSHSTK" },
364 { "CPU_ANY_AVX512_VBMI2_FLAGS",
365 "CpuAVX512_VBMI2" },
366 { "CPU_ANY_AVX512_VNNI_FLAGS",
367 "CpuAVX512_VNNI" },
368 { "CPU_ANY_AVX512_BITALG_FLAGS",
369 "CpuAVX512_BITALG" },
370 { "CPU_ANY_AVX512_BF16_FLAGS",
371 "CpuAVX512_BF16" },
372 { "CPU_ANY_MOVDIRI_FLAGS",
373 "CpuMOVDIRI" },
374 { "CPU_ANY_MOVDIR64B_FLAGS",
375 "CpuMOVDIR64B" },
376 { "CPU_ANY_ENQCMD_FLAGS",
377 "CpuENQCMD" },
378 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
379 "CpuAVX512_VP2INTERSECT" },
380 };
381
382 static initializer operand_type_init[] =
383 {
384 { "OPERAND_TYPE_NONE",
385 "0" },
386 { "OPERAND_TYPE_REG8",
387 "Reg|Byte" },
388 { "OPERAND_TYPE_REG16",
389 "Reg|Word" },
390 { "OPERAND_TYPE_REG32",
391 "Reg|Dword" },
392 { "OPERAND_TYPE_REG64",
393 "Reg|Qword" },
394 { "OPERAND_TYPE_IMM1",
395 "Imm1" },
396 { "OPERAND_TYPE_IMM8",
397 "Imm8" },
398 { "OPERAND_TYPE_IMM8S",
399 "Imm8S" },
400 { "OPERAND_TYPE_IMM16",
401 "Imm16" },
402 { "OPERAND_TYPE_IMM32",
403 "Imm32" },
404 { "OPERAND_TYPE_IMM32S",
405 "Imm32S" },
406 { "OPERAND_TYPE_IMM64",
407 "Imm64" },
408 { "OPERAND_TYPE_BASEINDEX",
409 "BaseIndex" },
410 { "OPERAND_TYPE_DISP8",
411 "Disp8" },
412 { "OPERAND_TYPE_DISP16",
413 "Disp16" },
414 { "OPERAND_TYPE_DISP32",
415 "Disp32" },
416 { "OPERAND_TYPE_DISP32S",
417 "Disp32S" },
418 { "OPERAND_TYPE_DISP64",
419 "Disp64" },
420 { "OPERAND_TYPE_INOUTPORTREG",
421 "InOutPortReg" },
422 { "OPERAND_TYPE_SHIFTCOUNT",
423 "ShiftCount" },
424 { "OPERAND_TYPE_CONTROL",
425 "Control" },
426 { "OPERAND_TYPE_TEST",
427 "Test" },
428 { "OPERAND_TYPE_DEBUG",
429 "Debug" },
430 { "OPERAND_TYPE_FLOATREG",
431 "Reg|Tbyte" },
432 { "OPERAND_TYPE_FLOATACC",
433 "Acc|Tbyte" },
434 { "OPERAND_TYPE_SREG",
435 "SReg" },
436 { "OPERAND_TYPE_JUMPABSOLUTE",
437 "JumpAbsolute" },
438 { "OPERAND_TYPE_REGMMX",
439 "RegMMX" },
440 { "OPERAND_TYPE_REGXMM",
441 "RegSIMD|Xmmword" },
442 { "OPERAND_TYPE_REGYMM",
443 "RegSIMD|Ymmword" },
444 { "OPERAND_TYPE_REGZMM",
445 "RegSIMD|Zmmword" },
446 { "OPERAND_TYPE_REGMASK",
447 "RegMask" },
448 { "OPERAND_TYPE_ESSEG",
449 "EsSeg" },
450 { "OPERAND_TYPE_ACC8",
451 "Acc|Byte" },
452 { "OPERAND_TYPE_ACC16",
453 "Acc|Word" },
454 { "OPERAND_TYPE_ACC32",
455 "Acc|Dword" },
456 { "OPERAND_TYPE_ACC64",
457 "Acc|Qword" },
458 { "OPERAND_TYPE_DISP16_32",
459 "Disp16|Disp32" },
460 { "OPERAND_TYPE_ANYDISP",
461 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
462 { "OPERAND_TYPE_IMM16_32",
463 "Imm16|Imm32" },
464 { "OPERAND_TYPE_IMM16_32S",
465 "Imm16|Imm32S" },
466 { "OPERAND_TYPE_IMM16_32_32S",
467 "Imm16|Imm32|Imm32S" },
468 { "OPERAND_TYPE_IMM32_64",
469 "Imm32|Imm64" },
470 { "OPERAND_TYPE_IMM32_32S_DISP32",
471 "Imm32|Imm32S|Disp32" },
472 { "OPERAND_TYPE_IMM64_DISP64",
473 "Imm64|Disp64" },
474 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
475 "Imm32|Imm32S|Imm64|Disp32" },
476 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
477 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
478 { "OPERAND_TYPE_REGBND",
479 "RegBND" },
480 };
481
482 typedef struct bitfield
483 {
484 int position;
485 int value;
486 const char *name;
487 } bitfield;
488
489 #define BITFIELD(n) { n, 0, #n }
490
491 static bitfield cpu_flags[] =
492 {
493 BITFIELD (Cpu186),
494 BITFIELD (Cpu286),
495 BITFIELD (Cpu386),
496 BITFIELD (Cpu486),
497 BITFIELD (Cpu586),
498 BITFIELD (Cpu686),
499 BITFIELD (CpuCMOV),
500 BITFIELD (CpuFXSR),
501 BITFIELD (CpuClflush),
502 BITFIELD (CpuNop),
503 BITFIELD (CpuSYSCALL),
504 BITFIELD (Cpu8087),
505 BITFIELD (Cpu287),
506 BITFIELD (Cpu387),
507 BITFIELD (Cpu687),
508 BITFIELD (CpuFISTTP),
509 BITFIELD (CpuMMX),
510 BITFIELD (CpuSSE),
511 BITFIELD (CpuSSE2),
512 BITFIELD (CpuSSE3),
513 BITFIELD (CpuSSSE3),
514 BITFIELD (CpuSSE4_1),
515 BITFIELD (CpuSSE4_2),
516 BITFIELD (CpuAVX),
517 BITFIELD (CpuAVX2),
518 BITFIELD (CpuAVX512F),
519 BITFIELD (CpuAVX512CD),
520 BITFIELD (CpuAVX512ER),
521 BITFIELD (CpuAVX512PF),
522 BITFIELD (CpuAVX512VL),
523 BITFIELD (CpuAVX512DQ),
524 BITFIELD (CpuAVX512BW),
525 BITFIELD (CpuL1OM),
526 BITFIELD (CpuK1OM),
527 BITFIELD (CpuIAMCU),
528 BITFIELD (CpuSSE4a),
529 BITFIELD (Cpu3dnow),
530 BITFIELD (Cpu3dnowA),
531 BITFIELD (CpuPadLock),
532 BITFIELD (CpuSVME),
533 BITFIELD (CpuVMX),
534 BITFIELD (CpuSMX),
535 BITFIELD (CpuABM),
536 BITFIELD (CpuXsave),
537 BITFIELD (CpuXsaveopt),
538 BITFIELD (CpuAES),
539 BITFIELD (CpuPCLMUL),
540 BITFIELD (CpuFMA),
541 BITFIELD (CpuFMA4),
542 BITFIELD (CpuXOP),
543 BITFIELD (CpuLWP),
544 BITFIELD (CpuBMI),
545 BITFIELD (CpuTBM),
546 BITFIELD (CpuLM),
547 BITFIELD (CpuMovbe),
548 BITFIELD (CpuCX16),
549 BITFIELD (CpuEPT),
550 BITFIELD (CpuRdtscp),
551 BITFIELD (CpuFSGSBase),
552 BITFIELD (CpuRdRnd),
553 BITFIELD (CpuF16C),
554 BITFIELD (CpuBMI2),
555 BITFIELD (CpuLZCNT),
556 BITFIELD (CpuHLE),
557 BITFIELD (CpuRTM),
558 BITFIELD (CpuINVPCID),
559 BITFIELD (CpuVMFUNC),
560 BITFIELD (CpuRDSEED),
561 BITFIELD (CpuADX),
562 BITFIELD (CpuPRFCHW),
563 BITFIELD (CpuSMAP),
564 BITFIELD (CpuSHA),
565 BITFIELD (CpuClflushOpt),
566 BITFIELD (CpuXSAVES),
567 BITFIELD (CpuXSAVEC),
568 BITFIELD (CpuPREFETCHWT1),
569 BITFIELD (CpuSE1),
570 BITFIELD (CpuCLWB),
571 BITFIELD (Cpu64),
572 BITFIELD (CpuNo64),
573 BITFIELD (CpuMPX),
574 BITFIELD (CpuAVX512IFMA),
575 BITFIELD (CpuAVX512VBMI),
576 BITFIELD (CpuAVX512_4FMAPS),
577 BITFIELD (CpuAVX512_4VNNIW),
578 BITFIELD (CpuAVX512_VPOPCNTDQ),
579 BITFIELD (CpuAVX512_VBMI2),
580 BITFIELD (CpuAVX512_VNNI),
581 BITFIELD (CpuAVX512_BITALG),
582 BITFIELD (CpuAVX512_BF16),
583 BITFIELD (CpuAVX512_VP2INTERSECT),
584 BITFIELD (CpuMWAITX),
585 BITFIELD (CpuCLZERO),
586 BITFIELD (CpuOSPKE),
587 BITFIELD (CpuRDPID),
588 BITFIELD (CpuPTWRITE),
589 BITFIELD (CpuIBT),
590 BITFIELD (CpuSHSTK),
591 BITFIELD (CpuGFNI),
592 BITFIELD (CpuVAES),
593 BITFIELD (CpuVPCLMULQDQ),
594 BITFIELD (CpuWBNOINVD),
595 BITFIELD (CpuPCONFIG),
596 BITFIELD (CpuWAITPKG),
597 BITFIELD (CpuCLDEMOTE),
598 BITFIELD (CpuMOVDIRI),
599 BITFIELD (CpuMOVDIR64B),
600 BITFIELD (CpuENQCMD),
601 #ifdef CpuUnused
602 BITFIELD (CpuUnused),
603 #endif
604 };
605
606 static bitfield opcode_modifiers[] =
607 {
608 BITFIELD (D),
609 BITFIELD (W),
610 BITFIELD (Load),
611 BITFIELD (Modrm),
612 BITFIELD (ShortForm),
613 BITFIELD (Jump),
614 BITFIELD (JumpDword),
615 BITFIELD (JumpByte),
616 BITFIELD (JumpInterSegment),
617 BITFIELD (FloatMF),
618 BITFIELD (FloatR),
619 BITFIELD (Size),
620 BITFIELD (CheckRegSize),
621 BITFIELD (IgnoreSize),
622 BITFIELD (DefaultSize),
623 BITFIELD (No_bSuf),
624 BITFIELD (No_wSuf),
625 BITFIELD (No_lSuf),
626 BITFIELD (No_sSuf),
627 BITFIELD (No_qSuf),
628 BITFIELD (No_ldSuf),
629 BITFIELD (FWait),
630 BITFIELD (IsString),
631 BITFIELD (RegMem),
632 BITFIELD (BNDPrefixOk),
633 BITFIELD (NoTrackPrefixOk),
634 BITFIELD (IsLockable),
635 BITFIELD (RegKludge),
636 BITFIELD (Implicit1stXmm0),
637 BITFIELD (RepPrefixOk),
638 BITFIELD (HLEPrefixOk),
639 BITFIELD (ToDword),
640 BITFIELD (ToQword),
641 BITFIELD (AddrPrefixOpReg),
642 BITFIELD (IsPrefix),
643 BITFIELD (ImmExt),
644 BITFIELD (NoRex64),
645 BITFIELD (Rex64),
646 BITFIELD (Ugh),
647 BITFIELD (Vex),
648 BITFIELD (VexVVVV),
649 BITFIELD (VexW),
650 BITFIELD (VexOpcode),
651 BITFIELD (VexSources),
652 BITFIELD (VecSIB),
653 BITFIELD (SSE2AVX),
654 BITFIELD (NoAVX),
655 BITFIELD (EVex),
656 BITFIELD (Masking),
657 BITFIELD (Broadcast),
658 BITFIELD (StaticRounding),
659 BITFIELD (SAE),
660 BITFIELD (Disp8MemShift),
661 BITFIELD (NoDefMask),
662 BITFIELD (ImplicitQuadGroup),
663 BITFIELD (Optimize),
664 BITFIELD (ATTMnemonic),
665 BITFIELD (ATTSyntax),
666 BITFIELD (IntelSyntax),
667 BITFIELD (AMD64),
668 BITFIELD (Intel64),
669 };
670
671 static bitfield operand_types[] =
672 {
673 BITFIELD (Reg),
674 BITFIELD (RegMMX),
675 BITFIELD (RegSIMD),
676 BITFIELD (RegMask),
677 BITFIELD (Imm1),
678 BITFIELD (Imm8),
679 BITFIELD (Imm8S),
680 BITFIELD (Imm16),
681 BITFIELD (Imm32),
682 BITFIELD (Imm32S),
683 BITFIELD (Imm64),
684 BITFIELD (BaseIndex),
685 BITFIELD (Disp8),
686 BITFIELD (Disp16),
687 BITFIELD (Disp32),
688 BITFIELD (Disp32S),
689 BITFIELD (Disp64),
690 BITFIELD (InOutPortReg),
691 BITFIELD (ShiftCount),
692 BITFIELD (Control),
693 BITFIELD (Debug),
694 BITFIELD (Test),
695 BITFIELD (SReg),
696 BITFIELD (Acc),
697 BITFIELD (JumpAbsolute),
698 BITFIELD (EsSeg),
699 BITFIELD (Byte),
700 BITFIELD (Word),
701 BITFIELD (Dword),
702 BITFIELD (Fword),
703 BITFIELD (Qword),
704 BITFIELD (Tbyte),
705 BITFIELD (Xmmword),
706 BITFIELD (Ymmword),
707 BITFIELD (Zmmword),
708 BITFIELD (Unspecified),
709 BITFIELD (Anysize),
710 BITFIELD (RegBND),
711 #ifdef OTUnused
712 BITFIELD (OTUnused),
713 #endif
714 };
715
716 static const char *filename;
717 static i386_cpu_flags active_cpu_flags;
718 static int active_isstring;
719
720 static int
721 compare (const void *x, const void *y)
722 {
723 const bitfield *xp = (const bitfield *) x;
724 const bitfield *yp = (const bitfield *) y;
725 return xp->position - yp->position;
726 }
727
728 static void
729 fail (const char *message, ...)
730 {
731 va_list args;
732
733 va_start (args, message);
734 fprintf (stderr, _("%s: error: "), program_name);
735 vfprintf (stderr, message, args);
736 va_end (args);
737 xexit (1);
738 }
739
740 static void
741 process_copyright (FILE *fp)
742 {
743 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
744 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\
745 \n\
746 This file is part of the GNU opcodes library.\n\
747 \n\
748 This library is free software; you can redistribute it and/or modify\n\
749 it under the terms of the GNU General Public License as published by\n\
750 the Free Software Foundation; either version 3, or (at your option)\n\
751 any later version.\n\
752 \n\
753 It is distributed in the hope that it will be useful, but WITHOUT\n\
754 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
755 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
756 License for more details.\n\
757 \n\
758 You should have received a copy of the GNU General Public License\n\
759 along with this program; if not, write to the Free Software\n\
760 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
761 MA 02110-1301, USA. */\n");
762 }
763
764 /* Remove leading white spaces. */
765
766 static char *
767 remove_leading_whitespaces (char *str)
768 {
769 while (ISSPACE (*str))
770 str++;
771 return str;
772 }
773
774 /* Remove trailing white spaces. */
775
776 static void
777 remove_trailing_whitespaces (char *str)
778 {
779 size_t last = strlen (str);
780
781 if (last == 0)
782 return;
783
784 do
785 {
786 last--;
787 if (ISSPACE (str [last]))
788 str[last] = '\0';
789 else
790 break;
791 }
792 while (last != 0);
793 }
794
795 /* Find next field separated by SEP and terminate it. Return a
796 pointer to the one after it. */
797
798 static char *
799 next_field (char *str, char sep, char **next, char *last)
800 {
801 char *p;
802
803 p = remove_leading_whitespaces (str);
804 for (str = p; *str != sep && *str != '\0'; str++);
805
806 *str = '\0';
807 remove_trailing_whitespaces (p);
808
809 *next = str + 1;
810
811 if (p >= last)
812 abort ();
813
814 return p;
815 }
816
817 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
818
819 static int
820 set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
821 int lineno)
822 {
823 char *str, *next, *last;
824 unsigned int i;
825
826 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
827 if (strcmp (cpu_flag_init[i].name, f) == 0)
828 {
829 /* Turn on selective bits. */
830 char *init = xstrdup (cpu_flag_init[i].init);
831 last = init + strlen (init);
832 for (next = init; next && next < last; )
833 {
834 str = next_field (next, '|', &next, last);
835 if (str)
836 set_bitfield (str, array, 1, size, lineno);
837 }
838 free (init);
839 return 0;
840 }
841
842 return -1;
843 }
844
845 static void
846 set_bitfield (char *f, bitfield *array, int value,
847 unsigned int size, int lineno)
848 {
849 unsigned int i;
850
851 if (strcmp (f, "CpuFP") == 0)
852 {
853 set_bitfield("Cpu387", array, value, size, lineno);
854 set_bitfield("Cpu287", array, value, size, lineno);
855 f = "Cpu8087";
856 }
857 else if (strcmp (f, "Mmword") == 0)
858 f= "Qword";
859 else if (strcmp (f, "Oword") == 0)
860 f= "Xmmword";
861
862 for (i = 0; i < size; i++)
863 if (strcasecmp (array[i].name, f) == 0)
864 {
865 array[i].value = value;
866 return;
867 }
868
869 if (value)
870 {
871 const char *v = strchr (f, '=');
872
873 if (v)
874 {
875 size_t n = v - f;
876 char *end;
877
878 for (i = 0; i < size; i++)
879 if (strncasecmp (array[i].name, f, n) == 0)
880 {
881 value = strtol (v + 1, &end, 0);
882 if (*end == '\0')
883 {
884 array[i].value = value;
885 return;
886 }
887 break;
888 }
889 }
890 }
891
892 /* Handle CPU_XXX_FLAGS. */
893 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
894 return;
895
896 if (lineno != -1)
897 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
898 else
899 fail (_("unknown bitfield: %s\n"), f);
900 }
901
902 static void
903 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
904 int macro, const char *comma, const char *indent)
905 {
906 unsigned int i;
907
908 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
909
910 fprintf (table, "%s{ { ", indent);
911
912 for (i = 0; i < size - 1; i++)
913 {
914 if (((i + 1) % 20) != 0)
915 fprintf (table, "%d, ", flags[i].value);
916 else
917 fprintf (table, "%d,", flags[i].value);
918 if (((i + 1) % 20) == 0)
919 {
920 /* We need \\ for macro. */
921 if (macro)
922 fprintf (table, " \\\n %s", indent);
923 else
924 fprintf (table, "\n %s", indent);
925 }
926 if (flags[i].value)
927 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
928 }
929
930 fprintf (table, "%d } }%s\n", flags[i].value, comma);
931 }
932
933 static void
934 process_i386_cpu_flag (FILE *table, char *flag, int macro,
935 const char *comma, const char *indent,
936 int lineno)
937 {
938 char *str, *next, *last;
939 unsigned int i;
940 bitfield flags [ARRAY_SIZE (cpu_flags)];
941
942 /* Copy the default cpu flags. */
943 memcpy (flags, cpu_flags, sizeof (cpu_flags));
944
945 if (strcasecmp (flag, "unknown") == 0)
946 {
947 /* We turn on everything except for cpu64 in case of
948 CPU_UNKNOWN_FLAGS. */
949 for (i = 0; i < ARRAY_SIZE (flags); i++)
950 if (flags[i].position != Cpu64)
951 flags[i].value = 1;
952 }
953 else if (flag[0] == '~')
954 {
955 last = flag + strlen (flag);
956
957 if (flag[1] == '(')
958 {
959 last -= 1;
960 next = flag + 2;
961 if (*last != ')')
962 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
963 lineno, flag);
964 *last = '\0';
965 }
966 else
967 next = flag + 1;
968
969 /* First we turn on everything except for cpu64. */
970 for (i = 0; i < ARRAY_SIZE (flags); i++)
971 if (flags[i].position != Cpu64)
972 flags[i].value = 1;
973
974 /* Turn off selective bits. */
975 for (; next && next < last; )
976 {
977 str = next_field (next, '|', &next, last);
978 if (str)
979 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
980 }
981 }
982 else if (strcmp (flag, "0"))
983 {
984 /* Turn on selective bits. */
985 last = flag + strlen (flag);
986 for (next = flag; next && next < last; )
987 {
988 str = next_field (next, '|', &next, last);
989 if (str)
990 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
991 }
992 }
993
994 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
995 comma, indent);
996 }
997
998 static void
999 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1000 {
1001 unsigned int i;
1002
1003 fprintf (table, " { ");
1004
1005 for (i = 0; i < size - 1; i++)
1006 {
1007 if (((i + 1) % 20) != 0)
1008 fprintf (table, "%d, ", modifier[i].value);
1009 else
1010 fprintf (table, "%d,", modifier[i].value);
1011 if (((i + 1) % 20) == 0)
1012 fprintf (table, "\n ");
1013 }
1014
1015 fprintf (table, "%d },\n", modifier[i].value);
1016 }
1017
1018 static int
1019 adjust_broadcast_modifier (char **opnd)
1020 {
1021 char *str, *next, *last, *op;
1022 int bcst_type = INT_MAX;
1023
1024 /* Skip the immediate operand. */
1025 op = opnd[0];
1026 if (strcasecmp(op, "Imm8") == 0)
1027 op = opnd[1];
1028
1029 op = xstrdup (op);
1030 last = op + strlen (op);
1031 for (next = op; next && next < last; )
1032 {
1033 str = next_field (next, '|', &next, last);
1034 if (str)
1035 {
1036 if (strcasecmp(str, "Byte") == 0)
1037 {
1038 /* The smalest broadcast type, no need to check
1039 further. */
1040 bcst_type = BYTE_BROADCAST;
1041 break;
1042 }
1043 else if (strcasecmp(str, "Word") == 0)
1044 {
1045 if (bcst_type > WORD_BROADCAST)
1046 bcst_type = WORD_BROADCAST;
1047 }
1048 else if (strcasecmp(str, "Dword") == 0)
1049 {
1050 if (bcst_type > DWORD_BROADCAST)
1051 bcst_type = DWORD_BROADCAST;
1052 }
1053 else if (strcasecmp(str, "Qword") == 0)
1054 {
1055 if (bcst_type > QWORD_BROADCAST)
1056 bcst_type = QWORD_BROADCAST;
1057 }
1058 }
1059 }
1060 free (op);
1061
1062 if (bcst_type == INT_MAX)
1063 fail (_("unknown broadcast operand: %s\n"), op);
1064
1065 return bcst_type;
1066 }
1067
1068 static void
1069 process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
1070 {
1071 char *str, *next, *last;
1072 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1073
1074 active_isstring = 0;
1075
1076 /* Copy the default opcode modifier. */
1077 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1078
1079 if (strcmp (mod, "0"))
1080 {
1081 unsigned int have_w = 0, bwlq_suf = 0xf;
1082
1083 last = mod + strlen (mod);
1084 for (next = mod; next && next < last; )
1085 {
1086 str = next_field (next, '|', &next, last);
1087 if (str)
1088 {
1089 int val = 1;
1090 if (strcasecmp(str, "Broadcast") == 0)
1091 val = adjust_broadcast_modifier (opnd);
1092 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1093 lineno);
1094 if (strcasecmp(str, "IsString") == 0)
1095 active_isstring = 1;
1096
1097 if (strcasecmp(str, "W") == 0)
1098 have_w = 1;
1099
1100 if (strcasecmp(str, "No_bSuf") == 0)
1101 bwlq_suf &= ~1;
1102 if (strcasecmp(str, "No_wSuf") == 0)
1103 bwlq_suf &= ~2;
1104 if (strcasecmp(str, "No_lSuf") == 0)
1105 bwlq_suf &= ~4;
1106 if (strcasecmp(str, "No_qSuf") == 0)
1107 bwlq_suf &= ~8;
1108 }
1109 }
1110
1111 if (have_w && !bwlq_suf)
1112 fail ("%s: %d: stray W modifier\n", filename, lineno);
1113 if (have_w && !(bwlq_suf & 1))
1114 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1115 filename, lineno);
1116 if (have_w && !(bwlq_suf & ~1))
1117 fprintf (stderr,
1118 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1119 filename, lineno);
1120 }
1121 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1122 }
1123
1124 enum stage {
1125 stage_macros,
1126 stage_opcodes,
1127 stage_registers,
1128 };
1129
1130 static void
1131 output_operand_type (FILE *table, bitfield *types, unsigned int size,
1132 enum stage stage, const char *indent)
1133 {
1134 unsigned int i;
1135
1136 fprintf (table, "{ { ");
1137
1138 for (i = 0; i < size - 1; i++)
1139 {
1140 if (((i + 1) % 20) != 0)
1141 fprintf (table, "%d, ", types[i].value);
1142 else
1143 fprintf (table, "%d,", types[i].value);
1144 if (((i + 1) % 20) == 0)
1145 {
1146 /* We need \\ for macro. */
1147 if (stage == stage_macros)
1148 fprintf (table, " \\\n%s", indent);
1149 else
1150 fprintf (table, "\n%s", indent);
1151 }
1152 }
1153
1154 fprintf (table, "%d } }", types[i].value);
1155 }
1156
1157 static void
1158 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1159 const char *indent, int lineno)
1160 {
1161 char *str, *next, *last;
1162 bitfield types [ARRAY_SIZE (operand_types)];
1163
1164 /* Copy the default operand type. */
1165 memcpy (types, operand_types, sizeof (types));
1166
1167 if (strcmp (op, "0"))
1168 {
1169 int baseindex = 0;
1170
1171 last = op + strlen (op);
1172 for (next = op; next && next < last; )
1173 {
1174 str = next_field (next, '|', &next, last);
1175 if (str)
1176 {
1177 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1178 if (strcasecmp(str, "BaseIndex") == 0)
1179 baseindex = 1;
1180 }
1181 }
1182
1183 if (stage == stage_opcodes && baseindex && !active_isstring)
1184 {
1185 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1186 if (!active_cpu_flags.bitfield.cpu64
1187 && !active_cpu_flags.bitfield.cpumpx)
1188 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1189 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1190 if (!active_cpu_flags.bitfield.cpuno64)
1191 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1192 }
1193 }
1194 output_operand_type (table, types, ARRAY_SIZE (types), stage,
1195 indent);
1196 }
1197
1198 static void
1199 output_i386_opcode (FILE *table, const char *name, char *str,
1200 char *last, int lineno)
1201 {
1202 unsigned int i;
1203 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1204 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1205
1206 /* Find number of operands. */
1207 operands = next_field (str, ',', &str, last);
1208
1209 /* Find base_opcode. */
1210 base_opcode = next_field (str, ',', &str, last);
1211
1212 /* Find extension_opcode. */
1213 extension_opcode = next_field (str, ',', &str, last);
1214
1215 /* Find opcode_length. */
1216 opcode_length = next_field (str, ',', &str, last);
1217
1218 /* Find cpu_flags. */
1219 cpu_flags = next_field (str, ',', &str, last);
1220
1221 /* Find opcode_modifier. */
1222 opcode_modifier = next_field (str, ',', &str, last);
1223
1224 /* Remove the first {. */
1225 str = remove_leading_whitespaces (str);
1226 if (*str != '{')
1227 abort ();
1228 str = remove_leading_whitespaces (str + 1);
1229
1230 i = strlen (str);
1231
1232 /* There are at least "X}". */
1233 if (i < 2)
1234 abort ();
1235
1236 /* Remove trailing white spaces and }. */
1237 do
1238 {
1239 i--;
1240 if (ISSPACE (str[i]) || str[i] == '}')
1241 str[i] = '\0';
1242 else
1243 break;
1244 }
1245 while (i != 0);
1246
1247 last = str + i;
1248
1249 /* Find operand_types. */
1250 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1251 {
1252 if (str >= last)
1253 {
1254 operand_types [i] = NULL;
1255 break;
1256 }
1257
1258 operand_types [i] = next_field (str, ',', &str, last);
1259 if (*operand_types[i] == '0')
1260 {
1261 if (i != 0)
1262 operand_types[i] = NULL;
1263 break;
1264 }
1265 }
1266
1267 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1268 name, base_opcode, extension_opcode, opcode_length, operands);
1269
1270 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1271
1272 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
1273
1274 fprintf (table, " { ");
1275
1276 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1277 {
1278 if (operand_types[i] == NULL || *operand_types[i] == '0')
1279 {
1280 if (i == 0)
1281 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1282 lineno);
1283 break;
1284 }
1285
1286 if (i != 0)
1287 fprintf (table, ",\n ");
1288
1289 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1290 "\t ", lineno);
1291 }
1292 fprintf (table, " } },\n");
1293 }
1294
1295 struct opcode_hash_entry
1296 {
1297 struct opcode_hash_entry *next;
1298 char *name;
1299 char *opcode;
1300 int lineno;
1301 };
1302
1303 /* Calculate the hash value of an opcode hash entry P. */
1304
1305 static hashval_t
1306 opcode_hash_hash (const void *p)
1307 {
1308 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1309 return htab_hash_string (entry->name);
1310 }
1311
1312 /* Compare a string Q against an opcode hash entry P. */
1313
1314 static int
1315 opcode_hash_eq (const void *p, const void *q)
1316 {
1317 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1318 const char *name = (const char *) q;
1319 return strcmp (name, entry->name) == 0;
1320 }
1321
1322 static void
1323 process_i386_opcodes (FILE *table)
1324 {
1325 FILE *fp;
1326 char buf[2048];
1327 unsigned int i, j;
1328 char *str, *p, *last, *name;
1329 struct opcode_hash_entry **hash_slot, **entry, *next;
1330 htab_t opcode_hash_table;
1331 struct opcode_hash_entry **opcode_array;
1332 unsigned int opcode_array_size = 1024;
1333 int lineno = 0, marker = 0;
1334
1335 filename = "i386-opc.tbl";
1336 fp = stdin;
1337
1338 i = 0;
1339 opcode_array = (struct opcode_hash_entry **)
1340 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1341
1342 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1343 opcode_hash_eq, NULL,
1344 xcalloc, free);
1345
1346 fprintf (table, "\n/* i386 opcode table. */\n\n");
1347 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1348
1349 /* Put everything on opcode array. */
1350 while (!feof (fp))
1351 {
1352 if (fgets (buf, sizeof (buf), fp) == NULL)
1353 break;
1354
1355 lineno++;
1356
1357 p = remove_leading_whitespaces (buf);
1358
1359 /* Skip comments. */
1360 str = strstr (p, "//");
1361 if (str != NULL)
1362 str[0] = '\0';
1363
1364 /* Remove trailing white spaces. */
1365 remove_trailing_whitespaces (p);
1366
1367 switch (p[0])
1368 {
1369 case '#':
1370 if (!strcmp("### MARKER ###", buf))
1371 marker = 1;
1372 else
1373 {
1374 /* Since we ignore all included files (we only care about their
1375 #define-s here), we don't need to monitor filenames. The final
1376 line number directive is going to refer to the main source file
1377 again. */
1378 char *end;
1379 unsigned long ln;
1380
1381 p = remove_leading_whitespaces (p + 1);
1382 if (!strncmp(p, "line", 4))
1383 p += 4;
1384 ln = strtoul (p, &end, 10);
1385 if (ln > 1 && ln < INT_MAX
1386 && *remove_leading_whitespaces (end) == '"')
1387 lineno = ln - 1;
1388 }
1389 /* Ignore comments. */
1390 case '\0':
1391 continue;
1392 break;
1393 default:
1394 if (!marker)
1395 continue;
1396 break;
1397 }
1398
1399 last = p + strlen (p);
1400
1401 /* Find name. */
1402 name = next_field (p, ',', &str, last);
1403
1404 /* Get the slot in hash table. */
1405 hash_slot = (struct opcode_hash_entry **)
1406 htab_find_slot_with_hash (opcode_hash_table, name,
1407 htab_hash_string (name),
1408 INSERT);
1409
1410 if (*hash_slot == NULL)
1411 {
1412 /* It is the new one. Put it on opcode array. */
1413 if (i >= opcode_array_size)
1414 {
1415 /* Grow the opcode array when needed. */
1416 opcode_array_size += 1024;
1417 opcode_array = (struct opcode_hash_entry **)
1418 xrealloc (opcode_array,
1419 sizeof (*opcode_array) * opcode_array_size);
1420 }
1421
1422 opcode_array[i] = (struct opcode_hash_entry *)
1423 xmalloc (sizeof (struct opcode_hash_entry));
1424 opcode_array[i]->next = NULL;
1425 opcode_array[i]->name = xstrdup (name);
1426 opcode_array[i]->opcode = xstrdup (str);
1427 opcode_array[i]->lineno = lineno;
1428 *hash_slot = opcode_array[i];
1429 i++;
1430 }
1431 else
1432 {
1433 /* Append it to the existing one. */
1434 entry = hash_slot;
1435 while ((*entry) != NULL)
1436 entry = &(*entry)->next;
1437 *entry = (struct opcode_hash_entry *)
1438 xmalloc (sizeof (struct opcode_hash_entry));
1439 (*entry)->next = NULL;
1440 (*entry)->name = (*hash_slot)->name;
1441 (*entry)->opcode = xstrdup (str);
1442 (*entry)->lineno = lineno;
1443 }
1444 }
1445
1446 /* Process opcode array. */
1447 for (j = 0; j < i; j++)
1448 {
1449 for (next = opcode_array[j]; next; next = next->next)
1450 {
1451 name = next->name;
1452 str = next->opcode;
1453 lineno = next->lineno;
1454 last = str + strlen (str);
1455 output_i386_opcode (table, name, str, last, lineno);
1456 }
1457 }
1458
1459 fclose (fp);
1460
1461 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1462
1463 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1464
1465 process_i386_opcode_modifier (table, "0", NULL, -1);
1466
1467 fprintf (table, " { ");
1468 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1469 fprintf (table, " } }\n");
1470
1471 fprintf (table, "};\n");
1472 }
1473
1474 static void
1475 process_i386_registers (FILE *table)
1476 {
1477 FILE *fp;
1478 char buf[2048];
1479 char *str, *p, *last;
1480 char *reg_name, *reg_type, *reg_flags, *reg_num;
1481 char *dw2_32_num, *dw2_64_num;
1482 int lineno = 0;
1483
1484 filename = "i386-reg.tbl";
1485 fp = fopen (filename, "r");
1486 if (fp == NULL)
1487 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1488 xstrerror (errno));
1489
1490 fprintf (table, "\n/* i386 register table. */\n\n");
1491 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1492
1493 while (!feof (fp))
1494 {
1495 if (fgets (buf, sizeof (buf), fp) == NULL)
1496 break;
1497
1498 lineno++;
1499
1500 p = remove_leading_whitespaces (buf);
1501
1502 /* Skip comments. */
1503 str = strstr (p, "//");
1504 if (str != NULL)
1505 str[0] = '\0';
1506
1507 /* Remove trailing white spaces. */
1508 remove_trailing_whitespaces (p);
1509
1510 switch (p[0])
1511 {
1512 case '#':
1513 fprintf (table, "%s\n", p);
1514 case '\0':
1515 continue;
1516 break;
1517 default:
1518 break;
1519 }
1520
1521 last = p + strlen (p);
1522
1523 /* Find reg_name. */
1524 reg_name = next_field (p, ',', &str, last);
1525
1526 /* Find reg_type. */
1527 reg_type = next_field (str, ',', &str, last);
1528
1529 /* Find reg_flags. */
1530 reg_flags = next_field (str, ',', &str, last);
1531
1532 /* Find reg_num. */
1533 reg_num = next_field (str, ',', &str, last);
1534
1535 fprintf (table, " { \"%s\",\n ", reg_name);
1536
1537 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1538 lineno);
1539
1540 /* Find 32-bit Dwarf2 register number. */
1541 dw2_32_num = next_field (str, ',', &str, last);
1542
1543 /* Find 64-bit Dwarf2 register number. */
1544 dw2_64_num = next_field (str, ',', &str, last);
1545
1546 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1547 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1548 }
1549
1550 fclose (fp);
1551
1552 fprintf (table, "};\n");
1553
1554 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1555 }
1556
1557 static void
1558 process_i386_initializers (void)
1559 {
1560 unsigned int i;
1561 FILE *fp = fopen ("i386-init.h", "w");
1562 char *init;
1563
1564 if (fp == NULL)
1565 fail (_("can't create i386-init.h, errno = %s\n"),
1566 xstrerror (errno));
1567
1568 process_copyright (fp);
1569
1570 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1571 {
1572 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1573 init = xstrdup (cpu_flag_init[i].init);
1574 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1575 free (init);
1576 }
1577
1578 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1579 {
1580 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1581 init = xstrdup (operand_type_init[i].init);
1582 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1583 free (init);
1584 }
1585 fprintf (fp, "\n");
1586
1587 fclose (fp);
1588 }
1589
1590 /* Program options. */
1591 #define OPTION_SRCDIR 200
1592
1593 struct option long_options[] =
1594 {
1595 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1596 {"debug", no_argument, NULL, 'd'},
1597 {"version", no_argument, NULL, 'V'},
1598 {"help", no_argument, NULL, 'h'},
1599 {0, no_argument, NULL, 0}
1600 };
1601
1602 static void
1603 print_version (void)
1604 {
1605 printf ("%s: version 1.0\n", program_name);
1606 xexit (0);
1607 }
1608
1609 static void
1610 usage (FILE * stream, int status)
1611 {
1612 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1613 program_name);
1614 xexit (status);
1615 }
1616
1617 int
1618 main (int argc, char **argv)
1619 {
1620 extern int chdir (char *);
1621 char *srcdir = NULL;
1622 int c;
1623 unsigned int i, cpumax;
1624 FILE *table;
1625
1626 program_name = *argv;
1627 xmalloc_set_program_name (program_name);
1628
1629 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1630 switch (c)
1631 {
1632 case OPTION_SRCDIR:
1633 srcdir = optarg;
1634 break;
1635 case 'V':
1636 case 'v':
1637 print_version ();
1638 break;
1639 case 'd':
1640 debug = 1;
1641 break;
1642 case 'h':
1643 case '?':
1644 usage (stderr, 0);
1645 default:
1646 case 0:
1647 break;
1648 }
1649
1650 if (optind != argc)
1651 usage (stdout, 1);
1652
1653 if (srcdir != NULL)
1654 if (chdir (srcdir) != 0)
1655 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1656 srcdir, xstrerror (errno));
1657
1658 /* cpu_flags isn't sorted by position. */
1659 cpumax = 0;
1660 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1661 if (cpu_flags[i].position > cpumax)
1662 cpumax = cpu_flags[i].position;
1663
1664 /* Check the unused bitfield in i386_cpu_flags. */
1665 #ifdef CpuUnused
1666 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
1667
1668 if ((cpumax - 1) != CpuMax)
1669 fail (_("CpuMax != %d!\n"), cpumax);
1670 #else
1671 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
1672
1673 if (cpumax != CpuMax)
1674 fail (_("CpuMax != %d!\n"), cpumax);
1675
1676 c = CpuNumOfBits - CpuMax - 1;
1677 if (c)
1678 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1679 #endif
1680
1681 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
1682
1683 /* Check the unused bitfield in i386_operand_type. */
1684 #ifdef OTUnused
1685 static_assert (ARRAY_SIZE (operand_types) == OTNum + 1);
1686 #else
1687 static_assert (ARRAY_SIZE (operand_types) == OTNum);
1688
1689 c = OTNumOfBits - OTMax - 1;
1690 if (c)
1691 fail (_("%d unused bits in i386_operand_type.\n"), c);
1692 #endif
1693
1694 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1695 compare);
1696
1697 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1698 sizeof (opcode_modifiers [0]), compare);
1699
1700 qsort (operand_types, ARRAY_SIZE (operand_types),
1701 sizeof (operand_types [0]), compare);
1702
1703 table = fopen ("i386-tbl.h", "w");
1704 if (table == NULL)
1705 fail (_("can't create i386-tbl.h, errno = %s\n"),
1706 xstrerror (errno));
1707
1708 process_copyright (table);
1709
1710 process_i386_opcodes (table);
1711 process_i386_registers (table);
1712 process_i386_initializers ();
1713
1714 fclose (table);
1715
1716 exit (0);
1717 }
This page took 0.10523 seconds and 4 git commands to generate.