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