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