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