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