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