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