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