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