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