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