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