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