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