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