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