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