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