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