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