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 #ifdef CpuUnused
591 BITFIELD (CpuUnused),
592 #endif
593 };
594
595 static bitfield opcode_modifiers[] =
596 {
597 BITFIELD (D),
598 BITFIELD (W),
599 BITFIELD (Load),
600 BITFIELD (Modrm),
601 BITFIELD (ShortForm),
602 BITFIELD (Jump),
603 BITFIELD (JumpDword),
604 BITFIELD (JumpByte),
605 BITFIELD (JumpInterSegment),
606 BITFIELD (FloatMF),
607 BITFIELD (FloatR),
608 BITFIELD (Size16),
609 BITFIELD (Size32),
610 BITFIELD (Size64),
611 BITFIELD (CheckRegSize),
612 BITFIELD (IgnoreSize),
613 BITFIELD (DefaultSize),
614 BITFIELD (No_bSuf),
615 BITFIELD (No_wSuf),
616 BITFIELD (No_lSuf),
617 BITFIELD (No_sSuf),
618 BITFIELD (No_qSuf),
619 BITFIELD (No_ldSuf),
620 BITFIELD (FWait),
621 BITFIELD (IsString),
622 BITFIELD (BNDPrefixOk),
623 BITFIELD (NoTrackPrefixOk),
624 BITFIELD (IsLockable),
625 BITFIELD (RegKludge),
626 BITFIELD (Implicit1stXmm0),
627 BITFIELD (RepPrefixOk),
628 BITFIELD (HLEPrefixOk),
629 BITFIELD (ToDword),
630 BITFIELD (ToQword),
631 BITFIELD (AddrPrefixOpReg),
632 BITFIELD (IsPrefix),
633 BITFIELD (ImmExt),
634 BITFIELD (NoRex64),
635 BITFIELD (Rex64),
636 BITFIELD (Ugh),
637 BITFIELD (Vex),
638 BITFIELD (VexVVVV),
639 BITFIELD (VexW),
640 BITFIELD (VexOpcode),
641 BITFIELD (VexSources),
642 BITFIELD (VecSIB),
643 BITFIELD (SSE2AVX),
644 BITFIELD (NoAVX),
645 BITFIELD (EVex),
646 BITFIELD (Masking),
647 BITFIELD (Broadcast),
648 BITFIELD (StaticRounding),
649 BITFIELD (SAE),
650 BITFIELD (Disp8MemShift),
651 BITFIELD (NoDefMask),
652 BITFIELD (ImplicitQuadGroup),
653 BITFIELD (Optimize),
654 BITFIELD (ATTMnemonic),
655 BITFIELD (ATTSyntax),
656 BITFIELD (IntelSyntax),
657 BITFIELD (AMD64),
658 BITFIELD (Intel64),
659 };
660
661 static bitfield operand_types[] =
662 {
663 BITFIELD (Reg),
664 BITFIELD (RegMMX),
665 BITFIELD (RegSIMD),
666 BITFIELD (RegMask),
667 BITFIELD (Imm1),
668 BITFIELD (Imm8),
669 BITFIELD (Imm8S),
670 BITFIELD (Imm16),
671 BITFIELD (Imm32),
672 BITFIELD (Imm32S),
673 BITFIELD (Imm64),
674 BITFIELD (BaseIndex),
675 BITFIELD (Disp8),
676 BITFIELD (Disp16),
677 BITFIELD (Disp32),
678 BITFIELD (Disp32S),
679 BITFIELD (Disp64),
680 BITFIELD (InOutPortReg),
681 BITFIELD (ShiftCount),
682 BITFIELD (Control),
683 BITFIELD (Debug),
684 BITFIELD (Test),
685 BITFIELD (SReg2),
686 BITFIELD (SReg3),
687 BITFIELD (Acc),
688 BITFIELD (JumpAbsolute),
689 BITFIELD (EsSeg),
690 BITFIELD (RegMem),
691 BITFIELD (Mem),
692 BITFIELD (Byte),
693 BITFIELD (Word),
694 BITFIELD (Dword),
695 BITFIELD (Fword),
696 BITFIELD (Qword),
697 BITFIELD (Tbyte),
698 BITFIELD (Xmmword),
699 BITFIELD (Ymmword),
700 BITFIELD (Zmmword),
701 BITFIELD (Unspecified),
702 BITFIELD (Anysize),
703 BITFIELD (Vec_Imm4),
704 BITFIELD (RegBND),
705 #ifdef OTUnused
706 BITFIELD (OTUnused),
707 #endif
708 };
709
710 static const char *filename;
711 static i386_cpu_flags active_cpu_flags;
712 static int active_isstring;
713
714 static int
715 compare (const void *x, const void *y)
716 {
717 const bitfield *xp = (const bitfield *) x;
718 const bitfield *yp = (const bitfield *) y;
719 return xp->position - yp->position;
720 }
721
722 static void
723 fail (const char *message, ...)
724 {
725 va_list args;
726
727 va_start (args, message);
728 fprintf (stderr, _("%s: error: "), program_name);
729 vfprintf (stderr, message, args);
730 va_end (args);
731 xexit (1);
732 }
733
734 static void
735 process_copyright (FILE *fp)
736 {
737 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
738 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
739 \n\
740 This file is part of the GNU opcodes library.\n\
741 \n\
742 This library is free software; you can redistribute it and/or modify\n\
743 it under the terms of the GNU General Public License as published by\n\
744 the Free Software Foundation; either version 3, or (at your option)\n\
745 any later version.\n\
746 \n\
747 It is distributed in the hope that it will be useful, but WITHOUT\n\
748 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
749 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
750 License for more details.\n\
751 \n\
752 You should have received a copy of the GNU General Public License\n\
753 along with this program; if not, write to the Free Software\n\
754 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
755 MA 02110-1301, USA. */\n");
756 }
757
758 /* Remove leading white spaces. */
759
760 static char *
761 remove_leading_whitespaces (char *str)
762 {
763 while (ISSPACE (*str))
764 str++;
765 return str;
766 }
767
768 /* Remove trailing white spaces. */
769
770 static void
771 remove_trailing_whitespaces (char *str)
772 {
773 size_t last = strlen (str);
774
775 if (last == 0)
776 return;
777
778 do
779 {
780 last--;
781 if (ISSPACE (str [last]))
782 str[last] = '\0';
783 else
784 break;
785 }
786 while (last != 0);
787 }
788
789 /* Find next field separated by SEP and terminate it. Return a
790 pointer to the one after it. */
791
792 static char *
793 next_field (char *str, char sep, char **next, char *last)
794 {
795 char *p;
796
797 p = remove_leading_whitespaces (str);
798 for (str = p; *str != sep && *str != '\0'; str++);
799
800 *str = '\0';
801 remove_trailing_whitespaces (p);
802
803 *next = str + 1;
804
805 if (p >= last)
806 abort ();
807
808 return p;
809 }
810
811 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
812
813 static int
814 set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
815 int lineno)
816 {
817 char *str, *next, *last;
818 unsigned int i;
819
820 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
821 if (strcmp (cpu_flag_init[i].name, f) == 0)
822 {
823 /* Turn on selective bits. */
824 char *init = xstrdup (cpu_flag_init[i].init);
825 last = init + strlen (init);
826 for (next = init; next && next < last; )
827 {
828 str = next_field (next, '|', &next, last);
829 if (str)
830 set_bitfield (str, array, 1, size, lineno);
831 }
832 free (init);
833 return 0;
834 }
835
836 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
837 if (strcmp (operand_type_shorthands[i].name, f) == 0)
838 {
839 /* Turn on selective bits. */
840 char *init = xstrdup (operand_type_shorthands[i].init);
841 last = init + strlen (init);
842 for (next = init; next && next < last; )
843 {
844 str = next_field (next, '|', &next, last);
845 if (str)
846 set_bitfield (str, array, 1, size, lineno);
847 }
848 free (init);
849 return 0;
850 }
851
852 return -1;
853 }
854
855 static void
856 set_bitfield (char *f, bitfield *array, int value,
857 unsigned int size, int lineno)
858 {
859 unsigned int i;
860
861 if (strcmp (f, "CpuFP") == 0)
862 {
863 set_bitfield("Cpu387", array, value, size, lineno);
864 set_bitfield("Cpu287", array, value, size, lineno);
865 f = "Cpu8087";
866 }
867 else if (strcmp (f, "Mmword") == 0)
868 f= "Qword";
869 else if (strcmp (f, "Oword") == 0)
870 f= "Xmmword";
871
872 for (i = 0; i < size; i++)
873 if (strcasecmp (array[i].name, f) == 0)
874 {
875 array[i].value = value;
876 return;
877 }
878
879 if (value)
880 {
881 const char *v = strchr (f, '=');
882
883 if (v)
884 {
885 size_t n = v - f;
886 char *end;
887
888 for (i = 0; i < size; i++)
889 if (strncasecmp (array[i].name, f, n) == 0)
890 {
891 value = strtol (v + 1, &end, 0);
892 if (*end == '\0')
893 {
894 array[i].value = value;
895 return;
896 }
897 break;
898 }
899 }
900 }
901
902 /* Handle shorthands. */
903 if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno))
904 return;
905
906 if (lineno != -1)
907 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
908 else
909 fail (_("unknown bitfield: %s\n"), f);
910 }
911
912 static void
913 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
914 int macro, const char *comma, const char *indent)
915 {
916 unsigned int i;
917
918 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
919
920 fprintf (table, "%s{ { ", indent);
921
922 for (i = 0; i < size - 1; i++)
923 {
924 if (((i + 1) % 20) != 0)
925 fprintf (table, "%d, ", flags[i].value);
926 else
927 fprintf (table, "%d,", flags[i].value);
928 if (((i + 1) % 20) == 0)
929 {
930 /* We need \\ for macro. */
931 if (macro)
932 fprintf (table, " \\\n %s", indent);
933 else
934 fprintf (table, "\n %s", indent);
935 }
936 if (flags[i].value)
937 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
938 }
939
940 fprintf (table, "%d } }%s\n", flags[i].value, comma);
941 }
942
943 static void
944 process_i386_cpu_flag (FILE *table, char *flag, int macro,
945 const char *comma, const char *indent,
946 int lineno)
947 {
948 char *str, *next, *last;
949 unsigned int i;
950 bitfield flags [ARRAY_SIZE (cpu_flags)];
951
952 /* Copy the default cpu flags. */
953 memcpy (flags, cpu_flags, sizeof (cpu_flags));
954
955 if (strcasecmp (flag, "unknown") == 0)
956 {
957 /* We turn on everything except for cpu64 in case of
958 CPU_UNKNOWN_FLAGS. */
959 for (i = 0; i < ARRAY_SIZE (flags); i++)
960 if (flags[i].position != Cpu64)
961 flags[i].value = 1;
962 }
963 else if (flag[0] == '~')
964 {
965 last = flag + strlen (flag);
966
967 if (flag[1] == '(')
968 {
969 last -= 1;
970 next = flag + 2;
971 if (*last != ')')
972 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
973 lineno, flag);
974 *last = '\0';
975 }
976 else
977 next = flag + 1;
978
979 /* First we turn on everything except for cpu64. */
980 for (i = 0; i < ARRAY_SIZE (flags); i++)
981 if (flags[i].position != Cpu64)
982 flags[i].value = 1;
983
984 /* Turn off selective bits. */
985 for (; next && next < last; )
986 {
987 str = next_field (next, '|', &next, last);
988 if (str)
989 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
990 }
991 }
992 else if (strcmp (flag, "0"))
993 {
994 /* Turn on selective bits. */
995 last = flag + strlen (flag);
996 for (next = flag; next && next < last; )
997 {
998 str = next_field (next, '|', &next, last);
999 if (str)
1000 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
1001 }
1002 }
1003
1004 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1005 comma, indent);
1006 }
1007
1008 static void
1009 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1010 {
1011 unsigned int i;
1012
1013 fprintf (table, " { ");
1014
1015 for (i = 0; i < size - 1; i++)
1016 {
1017 if (((i + 1) % 20) != 0)
1018 fprintf (table, "%d, ", modifier[i].value);
1019 else
1020 fprintf (table, "%d,", modifier[i].value);
1021 if (((i + 1) % 20) == 0)
1022 fprintf (table, "\n ");
1023 }
1024
1025 fprintf (table, "%d },\n", modifier[i].value);
1026 }
1027
1028 static void
1029 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
1030 {
1031 char *str, *next, *last;
1032 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1033
1034 active_isstring = 0;
1035
1036 /* Copy the default opcode modifier. */
1037 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1038
1039 if (strcmp (mod, "0"))
1040 {
1041 last = mod + strlen (mod);
1042 for (next = mod; next && next < last; )
1043 {
1044 str = next_field (next, '|', &next, last);
1045 if (str)
1046 {
1047 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
1048 lineno);
1049 if (strcasecmp(str, "IsString") == 0)
1050 active_isstring = 1;
1051 }
1052 }
1053 }
1054 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1055 }
1056
1057 enum stage {
1058 stage_macros,
1059 stage_opcodes,
1060 stage_registers,
1061 };
1062
1063 static void
1064 output_operand_type (FILE *table, bitfield *types, unsigned int size,
1065 enum stage stage, const char *indent)
1066 {
1067 unsigned int i;
1068
1069 fprintf (table, "{ { ");
1070
1071 for (i = 0; i < size - 1; i++)
1072 {
1073 if (((i + 1) % 20) != 0)
1074 fprintf (table, "%d, ", types[i].value);
1075 else
1076 fprintf (table, "%d,", types[i].value);
1077 if (((i + 1) % 20) == 0)
1078 {
1079 /* We need \\ for macro. */
1080 if (stage == stage_macros)
1081 fprintf (table, " \\\n%s", indent);
1082 else
1083 fprintf (table, "\n%s", indent);
1084 }
1085 }
1086
1087 fprintf (table, "%d } }", types[i].value);
1088 }
1089
1090 static void
1091 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1092 const char *indent, int lineno)
1093 {
1094 char *str, *next, *last;
1095 bitfield types [ARRAY_SIZE (operand_types)];
1096
1097 /* Copy the default operand type. */
1098 memcpy (types, operand_types, sizeof (types));
1099
1100 if (strcmp (op, "0"))
1101 {
1102 int baseindex = 0;
1103
1104 last = op + strlen (op);
1105 for (next = op; next && next < last; )
1106 {
1107 str = next_field (next, '|', &next, last);
1108 if (str)
1109 {
1110 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1111 if (strcasecmp(str, "BaseIndex") == 0)
1112 baseindex = 1;
1113 }
1114 }
1115
1116 if (stage == stage_opcodes && baseindex && !active_isstring)
1117 {
1118 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1119 if (!active_cpu_flags.bitfield.cpu64
1120 && !active_cpu_flags.bitfield.cpumpx)
1121 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1122 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1123 if (!active_cpu_flags.bitfield.cpuno64)
1124 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1125 }
1126 }
1127 output_operand_type (table, types, ARRAY_SIZE (types), stage,
1128 indent);
1129 }
1130
1131 static void
1132 output_i386_opcode (FILE *table, const char *name, char *str,
1133 char *last, int lineno)
1134 {
1135 unsigned int i;
1136 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1137 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1138
1139 /* Find number of operands. */
1140 operands = next_field (str, ',', &str, last);
1141
1142 /* Find base_opcode. */
1143 base_opcode = next_field (str, ',', &str, last);
1144
1145 /* Find extension_opcode. */
1146 extension_opcode = next_field (str, ',', &str, last);
1147
1148 /* Find opcode_length. */
1149 opcode_length = next_field (str, ',', &str, last);
1150
1151 /* Find cpu_flags. */
1152 cpu_flags = next_field (str, ',', &str, last);
1153
1154 /* Find opcode_modifier. */
1155 opcode_modifier = next_field (str, ',', &str, last);
1156
1157 /* Remove the first {. */
1158 str = remove_leading_whitespaces (str);
1159 if (*str != '{')
1160 abort ();
1161 str = remove_leading_whitespaces (str + 1);
1162
1163 i = strlen (str);
1164
1165 /* There are at least "X}". */
1166 if (i < 2)
1167 abort ();
1168
1169 /* Remove trailing white spaces and }. */
1170 do
1171 {
1172 i--;
1173 if (ISSPACE (str[i]) || str[i] == '}')
1174 str[i] = '\0';
1175 else
1176 break;
1177 }
1178 while (i != 0);
1179
1180 last = str + i;
1181
1182 /* Find operand_types. */
1183 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1184 {
1185 if (str >= last)
1186 {
1187 operand_types [i] = NULL;
1188 break;
1189 }
1190
1191 operand_types [i] = next_field (str, ',', &str, last);
1192 if (*operand_types[i] == '0')
1193 {
1194 if (i != 0)
1195 operand_types[i] = NULL;
1196 break;
1197 }
1198 }
1199
1200 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1201 name, operands, base_opcode, extension_opcode,
1202 opcode_length);
1203
1204 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1205
1206 process_i386_opcode_modifier (table, opcode_modifier, lineno);
1207
1208 fprintf (table, " { ");
1209
1210 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1211 {
1212 if (operand_types[i] == NULL || *operand_types[i] == '0')
1213 {
1214 if (i == 0)
1215 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1216 lineno);
1217 break;
1218 }
1219
1220 if (i != 0)
1221 fprintf (table, ",\n ");
1222
1223 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1224 "\t ", lineno);
1225 }
1226 fprintf (table, " } },\n");
1227 }
1228
1229 struct opcode_hash_entry
1230 {
1231 struct opcode_hash_entry *next;
1232 char *name;
1233 char *opcode;
1234 int lineno;
1235 };
1236
1237 /* Calculate the hash value of an opcode hash entry P. */
1238
1239 static hashval_t
1240 opcode_hash_hash (const void *p)
1241 {
1242 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1243 return htab_hash_string (entry->name);
1244 }
1245
1246 /* Compare a string Q against an opcode hash entry P. */
1247
1248 static int
1249 opcode_hash_eq (const void *p, const void *q)
1250 {
1251 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1252 const char *name = (const char *) q;
1253 return strcmp (name, entry->name) == 0;
1254 }
1255
1256 static void
1257 process_i386_opcodes (FILE *table)
1258 {
1259 FILE *fp;
1260 char buf[2048];
1261 unsigned int i, j;
1262 char *str, *p, *last, *name;
1263 struct opcode_hash_entry **hash_slot, **entry, *next;
1264 htab_t opcode_hash_table;
1265 struct opcode_hash_entry **opcode_array;
1266 unsigned int opcode_array_size = 1024;
1267 int lineno = 0;
1268
1269 filename = "i386-opc.tbl";
1270 fp = fopen (filename, "r");
1271
1272 if (fp == NULL)
1273 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1274 xstrerror (errno));
1275
1276 i = 0;
1277 opcode_array = (struct opcode_hash_entry **)
1278 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1279
1280 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1281 opcode_hash_eq, NULL,
1282 xcalloc, free);
1283
1284 fprintf (table, "\n/* i386 opcode table. */\n\n");
1285 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1286
1287 /* Put everything on opcode array. */
1288 while (!feof (fp))
1289 {
1290 if (fgets (buf, sizeof (buf), fp) == NULL)
1291 break;
1292
1293 lineno++;
1294
1295 p = remove_leading_whitespaces (buf);
1296
1297 /* Skip comments. */
1298 str = strstr (p, "//");
1299 if (str != NULL)
1300 str[0] = '\0';
1301
1302 /* Remove trailing white spaces. */
1303 remove_trailing_whitespaces (p);
1304
1305 switch (p[0])
1306 {
1307 case '#':
1308 /* Ignore comments. */
1309 case '\0':
1310 continue;
1311 break;
1312 default:
1313 break;
1314 }
1315
1316 last = p + strlen (p);
1317
1318 /* Find name. */
1319 name = next_field (p, ',', &str, last);
1320
1321 /* Get the slot in hash table. */
1322 hash_slot = (struct opcode_hash_entry **)
1323 htab_find_slot_with_hash (opcode_hash_table, name,
1324 htab_hash_string (name),
1325 INSERT);
1326
1327 if (*hash_slot == NULL)
1328 {
1329 /* It is the new one. Put it on opcode array. */
1330 if (i >= opcode_array_size)
1331 {
1332 /* Grow the opcode array when needed. */
1333 opcode_array_size += 1024;
1334 opcode_array = (struct opcode_hash_entry **)
1335 xrealloc (opcode_array,
1336 sizeof (*opcode_array) * opcode_array_size);
1337 }
1338
1339 opcode_array[i] = (struct opcode_hash_entry *)
1340 xmalloc (sizeof (struct opcode_hash_entry));
1341 opcode_array[i]->next = NULL;
1342 opcode_array[i]->name = xstrdup (name);
1343 opcode_array[i]->opcode = xstrdup (str);
1344 opcode_array[i]->lineno = lineno;
1345 *hash_slot = opcode_array[i];
1346 i++;
1347 }
1348 else
1349 {
1350 /* Append it to the existing one. */
1351 entry = hash_slot;
1352 while ((*entry) != NULL)
1353 entry = &(*entry)->next;
1354 *entry = (struct opcode_hash_entry *)
1355 xmalloc (sizeof (struct opcode_hash_entry));
1356 (*entry)->next = NULL;
1357 (*entry)->name = (*hash_slot)->name;
1358 (*entry)->opcode = xstrdup (str);
1359 (*entry)->lineno = lineno;
1360 }
1361 }
1362
1363 /* Process opcode array. */
1364 for (j = 0; j < i; j++)
1365 {
1366 for (next = opcode_array[j]; next; next = next->next)
1367 {
1368 name = next->name;
1369 str = next->opcode;
1370 lineno = next->lineno;
1371 last = str + strlen (str);
1372 output_i386_opcode (table, name, str, last, lineno);
1373 }
1374 }
1375
1376 fclose (fp);
1377
1378 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1379
1380 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1381
1382 process_i386_opcode_modifier (table, "0", -1);
1383
1384 fprintf (table, " { ");
1385 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1386 fprintf (table, " } }\n");
1387
1388 fprintf (table, "};\n");
1389 }
1390
1391 static void
1392 process_i386_registers (FILE *table)
1393 {
1394 FILE *fp;
1395 char buf[2048];
1396 char *str, *p, *last;
1397 char *reg_name, *reg_type, *reg_flags, *reg_num;
1398 char *dw2_32_num, *dw2_64_num;
1399 int lineno = 0;
1400
1401 filename = "i386-reg.tbl";
1402 fp = fopen (filename, "r");
1403 if (fp == NULL)
1404 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1405 xstrerror (errno));
1406
1407 fprintf (table, "\n/* i386 register table. */\n\n");
1408 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1409
1410 while (!feof (fp))
1411 {
1412 if (fgets (buf, sizeof (buf), fp) == NULL)
1413 break;
1414
1415 lineno++;
1416
1417 p = remove_leading_whitespaces (buf);
1418
1419 /* Skip comments. */
1420 str = strstr (p, "//");
1421 if (str != NULL)
1422 str[0] = '\0';
1423
1424 /* Remove trailing white spaces. */
1425 remove_trailing_whitespaces (p);
1426
1427 switch (p[0])
1428 {
1429 case '#':
1430 fprintf (table, "%s\n", p);
1431 case '\0':
1432 continue;
1433 break;
1434 default:
1435 break;
1436 }
1437
1438 last = p + strlen (p);
1439
1440 /* Find reg_name. */
1441 reg_name = next_field (p, ',', &str, last);
1442
1443 /* Find reg_type. */
1444 reg_type = next_field (str, ',', &str, last);
1445
1446 /* Find reg_flags. */
1447 reg_flags = next_field (str, ',', &str, last);
1448
1449 /* Find reg_num. */
1450 reg_num = next_field (str, ',', &str, last);
1451
1452 fprintf (table, " { \"%s\",\n ", reg_name);
1453
1454 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1455 lineno);
1456
1457 /* Find 32-bit Dwarf2 register number. */
1458 dw2_32_num = next_field (str, ',', &str, last);
1459
1460 /* Find 64-bit Dwarf2 register number. */
1461 dw2_64_num = next_field (str, ',', &str, last);
1462
1463 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1464 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1465 }
1466
1467 fclose (fp);
1468
1469 fprintf (table, "};\n");
1470
1471 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1472 }
1473
1474 static void
1475 process_i386_initializers (void)
1476 {
1477 unsigned int i;
1478 FILE *fp = fopen ("i386-init.h", "w");
1479 char *init;
1480
1481 if (fp == NULL)
1482 fail (_("can't create i386-init.h, errno = %s\n"),
1483 xstrerror (errno));
1484
1485 process_copyright (fp);
1486
1487 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1488 {
1489 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1490 init = xstrdup (cpu_flag_init[i].init);
1491 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1492 free (init);
1493 }
1494
1495 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1496 {
1497 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1498 init = xstrdup (operand_type_init[i].init);
1499 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1500 free (init);
1501 }
1502 fprintf (fp, "\n");
1503
1504 fclose (fp);
1505 }
1506
1507 /* Program options. */
1508 #define OPTION_SRCDIR 200
1509
1510 struct option long_options[] =
1511 {
1512 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1513 {"debug", no_argument, NULL, 'd'},
1514 {"version", no_argument, NULL, 'V'},
1515 {"help", no_argument, NULL, 'h'},
1516 {0, no_argument, NULL, 0}
1517 };
1518
1519 static void
1520 print_version (void)
1521 {
1522 printf ("%s: version 1.0\n", program_name);
1523 xexit (0);
1524 }
1525
1526 static void
1527 usage (FILE * stream, int status)
1528 {
1529 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1530 program_name);
1531 xexit (status);
1532 }
1533
1534 int
1535 main (int argc, char **argv)
1536 {
1537 extern int chdir (char *);
1538 char *srcdir = NULL;
1539 int c;
1540 unsigned int i, cpumax;
1541 FILE *table;
1542
1543 program_name = *argv;
1544 xmalloc_set_program_name (program_name);
1545
1546 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1547 switch (c)
1548 {
1549 case OPTION_SRCDIR:
1550 srcdir = optarg;
1551 break;
1552 case 'V':
1553 case 'v':
1554 print_version ();
1555 break;
1556 case 'd':
1557 debug = 1;
1558 break;
1559 case 'h':
1560 case '?':
1561 usage (stderr, 0);
1562 default:
1563 case 0:
1564 break;
1565 }
1566
1567 if (optind != argc)
1568 usage (stdout, 1);
1569
1570 if (srcdir != NULL)
1571 if (chdir (srcdir) != 0)
1572 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1573 srcdir, xstrerror (errno));
1574
1575 /* cpu_flags isn't sorted by position. */
1576 cpumax = 0;
1577 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1578 if (cpu_flags[i].position > cpumax)
1579 cpumax = cpu_flags[i].position;
1580
1581 /* Check the unused bitfield in i386_cpu_flags. */
1582 #ifdef CpuUnused
1583 if ((cpumax - 1) != CpuMax)
1584 fail (_("CpuMax != %d!\n"), cpumax);
1585 #else
1586 if (cpumax != CpuMax)
1587 fail (_("CpuMax != %d!\n"), cpumax);
1588
1589 c = CpuNumOfBits - CpuMax - 1;
1590 if (c)
1591 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1592 #endif
1593
1594 /* Check the unused bitfield in i386_operand_type. */
1595 #ifndef OTUnused
1596 c = OTNumOfBits - OTMax - 1;
1597 if (c)
1598 fail (_("%d unused bits in i386_operand_type.\n"), c);
1599 #endif
1600
1601 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1602 compare);
1603
1604 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1605 sizeof (opcode_modifiers [0]), compare);
1606
1607 qsort (operand_types, ARRAY_SIZE (operand_types),
1608 sizeof (operand_types [0]), compare);
1609
1610 table = fopen ("i386-tbl.h", "w");
1611 if (table == NULL)
1612 fail (_("can't create i386-tbl.h, errno = %s\n"),
1613 xstrerror (errno));
1614
1615 process_copyright (table);
1616
1617 process_i386_opcodes (table);
1618 process_i386_registers (table);
1619 process_i386_initializers ();
1620
1621 fclose (table);
1622
1623 exit (0);
1624 }
This page took 0.086487 seconds and 4 git commands to generate.