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