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