]>
Commit | Line | Data |
---|---|---|
3535ad49 JM |
1 | /* Accurate fp support for CGEN-based simulators. |
2 | Copyright (C) 1999 Cygnus Solutions. | |
3 | ||
4 | This implemention assumes: | |
5 | typedef USI SF; | |
6 | typedef UDI DF; | |
7 | ||
8 | TODO: | |
9 | - lazy encoding/decoding | |
10 | - checking return code (say by callback) | |
11 | - proper rounding | |
12 | */ | |
13 | ||
6df01ab8 MF |
14 | /* This must come before any other includes. */ |
15 | #include "defs.h" | |
16 | ||
3535ad49 JM |
17 | #include "sim-main.h" |
18 | #include "sim-fpu.h" | |
19 | ||
20 | /* SF mode support */ | |
21 | ||
22 | static SF | |
23 | addsf (CGEN_FPU* fpu, SF x, SF y) | |
24 | { | |
25 | sim_fpu op1; | |
26 | sim_fpu op2; | |
27 | sim_fpu ans; | |
e4c803f5 | 28 | uint32_t res; |
3535ad49 JM |
29 | sim_fpu_status status; |
30 | ||
31 | sim_fpu_32to (&op1, x); | |
32 | sim_fpu_32to (&op2, y); | |
33 | status = sim_fpu_add (&ans, &op1, &op2); | |
34 | if (status != 0) | |
35 | (*fpu->ops->error) (fpu, status); | |
36 | sim_fpu_to32 (&res, &ans); | |
37 | ||
38 | return res; | |
39 | } | |
40 | ||
41 | static SF | |
42 | subsf (CGEN_FPU* fpu, SF x, SF y) | |
43 | { | |
44 | sim_fpu op1; | |
45 | sim_fpu op2; | |
46 | sim_fpu ans; | |
e4c803f5 | 47 | uint32_t res; |
c2d11a7d | 48 | sim_fpu_status status; |
3535ad49 JM |
49 | |
50 | sim_fpu_32to (&op1, x); | |
51 | sim_fpu_32to (&op2, y); | |
c2d11a7d JM |
52 | status = sim_fpu_sub (&ans, &op1, &op2); |
53 | if (status != 0) | |
54 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
55 | sim_fpu_to32 (&res, &ans); |
56 | ||
57 | return res; | |
58 | } | |
59 | ||
60 | static SF | |
61 | mulsf (CGEN_FPU* fpu, SF x, SF y) | |
62 | { | |
63 | sim_fpu op1; | |
64 | sim_fpu op2; | |
65 | sim_fpu ans; | |
e4c803f5 | 66 | uint32_t res; |
c2d11a7d | 67 | sim_fpu_status status; |
3535ad49 JM |
68 | |
69 | sim_fpu_32to (&op1, x); | |
70 | sim_fpu_32to (&op2, y); | |
c2d11a7d JM |
71 | status = sim_fpu_mul (&ans, &op1, &op2); |
72 | if (status != 0) | |
73 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
74 | sim_fpu_to32 (&res, &ans); |
75 | ||
76 | return res; | |
77 | } | |
78 | ||
79 | static SF | |
80 | divsf (CGEN_FPU* fpu, SF x, SF y) | |
81 | { | |
82 | sim_fpu op1; | |
83 | sim_fpu op2; | |
84 | sim_fpu ans; | |
e4c803f5 | 85 | uint32_t res; |
917317f4 | 86 | sim_fpu_status status; |
3535ad49 JM |
87 | |
88 | sim_fpu_32to (&op1, x); | |
89 | sim_fpu_32to (&op2, y); | |
917317f4 JM |
90 | status = sim_fpu_div (&ans, &op1, &op2); |
91 | if (status != 0) | |
92 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
93 | sim_fpu_to32 (&res, &ans); |
94 | ||
95 | return res; | |
96 | } | |
97 | ||
07b95864 PG |
98 | static SF |
99 | remsf (CGEN_FPU* fpu, SF x, SF y) | |
100 | { | |
101 | sim_fpu op1; | |
102 | sim_fpu op2; | |
103 | sim_fpu ans; | |
e4c803f5 | 104 | uint32_t res; |
07b95864 PG |
105 | sim_fpu_status status; |
106 | ||
107 | sim_fpu_32to (&op1, x); | |
108 | sim_fpu_32to (&op2, y); | |
109 | status = sim_fpu_rem (&ans, &op1, &op2); | |
110 | if (status != 0) | |
111 | (*fpu->ops->error) (fpu, status); | |
112 | sim_fpu_to32 (&res, &ans); | |
113 | ||
114 | return res; | |
115 | } | |
116 | ||
3535ad49 JM |
117 | static SF |
118 | negsf (CGEN_FPU* fpu, SF x) | |
119 | { | |
120 | sim_fpu op1; | |
121 | sim_fpu ans; | |
e4c803f5 | 122 | uint32_t res; |
c2d11a7d | 123 | sim_fpu_status status; |
3535ad49 JM |
124 | |
125 | sim_fpu_32to (&op1, x); | |
c2d11a7d JM |
126 | status = sim_fpu_neg (&ans, &op1); |
127 | if (status != 0) | |
128 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
129 | sim_fpu_to32 (&res, &ans); |
130 | ||
131 | return res; | |
132 | } | |
133 | ||
134 | static SF | |
135 | abssf (CGEN_FPU* fpu, SF x) | |
136 | { | |
137 | sim_fpu op1; | |
138 | sim_fpu ans; | |
e4c803f5 | 139 | uint32_t res; |
c2d11a7d | 140 | sim_fpu_status status; |
3535ad49 JM |
141 | |
142 | sim_fpu_32to (&op1, x); | |
c2d11a7d JM |
143 | status = sim_fpu_abs (&ans, &op1); |
144 | if (status != 0) | |
145 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
146 | sim_fpu_to32 (&res, &ans); |
147 | ||
148 | return res; | |
149 | } | |
150 | ||
151 | static SF | |
152 | sqrtsf (CGEN_FPU* fpu, SF x) | |
153 | { | |
154 | sim_fpu op1; | |
155 | sim_fpu ans; | |
e4c803f5 | 156 | uint32_t res; |
c2d11a7d | 157 | sim_fpu_status status; |
3535ad49 JM |
158 | |
159 | sim_fpu_32to (&op1, x); | |
c2d11a7d JM |
160 | status = sim_fpu_sqrt (&ans, &op1); |
161 | if (status != 0) | |
162 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
163 | sim_fpu_to32 (&res, &ans); |
164 | ||
165 | return res; | |
166 | } | |
167 | ||
168 | static SF | |
169 | invsf (CGEN_FPU* fpu, SF x) | |
170 | { | |
171 | sim_fpu op1; | |
172 | sim_fpu ans; | |
e4c803f5 | 173 | uint32_t res; |
c2d11a7d | 174 | sim_fpu_status status; |
3535ad49 JM |
175 | |
176 | sim_fpu_32to (&op1, x); | |
c2d11a7d JM |
177 | status = sim_fpu_inv (&ans, &op1); |
178 | if (status != 0) | |
179 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
180 | sim_fpu_to32 (&res, &ans); |
181 | ||
182 | return res; | |
183 | } | |
184 | ||
185 | static SF | |
186 | minsf (CGEN_FPU* fpu, SF x, SF y) | |
187 | { | |
188 | sim_fpu op1; | |
189 | sim_fpu op2; | |
190 | sim_fpu ans; | |
e4c803f5 | 191 | uint32_t res; |
c2d11a7d | 192 | sim_fpu_status status; |
3535ad49 JM |
193 | |
194 | sim_fpu_32to (&op1, x); | |
195 | sim_fpu_32to (&op2, y); | |
c2d11a7d JM |
196 | status = sim_fpu_min (&ans, &op1, &op2); |
197 | if (status != 0) | |
198 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
199 | sim_fpu_to32 (&res, &ans); |
200 | ||
201 | return res; | |
202 | } | |
203 | ||
204 | static SF | |
205 | maxsf (CGEN_FPU* fpu, SF x, SF y) | |
206 | { | |
207 | sim_fpu op1; | |
208 | sim_fpu op2; | |
209 | sim_fpu ans; | |
e4c803f5 | 210 | uint32_t res; |
c2d11a7d | 211 | sim_fpu_status status; |
3535ad49 JM |
212 | |
213 | sim_fpu_32to (&op1, x); | |
214 | sim_fpu_32to (&op2, y); | |
c2d11a7d JM |
215 | status = sim_fpu_max (&ans, &op1, &op2); |
216 | if (status != 0) | |
217 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
218 | sim_fpu_to32 (&res, &ans); |
219 | ||
220 | return res; | |
221 | } | |
222 | ||
223 | static CGEN_FP_CMP | |
224 | cmpsf (CGEN_FPU* fpu, SF x, SF y) | |
225 | { | |
226 | sim_fpu op1; | |
227 | sim_fpu op2; | |
228 | ||
229 | sim_fpu_32to (&op1, x); | |
230 | sim_fpu_32to (&op2, y); | |
231 | ||
232 | if (sim_fpu_is_nan (&op1) | |
233 | || sim_fpu_is_nan (&op2)) | |
234 | return FP_CMP_NAN; | |
235 | ||
236 | if (x < y) | |
237 | return FP_CMP_LT; | |
238 | if (x > y) | |
239 | return FP_CMP_GT; | |
240 | return FP_CMP_EQ; | |
241 | } | |
242 | ||
243 | static int | |
244 | eqsf (CGEN_FPU* fpu, SF x, SF y) | |
245 | { | |
246 | sim_fpu op1; | |
247 | sim_fpu op2; | |
248 | ||
249 | sim_fpu_32to (&op1, x); | |
250 | sim_fpu_32to (&op2, y); | |
251 | return sim_fpu_is_eq (&op1, &op2); | |
252 | } | |
253 | ||
254 | static int | |
255 | nesf (CGEN_FPU* fpu, SF x, SF y) | |
256 | { | |
257 | sim_fpu op1; | |
258 | sim_fpu op2; | |
259 | ||
260 | sim_fpu_32to (&op1, x); | |
261 | sim_fpu_32to (&op2, y); | |
262 | return sim_fpu_is_ne (&op1, &op2); | |
263 | } | |
264 | ||
265 | static int | |
266 | ltsf (CGEN_FPU* fpu, SF x, SF y) | |
267 | { | |
268 | sim_fpu op1; | |
269 | sim_fpu op2; | |
270 | ||
271 | sim_fpu_32to (&op1, x); | |
272 | sim_fpu_32to (&op2, y); | |
273 | return sim_fpu_is_lt (&op1, &op2); | |
274 | } | |
275 | ||
276 | static int | |
277 | lesf (CGEN_FPU* fpu, SF x, SF y) | |
278 | { | |
279 | sim_fpu op1; | |
280 | sim_fpu op2; | |
281 | ||
282 | sim_fpu_32to (&op1, x); | |
283 | sim_fpu_32to (&op2, y); | |
284 | return sim_fpu_is_le (&op1, &op2); | |
285 | } | |
286 | ||
287 | static int | |
288 | gtsf (CGEN_FPU* fpu, SF x, SF y) | |
289 | { | |
290 | sim_fpu op1; | |
291 | sim_fpu op2; | |
292 | ||
293 | sim_fpu_32to (&op1, x); | |
294 | sim_fpu_32to (&op2, y); | |
295 | return sim_fpu_is_gt (&op1, &op2); | |
296 | } | |
297 | ||
298 | static int | |
299 | gesf (CGEN_FPU* fpu, SF x, SF y) | |
300 | { | |
301 | sim_fpu op1; | |
302 | sim_fpu op2; | |
303 | ||
304 | sim_fpu_32to (&op1, x); | |
305 | sim_fpu_32to (&op2, y); | |
306 | return sim_fpu_is_ge (&op1, &op2); | |
307 | } | |
308 | ||
f1cc84f5 SH |
309 | static int |
310 | unorderedsf (CGEN_FPU* fpu, SF x, SF y) | |
311 | { | |
312 | sim_fpu op1; | |
313 | sim_fpu op2; | |
314 | ||
315 | sim_fpu_32to (&op1, x); | |
316 | sim_fpu_32to (&op2, y); | |
317 | return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2); | |
318 | } | |
319 | ||
320 | ||
f8603f2f | 321 | static DF |
d2c7a1a6 | 322 | fextsfdf (CGEN_FPU* fpu, int how UNUSED, SF x) |
f8603f2f DB |
323 | { |
324 | sim_fpu op1; | |
e4c803f5 | 325 | uint64_t res; |
f8603f2f DB |
326 | |
327 | sim_fpu_32to (&op1, x); | |
328 | sim_fpu_to64 (&res, &op1); | |
329 | ||
330 | return res; | |
331 | } | |
332 | ||
333 | static SF | |
d2c7a1a6 | 334 | ftruncdfsf (CGEN_FPU* fpu, int how UNUSED, DF x) |
f8603f2f DB |
335 | { |
336 | sim_fpu op1; | |
e4c803f5 | 337 | uint32_t res; |
f8603f2f DB |
338 | |
339 | sim_fpu_64to (&op1, x); | |
340 | sim_fpu_to32 (&res, &op1); | |
341 | ||
342 | return res; | |
343 | } | |
344 | ||
3535ad49 | 345 | static SF |
d2c7a1a6 | 346 | floatsisf (CGEN_FPU* fpu, int how UNUSED, SI x) |
3535ad49 JM |
347 | { |
348 | sim_fpu ans; | |
e4c803f5 | 349 | uint32_t res; |
3535ad49 JM |
350 | |
351 | sim_fpu_i32to (&ans, x, sim_fpu_round_near); | |
352 | sim_fpu_to32 (&res, &ans); | |
353 | return res; | |
354 | } | |
355 | ||
9846de1b | 356 | static DF |
d2c7a1a6 | 357 | floatsidf (CGEN_FPU* fpu, int how UNUSED, SI x) |
9846de1b JM |
358 | { |
359 | sim_fpu ans; | |
e4c803f5 | 360 | uint64_t res; |
9846de1b JM |
361 | |
362 | sim_fpu_i32to (&ans, x, sim_fpu_round_near); | |
363 | sim_fpu_to64 (&res, &ans); | |
364 | return res; | |
365 | } | |
366 | ||
688cea90 SH |
367 | static DF |
368 | floatdidf (CGEN_FPU* fpu, int how UNUSED, DI x) | |
369 | { | |
370 | sim_fpu ans; | |
e4c803f5 | 371 | uint64_t res; |
688cea90 SH |
372 | |
373 | sim_fpu_i64to (&ans, x, sim_fpu_round_near); | |
374 | sim_fpu_to64 (&res, &ans); | |
375 | return res; | |
376 | } | |
377 | ||
3535ad49 | 378 | static SF |
d2c7a1a6 | 379 | ufloatsisf (CGEN_FPU* fpu, int how UNUSED, USI x) |
3535ad49 JM |
380 | { |
381 | sim_fpu ans; | |
e4c803f5 | 382 | uint32_t res; |
3535ad49 JM |
383 | |
384 | sim_fpu_u32to (&ans, x, sim_fpu_round_near); | |
385 | sim_fpu_to32 (&res, &ans); | |
386 | return res; | |
387 | } | |
388 | ||
389 | static SI | |
d2c7a1a6 | 390 | fixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x) |
3535ad49 JM |
391 | { |
392 | sim_fpu op1; | |
e4c803f5 | 393 | int32_t res; |
3535ad49 JM |
394 | |
395 | sim_fpu_32to (&op1, x); | |
396 | sim_fpu_to32i (&res, &op1, sim_fpu_round_near); | |
397 | return res; | |
398 | } | |
399 | ||
9846de1b | 400 | static SI |
d2c7a1a6 | 401 | fixdfsi (CGEN_FPU* fpu, int how UNUSED, DF x) |
9846de1b JM |
402 | { |
403 | sim_fpu op1; | |
e4c803f5 | 404 | int32_t res; |
9846de1b JM |
405 | |
406 | sim_fpu_64to (&op1, x); | |
407 | sim_fpu_to32i (&res, &op1, sim_fpu_round_near); | |
408 | return res; | |
409 | } | |
410 | ||
688cea90 SH |
411 | static DI |
412 | fixdfdi (CGEN_FPU* fpu, int how UNUSED, DF x) | |
413 | { | |
414 | sim_fpu op1; | |
e4c803f5 | 415 | int64_t res; |
688cea90 SH |
416 | |
417 | sim_fpu_64to (&op1, x); | |
418 | sim_fpu_to64i (&res, &op1, sim_fpu_round_near); | |
419 | return res; | |
420 | } | |
421 | ||
3535ad49 | 422 | static USI |
d2c7a1a6 | 423 | ufixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x) |
3535ad49 JM |
424 | { |
425 | sim_fpu op1; | |
e4c803f5 | 426 | uint32_t res; |
3535ad49 JM |
427 | |
428 | sim_fpu_32to (&op1, x); | |
429 | sim_fpu_to32u (&res, &op1, sim_fpu_round_near); | |
430 | return res; | |
431 | } | |
432 | \f | |
433 | /* DF mode support */ | |
434 | ||
435 | static DF | |
436 | adddf (CGEN_FPU* fpu, DF x, DF y) | |
437 | { | |
438 | sim_fpu op1; | |
439 | sim_fpu op2; | |
440 | sim_fpu ans; | |
e4c803f5 | 441 | uint64_t res; |
3535ad49 JM |
442 | sim_fpu_status status; |
443 | ||
444 | sim_fpu_64to (&op1, x); | |
445 | sim_fpu_64to (&op2, y); | |
446 | status = sim_fpu_add (&ans, &op1, &op2); | |
447 | if (status != 0) | |
448 | (*fpu->ops->error) (fpu, status); | |
449 | sim_fpu_to64 (&res, &ans); | |
450 | ||
451 | return res; | |
452 | } | |
453 | ||
454 | static DF | |
455 | subdf (CGEN_FPU* fpu, DF x, DF y) | |
456 | { | |
457 | sim_fpu op1; | |
458 | sim_fpu op2; | |
459 | sim_fpu ans; | |
e4c803f5 | 460 | uint64_t res; |
c2d11a7d | 461 | sim_fpu_status status; |
3535ad49 JM |
462 | |
463 | sim_fpu_64to (&op1, x); | |
464 | sim_fpu_64to (&op2, y); | |
c2d11a7d JM |
465 | status = sim_fpu_sub (&ans, &op1, &op2); |
466 | if (status != 0) | |
467 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
468 | sim_fpu_to64 (&res, &ans); |
469 | ||
470 | return res; | |
471 | } | |
472 | ||
473 | static DF | |
474 | muldf (CGEN_FPU* fpu, DF x, DF y) | |
475 | { | |
476 | sim_fpu op1; | |
477 | sim_fpu op2; | |
478 | sim_fpu ans; | |
e4c803f5 | 479 | uint64_t res; |
c2d11a7d | 480 | sim_fpu_status status; |
3535ad49 JM |
481 | |
482 | sim_fpu_64to (&op1, x); | |
483 | sim_fpu_64to (&op2, y); | |
c2d11a7d JM |
484 | status = sim_fpu_mul (&ans, &op1, &op2); |
485 | if (status != 0) | |
486 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
487 | sim_fpu_to64 (&res, &ans); |
488 | ||
489 | return res; | |
490 | } | |
491 | ||
492 | static DF | |
493 | divdf (CGEN_FPU* fpu, DF x, DF y) | |
494 | { | |
495 | sim_fpu op1; | |
496 | sim_fpu op2; | |
497 | sim_fpu ans; | |
e4c803f5 | 498 | uint64_t res; |
c2d11a7d | 499 | sim_fpu_status status; |
3535ad49 JM |
500 | |
501 | sim_fpu_64to (&op1, x); | |
502 | sim_fpu_64to (&op2, y); | |
c2d11a7d JM |
503 | status = sim_fpu_div (&ans, &op1, &op2); |
504 | if (status != 0) | |
505 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
506 | sim_fpu_to64 (&res, &ans); |
507 | ||
508 | return res; | |
509 | } | |
510 | ||
07b95864 PG |
511 | static DF |
512 | remdf (CGEN_FPU* fpu, DF x, DF y) | |
513 | { | |
514 | sim_fpu op1; | |
515 | sim_fpu op2; | |
516 | sim_fpu ans; | |
e4c803f5 | 517 | uint64_t res; |
07b95864 PG |
518 | sim_fpu_status status; |
519 | ||
520 | sim_fpu_64to (&op1, x); | |
521 | sim_fpu_64to (&op2, y); | |
522 | status = sim_fpu_rem (&ans, &op1, &op2); | |
523 | if (status != 0) | |
524 | (*fpu->ops->error) (fpu, status); | |
525 | sim_fpu_to64(&res, &ans); | |
526 | ||
527 | return res; | |
528 | } | |
529 | ||
3535ad49 JM |
530 | static DF |
531 | negdf (CGEN_FPU* fpu, DF x) | |
532 | { | |
533 | sim_fpu op1; | |
534 | sim_fpu ans; | |
e4c803f5 | 535 | uint64_t res; |
c2d11a7d | 536 | sim_fpu_status status; |
3535ad49 JM |
537 | |
538 | sim_fpu_64to (&op1, x); | |
c2d11a7d JM |
539 | status = sim_fpu_neg (&ans, &op1); |
540 | if (status != 0) | |
541 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
542 | sim_fpu_to64 (&res, &ans); |
543 | ||
544 | return res; | |
545 | } | |
546 | ||
547 | static DF | |
548 | absdf (CGEN_FPU* fpu, DF x) | |
549 | { | |
550 | sim_fpu op1; | |
551 | sim_fpu ans; | |
e4c803f5 | 552 | uint64_t res; |
c2d11a7d | 553 | sim_fpu_status status; |
3535ad49 JM |
554 | |
555 | sim_fpu_64to (&op1, x); | |
c2d11a7d JM |
556 | status = sim_fpu_abs (&ans, &op1); |
557 | if (status != 0) | |
558 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
559 | sim_fpu_to64 (&res, &ans); |
560 | ||
561 | return res; | |
562 | } | |
563 | ||
564 | static DF | |
565 | sqrtdf (CGEN_FPU* fpu, DF x) | |
566 | { | |
567 | sim_fpu op1; | |
568 | sim_fpu ans; | |
e4c803f5 | 569 | uint64_t res; |
c2d11a7d | 570 | sim_fpu_status status; |
3535ad49 JM |
571 | |
572 | sim_fpu_64to (&op1, x); | |
c2d11a7d JM |
573 | status = sim_fpu_sqrt (&ans, &op1); |
574 | if (status != 0) | |
575 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
576 | sim_fpu_to64 (&res, &ans); |
577 | ||
578 | return res; | |
579 | } | |
580 | ||
581 | static DF | |
582 | invdf (CGEN_FPU* fpu, DF x) | |
583 | { | |
584 | sim_fpu op1; | |
585 | sim_fpu ans; | |
e4c803f5 | 586 | uint64_t res; |
c2d11a7d | 587 | sim_fpu_status status; |
3535ad49 JM |
588 | |
589 | sim_fpu_64to (&op1, x); | |
c2d11a7d JM |
590 | status = sim_fpu_inv (&ans, &op1); |
591 | if (status != 0) | |
592 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
593 | sim_fpu_to64 (&res, &ans); |
594 | ||
595 | return res; | |
596 | } | |
597 | ||
598 | static DF | |
599 | mindf (CGEN_FPU* fpu, DF x, DF y) | |
600 | { | |
601 | sim_fpu op1; | |
602 | sim_fpu op2; | |
603 | sim_fpu ans; | |
e4c803f5 | 604 | uint64_t res; |
c2d11a7d | 605 | sim_fpu_status status; |
3535ad49 JM |
606 | |
607 | sim_fpu_64to (&op1, x); | |
608 | sim_fpu_64to (&op2, y); | |
c2d11a7d JM |
609 | status = sim_fpu_min (&ans, &op1, &op2); |
610 | if (status != 0) | |
611 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
612 | sim_fpu_to64 (&res, &ans); |
613 | ||
614 | return res; | |
615 | } | |
616 | ||
617 | static DF | |
618 | maxdf (CGEN_FPU* fpu, DF x, DF y) | |
619 | { | |
620 | sim_fpu op1; | |
621 | sim_fpu op2; | |
622 | sim_fpu ans; | |
e4c803f5 | 623 | uint64_t res; |
c2d11a7d | 624 | sim_fpu_status status; |
3535ad49 JM |
625 | |
626 | sim_fpu_64to (&op1, x); | |
627 | sim_fpu_64to (&op2, y); | |
c2d11a7d JM |
628 | status = sim_fpu_max (&ans, &op1, &op2); |
629 | if (status != 0) | |
630 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
631 | sim_fpu_to64 (&res, &ans); |
632 | ||
633 | return res; | |
634 | } | |
635 | ||
636 | static CGEN_FP_CMP | |
637 | cmpdf (CGEN_FPU* fpu, DF x, DF y) | |
638 | { | |
639 | sim_fpu op1; | |
640 | sim_fpu op2; | |
641 | ||
642 | sim_fpu_64to (&op1, x); | |
643 | sim_fpu_64to (&op2, y); | |
644 | ||
645 | if (sim_fpu_is_nan (&op1) | |
646 | || sim_fpu_is_nan (&op2)) | |
647 | return FP_CMP_NAN; | |
648 | ||
649 | if (x < y) | |
650 | return FP_CMP_LT; | |
651 | if (x > y) | |
652 | return FP_CMP_GT; | |
653 | return FP_CMP_EQ; | |
654 | } | |
655 | ||
656 | static int | |
657 | eqdf (CGEN_FPU* fpu, DF x, DF y) | |
658 | { | |
659 | sim_fpu op1; | |
660 | sim_fpu op2; | |
661 | ||
662 | sim_fpu_64to (&op1, x); | |
663 | sim_fpu_64to (&op2, y); | |
664 | return sim_fpu_is_eq (&op1, &op2); | |
665 | } | |
666 | ||
667 | static int | |
668 | nedf (CGEN_FPU* fpu, DF x, DF y) | |
669 | { | |
670 | sim_fpu op1; | |
671 | sim_fpu op2; | |
672 | ||
673 | sim_fpu_64to (&op1, x); | |
674 | sim_fpu_64to (&op2, y); | |
675 | return sim_fpu_is_ne (&op1, &op2); | |
676 | } | |
677 | ||
678 | static int | |
679 | ltdf (CGEN_FPU* fpu, DF x, DF y) | |
680 | { | |
681 | sim_fpu op1; | |
682 | sim_fpu op2; | |
683 | ||
684 | sim_fpu_64to (&op1, x); | |
685 | sim_fpu_64to (&op2, y); | |
686 | return sim_fpu_is_lt (&op1, &op2); | |
687 | } | |
688 | ||
689 | static int | |
690 | ledf (CGEN_FPU* fpu, DF x, DF y) | |
691 | { | |
692 | sim_fpu op1; | |
693 | sim_fpu op2; | |
694 | ||
695 | sim_fpu_64to (&op1, x); | |
696 | sim_fpu_64to (&op2, y); | |
697 | return sim_fpu_is_le (&op1, &op2); | |
698 | } | |
699 | ||
700 | static int | |
701 | gtdf (CGEN_FPU* fpu, DF x, DF y) | |
702 | { | |
703 | sim_fpu op1; | |
704 | sim_fpu op2; | |
705 | ||
706 | sim_fpu_64to (&op1, x); | |
707 | sim_fpu_64to (&op2, y); | |
708 | return sim_fpu_is_gt (&op1, &op2); | |
709 | } | |
710 | ||
711 | static int | |
712 | gedf (CGEN_FPU* fpu, DF x, DF y) | |
713 | { | |
714 | sim_fpu op1; | |
715 | sim_fpu op2; | |
716 | ||
717 | sim_fpu_64to (&op1, x); | |
718 | sim_fpu_64to (&op2, y); | |
719 | return sim_fpu_is_ge (&op1, &op2); | |
720 | } | |
f1cc84f5 SH |
721 | |
722 | static int | |
723 | unordereddf (CGEN_FPU* fpu, DF x, DF y) | |
724 | { | |
725 | sim_fpu op1; | |
726 | sim_fpu op2; | |
727 | ||
728 | sim_fpu_64to (&op1, x); | |
729 | sim_fpu_64to (&op2, y); | |
730 | return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2); | |
731 | } | |
3535ad49 JM |
732 | \f |
733 | /* Initialize FP_OPS to use accurate library. */ | |
734 | ||
735 | void | |
736 | cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error) | |
737 | { | |
738 | CGEN_FP_OPS* o; | |
739 | ||
740 | fpu->owner = cpu; | |
741 | /* ??? small memory leak, not freed by sim_close */ | |
742 | fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS)); | |
743 | ||
744 | o = fpu->ops; | |
745 | memset (o, 0, sizeof (*o)); | |
746 | ||
747 | o->error = error; | |
748 | ||
749 | o->addsf = addsf; | |
750 | o->subsf = subsf; | |
751 | o->mulsf = mulsf; | |
752 | o->divsf = divsf; | |
07b95864 | 753 | o->remsf = remsf; |
3535ad49 JM |
754 | o->negsf = negsf; |
755 | o->abssf = abssf; | |
756 | o->sqrtsf = sqrtsf; | |
757 | o->invsf = invsf; | |
758 | o->minsf = minsf; | |
759 | o->maxsf = maxsf; | |
760 | o->cmpsf = cmpsf; | |
761 | o->eqsf = eqsf; | |
762 | o->nesf = nesf; | |
763 | o->ltsf = ltsf; | |
764 | o->lesf = lesf; | |
765 | o->gtsf = gtsf; | |
766 | o->gesf = gesf; | |
f1cc84f5 | 767 | o->unorderedsf = unorderedsf; |
3535ad49 JM |
768 | |
769 | o->adddf = adddf; | |
770 | o->subdf = subdf; | |
771 | o->muldf = muldf; | |
772 | o->divdf = divdf; | |
07b95864 | 773 | o->remdf = remdf; |
3535ad49 JM |
774 | o->negdf = negdf; |
775 | o->absdf = absdf; | |
776 | o->sqrtdf = sqrtdf; | |
777 | o->invdf = invdf; | |
778 | o->mindf = mindf; | |
779 | o->maxdf = maxdf; | |
780 | o->cmpdf = cmpdf; | |
781 | o->eqdf = eqdf; | |
782 | o->nedf = nedf; | |
783 | o->ltdf = ltdf; | |
784 | o->ledf = ledf; | |
785 | o->gtdf = gtdf; | |
786 | o->gedf = gedf; | |
f1cc84f5 | 787 | o->unordereddf = unordereddf; |
f8603f2f DB |
788 | o->fextsfdf = fextsfdf; |
789 | o->ftruncdfsf = ftruncdfsf; | |
3535ad49 | 790 | o->floatsisf = floatsisf; |
9846de1b | 791 | o->floatsidf = floatsidf; |
688cea90 | 792 | o->floatdidf = floatdidf; |
3535ad49 JM |
793 | o->ufloatsisf = ufloatsisf; |
794 | o->fixsfsi = fixsfsi; | |
9846de1b | 795 | o->fixdfsi = fixdfsi; |
688cea90 | 796 | o->fixdfdi = fixdfdi; |
3535ad49 JM |
797 | o->ufixsfsi = ufixsfsi; |
798 | } |