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