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