This source file includes following definitions.
- valid_abi_p
- fp_mode_for_abi
- cpu_supports_fr0_p
- determine_fpu_mode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21 #include <errno.h>
22
23 #include "mipsfpu.h"
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 #define MIPS_ABI_FP_ANY 0
44 #define MIPS_ABI_FP_DOUBLE 1
45 #define MIPS_ABI_FP_SINGLE 2
46 #define MIPS_ABI_FP_SOFT 3
47 #define MIPS_ABI_FP_OLD_64 4
48 #define MIPS_ABI_FP_XX 5
49 #define MIPS_ABI_FP_64 6
50 #define MIPS_ABI_FP_64A 7
51
52 #define EF_MIPS_NOREORDER 1
53 #define EF_MIPS_PIC 2
54 #define EF_MIPS_CPIC 4
55 #define EF_MIPS_XGOT 8
56 #define EF_MIPS_64BIT_WHIRL 16
57 #define EF_MIPS_ABI2 32
58 #define EF_MIPS_ABI_ON32 64
59 #define EF_MIPS_FP64 512
60 #define EF_MIPS_NAN2008 1024
61 #define EF_MIPS_ARCH 0xf0000000
62
63
64
65
66
67
68 struct mode_description
69 {
70
71
72
73 bool single;
74
75
76
77 bool soft;
78
79
80
81 bool fr1;
82
83
84
85 bool frdefault;
86
87
88
89 bool fre;
90 };
91
92 static struct mode_description fpu_reqs[] =
93 {
94 [MIPS_ABI_FP_ANY] = { true, true, true, true, true, },
95 [MIPS_ABI_FP_DOUBLE] = { false, false, false, true, true, },
96 [MIPS_ABI_FP_SINGLE] = { true, false, false, false, false, },
97 [MIPS_ABI_FP_SOFT] = { false, true, false, false, false, },
98 [MIPS_ABI_FP_OLD_64] = { false, false, false, false, false, },
99 [MIPS_ABI_FP_XX] = { false, false, true, true, true, },
100 [MIPS_ABI_FP_64] = { false, false, true, false, false, },
101 [MIPS_ABI_FP_64A] = { false, false, true, false, true, },
102 };
103
104
105
106
107
108 static bool
109 valid_abi_p (int abi)
110 {
111 switch (abi)
112 {
113 case MIPS_ABI_FP_ANY:
114 case MIPS_ABI_FP_DOUBLE:
115 case MIPS_ABI_FP_SINGLE:
116 case MIPS_ABI_FP_SOFT:
117 case MIPS_ABI_FP_OLD_64:
118 case MIPS_ABI_FP_XX:
119 case MIPS_ABI_FP_64:
120 case MIPS_ABI_FP_64A:
121 return true;
122
123 default:
124 return false;
125 }
126 }
127
128
129
130
131 static int
132 fp_mode_for_abi (int abi)
133 {
134 struct mode_description *desc;
135
136 desc = &fpu_reqs[abi];
137
138 if (desc->fre)
139 return FP_FRE;
140 else if (desc->fr1)
141 return FP_FR1;
142
143 return FP_FR0;
144 }
145
146
147
148
149 bool
150 cpu_supports_fr0_p (void)
151 {
152 #if defined __mips_isa_rev && __mips_isa_rev >= 6
153 return true;
154 #else
155 return false;
156 #endif
157 }
158
159
160
161
162
163
164
165
166
167
168
169
170
171 int
172 determine_fpu_mode (elf_header *header, elf_header *interpreter,
173 int *mode, struct mips_elf_abi_flags *abiflags,
174 struct mips_elf_abi_flags *abiflags1)
175 {
176 int exec_abi, interpreter_abi;
177 struct mode_description *exec_desc, *interpreter_desc, common;
178
179
180
181
182
183 exec_abi = MIPS_ABI_FP_ANY;
184
185
186
187 if (header->e_flags & EF_MIPS_FP64)
188 exec_abi = MIPS_ABI_FP_OLD_64;
189
190
191
192 if (abiflags && valid_abi_p (abiflags->fp_abi))
193 exec_abi = abiflags->fp_abi;
194 else if (abiflags)
195 {
196 errno = ENOEXEC;
197 return 1;
198 }
199
200
201
202 interpreter_abi = MIPS_ABI_FP_ANY;
203
204 if (interpreter)
205 {
206 if (interpreter->e_flags & EF_MIPS_FP64)
207 interpreter_abi = MIPS_ABI_FP_OLD_64;
208
209 if (abiflags1 && valid_abi_p (abiflags->fp_abi))
210 interpreter_abi = abiflags->fp_abi;
211 else if (abiflags1)
212 {
213 errno = ELIBBAD;
214 return 1;
215 }
216 }
217
218
219
220
221 if (!interpreter)
222 {
223 *mode = fp_mode_for_abi (exec_abi);
224 return 0;
225 }
226
227
228
229
230
231
232
233 if (exec_abi == interpreter_abi)
234 {
235 *mode = fp_mode_for_abi (exec_abi);
236 return 0;
237 }
238 else if (exec_abi == MIPS_ABI_FP_ANY)
239 {
240 *mode = fp_mode_for_abi (interpreter_abi);
241 return 0;
242 }
243 else if (interpreter_abi == MIPS_ABI_FP_ANY)
244 {
245 *mode = fp_mode_for_abi (exec_abi);
246 return 0;
247 }
248
249
250
251
252 exec_desc = &fpu_reqs[exec_abi];
253 interpreter_desc = &fpu_reqs[interpreter_abi];
254
255
256 common.single = exec_desc->single && interpreter_desc->single;
257 common.soft = exec_desc->soft && interpreter_desc->soft;
258 common.fr1 = exec_desc->fr1 && interpreter_desc->fr1;
259 common.frdefault = exec_desc->frdefault && interpreter_desc->frdefault;
260 common.fre = exec_desc->fre && interpreter_desc->fre;
261
262
263
264
265 if (!(header->e_flags & EF_MIPS_ABI2))
266 *mode = FP_FR0;
267 else
268
269 *mode = FP_FR1;
270
271 if (common.fre && !common.frdefault && !common.fr1)
272
273 *mode = FP_FRE;
274 else if ((common.fr1 && common.frdefault)
275 || (common.single && !common.frdefault)
276 || common.fr1)
277
278 *mode = FP_FR1;
279 else if (!common.fre && !common.frdefault
280 && !common.fr1 && !common.single
281 && !common.soft)
282 {
283
284 errno = ELIBBAD;
285 return -1;
286 }
287
288 return 0;
289 }