]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/i386-gen.c
x86: drop "mem" operand type attribute
[thirdparty/binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.
2
3 This file is part of the GNU opcodes library.
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
19
20 #include "sysdep.h"
21 #include <stdio.h>
22 #include <errno.h>
23 #include "getopt.h"
24 #include "libiberty.h"
25 #include "hashtab.h"
26 #include "safe-ctype.h"
27
28 #include "i386-opc.h"
29
30 #include <libintl.h>
31 #define _(String) gettext (String)
32
33 static const char *program_name = NULL;
34 static int debug = 0;
35
36 typedef struct initializer
37 {
38 const char *name;
39 const char *init;
40 } initializer;
41
42 static initializer cpu_flag_init[] =
43 {
44 { "CPU_UNKNOWN_FLAGS",
45 "~(CpuL1OM|CpuK1OM)" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
50 { "CPU_NONE_FLAGS",
51 "0" },
52 { "CPU_I186_FLAGS",
53 "Cpu186" },
54 { "CPU_I286_FLAGS",
55 "CPU_I186_FLAGS|Cpu286" },
56 { "CPU_I386_FLAGS",
57 "CPU_I286_FLAGS|Cpu386" },
58 { "CPU_I486_FLAGS",
59 "CPU_I386_FLAGS|Cpu486" },
60 { "CPU_I586_FLAGS",
61 "CPU_I486_FLAGS|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|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 "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG" },
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 (CpuClflushOpt),
555 BITFIELD (CpuXSAVES),
556 BITFIELD (CpuXSAVEC),
557 BITFIELD (CpuPREFETCHWT1),
558 BITFIELD (CpuSE1),
559 BITFIELD (CpuCLWB),
560 BITFIELD (Cpu64),
561 BITFIELD (CpuNo64),
562 BITFIELD (CpuMPX),
563 BITFIELD (CpuAVX512IFMA),
564 BITFIELD (CpuAVX512VBMI),
565 BITFIELD (CpuAVX512_4FMAPS),
566 BITFIELD (CpuAVX512_4VNNIW),
567 BITFIELD (CpuAVX512_VPOPCNTDQ),
568 BITFIELD (CpuAVX512_VBMI2),
569 BITFIELD (CpuAVX512_VNNI),
570 BITFIELD (CpuAVX512_BITALG),
571 BITFIELD (CpuMWAITX),
572 BITFIELD (CpuCLZERO),
573 BITFIELD (CpuOSPKE),
574 BITFIELD (CpuRDPID),
575 BITFIELD (CpuPTWRITE),
576 BITFIELD (CpuIBT),
577 BITFIELD (CpuSHSTK),
578 BITFIELD (CpuGFNI),
579 BITFIELD (CpuVAES),
580 BITFIELD (CpuVPCLMULQDQ),
581 BITFIELD (CpuWBNOINVD),
582 BITFIELD (CpuPCONFIG),
583 BITFIELD (CpuWAITPKG),
584 BITFIELD (CpuCLDEMOTE),
585 BITFIELD (CpuMOVDIRI),
586 BITFIELD (CpuMOVDIR64B),
587 #ifdef CpuUnused
588 BITFIELD (CpuUnused),
589 #endif
590 };
591
592 static bitfield opcode_modifiers[] =
593 {
594 BITFIELD (D),
595 BITFIELD (W),
596 BITFIELD (Load),
597 BITFIELD (Modrm),
598 BITFIELD (ShortForm),
599 BITFIELD (Jump),
600 BITFIELD (JumpDword),
601 BITFIELD (JumpByte),
602 BITFIELD (JumpInterSegment),
603 BITFIELD (FloatMF),
604 BITFIELD (FloatR),
605 BITFIELD (Size16),
606 BITFIELD (Size32),
607 BITFIELD (Size64),
608 BITFIELD (CheckRegSize),
609 BITFIELD (IgnoreSize),
610 BITFIELD (DefaultSize),
611 BITFIELD (No_bSuf),
612 BITFIELD (No_wSuf),
613 BITFIELD (No_lSuf),
614 BITFIELD (No_sSuf),
615 BITFIELD (No_qSuf),
616 BITFIELD (No_ldSuf),
617 BITFIELD (FWait),
618 BITFIELD (IsString),
619 BITFIELD (BNDPrefixOk),
620 BITFIELD (NoTrackPrefixOk),
621 BITFIELD (IsLockable),
622 BITFIELD (RegKludge),
623 BITFIELD (Implicit1stXmm0),
624 BITFIELD (RepPrefixOk),
625 BITFIELD (HLEPrefixOk),
626 BITFIELD (ToDword),
627 BITFIELD (ToQword),
628 BITFIELD (AddrPrefixOpReg),
629 BITFIELD (IsPrefix),
630 BITFIELD (ImmExt),
631 BITFIELD (NoRex64),
632 BITFIELD (Rex64),
633 BITFIELD (Ugh),
634 BITFIELD (Vex),
635 BITFIELD (VexVVVV),
636 BITFIELD (VexW),
637 BITFIELD (VexOpcode),
638 BITFIELD (VexSources),
639 BITFIELD (VecSIB),
640 BITFIELD (SSE2AVX),
641 BITFIELD (NoAVX),
642 BITFIELD (EVex),
643 BITFIELD (Masking),
644 BITFIELD (Broadcast),
645 BITFIELD (StaticRounding),
646 BITFIELD (SAE),
647 BITFIELD (Disp8MemShift),
648 BITFIELD (NoDefMask),
649 BITFIELD (ImplicitQuadGroup),
650 BITFIELD (Optimize),
651 BITFIELD (ATTMnemonic),
652 BITFIELD (ATTSyntax),
653 BITFIELD (IntelSyntax),
654 BITFIELD (AMD64),
655 BITFIELD (Intel64),
656 };
657
658 static bitfield operand_types[] =
659 {
660 BITFIELD (Reg),
661 BITFIELD (RegMMX),
662 BITFIELD (RegSIMD),
663 BITFIELD (RegMask),
664 BITFIELD (Imm1),
665 BITFIELD (Imm8),
666 BITFIELD (Imm8S),
667 BITFIELD (Imm16),
668 BITFIELD (Imm32),
669 BITFIELD (Imm32S),
670 BITFIELD (Imm64),
671 BITFIELD (BaseIndex),
672 BITFIELD (Disp8),
673 BITFIELD (Disp16),
674 BITFIELD (Disp32),
675 BITFIELD (Disp32S),
676 BITFIELD (Disp64),
677 BITFIELD (InOutPortReg),
678 BITFIELD (ShiftCount),
679 BITFIELD (Control),
680 BITFIELD (Debug),
681 BITFIELD (Test),
682 BITFIELD (SReg2),
683 BITFIELD (SReg3),
684 BITFIELD (Acc),
685 BITFIELD (JumpAbsolute),
686 BITFIELD (EsSeg),
687 BITFIELD (RegMem),
688 BITFIELD (Byte),
689 BITFIELD (Word),
690 BITFIELD (Dword),
691 BITFIELD (Fword),
692 BITFIELD (Qword),
693 BITFIELD (Tbyte),
694 BITFIELD (Xmmword),
695 BITFIELD (Ymmword),
696 BITFIELD (Zmmword),
697 BITFIELD (Unspecified),
698 BITFIELD (Anysize),
699 BITFIELD (Vec_Imm4),
700 BITFIELD (RegBND),
701 #ifdef OTUnused
702 BITFIELD (OTUnused),
703 #endif
704 };
705
706 static const char *filename;
707 static i386_cpu_flags active_cpu_flags;
708 static int active_isstring;
709
710 static int
711 compare (const void *x, const void *y)
712 {
713 const bitfield *xp = (const bitfield *) x;
714 const bitfield *yp = (const bitfield *) y;
715 return xp->position - yp->position;
716 }
717
718 static void
719 fail (const char *message, ...)
720 {
721 va_list args;
722
723 va_start (args, message);
724 fprintf (stderr, _("%s: error: "), program_name);
725 vfprintf (stderr, message, args);
726 va_end (args);
727 xexit (1);
728 }
729
730 static void
731 process_copyright (FILE *fp)
732 {
733 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
734 /* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
735 \n\
736 This file is part of the GNU opcodes library.\n\
737 \n\
738 This library is free software; you can redistribute it and/or modify\n\
739 it under the terms of the GNU General Public License as published by\n\
740 the Free Software Foundation; either version 3, or (at your option)\n\
741 any later version.\n\
742 \n\
743 It is distributed in the hope that it will be useful, but WITHOUT\n\
744 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
745 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
746 License for more details.\n\
747 \n\
748 You should have received a copy of the GNU General Public License\n\
749 along with this program; if not, write to the Free Software\n\
750 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
751 MA 02110-1301, USA. */\n");
752 }
753
754 /* Remove leading white spaces. */
755
756 static char *
757 remove_leading_whitespaces (char *str)
758 {
759 while (ISSPACE (*str))
760 str++;
761 return str;
762 }
763
764 /* Remove trailing white spaces. */
765
766 static void
767 remove_trailing_whitespaces (char *str)
768 {
769 size_t last = strlen (str);
770
771 if (last == 0)
772 return;
773
774 do
775 {
776 last--;
777 if (ISSPACE (str [last]))
778 str[last] = '\0';
779 else
780 break;
781 }
782 while (last != 0);
783 }
784
785 /* Find next field separated by SEP and terminate it. Return a
786 pointer to the one after it. */
787
788 static char *
789 next_field (char *str, char sep, char **next, char *last)
790 {
791 char *p;
792
793 p = remove_leading_whitespaces (str);
794 for (str = p; *str != sep && *str != '\0'; str++);
795
796 *str = '\0';
797 remove_trailing_whitespaces (p);
798
799 *next = str + 1;
800
801 if (p >= last)
802 abort ();
803
804 return p;
805 }
806
807 static void set_bitfield (char *, bitfield *, int, unsigned int, int);
808
809 static int
810 set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
811 int lineno)
812 {
813 char *str, *next, *last;
814 unsigned int i;
815
816 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
817 if (strcmp (cpu_flag_init[i].name, f) == 0)
818 {
819 /* Turn on selective bits. */
820 char *init = xstrdup (cpu_flag_init[i].init);
821 last = init + strlen (init);
822 for (next = init; next && next < last; )
823 {
824 str = next_field (next, '|', &next, last);
825 if (str)
826 set_bitfield (str, array, 1, size, lineno);
827 }
828 free (init);
829 return 0;
830 }
831
832 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
833 if (strcmp (operand_type_shorthands[i].name, f) == 0)
834 {
835 /* Turn on selective bits. */
836 char *init = xstrdup (operand_type_shorthands[i].init);
837 last = init + strlen (init);
838 for (next = init; next && next < last; )
839 {
840 str = next_field (next, '|', &next, last);
841 if (str)
842 set_bitfield (str, array, 1, size, lineno);
843 }
844 free (init);
845 return 0;
846 }
847
848 return -1;
849 }
850
851 static void
852 set_bitfield (char *f, bitfield *array, int value,
853 unsigned int size, int lineno)
854 {
855 unsigned int i;
856
857 if (strcmp (f, "CpuFP") == 0)
858 {
859 set_bitfield("Cpu387", array, value, size, lineno);
860 set_bitfield("Cpu287", array, value, size, lineno);
861 f = "Cpu8087";
862 }
863 else if (strcmp (f, "Mmword") == 0)
864 f= "Qword";
865 else if (strcmp (f, "Oword") == 0)
866 f= "Xmmword";
867
868 for (i = 0; i < size; i++)
869 if (strcasecmp (array[i].name, f) == 0)
870 {
871 array[i].value = value;
872 return;
873 }
874
875 if (value)
876 {
877 const char *v = strchr (f, '=');
878
879 if (v)
880 {
881 size_t n = v - f;
882 char *end;
883
884 for (i = 0; i < size; i++)
885 if (strncasecmp (array[i].name, f, n) == 0)
886 {
887 value = strtol (v + 1, &end, 0);
888 if (*end == '\0')
889 {
890 array[i].value = value;
891 return;
892 }
893 break;
894 }
895 }
896 }
897
898 /* Handle shorthands. */
899 if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno))
900 return;
901
902 if (lineno != -1)
903 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
904 else
905 fail (_("unknown bitfield: %s\n"), f);
906 }
907
908 static void
909 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
910 int macro, const char *comma, const char *indent)
911 {
912 unsigned int i;
913
914 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
915
916 fprintf (table, "%s{ { ", indent);
917
918 for (i = 0; i < size - 1; i++)
919 {
920 if (((i + 1) % 20) != 0)
921 fprintf (table, "%d, ", flags[i].value);
922 else
923 fprintf (table, "%d,", flags[i].value);
924 if (((i + 1) % 20) == 0)
925 {
926 /* We need \\ for macro. */
927 if (macro)
928 fprintf (table, " \\\n %s", indent);
929 else
930 fprintf (table, "\n %s", indent);
931 }
932 if (flags[i].value)
933 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
934 }
935
936 fprintf (table, "%d } }%s\n", flags[i].value, comma);
937 }
938
939 static void
940 process_i386_cpu_flag (FILE *table, char *flag, int macro,
941 const char *comma, const char *indent,
942 int lineno)
943 {
944 char *str, *next, *last;
945 unsigned int i;
946 bitfield flags [ARRAY_SIZE (cpu_flags)];
947
948 /* Copy the default cpu flags. */
949 memcpy (flags, cpu_flags, sizeof (cpu_flags));
950
951 if (strcasecmp (flag, "unknown") == 0)
952 {
953 /* We turn on everything except for cpu64 in case of
954 CPU_UNKNOWN_FLAGS. */
955 for (i = 0; i < ARRAY_SIZE (flags); i++)
956 if (flags[i].position != Cpu64)
957 flags[i].value = 1;
958 }
959 else if (flag[0] == '~')
960 {
961 last = flag + strlen (flag);
962
963 if (flag[1] == '(')
964 {
965 last -= 1;
966 next = flag + 2;
967 if (*last != ')')
968 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
969 lineno, flag);
970 *last = '\0';
971 }
972 else
973 next = flag + 1;
974
975 /* First we turn on everything except for cpu64. */
976 for (i = 0; i < ARRAY_SIZE (flags); i++)
977 if (flags[i].position != Cpu64)
978 flags[i].value = 1;
979
980 /* Turn off selective bits. */
981 for (; next && next < last; )
982 {
983 str = next_field (next, '|', &next, last);
984 if (str)
985 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
986 }
987 }
988 else if (strcmp (flag, "0"))
989 {
990 /* Turn on selective bits. */
991 last = flag + strlen (flag);
992 for (next = flag; next && next < last; )
993 {
994 str = next_field (next, '|', &next, last);
995 if (str)
996 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
997 }
998 }
999
1000 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1001 comma, indent);
1002 }
1003
1004 static void
1005 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1006 {
1007 unsigned int i;
1008
1009 fprintf (table, " { ");
1010
1011 for (i = 0; i < size - 1; i++)
1012 {
1013 if (((i + 1) % 20) != 0)
1014 fprintf (table, "%d, ", modifier[i].value);
1015 else
1016 fprintf (table, "%d,", modifier[i].value);
1017 if (((i + 1) % 20) == 0)
1018 fprintf (table, "\n ");
1019 }
1020
1021 fprintf (table, "%d },\n", modifier[i].value);
1022 }
1023
1024 static int
1025 adjust_broadcast_modifier (char **opnd)
1026 {
1027 char *str, *next, *last, *op;
1028 int bcst_type = INT_MAX;
1029
1030 /* Skip the immediate operand. */
1031 op = opnd[0];
1032 if (strcasecmp(op, "Imm8") == 0)
1033 op = opnd[1];
1034
1035 op = xstrdup (op);
1036 last = op + strlen (op);
1037 for (next = op; next && next < last; )
1038 {
1039 str = next_field (next, '|', &next, last);
1040 if (str)
1041 {
1042 if (strcasecmp(str, "Byte") == 0)
1043 {
1044 /* The smalest broadcast type, no need to check
1045 further. */
1046 bcst_type = BYTE_BROADCAST;
1047 break;
1048 }
1049 else if (strcasecmp(str, "Word") == 0)
1050 {
1051 if (bcst_type > WORD_BROADCAST)
1052 bcst_type = WORD_BROADCAST;
1053 }
1054 else if (strcasecmp(str, "Dword") == 0)
1055 {
1056 if (bcst_type > DWORD_BROADCAST)
1057 bcst_type = DWORD_BROADCAST;
1058 }
1059 else if (strcasecmp(str, "Qword") == 0)
1060 {
1061 if (bcst_type > QWORD_BROADCAST)
1062 bcst_type = QWORD_BROADCAST;
1063 }
1064 }
1065 }
1066 free (op);
1067
1068 if (bcst_type == INT_MAX)
1069 fail (_("unknown broadcast operand: %s\n"), op);
1070
1071 return bcst_type;
1072 }
1073
1074 static void
1075 process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
1076 {
1077 char *str, *next, *last;
1078 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1079
1080 active_isstring = 0;
1081
1082 /* Copy the default opcode modifier. */
1083 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1084
1085 if (strcmp (mod, "0"))
1086 {
1087 last = mod + strlen (mod);
1088 for (next = mod; next && next < last; )
1089 {
1090 str = next_field (next, '|', &next, last);
1091 if (str)
1092 {
1093 int val = 1;
1094 if (strcasecmp(str, "Broadcast") == 0)
1095 val = adjust_broadcast_modifier (opnd);
1096 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
1097 lineno);
1098 if (strcasecmp(str, "IsString") == 0)
1099 active_isstring = 1;
1100 }
1101 }
1102 }
1103 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1104 }
1105
1106 enum stage {
1107 stage_macros,
1108 stage_opcodes,
1109 stage_registers,
1110 };
1111
1112 static void
1113 output_operand_type (FILE *table, bitfield *types, unsigned int size,
1114 enum stage stage, const char *indent)
1115 {
1116 unsigned int i;
1117
1118 fprintf (table, "{ { ");
1119
1120 for (i = 0; i < size - 1; i++)
1121 {
1122 if (((i + 1) % 20) != 0)
1123 fprintf (table, "%d, ", types[i].value);
1124 else
1125 fprintf (table, "%d,", types[i].value);
1126 if (((i + 1) % 20) == 0)
1127 {
1128 /* We need \\ for macro. */
1129 if (stage == stage_macros)
1130 fprintf (table, " \\\n%s", indent);
1131 else
1132 fprintf (table, "\n%s", indent);
1133 }
1134 }
1135
1136 fprintf (table, "%d } }", types[i].value);
1137 }
1138
1139 static void
1140 process_i386_operand_type (FILE *table, char *op, enum stage stage,
1141 const char *indent, int lineno)
1142 {
1143 char *str, *next, *last;
1144 bitfield types [ARRAY_SIZE (operand_types)];
1145
1146 /* Copy the default operand type. */
1147 memcpy (types, operand_types, sizeof (types));
1148
1149 if (strcmp (op, "0"))
1150 {
1151 int baseindex = 0;
1152
1153 last = op + strlen (op);
1154 for (next = op; next && next < last; )
1155 {
1156 str = next_field (next, '|', &next, last);
1157 if (str)
1158 {
1159 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1160 if (strcasecmp(str, "BaseIndex") == 0)
1161 baseindex = 1;
1162 }
1163 }
1164
1165 if (stage == stage_opcodes && baseindex && !active_isstring)
1166 {
1167 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1168 if (!active_cpu_flags.bitfield.cpu64
1169 && !active_cpu_flags.bitfield.cpumpx)
1170 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1171 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1172 if (!active_cpu_flags.bitfield.cpuno64)
1173 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
1174 }
1175 }
1176 output_operand_type (table, types, ARRAY_SIZE (types), stage,
1177 indent);
1178 }
1179
1180 static void
1181 output_i386_opcode (FILE *table, const char *name, char *str,
1182 char *last, int lineno)
1183 {
1184 unsigned int i;
1185 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1186 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1187
1188 /* Find number of operands. */
1189 operands = next_field (str, ',', &str, last);
1190
1191 /* Find base_opcode. */
1192 base_opcode = next_field (str, ',', &str, last);
1193
1194 /* Find extension_opcode. */
1195 extension_opcode = next_field (str, ',', &str, last);
1196
1197 /* Find opcode_length. */
1198 opcode_length = next_field (str, ',', &str, last);
1199
1200 /* Find cpu_flags. */
1201 cpu_flags = next_field (str, ',', &str, last);
1202
1203 /* Find opcode_modifier. */
1204 opcode_modifier = next_field (str, ',', &str, last);
1205
1206 /* Remove the first {. */
1207 str = remove_leading_whitespaces (str);
1208 if (*str != '{')
1209 abort ();
1210 str = remove_leading_whitespaces (str + 1);
1211
1212 i = strlen (str);
1213
1214 /* There are at least "X}". */
1215 if (i < 2)
1216 abort ();
1217
1218 /* Remove trailing white spaces and }. */
1219 do
1220 {
1221 i--;
1222 if (ISSPACE (str[i]) || str[i] == '}')
1223 str[i] = '\0';
1224 else
1225 break;
1226 }
1227 while (i != 0);
1228
1229 last = str + i;
1230
1231 /* Find operand_types. */
1232 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1233 {
1234 if (str >= last)
1235 {
1236 operand_types [i] = NULL;
1237 break;
1238 }
1239
1240 operand_types [i] = next_field (str, ',', &str, last);
1241 if (*operand_types[i] == '0')
1242 {
1243 if (i != 0)
1244 operand_types[i] = NULL;
1245 break;
1246 }
1247 }
1248
1249 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1250 name, operands, base_opcode, extension_opcode,
1251 opcode_length);
1252
1253 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1254
1255 process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
1256
1257 fprintf (table, " { ");
1258
1259 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1260 {
1261 if (operand_types[i] == NULL || *operand_types[i] == '0')
1262 {
1263 if (i == 0)
1264 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1265 lineno);
1266 break;
1267 }
1268
1269 if (i != 0)
1270 fprintf (table, ",\n ");
1271
1272 process_i386_operand_type (table, operand_types[i], stage_opcodes,
1273 "\t ", lineno);
1274 }
1275 fprintf (table, " } },\n");
1276 }
1277
1278 struct opcode_hash_entry
1279 {
1280 struct opcode_hash_entry *next;
1281 char *name;
1282 char *opcode;
1283 int lineno;
1284 };
1285
1286 /* Calculate the hash value of an opcode hash entry P. */
1287
1288 static hashval_t
1289 opcode_hash_hash (const void *p)
1290 {
1291 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1292 return htab_hash_string (entry->name);
1293 }
1294
1295 /* Compare a string Q against an opcode hash entry P. */
1296
1297 static int
1298 opcode_hash_eq (const void *p, const void *q)
1299 {
1300 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1301 const char *name = (const char *) q;
1302 return strcmp (name, entry->name) == 0;
1303 }
1304
1305 static void
1306 process_i386_opcodes (FILE *table)
1307 {
1308 FILE *fp;
1309 char buf[2048];
1310 unsigned int i, j;
1311 char *str, *p, *last, *name;
1312 struct opcode_hash_entry **hash_slot, **entry, *next;
1313 htab_t opcode_hash_table;
1314 struct opcode_hash_entry **opcode_array;
1315 unsigned int opcode_array_size = 1024;
1316 int lineno = 0, marker = 0;
1317
1318 filename = "i386-opc.tbl";
1319 fp = stdin;
1320
1321 i = 0;
1322 opcode_array = (struct opcode_hash_entry **)
1323 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1324
1325 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1326 opcode_hash_eq, NULL,
1327 xcalloc, free);
1328
1329 fprintf (table, "\n/* i386 opcode table. */\n\n");
1330 fprintf (table, "const insn_template i386_optab[] =\n{\n");
1331
1332 /* Put everything on opcode array. */
1333 while (!feof (fp))
1334 {
1335 if (fgets (buf, sizeof (buf), fp) == NULL)
1336 break;
1337
1338 lineno++;
1339
1340 p = remove_leading_whitespaces (buf);
1341
1342 /* Skip comments. */
1343 str = strstr (p, "//");
1344 if (str != NULL)
1345 str[0] = '\0';
1346
1347 /* Remove trailing white spaces. */
1348 remove_trailing_whitespaces (p);
1349
1350 switch (p[0])
1351 {
1352 case '#':
1353 if (!strcmp("### MARKER ###", buf))
1354 marker = 1;
1355 else
1356 {
1357 /* Since we ignore all included files (we only care about their
1358 #define-s here), we don't need to monitor filenames. The final
1359 line number directive is going to refer to the main source file
1360 again. */
1361 char *end;
1362 unsigned long ln;
1363
1364 p = remove_leading_whitespaces (p + 1);
1365 if (!strncmp(p, "line", 4))
1366 p += 4;
1367 ln = strtoul (p, &end, 10);
1368 if (ln > 1 && ln < INT_MAX
1369 && *remove_leading_whitespaces (end) == '"')
1370 lineno = ln - 1;
1371 }
1372 /* Ignore comments. */
1373 case '\0':
1374 continue;
1375 break;
1376 default:
1377 if (!marker)
1378 continue;
1379 break;
1380 }
1381
1382 last = p + strlen (p);
1383
1384 /* Find name. */
1385 name = next_field (p, ',', &str, last);
1386
1387 /* Get the slot in hash table. */
1388 hash_slot = (struct opcode_hash_entry **)
1389 htab_find_slot_with_hash (opcode_hash_table, name,
1390 htab_hash_string (name),
1391 INSERT);
1392
1393 if (*hash_slot == NULL)
1394 {
1395 /* It is the new one. Put it on opcode array. */
1396 if (i >= opcode_array_size)
1397 {
1398 /* Grow the opcode array when needed. */
1399 opcode_array_size += 1024;
1400 opcode_array = (struct opcode_hash_entry **)
1401 xrealloc (opcode_array,
1402 sizeof (*opcode_array) * opcode_array_size);
1403 }
1404
1405 opcode_array[i] = (struct opcode_hash_entry *)
1406 xmalloc (sizeof (struct opcode_hash_entry));
1407 opcode_array[i]->next = NULL;
1408 opcode_array[i]->name = xstrdup (name);
1409 opcode_array[i]->opcode = xstrdup (str);
1410 opcode_array[i]->lineno = lineno;
1411 *hash_slot = opcode_array[i];
1412 i++;
1413 }
1414 else
1415 {
1416 /* Append it to the existing one. */
1417 entry = hash_slot;
1418 while ((*entry) != NULL)
1419 entry = &(*entry)->next;
1420 *entry = (struct opcode_hash_entry *)
1421 xmalloc (sizeof (struct opcode_hash_entry));
1422 (*entry)->next = NULL;
1423 (*entry)->name = (*hash_slot)->name;
1424 (*entry)->opcode = xstrdup (str);
1425 (*entry)->lineno = lineno;
1426 }
1427 }
1428
1429 /* Process opcode array. */
1430 for (j = 0; j < i; j++)
1431 {
1432 for (next = opcode_array[j]; next; next = next->next)
1433 {
1434 name = next->name;
1435 str = next->opcode;
1436 lineno = next->lineno;
1437 last = str + strlen (str);
1438 output_i386_opcode (table, name, str, last, lineno);
1439 }
1440 }
1441
1442 fclose (fp);
1443
1444 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1445
1446 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1447
1448 process_i386_opcode_modifier (table, "0", NULL, -1);
1449
1450 fprintf (table, " { ");
1451 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
1452 fprintf (table, " } }\n");
1453
1454 fprintf (table, "};\n");
1455 }
1456
1457 static void
1458 process_i386_registers (FILE *table)
1459 {
1460 FILE *fp;
1461 char buf[2048];
1462 char *str, *p, *last;
1463 char *reg_name, *reg_type, *reg_flags, *reg_num;
1464 char *dw2_32_num, *dw2_64_num;
1465 int lineno = 0;
1466
1467 filename = "i386-reg.tbl";
1468 fp = fopen (filename, "r");
1469 if (fp == NULL)
1470 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1471 xstrerror (errno));
1472
1473 fprintf (table, "\n/* i386 register table. */\n\n");
1474 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1475
1476 while (!feof (fp))
1477 {
1478 if (fgets (buf, sizeof (buf), fp) == NULL)
1479 break;
1480
1481 lineno++;
1482
1483 p = remove_leading_whitespaces (buf);
1484
1485 /* Skip comments. */
1486 str = strstr (p, "//");
1487 if (str != NULL)
1488 str[0] = '\0';
1489
1490 /* Remove trailing white spaces. */
1491 remove_trailing_whitespaces (p);
1492
1493 switch (p[0])
1494 {
1495 case '#':
1496 fprintf (table, "%s\n", p);
1497 case '\0':
1498 continue;
1499 break;
1500 default:
1501 break;
1502 }
1503
1504 last = p + strlen (p);
1505
1506 /* Find reg_name. */
1507 reg_name = next_field (p, ',', &str, last);
1508
1509 /* Find reg_type. */
1510 reg_type = next_field (str, ',', &str, last);
1511
1512 /* Find reg_flags. */
1513 reg_flags = next_field (str, ',', &str, last);
1514
1515 /* Find reg_num. */
1516 reg_num = next_field (str, ',', &str, last);
1517
1518 fprintf (table, " { \"%s\",\n ", reg_name);
1519
1520 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1521 lineno);
1522
1523 /* Find 32-bit Dwarf2 register number. */
1524 dw2_32_num = next_field (str, ',', &str, last);
1525
1526 /* Find 64-bit Dwarf2 register number. */
1527 dw2_64_num = next_field (str, ',', &str, last);
1528
1529 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1530 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1531 }
1532
1533 fclose (fp);
1534
1535 fprintf (table, "};\n");
1536
1537 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1538 }
1539
1540 static void
1541 process_i386_initializers (void)
1542 {
1543 unsigned int i;
1544 FILE *fp = fopen ("i386-init.h", "w");
1545 char *init;
1546
1547 if (fp == NULL)
1548 fail (_("can't create i386-init.h, errno = %s\n"),
1549 xstrerror (errno));
1550
1551 process_copyright (fp);
1552
1553 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1554 {
1555 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1556 init = xstrdup (cpu_flag_init[i].init);
1557 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1558 free (init);
1559 }
1560
1561 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1562 {
1563 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1564 init = xstrdup (operand_type_init[i].init);
1565 process_i386_operand_type (fp, init, stage_macros, " ", -1);
1566 free (init);
1567 }
1568 fprintf (fp, "\n");
1569
1570 fclose (fp);
1571 }
1572
1573 /* Program options. */
1574 #define OPTION_SRCDIR 200
1575
1576 struct option long_options[] =
1577 {
1578 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1579 {"debug", no_argument, NULL, 'd'},
1580 {"version", no_argument, NULL, 'V'},
1581 {"help", no_argument, NULL, 'h'},
1582 {0, no_argument, NULL, 0}
1583 };
1584
1585 static void
1586 print_version (void)
1587 {
1588 printf ("%s: version 1.0\n", program_name);
1589 xexit (0);
1590 }
1591
1592 static void
1593 usage (FILE * stream, int status)
1594 {
1595 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1596 program_name);
1597 xexit (status);
1598 }
1599
1600 int
1601 main (int argc, char **argv)
1602 {
1603 extern int chdir (char *);
1604 char *srcdir = NULL;
1605 int c;
1606 unsigned int i, cpumax;
1607 FILE *table;
1608
1609 program_name = *argv;
1610 xmalloc_set_program_name (program_name);
1611
1612 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1613 switch (c)
1614 {
1615 case OPTION_SRCDIR:
1616 srcdir = optarg;
1617 break;
1618 case 'V':
1619 case 'v':
1620 print_version ();
1621 break;
1622 case 'd':
1623 debug = 1;
1624 break;
1625 case 'h':
1626 case '?':
1627 usage (stderr, 0);
1628 default:
1629 case 0:
1630 break;
1631 }
1632
1633 if (optind != argc)
1634 usage (stdout, 1);
1635
1636 if (srcdir != NULL)
1637 if (chdir (srcdir) != 0)
1638 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1639 srcdir, xstrerror (errno));
1640
1641 /* cpu_flags isn't sorted by position. */
1642 cpumax = 0;
1643 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1644 if (cpu_flags[i].position > cpumax)
1645 cpumax = cpu_flags[i].position;
1646
1647 /* Check the unused bitfield in i386_cpu_flags. */
1648 #ifdef CpuUnused
1649 if ((cpumax - 1) != CpuMax)
1650 fail (_("CpuMax != %d!\n"), cpumax);
1651 #else
1652 if (cpumax != CpuMax)
1653 fail (_("CpuMax != %d!\n"), cpumax);
1654
1655 c = CpuNumOfBits - CpuMax - 1;
1656 if (c)
1657 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1658 #endif
1659
1660 /* Check the unused bitfield in i386_operand_type. */
1661 #ifndef OTUnused
1662 c = OTNumOfBits - OTMax - 1;
1663 if (c)
1664 fail (_("%d unused bits in i386_operand_type.\n"), c);
1665 #endif
1666
1667 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1668 compare);
1669
1670 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1671 sizeof (opcode_modifiers [0]), compare);
1672
1673 qsort (operand_types, ARRAY_SIZE (operand_types),
1674 sizeof (operand_types [0]), compare);
1675
1676 table = fopen ("i386-tbl.h", "w");
1677 if (table == NULL)
1678 fail (_("can't create i386-tbl.h, errno = %s\n"),
1679 xstrerror (errno));
1680
1681 process_copyright (table);
1682
1683 process_i386_opcodes (table);
1684 process_i386_registers (table);
1685 process_i386_initializers ();
1686
1687 fclose (table);
1688
1689 exit (0);
1690 }