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