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