e02379570140a525ed6bb94c600ed78454dc3549
[deliverable/binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.
2
3 This file is part of the GNU opcodes library.
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
19
20 #include "sysdep.h"
21 #include <stdio.h>
22 #include <errno.h>
23 #include "getopt.h"
24 #include "libiberty.h"
25 #include "hashtab.h"
26 #include "safe-ctype.h"
27
28 #include "i386-opc.h"
29
30 #include <libintl.h>
31 #define _(String) gettext (String)
32
33 static const char *program_name = NULL;
34 static int debug = 0;
35
36 typedef struct initializer
37 {
38 const char *name;
39 const char *init;
40 } initializer;
41
42 static initializer cpu_flag_init[] =
43 {
44 { "CPU_UNKNOWN_FLAGS",
45 "~(CpuL1OM|CpuK1OM)" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
50 { "CPU_NONE_FLAGS",
51 "0" },
52 { "CPU_I186_FLAGS",
53 "Cpu186" },
54 { "CPU_I286_FLAGS",
55 "CPU_I186_FLAGS|Cpu286" },
56 { "CPU_I386_FLAGS",
57 "CPU_I286_FLAGS|Cpu386" },
58 { "CPU_I486_FLAGS",
59 "CPU_I386_FLAGS|Cpu486" },
60 { "CPU_I586_FLAGS",
61 "CPU_I486_FLAGS|CPU_387_FLAGS|Cpu586" },
62 { "CPU_I686_FLAGS",
63 "CPU_I586_FLAGS|Cpu686|Cpu687" },
64 { "CPU_PENTIUMPRO_FLAGS",
65 "CPU_I686_FLAGS|CpuNop" },
66 { "CPU_P2_FLAGS",
67 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
68 { "CPU_P3_FLAGS",
69 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
70 { "CPU_P4_FLAGS",
71 "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
72 { "CPU_NOCONA_FLAGS",
73 "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
74 { "CPU_CORE_FLAGS",
75 "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
76 { "CPU_CORE2_FLAGS",
77 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
78 { "CPU_COREI7_FLAGS",
79 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
80 { "CPU_K6_FLAGS",
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
82 { "CPU_K6_2_FLAGS",
83 "CPU_K6_FLAGS|Cpu3dnow" },
84 { "CPU_ATHLON_FLAGS",
85 "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
86 { "CPU_K8_FLAGS",
87 "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
88 { "CPU_AMDFAM10_FLAGS",
89 "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
90 { "CPU_BDVER1_FLAGS",
91 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuFMA4|CpuXOP|CpuLWP|CpuSVME|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
92 { "CPU_BDVER2_FLAGS",
93 "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
94 { "CPU_BDVER3_FLAGS",
95 "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
96 { "CPU_BDVER4_FLAGS",
97 "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
98 { "CPU_ZNVER1_FLAGS",
99 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
100 { "CPU_BTVER1_FLAGS",
101 "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
102 { "CPU_BTVER2_FLAGS",
103 "CPU_BTVER1_FLAGS|CPU_SSE4_2_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW" },
104 { "CPU_8087_FLAGS",
105 "Cpu8087" },
106 { "CPU_287_FLAGS",
107 "CPU_8087_FLAGS|Cpu287" },
108 { "CPU_387_FLAGS",
109 "CPU_287_FLAGS|Cpu387" },
110 { "CPU_687_FLAGS",
111 "CPU_387_FLAGS|Cpu687" },
112 { "CPU_CLFLUSH_FLAGS",
113 "CpuClflush" },
114 { "CPU_NOP_FLAGS",
115 "CpuNop" },
116 { "CPU_SYSCALL_FLAGS",
117 "CpuSYSCALL" },
118 { "CPU_MMX_FLAGS",
119 "CpuRegMMX|CpuMMX" },
120 { "CPU_SSE_FLAGS",
121 "CpuRegXMM|CpuSSE" },
122 { "CPU_SSE2_FLAGS",
123 "CPU_SSE_FLAGS|CpuSSE2" },
124 { "CPU_SSE3_FLAGS",
125 "CPU_SSE2_FLAGS|CpuSSE3" },
126 { "CPU_SSSE3_FLAGS",
127 "CPU_SSE3_FLAGS|CpuSSSE3" },
128 { "CPU_SSE4_1_FLAGS",
129 "CPU_SSSE3_FLAGS|CpuSSE4_1" },
130 { "CPU_SSE4_2_FLAGS",
131 "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
132 { "CPU_VMX_FLAGS",
133 "CpuVMX" },
134 { "CPU_SMX_FLAGS",
135 "CpuSMX" },
136 { "CPU_XSAVE_FLAGS",
137 "CpuXsave" },
138 { "CPU_XSAVEOPT_FLAGS",
139 "CPU_XSAVE_FLAGS|CpuXsaveopt" },
140 { "CPU_AES_FLAGS",
141 "CPU_SSE2_FLAGS|CpuAES" },
142 { "CPU_PCLMUL_FLAGS",
143 "CPU_SSE2_FLAGS|CpuPCLMUL" },
144 { "CPU_FMA_FLAGS",
145 "CPU_AVX_FLAGS|CpuFMA" },
146 { "CPU_FMA4_FLAGS",
147 "CPU_AVX_FLAGS|CpuFMA4" },
148 { "CPU_XOP_FLAGS",
149 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
150 { "CPU_LWP_FLAGS",
151 "CpuLWP" },
152 { "CPU_BMI_FLAGS",
153 "CpuBMI" },
154 { "CPU_TBM_FLAGS",
155 "CpuTBM" },
156 { "CPU_MOVBE_FLAGS",
157 "CpuMovbe" },
158 { "CPU_CX16_FLAGS",
159 "CpuCX16" },
160 { "CPU_RDTSCP_FLAGS",
161 "CpuRdtscp" },
162 { "CPU_EPT_FLAGS",
163 "CpuEPT" },
164 { "CPU_FSGSBASE_FLAGS",
165 "CpuFSGSBase" },
166 { "CPU_RDRND_FLAGS",
167 "CpuRdRnd" },
168 { "CPU_F16C_FLAGS",
169 "CPU_AVX_FLAGS|CpuF16C" },
170 { "CPU_BMI2_FLAGS",
171 "CpuBMI2" },
172 { "CPU_LZCNT_FLAGS",
173 "CpuLZCNT" },
174 { "CPU_HLE_FLAGS",
175 "CpuHLE" },
176 { "CPU_RTM_FLAGS",
177 "CpuRTM" },
178 { "CPU_INVPCID_FLAGS",
179 "CpuINVPCID" },
180 { "CPU_VMFUNC_FLAGS",
181 "CpuVMFUNC" },
182 { "CPU_3DNOW_FLAGS",
183 "CPU_MMX_FLAGS|Cpu3dnow" },
184 { "CPU_3DNOWA_FLAGS",
185 "CPU_3DNOW_FLAGS|Cpu3dnowA" },
186 { "CPU_PADLOCK_FLAGS",
187 "CpuPadLock" },
188 { "CPU_SVME_FLAGS",
189 "CpuSVME" },
190 { "CPU_SSE4A_FLAGS",
191 "CPU_SSE3_FLAGS|CpuSSE4a" },
192 { "CPU_ABM_FLAGS",
193 "CpuABM" },
194 { "CPU_AVX_FLAGS",
195 "CPU_SSE4_2_FLAGS|CpuRegYMM|CpuAVX" },
196 { "CPU_AVX2_FLAGS",
197 "CPU_AVX_FLAGS|CpuAVX2" },
198 /* Don't use CPU_AVX2_FLAGS on CPU_AVX512F_FLAGS since AVX512F doesn't
199 support YMM registers. */
200 { "CPU_AVX512F_FLAGS",
201 "CpuVREX|CPU_SSE4_2_FLAGS|CpuRegZMM|CpuRegMask|CpuAVX|CpuAVX2|CpuAVX512F" },
202 { "CPU_AVX512CD_FLAGS",
203 "CPU_AVX512F_FLAGS|CpuAVX512CD" },
204 { "CPU_AVX512ER_FLAGS",
205 "CPU_AVX512F_FLAGS|CpuAVX512ER" },
206 { "CPU_AVX512PF_FLAGS",
207 "CPU_AVX512F_FLAGS|CpuAVX512PF" },
208 { "CPU_AVX512DQ_FLAGS",
209 "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
210 { "CPU_AVX512BW_FLAGS",
211 "CPU_AVX512F_FLAGS|CpuAVX512BW" },
212 { "CPU_AVX512VL_FLAGS",
213 /* Use CPU_AVX2_FLAGS on CPU_AVX512VL_FLAGS since AVX512VL supports YMM
214 registers. */
215 "CPU_AVX512F_FLAGS|CPU_AVX2_FLAGS|CpuAVX512VL" },
216 { "CPU_AVX512IFMA_FLAGS",
217 "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
218 { "CPU_AVX512VBMI_FLAGS",
219 "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
220 { "CPU_AVX512_4FMAPS_FLAGS",
221 "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
222 { "CPU_AVX512_4VNNIW_FLAGS",
223 "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
224 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
225 "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
226 { "CPU_AVX512_VBMI2_FLAGS",
227 "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
228 { "CPU_AVX512_VNNI_FLAGS",
229 "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
230 { "CPU_AVX512_BITALG_FLAGS",
231 "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
232 { "CPU_L1OM_FLAGS",
233 "unknown" },
234 { "CPU_K1OM_FLAGS",
235 "unknown" },
236 { "CPU_IAMCU_FLAGS",
237 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
238 { "CPU_ADX_FLAGS",
239 "CpuADX" },
240 { "CPU_RDSEED_FLAGS",
241 "CpuRdSeed" },
242 { "CPU_PRFCHW_FLAGS",
243 "CpuPRFCHW" },
244 { "CPU_SMAP_FLAGS",
245 "CpuSMAP" },
246 { "CPU_MPX_FLAGS",
247 "CpuMPX" },
248 { "CPU_SHA_FLAGS",
249 "CPU_SSE2_FLAGS|CpuSHA" },
250 { "CPU_CLFLUSHOPT_FLAGS",
251 "CpuClflushOpt" },
252 { "CPU_XSAVES_FLAGS",
253 "CPU_XSAVE_FLAGS|CpuXSAVES" },
254 { "CPU_XSAVEC_FLAGS",
255 "CPU_XSAVE_FLAGS|CpuXSAVEC" },
256 { "CPU_PREFETCHWT1_FLAGS",
257 "CpuPREFETCHWT1" },
258 { "CPU_SE1_FLAGS",
259 "CpuSE1" },
260 { "CPU_CLWB_FLAGS",
261 "CpuCLWB" },
262 { "CPU_CLZERO_FLAGS",
263 "CpuCLZERO" },
264 { "CPU_MWAITX_FLAGS",
265 "CpuMWAITX" },
266 { "CPU_OSPKE_FLAGS",
267 "CpuOSPKE" },
268 { "CPU_RDPID_FLAGS",
269 "CpuRDPID" },
270 { "CPU_PTWRITE_FLAGS",
271 "CpuPTWRITE" },
272 { "CPU_IBT_FLAGS",
273 "CpuIBT" },
274 { "CPU_SHSTK_FLAGS",
275 "CpuSHSTK" },
276 { "CPU_GFNI_FLAGS",
277 "CpuGFNI" },
278 { "CPU_VAES_FLAGS",
279 "CpuVAES" },
280 { "CPU_VPCLMULQDQ_FLAGS",
281 "CpuVPCLMULQDQ" },
282 { "CPU_WBNOINVD_FLAGS",
283 "CpuWBNOINVD" },
284 { "CPU_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 (VecESize),
642 BITFIELD (Broadcast),
643 BITFIELD (StaticRounding),
644 BITFIELD (SAE),
645 BITFIELD (Disp8MemShift),
646 BITFIELD (NoDefMask),
647 BITFIELD (ImplicitQuadGroup),
648 BITFIELD (Optimize),
649 BITFIELD (ATTMnemonic),
650 BITFIELD (ATTSyntax),
651 BITFIELD (IntelSyntax),
652 BITFIELD (AMD64),
653 BITFIELD (Intel64),
654 };
655
656 static bitfield operand_types[] =
657 {
658 BITFIELD (Reg),
659 BITFIELD (RegMMX),
660 BITFIELD (RegSIMD),
661 BITFIELD (RegMask),
662 BITFIELD (Imm1),
663 BITFIELD (Imm8),
664 BITFIELD (Imm8S),
665 BITFIELD (Imm16),
666 BITFIELD (Imm32),
667 BITFIELD (Imm32S),
668 BITFIELD (Imm64),
669 BITFIELD (BaseIndex),
670 BITFIELD (Disp8),
671 BITFIELD (Disp16),
672 BITFIELD (Disp32),
673 BITFIELD (Disp32S),
674 BITFIELD (Disp64),
675 BITFIELD (InOutPortReg),
676 BITFIELD (ShiftCount),
677 BITFIELD (Control),
678 BITFIELD (Debug),
679 BITFIELD (Test),
680 BITFIELD (SReg2),
681 BITFIELD (SReg3),
682 BITFIELD (Acc),
683 BITFIELD (JumpAbsolute),
684 BITFIELD (EsSeg),
685 BITFIELD (RegMem),
686 BITFIELD (Mem),
687 BITFIELD (Byte),
688 BITFIELD (Word),
689 BITFIELD (Dword),
690 BITFIELD (Fword),
691 BITFIELD (Qword),
692 BITFIELD (Tbyte),
693 BITFIELD (Xmmword),
694 BITFIELD (Ymmword),
695 BITFIELD (Zmmword),
696 BITFIELD (Unspecified),
697 BITFIELD (Anysize),
698 BITFIELD (Vec_Imm4),
699 BITFIELD (RegBND),
700 #ifdef OTUnused
701 BITFIELD (OTUnused),
702 #endif
703 };
704
705 static const char *filename;
706 static i386_cpu_flags active_cpu_flags;
707 static int active_isstring;
708
709 static int
710 compare (const void *x, const void *y)
711 {
712 const bitfield *xp = (const bitfield *) x;
713 const bitfield *yp = (const bitfield *) y;
714 return xp->position - yp->position;
715 }
716
717 static void
718 fail (const char *message, ...)
719 {
720 va_list args;
721
722 va_start (args, message);
723 fprintf (stderr, _("%s: error: "), program_name);
724 vfprintf (stderr, message, args);
725 va_end (args);
726 xexit (1);
727 }
728
729 static void
730 process_copyright (FILE *fp)
731 {
732 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
733 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
734 \n\
735 This file is part of the GNU opcodes library.\n\
736 \n\
737 This library is free software; you can redistribute it and/or modify\n\
738 it under the terms of the GNU General Public License as published by\n\
739 the Free Software Foundation; either version 3, or (at your option)\n\
740 any later version.\n\
741 \n\
742 It is distributed in the hope that it will be useful, but WITHOUT\n\
743 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
744 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
745 License for more details.\n\
746 \n\
747 You should have received a copy of the GNU General Public License\n\
748 along with this program; if not, write to the Free Software\n\
749 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
750 MA 02110-1301, USA. */\n");
751 }
752
753 /* Remove leading white spaces. */
754
755 static char *
756 remove_leading_whitespaces (char *str)
757 {
758 while (ISSPACE (*str))
759 str++;
760 return str;
761 }
762
763 /* Remove trailing white spaces. */
764
765 static void
766 remove_trailing_whitespaces (char *str)
767 {
768 size_t last = strlen (str);
769
770 if (last == 0)
771 return;
772
773 do
774 {
775 last--;
776 if (ISSPACE (str [last]))
777 str[last] = '\0';
778 else
779 break;
780 }
781 while (last != 0);
782 }
783
784 /* Find next field separated by SEP and terminate it. Return a
785 pointer to the one after it. */
786
787 static char *
788 next_field (char *str, char sep, char **next, char *last)
789 {
790 char *p;
791
792 p = remove_leading_whitespaces (str);
793 for (str = p; *str != sep && *str != '\0'; str++);
794
795 *str = '\0';
796 remove_trailing_whitespaces (p);
797
798 *next = str + 1;
799
800 if (p >= last)
801 abort ();
802
803 return p;
804 }
805
806 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
807
808 static int
809 set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
810 int lineno)
811 {
812 char *str, *next, *last;
813 unsigned int i;
814
815 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
816 if (strcmp (cpu_flag_init[i].name, f) == 0)
817 {
818 /* Turn on selective bits. */
819 char *init = xstrdup (cpu_flag_init[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 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
832 if (strcmp (operand_type_shorthands[i].name, f) == 0)
833 {
834 /* Turn on selective bits. */
835 char *init = xstrdup (operand_type_shorthands[i].init);
836 last = init + strlen (init);
837 for (next = init; next && next < last; )
838 {
839 str = next_field (next, '|', &next, last);
840 if (str)
841 set_bitfield (str, array, 1, size, lineno);
842 }
843 free (init);
844 return 0;
845 }
846
847 return -1;
848 }
849
850 static void
851 set_bitfield (char *f, bitfield *array, int value,
852 unsigned int size, int lineno)
853 {
854 unsigned int i;
855
856 if (strcmp (f, "CpuFP") == 0)
857 {
858 set_bitfield("Cpu387", array, value, size, lineno);
859 set_bitfield("Cpu287", array, value, size, lineno);
860 f = "Cpu8087";
861 }
862 else if (strcmp (f, "Mmword") == 0)
863 f= "Qword";
864 else if (strcmp (f, "Oword") == 0)
865 f= "Xmmword";
866
867 for (i = 0; i < size; i++)
868 if (strcasecmp (array[i].name, f) == 0)
869 {
870 array[i].value = value;
871 return;
872 }
873
874 if (value)
875 {
876 const char *v = strchr (f, '=');
877
878 if (v)
879 {
880 size_t n = v - f;
881 char *end;
882
883 for (i = 0; i < size; i++)
884 if (strncasecmp (array[i].name, f, n) == 0)
885 {
886 value = strtol (v + 1, &end, 0);
887 if (*end == '\0')
888 {
889 array[i].value = value;
890 return;
891 }
892 break;
893 }
894 }
895 }
896
897 /* Handle shorthands. */
898 if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno))
899 return;
900
901 if (lineno != -1)
902 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
903 else
904 fail (_("unknown bitfield: %s\n"), f);
905 }
906
907 static void
908 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
909 int macro, const char *comma, const char *indent)
910 {
911 unsigned int i;
912
913 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
914
915 fprintf (table, "%s{ { ", indent);
916
917 for (i = 0; i < size - 1; i++)
918 {
919 if (((i + 1) % 20) != 0)
920 fprintf (table, "%d, ", flags[i].value);
921 else
922 fprintf (table, "%d,", flags[i].value);
923 if (((i + 1) % 20) == 0)
924 {
925 /* We need \\ for macro. */
926 if (macro)
927 fprintf (table, " \\\n %s", indent);
928 else
929 fprintf (table, "\n %s", indent);
930 }
931 if (flags[i].value)
932 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
933 }
934
935 fprintf (table, "%d } }%s\n", flags[i].value, comma);
936 }
937
938 static void
939 process_i386_cpu_flag (FILE *table, char *flag, int macro,
940 const char *comma, const char *indent,
941 int lineno)
942 {
943 char *str, *next, *last;
944 unsigned int i;
945 bitfield flags [ARRAY_SIZE (cpu_flags)];
946
947 /* Copy the default cpu flags. */
948 memcpy (flags, cpu_flags, sizeof (cpu_flags));
949
950 if (strcasecmp (flag, "unknown") == 0)
951 {
952 /* We turn on everything except for cpu64 in case of
953 CPU_UNKNOWN_FLAGS. */
954 for (i = 0; i < ARRAY_SIZE (flags); i++)
955 if (flags[i].position != Cpu64)
956 flags[i].value = 1;
957 }
958 else if (flag[0] == '~')
959 {
960 last = flag + strlen (flag);
961
962 if (flag[1] == '(')
963 {
964 last -= 1;
965 next = flag + 2;
966 if (*last != ')')
967 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
968 lineno, flag);
969 *last = '\0';
970 }
971 else
972 next = flag + 1;
973
974 /* First we turn on everything except for cpu64. */
975 for (i = 0; i < ARRAY_SIZE (flags); i++)
976 if (flags[i].position != Cpu64)
977 flags[i].value = 1;
978
979 /* Turn off selective bits. */
980 for (; next && next < last; )
981 {
982 str = next_field (next, '|', &next, last);
983 if (str)
984 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
985 }
986 }
987 else if (strcmp (flag, "0"))
988 {
989 /* Turn on selective bits. */
990 last = flag + strlen (flag);
991 for (next = flag; next && next < last; )
992 {
993 str = next_field (next, '|', &next, last);
994 if (str)
995 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
996 }
997 }
998
999 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1000 comma, indent);
1001 }
1002
1003 static void
1004 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1005 {
1006 unsigned int i;
1007
1008 fprintf (table, " { ");
1009
1010 for (i = 0; i < size - 1; i++)
1011 {
1012 if (((i + 1) % 20) != 0)
1013 fprintf (table, "%d, ", modifier[i].value);
1014 else
1015 fprintf (table, "%d,", modifier[i].value);
1016 if (((i + 1) % 20) == 0)
1017 fprintf (table, "\n ");
1018 }
1019
1020 fprintf (table, "%d },\n", modifier[i].value);
1021 }
1022
1023 static void
1024 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
1025 {
1026 char *str, *next, *last;
1027 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1028
1029 active_isstring = 0;
1030
1031 /* Copy the default opcode modifier. */
1032 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1033
1034 if (strcmp (mod, "0"))
1035 {
1036 last = mod + strlen (mod);
1037 for (next = mod; next && next < last; )
1038 {
1039 str = next_field (next, '|', &next, last);
1040 if (str)
1041 {
1042 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
1043 lineno);
1044 if (strcasecmp(str, "IsString") == 0)
1045 active_isstring = 1;
1046 }
1047 }
1048 }
1049 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1050 }
1051
1052 enum stage {
1053 stage_macros,
1054 stage_opcodes,
1055 stage_registers,
1056 };
1057
1058 static void
1059 output_operand_type (FILE *table, bitfield *types, unsigned int size,
1060 enum stage stage, const char *indent)
1061 {
1062 unsigned int i;
1063
1064 fprintf (table, "{ { ");
1065
1066 for (i = 0; i < size - 1; i++)
1067 {
1068 if (((i + 1) % 20) != 0)
1069 fprintf (table, "%d, ", types[i].value);
1070 else
1071 fprintf (table, "%d,", types[i].value);
1072 if (((i + 1) % 20) == 0)
1073 {
1074 /* We need \\ for macro. */
1075 if (stage == stage_macros)
1076 fprintf (table, " \\\n%s", indent);
1077 else
1078 fprintf (table, "\n%s", indent);
1079 }
1080 }
1081
1082 fprintf (table, "%d } }", types[i].value);
1083 }
1084
1085 static void
1086 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1087 const char *indent, int lineno)
1088 {
1089 char *str, *next, *last;
1090 bitfield types [ARRAY_SIZE (operand_types)];
1091
1092 /* Copy the default operand type. */
1093 memcpy (types, operand_types, sizeof (types));
1094
1095 if (strcmp (op, "0"))
1096 {
1097 int baseindex = 0;
1098
1099 last = op + strlen (op);
1100 for (next = op; next && next < last; )
1101 {
1102 str = next_field (next, '|', &next, last);
1103 if (str)
1104 {
1105 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1106 if (strcasecmp(str, "BaseIndex") == 0)
1107 baseindex = 1;
1108 }
1109 }
1110
1111 if (stage == stage_opcodes && baseindex && !active_isstring)
1112 {
1113 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1114 if (!active_cpu_flags.bitfield.cpu64
1115 && !active_cpu_flags.bitfield.cpumpx)
1116 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1117 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1118 if (!active_cpu_flags.bitfield.cpuno64)
1119 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1120 }
1121 }
1122 output_operand_type (table, types, ARRAY_SIZE (types), stage,
1123 indent);
1124 }
1125
1126 static void
1127 output_i386_opcode (FILE *table, const char *name, char *str,
1128 char *last, int lineno)
1129 {
1130 unsigned int i;
1131 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1132 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1133
1134 /* Find number of operands. */
1135 operands = next_field (str, ',', &str, last);
1136
1137 /* Find base_opcode. */
1138 base_opcode = next_field (str, ',', &str, last);
1139
1140 /* Find extension_opcode. */
1141 extension_opcode = next_field (str, ',', &str, last);
1142
1143 /* Find opcode_length. */
1144 opcode_length = next_field (str, ',', &str, last);
1145
1146 /* Find cpu_flags. */
1147 cpu_flags = next_field (str, ',', &str, last);
1148
1149 /* Find opcode_modifier. */
1150 opcode_modifier = next_field (str, ',', &str, last);
1151
1152 /* Remove the first {. */
1153 str = remove_leading_whitespaces (str);
1154 if (*str != '{')
1155 abort ();
1156 str = remove_leading_whitespaces (str + 1);
1157
1158 i = strlen (str);
1159
1160 /* There are at least "X}". */
1161 if (i < 2)
1162 abort ();
1163
1164 /* Remove trailing white spaces and }. */
1165 do
1166 {
1167 i--;
1168 if (ISSPACE (str[i]) || str[i] == '}')
1169 str[i] = '\0';
1170 else
1171 break;
1172 }
1173 while (i != 0);
1174
1175 last = str + i;
1176
1177 /* Find operand_types. */
1178 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1179 {
1180 if (str >= last)
1181 {
1182 operand_types [i] = NULL;
1183 break;
1184 }
1185
1186 operand_types [i] = next_field (str, ',', &str, last);
1187 if (*operand_types[i] == '0')
1188 {
1189 if (i != 0)
1190 operand_types[i] = NULL;
1191 break;
1192 }
1193 }
1194
1195 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1196 name, operands, base_opcode, extension_opcode,
1197 opcode_length);
1198
1199 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1200
1201 process_i386_opcode_modifier (table, opcode_modifier, lineno);
1202
1203 fprintf (table, " { ");
1204
1205 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1206 {
1207 if (operand_types[i] == NULL || *operand_types[i] == '0')
1208 {
1209 if (i == 0)
1210 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1211 lineno);
1212 break;
1213 }
1214
1215 if (i != 0)
1216 fprintf (table, ",\n ");
1217
1218 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1219 "\t ", lineno);
1220 }
1221 fprintf (table, " } },\n");
1222 }
1223
1224 struct opcode_hash_entry
1225 {
1226 struct opcode_hash_entry *next;
1227 char *name;
1228 char *opcode;
1229 int lineno;
1230 };
1231
1232 /* Calculate the hash value of an opcode hash entry P. */
1233
1234 static hashval_t
1235 opcode_hash_hash (const void *p)
1236 {
1237 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1238 return htab_hash_string (entry->name);
1239 }
1240
1241 /* Compare a string Q against an opcode hash entry P. */
1242
1243 static int
1244 opcode_hash_eq (const void *p, const void *q)
1245 {
1246 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1247 const char *name = (const char *) q;
1248 return strcmp (name, entry->name) == 0;
1249 }
1250
1251 static void
1252 process_i386_opcodes (FILE *table)
1253 {
1254 FILE *fp;
1255 char buf[2048];
1256 unsigned int i, j;
1257 char *str, *p, *last, *name;
1258 struct opcode_hash_entry **hash_slot, **entry, *next;
1259 htab_t opcode_hash_table;
1260 struct opcode_hash_entry **opcode_array;
1261 unsigned int opcode_array_size = 1024;
1262 int lineno = 0;
1263
1264 filename = "i386-opc.tbl";
1265 fp = fopen (filename, "r");
1266
1267 if (fp == NULL)
1268 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
1269 xstrerror (errno));
1270
1271 i = 0;
1272 opcode_array = (struct opcode_hash_entry **)
1273 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1274
1275 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1276 opcode_hash_eq, NULL,
1277 xcalloc, free);
1278
1279 fprintf (table, "\n/* i386 opcode table. */\n\n");
1280 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1281
1282 /* Put everything on opcode array. */
1283 while (!feof (fp))
1284 {
1285 if (fgets (buf, sizeof (buf), fp) == NULL)
1286 break;
1287
1288 lineno++;
1289
1290 p = remove_leading_whitespaces (buf);
1291
1292 /* Skip comments. */
1293 str = strstr (p, "//");
1294 if (str != NULL)
1295 str[0] = '\0';
1296
1297 /* Remove trailing white spaces. */
1298 remove_trailing_whitespaces (p);
1299
1300 switch (p[0])
1301 {
1302 case '#':
1303 /* Ignore comments. */
1304 case '\0':
1305 continue;
1306 break;
1307 default:
1308 break;
1309 }
1310
1311 last = p + strlen (p);
1312
1313 /* Find name. */
1314 name = next_field (p, ',', &str, last);
1315
1316 /* Get the slot in hash table. */
1317 hash_slot = (struct opcode_hash_entry **)
1318 htab_find_slot_with_hash (opcode_hash_table, name,
1319 htab_hash_string (name),
1320 INSERT);
1321
1322 if (*hash_slot == NULL)
1323 {
1324 /* It is the new one. Put it on opcode array. */
1325 if (i >= opcode_array_size)
1326 {
1327 /* Grow the opcode array when needed. */
1328 opcode_array_size += 1024;
1329 opcode_array = (struct opcode_hash_entry **)
1330 xrealloc (opcode_array,
1331 sizeof (*opcode_array) * opcode_array_size);
1332 }
1333
1334 opcode_array[i] = (struct opcode_hash_entry *)
1335 xmalloc (sizeof (struct opcode_hash_entry));
1336 opcode_array[i]->next = NULL;
1337 opcode_array[i]->name = xstrdup (name);
1338 opcode_array[i]->opcode = xstrdup (str);
1339 opcode_array[i]->lineno = lineno;
1340 *hash_slot = opcode_array[i];
1341 i++;
1342 }
1343 else
1344 {
1345 /* Append it to the existing one. */
1346 entry = hash_slot;
1347 while ((*entry) != NULL)
1348 entry = &(*entry)->next;
1349 *entry = (struct opcode_hash_entry *)
1350 xmalloc (sizeof (struct opcode_hash_entry));
1351 (*entry)->next = NULL;
1352 (*entry)->name = (*hash_slot)->name;
1353 (*entry)->opcode = xstrdup (str);
1354 (*entry)->lineno = lineno;
1355 }
1356 }
1357
1358 /* Process opcode array. */
1359 for (j = 0; j < i; j++)
1360 {
1361 for (next = opcode_array[j]; next; next = next->next)
1362 {
1363 name = next->name;
1364 str = next->opcode;
1365 lineno = next->lineno;
1366 last = str + strlen (str);
1367 output_i386_opcode (table, name, str, last, lineno);
1368 }
1369 }
1370
1371 fclose (fp);
1372
1373 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1374
1375 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1376
1377 process_i386_opcode_modifier (table, "0", -1);
1378
1379 fprintf (table, " { ");
1380 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1381 fprintf (table, " } }\n");
1382
1383 fprintf (table, "};\n");
1384 }
1385
1386 static void
1387 process_i386_registers (FILE *table)
1388 {
1389 FILE *fp;
1390 char buf[2048];
1391 char *str, *p, *last;
1392 char *reg_name, *reg_type, *reg_flags, *reg_num;
1393 char *dw2_32_num, *dw2_64_num;
1394 int lineno = 0;
1395
1396 filename = "i386-reg.tbl";
1397 fp = fopen (filename, "r");
1398 if (fp == NULL)
1399 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1400 xstrerror (errno));
1401
1402 fprintf (table, "\n/* i386 register table. */\n\n");
1403 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1404
1405 while (!feof (fp))
1406 {
1407 if (fgets (buf, sizeof (buf), fp) == NULL)
1408 break;
1409
1410 lineno++;
1411
1412 p = remove_leading_whitespaces (buf);
1413
1414 /* Skip comments. */
1415 str = strstr (p, "//");
1416 if (str != NULL)
1417 str[0] = '\0';
1418
1419 /* Remove trailing white spaces. */
1420 remove_trailing_whitespaces (p);
1421
1422 switch (p[0])
1423 {
1424 case '#':
1425 fprintf (table, "%s\n", p);
1426 case '\0':
1427 continue;
1428 break;
1429 default:
1430 break;
1431 }
1432
1433 last = p + strlen (p);
1434
1435 /* Find reg_name. */
1436 reg_name = next_field (p, ',', &str, last);
1437
1438 /* Find reg_type. */
1439 reg_type = next_field (str, ',', &str, last);
1440
1441 /* Find reg_flags. */
1442 reg_flags = next_field (str, ',', &str, last);
1443
1444 /* Find reg_num. */
1445 reg_num = next_field (str, ',', &str, last);
1446
1447 fprintf (table, " { \"%s\",\n ", reg_name);
1448
1449 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1450 lineno);
1451
1452 /* Find 32-bit Dwarf2 register number. */
1453 dw2_32_num = next_field (str, ',', &str, last);
1454
1455 /* Find 64-bit Dwarf2 register number. */
1456 dw2_64_num = next_field (str, ',', &str, last);
1457
1458 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1459 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1460 }
1461
1462 fclose (fp);
1463
1464 fprintf (table, "};\n");
1465
1466 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1467 }
1468
1469 static void
1470 process_i386_initializers (void)
1471 {
1472 unsigned int i;
1473 FILE *fp = fopen ("i386-init.h", "w");
1474 char *init;
1475
1476 if (fp == NULL)
1477 fail (_("can't create i386-init.h, errno = %s\n"),
1478 xstrerror (errno));
1479
1480 process_copyright (fp);
1481
1482 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1483 {
1484 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1485 init = xstrdup (cpu_flag_init[i].init);
1486 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1487 free (init);
1488 }
1489
1490 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1491 {
1492 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1493 init = xstrdup (operand_type_init[i].init);
1494 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1495 free (init);
1496 }
1497 fprintf (fp, "\n");
1498
1499 fclose (fp);
1500 }
1501
1502 /* Program options. */
1503 #define OPTION_SRCDIR 200
1504
1505 struct option long_options[] =
1506 {
1507 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1508 {"debug", no_argument, NULL, 'd'},
1509 {"version", no_argument, NULL, 'V'},
1510 {"help", no_argument, NULL, 'h'},
1511 {0, no_argument, NULL, 0}
1512 };
1513
1514 static void
1515 print_version (void)
1516 {
1517 printf ("%s: version 1.0\n", program_name);
1518 xexit (0);
1519 }
1520
1521 static void
1522 usage (FILE * stream, int status)
1523 {
1524 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1525 program_name);
1526 xexit (status);
1527 }
1528
1529 int
1530 main (int argc, char **argv)
1531 {
1532 extern int chdir (char *);
1533 char *srcdir = NULL;
1534 int c;
1535 unsigned int i, cpumax;
1536 FILE *table;
1537
1538 program_name = *argv;
1539 xmalloc_set_program_name (program_name);
1540
1541 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1542 switch (c)
1543 {
1544 case OPTION_SRCDIR:
1545 srcdir = optarg;
1546 break;
1547 case 'V':
1548 case 'v':
1549 print_version ();
1550 break;
1551 case 'd':
1552 debug = 1;
1553 break;
1554 case 'h':
1555 case '?':
1556 usage (stderr, 0);
1557 default:
1558 case 0:
1559 break;
1560 }
1561
1562 if (optind != argc)
1563 usage (stdout, 1);
1564
1565 if (srcdir != NULL)
1566 if (chdir (srcdir) != 0)
1567 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1568 srcdir, xstrerror (errno));
1569
1570 /* cpu_flags isn't sorted by position. */
1571 cpumax = 0;
1572 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1573 if (cpu_flags[i].position > cpumax)
1574 cpumax = cpu_flags[i].position;
1575
1576 /* Check the unused bitfield in i386_cpu_flags. */
1577 #ifdef CpuUnused
1578 if ((cpumax - 1) != CpuMax)
1579 fail (_("CpuMax != %d!\n"), cpumax);
1580 #else
1581 if (cpumax != CpuMax)
1582 fail (_("CpuMax != %d!\n"), cpumax);
1583
1584 c = CpuNumOfBits - CpuMax - 1;
1585 if (c)
1586 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1587 #endif
1588
1589 /* Check the unused bitfield in i386_operand_type. */
1590 #ifndef OTUnused
1591 c = OTNumOfBits - OTMax - 1;
1592 if (c)
1593 fail (_("%d unused bits in i386_operand_type.\n"), c);
1594 #endif
1595
1596 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1597 compare);
1598
1599 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1600 sizeof (opcode_modifiers [0]), compare);
1601
1602 qsort (operand_types, ARRAY_SIZE (operand_types),
1603 sizeof (operand_types [0]), compare);
1604
1605 table = fopen ("i386-tbl.h", "w");
1606 if (table == NULL)
1607 fail (_("can't create i386-tbl.h, errno = %s\n"),
1608 xstrerror (errno));
1609
1610 process_copyright (table);
1611
1612 process_i386_opcodes (table);
1613 process_i386_registers (table);
1614 process_i386_initializers ();
1615
1616 fclose (table);
1617
1618 exit (0);
1619 }
This page took 0.060668 seconds and 3 git commands to generate.