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