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