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