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