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