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