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