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