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