x86: Add -O[2|s] assembler command-line options
[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),
601 BITFIELD (FloatD),
602 BITFIELD (Size16),
603 BITFIELD (Size32),
604 BITFIELD (Size64),
56ffb741 605 BITFIELD (CheckRegSize),
40fb9820
L
606 BITFIELD (IgnoreSize),
607 BITFIELD (DefaultSize),
608 BITFIELD (No_bSuf),
609 BITFIELD (No_wSuf),
610 BITFIELD (No_lSuf),
611 BITFIELD (No_sSuf),
612 BITFIELD (No_qSuf),
7ce189b3 613 BITFIELD (No_ldSuf),
40fb9820
L
614 BITFIELD (FWait),
615 BITFIELD (IsString),
7e8b059b 616 BITFIELD (BNDPrefixOk),
04ef582a 617 BITFIELD (NoTrackPrefixOk),
c32fa91d 618 BITFIELD (IsLockable),
40fb9820 619 BITFIELD (RegKludge),
c0f3af97 620 BITFIELD (Implicit1stXmm0),
29c048b6 621 BITFIELD (RepPrefixOk),
42164a71 622 BITFIELD (HLEPrefixOk),
ca61edf2
L
623 BITFIELD (ToDword),
624 BITFIELD (ToQword),
625 BITFIELD (AddrPrefixOp0),
40fb9820
L
626 BITFIELD (IsPrefix),
627 BITFIELD (ImmExt),
628 BITFIELD (NoRex64),
629 BITFIELD (Rex64),
630 BITFIELD (Ugh),
c0f3af97 631 BITFIELD (Vex),
2426c15f 632 BITFIELD (VexVVVV),
1ef99a7b 633 BITFIELD (VexW),
7f399153 634 BITFIELD (VexOpcode),
8cd7925b 635 BITFIELD (VexSources),
c0f3af97 636 BITFIELD (VexImmExt),
6c30d220 637 BITFIELD (VecSIB),
c0f3af97 638 BITFIELD (SSE2AVX),
81f8a913 639 BITFIELD (NoAVX),
43234a1e
L
640 BITFIELD (EVex),
641 BITFIELD (Masking),
642 BITFIELD (VecESize),
643 BITFIELD (Broadcast),
644 BITFIELD (StaticRounding),
645 BITFIELD (SAE),
646 BITFIELD (Disp8MemShift),
647 BITFIELD (NoDefMask),
920d2ddc 648 BITFIELD (ImplicitQuadGroup),
b6f8c7c4 649 BITFIELD (Optimize),
1efbbeb4
L
650 BITFIELD (OldGcc),
651 BITFIELD (ATTMnemonic),
e1d4d893 652 BITFIELD (ATTSyntax),
5c07affc 653 BITFIELD (IntelSyntax),
e92bae62
L
654 BITFIELD (AMD64),
655 BITFIELD (Intel64),
40fb9820
L
656};
657
658static bitfield operand_types[] =
659{
dc821c5f 660 BITFIELD (Reg),
40fb9820 661 BITFIELD (RegMMX),
1b54b8d7 662 BITFIELD (RegSIMD),
43234a1e 663 BITFIELD (RegMask),
94ff3a50 664 BITFIELD (Imm1),
40fb9820
L
665 BITFIELD (Imm8),
666 BITFIELD (Imm8S),
667 BITFIELD (Imm16),
668 BITFIELD (Imm32),
669 BITFIELD (Imm32S),
670 BITFIELD (Imm64),
40fb9820
L
671 BITFIELD (BaseIndex),
672 BITFIELD (Disp8),
673 BITFIELD (Disp16),
674 BITFIELD (Disp32),
675 BITFIELD (Disp32S),
676 BITFIELD (Disp64),
677 BITFIELD (InOutPortReg),
678 BITFIELD (ShiftCount),
679 BITFIELD (Control),
680 BITFIELD (Debug),
681 BITFIELD (Test),
682 BITFIELD (SReg2),
683 BITFIELD (SReg3),
684 BITFIELD (Acc),
40fb9820
L
685 BITFIELD (JumpAbsolute),
686 BITFIELD (EsSeg),
687 BITFIELD (RegMem),
5c07affc 688 BITFIELD (Mem),
7d5e4556
L
689 BITFIELD (Byte),
690 BITFIELD (Word),
691 BITFIELD (Dword),
692 BITFIELD (Fword),
693 BITFIELD (Qword),
694 BITFIELD (Tbyte),
695 BITFIELD (Xmmword),
c0f3af97 696 BITFIELD (Ymmword),
43234a1e 697 BITFIELD (Zmmword),
7d5e4556
L
698 BITFIELD (Unspecified),
699 BITFIELD (Anysize),
a683cc34 700 BITFIELD (Vec_Imm4),
7e8b059b 701 BITFIELD (RegBND),
40fb9820
L
702#ifdef OTUnused
703 BITFIELD (OTUnused),
704#endif
705};
706
3d4d5afa 707static const char *filename;
7ac20022
JB
708static i386_cpu_flags active_cpu_flags;
709static int active_isstring;
3d4d5afa 710
40fb9820
L
711static int
712compare (const void *x, const void *y)
713{
714 const bitfield *xp = (const bitfield *) x;
715 const bitfield *yp = (const bitfield *) y;
716 return xp->position - yp->position;
717}
718
40b8e679
L
719static void
720fail (const char *message, ...)
721{
722 va_list args;
29c048b6 723
40b8e679
L
724 va_start (args, message);
725 fprintf (stderr, _("%s: Error: "), program_name);
726 vfprintf (stderr, message, args);
727 va_end (args);
728 xexit (1);
729}
730
72ffa0fb
L
731static void
732process_copyright (FILE *fp)
733{
734 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
219d1afa 735/* Copyright (C) 2007-2018 Free Software Foundation, Inc.\n\
72ffa0fb
L
736\n\
737 This file is part of the GNU opcodes library.\n\
738\n\
739 This library is free software; you can redistribute it and/or modify\n\
740 it under the terms of the GNU General Public License as published by\n\
741 the Free Software Foundation; either version 3, or (at your option)\n\
742 any later version.\n\
743\n\
744 It is distributed in the hope that it will be useful, but WITHOUT\n\
745 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
746 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
747 License for more details.\n\
748\n\
749 You should have received a copy of the GNU General Public License\n\
750 along with this program; if not, write to the Free Software\n\
751 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
752 MA 02110-1301, USA. */\n");
753}
754
40b8e679
L
755/* Remove leading white spaces. */
756
757static char *
758remove_leading_whitespaces (char *str)
759{
760 while (ISSPACE (*str))
761 str++;
762 return str;
763}
764
765/* Remove trailing white spaces. */
766
767static void
768remove_trailing_whitespaces (char *str)
769{
770 size_t last = strlen (str);
771
772 if (last == 0)
773 return;
774
775 do
776 {
777 last--;
778 if (ISSPACE (str [last]))
779 str[last] = '\0';
780 else
781 break;
782 }
783 while (last != 0);
784}
785
93b1ec2c 786/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
787 pointer to the one after it. */
788
789static char *
c587b3f9 790next_field (char *str, char sep, char **next, char *last)
40b8e679
L
791{
792 char *p;
793
794 p = remove_leading_whitespaces (str);
93b1ec2c 795 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
796
797 *str = '\0';
798 remove_trailing_whitespaces (p);
799
29c048b6 800 *next = str + 1;
40b8e679 801
c587b3f9
L
802 if (p >= last)
803 abort ();
804
40b8e679
L
805 return p;
806}
807
1848e567
L
808static void set_bitfield (char *, bitfield *, int, unsigned int, int);
809
810static int
dc821c5f
JB
811set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size,
812 int lineno)
1848e567
L
813{
814 char *str, *next, *last;
815 unsigned int i;
816
817 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
818 if (strcmp (cpu_flag_init[i].name, f) == 0)
819 {
820 /* Turn on selective bits. */
821 char *init = xstrdup (cpu_flag_init[i].init);
822 last = init + strlen (init);
823 for (next = init; next && next < last; )
824 {
825 str = next_field (next, '|', &next, last);
826 if (str)
827 set_bitfield (str, array, 1, size, lineno);
828 }
829 free (init);
830 return 0;
831 }
832
dc821c5f
JB
833 for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++)
834 if (strcmp (operand_type_shorthands[i].name, f) == 0)
835 {
836 /* Turn on selective bits. */
837 char *init = xstrdup (operand_type_shorthands[i].init);
838 last = init + strlen (init);
839 for (next = init; next && next < last; )
840 {
841 str = next_field (next, '|', &next, last);
842 if (str)
843 set_bitfield (str, array, 1, size, lineno);
844 }
845 free (init);
846 return 0;
847 }
848
1848e567
L
849 return -1;
850}
851
40fb9820 852static void
1848e567 853set_bitfield (char *f, bitfield *array, int value,
8a9036a4 854 unsigned int size, int lineno)
40fb9820
L
855{
856 unsigned int i;
857
309d3373
JB
858 if (strcmp (f, "CpuFP") == 0)
859 {
8a9036a4
L
860 set_bitfield("Cpu387", array, value, size, lineno);
861 set_bitfield("Cpu287", array, value, size, lineno);
309d3373
JB
862 f = "Cpu8087";
863 }
864 else if (strcmp (f, "Mmword") == 0)
7d5e4556
L
865 f= "Qword";
866 else if (strcmp (f, "Oword") == 0)
867 f= "Xmmword";
40fb9820
L
868
869 for (i = 0; i < size; i++)
870 if (strcasecmp (array[i].name, f) == 0)
871 {
8a9036a4 872 array[i].value = value;
40fb9820
L
873 return;
874 }
875
2bf05e57
L
876 if (value)
877 {
878 const char *v = strchr (f, '=');
879
880 if (v)
881 {
882 size_t n = v - f;
883 char *end;
884
885 for (i = 0; i < size; i++)
886 if (strncasecmp (array[i].name, f, n) == 0)
887 {
888 value = strtol (v + 1, &end, 0);
889 if (*end == '\0')
890 {
891 array[i].value = value;
892 return;
893 }
894 break;
895 }
896 }
897 }
898
dc821c5f
JB
899 /* Handle shorthands. */
900 if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno))
1848e567
L
901 return;
902
bd5295b2
L
903 if (lineno != -1)
904 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
905 else
906 fail (_("Unknown bitfield: %s\n"), f);
40fb9820
L
907}
908
909static void
910output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
911 int macro, const char *comma, const char *indent)
912{
913 unsigned int i;
914
7ac20022
JB
915 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
916
40fb9820
L
917 fprintf (table, "%s{ { ", indent);
918
919 for (i = 0; i < size - 1; i++)
920 {
10632b79
L
921 if (((i + 1) % 20) != 0)
922 fprintf (table, "%d, ", flags[i].value);
923 else
924 fprintf (table, "%d,", flags[i].value);
40fb9820
L
925 if (((i + 1) % 20) == 0)
926 {
927 /* We need \\ for macro. */
928 if (macro)
929 fprintf (table, " \\\n %s", indent);
930 else
931 fprintf (table, "\n %s", indent);
932 }
7ac20022
JB
933 if (flags[i].value)
934 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
40fb9820
L
935 }
936
937 fprintf (table, "%d } }%s\n", flags[i].value, comma);
938}
939
940static void
941process_i386_cpu_flag (FILE *table, char *flag, int macro,
bd5295b2
L
942 const char *comma, const char *indent,
943 int lineno)
40fb9820
L
944{
945 char *str, *next, *last;
8a9036a4 946 unsigned int i;
40fb9820
L
947 bitfield flags [ARRAY_SIZE (cpu_flags)];
948
949 /* Copy the default cpu flags. */
950 memcpy (flags, cpu_flags, sizeof (cpu_flags));
951
952 if (strcasecmp (flag, "unknown") == 0)
953 {
40fb9820 954 /* We turn on everything except for cpu64 in case of
8a9036a4
L
955 CPU_UNKNOWN_FLAGS. */
956 for (i = 0; i < ARRAY_SIZE (flags); i++)
957 if (flags[i].position != Cpu64)
958 flags[i].value = 1;
959 }
960 else if (flag[0] == '~')
961 {
962 last = flag + strlen (flag);
963
964 if (flag[1] == '(')
965 {
966 last -= 1;
967 next = flag + 2;
968 if (*last != ')')
969 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
970 lineno, flag);
971 *last = '\0';
972 }
973 else
974 next = flag + 1;
975
976 /* First we turn on everything except for cpu64. */
40fb9820
L
977 for (i = 0; i < ARRAY_SIZE (flags); i++)
978 if (flags[i].position != Cpu64)
979 flags[i].value = 1;
8a9036a4
L
980
981 /* Turn off selective bits. */
982 for (; next && next < last; )
983 {
984 str = next_field (next, '|', &next, last);
985 if (str)
986 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
987 }
40fb9820
L
988 }
989 else if (strcmp (flag, "0"))
990 {
8a9036a4 991 /* Turn on selective bits. */
40fb9820
L
992 last = flag + strlen (flag);
993 for (next = flag; next && next < last; )
994 {
c587b3f9 995 str = next_field (next, '|', &next, last);
40fb9820 996 if (str)
8a9036a4 997 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
40fb9820
L
998 }
999 }
1000
1001 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1002 comma, indent);
1003}
1004
1005static void
1006output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1007{
1008 unsigned int i;
1009
1010 fprintf (table, " { ");
1011
1012 for (i = 0; i < size - 1; i++)
1013 {
10632b79
L
1014 if (((i + 1) % 20) != 0)
1015 fprintf (table, "%d, ", modifier[i].value);
1016 else
1017 fprintf (table, "%d,", modifier[i].value);
40fb9820
L
1018 if (((i + 1) % 20) == 0)
1019 fprintf (table, "\n ");
1020 }
1021
1022 fprintf (table, "%d },\n", modifier[i].value);
1023}
1024
1025static void
bd5295b2 1026process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
40fb9820
L
1027{
1028 char *str, *next, *last;
1029 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1030
7ac20022
JB
1031 active_isstring = 0;
1032
40fb9820
L
1033 /* Copy the default opcode modifier. */
1034 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1035
1036 if (strcmp (mod, "0"))
1037 {
1038 last = mod + strlen (mod);
1039 for (next = mod; next && next < last; )
1040 {
c587b3f9 1041 str = next_field (next, '|', &next, last);
40fb9820 1042 if (str)
7ac20022
JB
1043 {
1044 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
8a9036a4 1045 lineno);
7ac20022
JB
1046 if (strcasecmp(str, "IsString") == 0)
1047 active_isstring = 1;
1048 }
40fb9820
L
1049 }
1050 }
1051 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1052}
1053
7ac20022
JB
1054enum stage {
1055 stage_macros,
1056 stage_opcodes,
1057 stage_registers,
1058};
1059
40fb9820
L
1060static void
1061output_operand_type (FILE *table, bitfield *types, unsigned int size,
7ac20022 1062 enum stage stage, const char *indent)
40fb9820
L
1063{
1064 unsigned int i;
1065
1066 fprintf (table, "{ { ");
1067
1068 for (i = 0; i < size - 1; i++)
1069 {
10632b79
L
1070 if (((i + 1) % 20) != 0)
1071 fprintf (table, "%d, ", types[i].value);
1072 else
1073 fprintf (table, "%d,", types[i].value);
40fb9820
L
1074 if (((i + 1) % 20) == 0)
1075 {
1076 /* We need \\ for macro. */
7ac20022 1077 if (stage == stage_macros)
10632b79 1078 fprintf (table, " \\\n%s", indent);
40fb9820
L
1079 else
1080 fprintf (table, "\n%s", indent);
1081 }
1082 }
1083
1084 fprintf (table, "%d } }", types[i].value);
1085}
1086
1087static void
7ac20022 1088process_i386_operand_type (FILE *table, char *op, enum stage stage,
bd5295b2 1089 const char *indent, int lineno)
40fb9820
L
1090{
1091 char *str, *next, *last;
1092 bitfield types [ARRAY_SIZE (operand_types)];
1093
1094 /* Copy the default operand type. */
1095 memcpy (types, operand_types, sizeof (types));
1096
1097 if (strcmp (op, "0"))
1098 {
7ac20022
JB
1099 int baseindex = 0;
1100
40fb9820
L
1101 last = op + strlen (op);
1102 for (next = op; next && next < last; )
1103 {
c587b3f9 1104 str = next_field (next, '|', &next, last);
40fb9820 1105 if (str)
7ac20022
JB
1106 {
1107 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1108 if (strcasecmp(str, "BaseIndex") == 0)
1109 baseindex = 1;
1110 }
1111 }
1112
1113 if (stage == stage_opcodes && baseindex && !active_isstring)
1114 {
1115 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1116 if (!active_cpu_flags.bitfield.cpu64
1117 && !active_cpu_flags.bitfield.cpumpx)
1118 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
1119 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
1120 if (!active_cpu_flags.bitfield.cpuno64)
1121 set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
1122 }
1123 }
7ac20022 1124 output_operand_type (table, types, ARRAY_SIZE (types), stage,
40fb9820
L
1125 indent);
1126}
1127
c587b3f9
L
1128static void
1129output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 1130 char *last, int lineno)
c587b3f9
L
1131{
1132 unsigned int i;
1133 char *operands, *base_opcode, *extension_opcode, *opcode_length;
1134 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
1135
1136 /* Find number of operands. */
1137 operands = next_field (str, ',', &str, last);
1138
1139 /* Find base_opcode. */
1140 base_opcode = next_field (str, ',', &str, last);
1141
1142 /* Find extension_opcode. */
1143 extension_opcode = next_field (str, ',', &str, last);
1144
1145 /* Find opcode_length. */
1146 opcode_length = next_field (str, ',', &str, last);
1147
1148 /* Find cpu_flags. */
1149 cpu_flags = next_field (str, ',', &str, last);
1150
1151 /* Find opcode_modifier. */
1152 opcode_modifier = next_field (str, ',', &str, last);
1153
1154 /* Remove the first {. */
1155 str = remove_leading_whitespaces (str);
1156 if (*str != '{')
1157 abort ();
1158 str = remove_leading_whitespaces (str + 1);
1159
1160 i = strlen (str);
1161
1162 /* There are at least "X}". */
1163 if (i < 2)
1164 abort ();
1165
1166 /* Remove trailing white spaces and }. */
1167 do
1168 {
1169 i--;
1170 if (ISSPACE (str[i]) || str[i] == '}')
1171 str[i] = '\0';
1172 else
1173 break;
1174 }
1175 while (i != 0);
1176
1177 last = str + i;
1178
1179 /* Find operand_types. */
1180 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1181 {
1182 if (str >= last)
1183 {
1184 operand_types [i] = NULL;
1185 break;
1186 }
1187
1188 operand_types [i] = next_field (str, ',', &str, last);
1189 if (*operand_types[i] == '0')
1190 {
1191 if (i != 0)
1192 operand_types[i] = NULL;
1193 break;
1194 }
1195 }
1196
1197 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
1198 name, operands, base_opcode, extension_opcode,
1199 opcode_length);
1200
bd5295b2 1201 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
c587b3f9 1202
bd5295b2 1203 process_i386_opcode_modifier (table, opcode_modifier, lineno);
c587b3f9
L
1204
1205 fprintf (table, " { ");
1206
1207 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1208 {
1209 if (operand_types[i] == NULL || *operand_types[i] == '0')
1210 {
1211 if (i == 0)
7ac20022
JB
1212 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1213 lineno);
c587b3f9
L
1214 break;
1215 }
1216
1217 if (i != 0)
1218 fprintf (table, ",\n ");
1219
7ac20022 1220 process_i386_operand_type (table, operand_types[i], stage_opcodes,
bd5295b2 1221 "\t ", lineno);
c587b3f9
L
1222 }
1223 fprintf (table, " } },\n");
1224}
1225
1226struct opcode_hash_entry
1227{
1228 struct opcode_hash_entry *next;
1229 char *name;
1230 char *opcode;
bd5295b2 1231 int lineno;
c587b3f9
L
1232};
1233
1234/* Calculate the hash value of an opcode hash entry P. */
1235
1236static hashval_t
1237opcode_hash_hash (const void *p)
1238{
1239 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1240 return htab_hash_string (entry->name);
1241}
1242
1243/* Compare a string Q against an opcode hash entry P. */
1244
1245static int
1246opcode_hash_eq (const void *p, const void *q)
1247{
1248 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1249 const char *name = (const char *) q;
1250 return strcmp (name, entry->name) == 0;
1251}
1252
40b8e679 1253static void
72ffa0fb 1254process_i386_opcodes (FILE *table)
40b8e679 1255{
3d4d5afa 1256 FILE *fp;
40b8e679 1257 char buf[2048];
c587b3f9
L
1258 unsigned int i, j;
1259 char *str, *p, *last, *name;
1260 struct opcode_hash_entry **hash_slot, **entry, *next;
1261 htab_t opcode_hash_table;
1262 struct opcode_hash_entry **opcode_array;
1263 unsigned int opcode_array_size = 1024;
bd5295b2 1264 int lineno = 0;
40b8e679 1265
3d4d5afa
L
1266 filename = "i386-opc.tbl";
1267 fp = fopen (filename, "r");
1268
40b8e679 1269 if (fp == NULL)
34edb9ad 1270 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
40fb9820 1271 xstrerror (errno));
40b8e679 1272
c587b3f9
L
1273 i = 0;
1274 opcode_array = (struct opcode_hash_entry **)
1275 xmalloc (sizeof (*opcode_array) * opcode_array_size);
1276
1277 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1278 opcode_hash_eq, NULL,
1279 xcalloc, free);
1280
34edb9ad 1281 fprintf (table, "\n/* i386 opcode table. */\n\n");
d3ce72d0 1282 fprintf (table, "const insn_template i386_optab[] =\n{\n");
40b8e679 1283
c587b3f9 1284 /* Put everything on opcode array. */
40b8e679
L
1285 while (!feof (fp))
1286 {
1287 if (fgets (buf, sizeof (buf), fp) == NULL)
1288 break;
1289
3d4d5afa
L
1290 lineno++;
1291
40b8e679
L
1292 p = remove_leading_whitespaces (buf);
1293
1294 /* Skip comments. */
1295 str = strstr (p, "//");
1296 if (str != NULL)
1297 str[0] = '\0';
1298
1299 /* Remove trailing white spaces. */
1300 remove_trailing_whitespaces (p);
1301
1302 switch (p[0])
1303 {
1304 case '#':
c587b3f9 1305 /* Ignore comments. */
40b8e679
L
1306 case '\0':
1307 continue;
1308 break;
1309 default:
1310 break;
1311 }
1312
1313 last = p + strlen (p);
1314
1315 /* Find name. */
c587b3f9 1316 name = next_field (p, ',', &str, last);
40b8e679 1317
c587b3f9
L
1318 /* Get the slot in hash table. */
1319 hash_slot = (struct opcode_hash_entry **)
1320 htab_find_slot_with_hash (opcode_hash_table, name,
1321 htab_hash_string (name),
1322 INSERT);
40b8e679 1323
c587b3f9 1324 if (*hash_slot == NULL)
40b8e679 1325 {
c587b3f9
L
1326 /* It is the new one. Put it on opcode array. */
1327 if (i >= opcode_array_size)
40b8e679 1328 {
c587b3f9
L
1329 /* Grow the opcode array when needed. */
1330 opcode_array_size += 1024;
1331 opcode_array = (struct opcode_hash_entry **)
1332 xrealloc (opcode_array,
1333 sizeof (*opcode_array) * opcode_array_size);
40b8e679
L
1334 }
1335
c587b3f9
L
1336 opcode_array[i] = (struct opcode_hash_entry *)
1337 xmalloc (sizeof (struct opcode_hash_entry));
1338 opcode_array[i]->next = NULL;
1339 opcode_array[i]->name = xstrdup (name);
1340 opcode_array[i]->opcode = xstrdup (str);
bd5295b2 1341 opcode_array[i]->lineno = lineno;
c587b3f9
L
1342 *hash_slot = opcode_array[i];
1343 i++;
40b8e679 1344 }
c587b3f9 1345 else
40b8e679 1346 {
c587b3f9
L
1347 /* Append it to the existing one. */
1348 entry = hash_slot;
1349 while ((*entry) != NULL)
1350 entry = &(*entry)->next;
1351 *entry = (struct opcode_hash_entry *)
1352 xmalloc (sizeof (struct opcode_hash_entry));
1353 (*entry)->next = NULL;
1354 (*entry)->name = (*hash_slot)->name;
1355 (*entry)->opcode = xstrdup (str);
bd5295b2 1356 (*entry)->lineno = lineno;
c587b3f9
L
1357 }
1358 }
40b8e679 1359
c587b3f9
L
1360 /* Process opcode array. */
1361 for (j = 0; j < i; j++)
1362 {
1363 for (next = opcode_array[j]; next; next = next->next)
1364 {
1365 name = next->name;
1366 str = next->opcode;
bd5295b2 1367 lineno = next->lineno;
c587b3f9 1368 last = str + strlen (str);
bd5295b2 1369 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1370 }
40b8e679
L
1371 }
1372
34edb9ad
L
1373 fclose (fp);
1374
4dffcebc 1375 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820 1376
bd5295b2 1377 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
40fb9820 1378
bd5295b2 1379 process_i386_opcode_modifier (table, "0", -1);
29c048b6 1380
40fb9820 1381 fprintf (table, " { ");
7ac20022 1382 process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1);
40fb9820
L
1383 fprintf (table, " } }\n");
1384
34edb9ad 1385 fprintf (table, "};\n");
40b8e679
L
1386}
1387
1388static void
72ffa0fb 1389process_i386_registers (FILE *table)
40b8e679 1390{
3d4d5afa 1391 FILE *fp;
40b8e679
L
1392 char buf[2048];
1393 char *str, *p, *last;
1394 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1395 char *dw2_32_num, *dw2_64_num;
bd5295b2 1396 int lineno = 0;
40b8e679 1397
3d4d5afa
L
1398 filename = "i386-reg.tbl";
1399 fp = fopen (filename, "r");
40b8e679 1400 if (fp == NULL)
34edb9ad 1401 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1402 xstrerror (errno));
40b8e679 1403
34edb9ad
L
1404 fprintf (table, "\n/* i386 register table. */\n\n");
1405 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1406
1407 while (!feof (fp))
1408 {
1409 if (fgets (buf, sizeof (buf), fp) == NULL)
1410 break;
1411
3d4d5afa
L
1412 lineno++;
1413
40b8e679
L
1414 p = remove_leading_whitespaces (buf);
1415
1416 /* Skip comments. */
1417 str = strstr (p, "//");
1418 if (str != NULL)
1419 str[0] = '\0';
1420
1421 /* Remove trailing white spaces. */
1422 remove_trailing_whitespaces (p);
1423
1424 switch (p[0])
1425 {
1426 case '#':
34edb9ad 1427 fprintf (table, "%s\n", p);
40b8e679
L
1428 case '\0':
1429 continue;
1430 break;
1431 default:
1432 break;
1433 }
1434
1435 last = p + strlen (p);
1436
1437 /* Find reg_name. */
c587b3f9 1438 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1439
1440 /* Find reg_type. */
c587b3f9 1441 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1442
1443 /* Find reg_flags. */
c587b3f9 1444 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1445
1446 /* Find reg_num. */
c587b3f9 1447 reg_num = next_field (str, ',', &str, last);
a60de03c 1448
40fb9820
L
1449 fprintf (table, " { \"%s\",\n ", reg_name);
1450
7ac20022
JB
1451 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1452 lineno);
40fb9820 1453
a60de03c 1454 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1455 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1456
1457 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1458 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1459
1460 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1461 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1462 }
1463
34edb9ad
L
1464 fclose (fp);
1465
1466 fprintf (table, "};\n");
40b8e679 1467
34edb9ad 1468 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1469}
1470
40fb9820
L
1471static void
1472process_i386_initializers (void)
1473{
1474 unsigned int i;
1475 FILE *fp = fopen ("i386-init.h", "w");
1476 char *init;
1477
1478 if (fp == NULL)
1479 fail (_("can't create i386-init.h, errno = %s\n"),
1480 xstrerror (errno));
1481
1482 process_copyright (fp);
1483
1484 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1485 {
1486 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1487 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1488 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1489 free (init);
1490 }
1491
1492 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1493 {
1494 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1495 init = xstrdup (operand_type_init[i].init);
7ac20022 1496 process_i386_operand_type (fp, init, stage_macros, " ", -1);
40fb9820
L
1497 free (init);
1498 }
1499 fprintf (fp, "\n");
1500
1501 fclose (fp);
1502}
1503
40b8e679
L
1504/* Program options. */
1505#define OPTION_SRCDIR 200
1506
29c048b6 1507struct option long_options[] =
40b8e679
L
1508{
1509 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1510 {"debug", no_argument, NULL, 'd'},
1511 {"version", no_argument, NULL, 'V'},
1512 {"help", no_argument, NULL, 'h'},
1513 {0, no_argument, NULL, 0}
1514};
1515
1516static void
1517print_version (void)
1518{
1519 printf ("%s: version 1.0\n", program_name);
1520 xexit (0);
1521}
1522
1523static void
1524usage (FILE * stream, int status)
1525{
1526 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1527 program_name);
1528 xexit (status);
1529}
1530
1531int
1532main (int argc, char **argv)
1533{
1534 extern int chdir (char *);
1535 char *srcdir = NULL;
8b40d594 1536 int c;
e92bae62 1537 unsigned int i, cpumax;
72ffa0fb 1538 FILE *table;
29c048b6 1539
40b8e679
L
1540 program_name = *argv;
1541 xmalloc_set_program_name (program_name);
1542
1543 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1544 switch (c)
1545 {
1546 case OPTION_SRCDIR:
1547 srcdir = optarg;
1548 break;
1549 case 'V':
1550 case 'v':
1551 print_version ();
1552 break;
1553 case 'd':
1554 debug = 1;
1555 break;
1556 case 'h':
1557 case '?':
1558 usage (stderr, 0);
1559 default:
1560 case 0:
1561 break;
1562 }
1563
1564 if (optind != argc)
1565 usage (stdout, 1);
1566
29c048b6 1567 if (srcdir != NULL)
40b8e679
L
1568 if (chdir (srcdir) != 0)
1569 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
1570 srcdir, xstrerror (errno));
1571
e92bae62
L
1572 /* cpu_flags isn't sorted by position. */
1573 cpumax = 0;
1574 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
1575 if (cpu_flags[i].position > cpumax)
1576 cpumax = cpu_flags[i].position;
1577
40fb9820 1578 /* Check the unused bitfield in i386_cpu_flags. */
e89c5eaa 1579#ifdef CpuUnused
e92bae62
L
1580 if ((cpumax - 1) != CpuMax)
1581 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1582#else
e92bae62
L
1583 if (cpumax != CpuMax)
1584 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 1585
8b40d594
L
1586 c = CpuNumOfBits - CpuMax - 1;
1587 if (c)
1588 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
1589#endif
1590
1591 /* Check the unused bitfield in i386_operand_type. */
1592#ifndef OTUnused
8b40d594
L
1593 c = OTNumOfBits - OTMax - 1;
1594 if (c)
1595 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
1596#endif
1597
1598 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1599 compare);
1600
1601 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1602 sizeof (opcode_modifiers [0]), compare);
1603
1604 qsort (operand_types, ARRAY_SIZE (operand_types),
1605 sizeof (operand_types [0]), compare);
40b8e679 1606
34edb9ad
L
1607 table = fopen ("i386-tbl.h", "w");
1608 if (table == NULL)
40fb9820
L
1609 fail (_("can't create i386-tbl.h, errno = %s\n"),
1610 xstrerror (errno));
34edb9ad 1611
72ffa0fb 1612 process_copyright (table);
40b8e679 1613
72ffa0fb
L
1614 process_i386_opcodes (table);
1615 process_i386_registers (table);
40fb9820 1616 process_i386_initializers ();
40b8e679 1617
34edb9ad
L
1618 fclose (table);
1619
40b8e679
L
1620 exit (0);
1621}
This page took 0.655802 seconds and 4 git commands to generate.