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