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