1 /* Accurate fp support for CGEN-based simulators.
2 Copyright (C) 1999 Cygnus Solutions.
4 This implemention assumes:
9 - lazy encoding/decoding
10 - checking return code (say by callback)
20 addsf (CGEN_FPU
* fpu
, SF x
, SF y
)
26 sim_fpu_status status
;
28 sim_fpu_32to (&op1
, x
);
29 sim_fpu_32to (&op2
, y
);
30 status
= sim_fpu_add (&ans
, &op1
, &op2
);
32 (*fpu
->ops
->error
) (fpu
, status
);
33 sim_fpu_to32 (&res
, &ans
);
39 subsf (CGEN_FPU
* fpu
, SF x
, SF y
)
45 sim_fpu_status status
;
47 sim_fpu_32to (&op1
, x
);
48 sim_fpu_32to (&op2
, y
);
49 status
= sim_fpu_sub (&ans
, &op1
, &op2
);
51 (*fpu
->ops
->error
) (fpu
, status
);
52 sim_fpu_to32 (&res
, &ans
);
58 mulsf (CGEN_FPU
* fpu
, SF x
, SF y
)
64 sim_fpu_status status
;
66 sim_fpu_32to (&op1
, x
);
67 sim_fpu_32to (&op2
, y
);
68 status
= sim_fpu_mul (&ans
, &op1
, &op2
);
70 (*fpu
->ops
->error
) (fpu
, status
);
71 sim_fpu_to32 (&res
, &ans
);
77 divsf (CGEN_FPU
* fpu
, SF x
, SF y
)
83 sim_fpu_status status
;
85 sim_fpu_32to (&op1
, x
);
86 sim_fpu_32to (&op2
, y
);
87 status
= sim_fpu_div (&ans
, &op1
, &op2
);
89 (*fpu
->ops
->error
) (fpu
, status
);
90 sim_fpu_to32 (&res
, &ans
);
96 remsf (CGEN_FPU
* fpu
, SF x
, SF y
)
102 sim_fpu_status status
;
104 sim_fpu_32to (&op1
, x
);
105 sim_fpu_32to (&op2
, y
);
106 status
= sim_fpu_rem (&ans
, &op1
, &op2
);
108 (*fpu
->ops
->error
) (fpu
, status
);
109 sim_fpu_to32 (&res
, &ans
);
115 negsf (CGEN_FPU
* fpu
, SF x
)
120 sim_fpu_status status
;
122 sim_fpu_32to (&op1
, x
);
123 status
= sim_fpu_neg (&ans
, &op1
);
125 (*fpu
->ops
->error
) (fpu
, status
);
126 sim_fpu_to32 (&res
, &ans
);
132 abssf (CGEN_FPU
* fpu
, SF x
)
137 sim_fpu_status status
;
139 sim_fpu_32to (&op1
, x
);
140 status
= sim_fpu_abs (&ans
, &op1
);
142 (*fpu
->ops
->error
) (fpu
, status
);
143 sim_fpu_to32 (&res
, &ans
);
149 sqrtsf (CGEN_FPU
* fpu
, SF x
)
154 sim_fpu_status status
;
156 sim_fpu_32to (&op1
, x
);
157 status
= sim_fpu_sqrt (&ans
, &op1
);
159 (*fpu
->ops
->error
) (fpu
, status
);
160 sim_fpu_to32 (&res
, &ans
);
166 invsf (CGEN_FPU
* fpu
, SF x
)
171 sim_fpu_status status
;
173 sim_fpu_32to (&op1
, x
);
174 status
= sim_fpu_inv (&ans
, &op1
);
176 (*fpu
->ops
->error
) (fpu
, status
);
177 sim_fpu_to32 (&res
, &ans
);
183 minsf (CGEN_FPU
* fpu
, SF x
, SF y
)
189 sim_fpu_status status
;
191 sim_fpu_32to (&op1
, x
);
192 sim_fpu_32to (&op2
, y
);
193 status
= sim_fpu_min (&ans
, &op1
, &op2
);
195 (*fpu
->ops
->error
) (fpu
, status
);
196 sim_fpu_to32 (&res
, &ans
);
202 maxsf (CGEN_FPU
* fpu
, SF x
, SF y
)
208 sim_fpu_status status
;
210 sim_fpu_32to (&op1
, x
);
211 sim_fpu_32to (&op2
, y
);
212 status
= sim_fpu_max (&ans
, &op1
, &op2
);
214 (*fpu
->ops
->error
) (fpu
, status
);
215 sim_fpu_to32 (&res
, &ans
);
221 cmpsf (CGEN_FPU
* fpu
, SF x
, SF y
)
226 sim_fpu_32to (&op1
, x
);
227 sim_fpu_32to (&op2
, y
);
229 if (sim_fpu_is_nan (&op1
)
230 || sim_fpu_is_nan (&op2
))
241 eqsf (CGEN_FPU
* fpu
, SF x
, SF y
)
246 sim_fpu_32to (&op1
, x
);
247 sim_fpu_32to (&op2
, y
);
248 return sim_fpu_is_eq (&op1
, &op2
);
252 nesf (CGEN_FPU
* fpu
, SF x
, SF y
)
257 sim_fpu_32to (&op1
, x
);
258 sim_fpu_32to (&op2
, y
);
259 return sim_fpu_is_ne (&op1
, &op2
);
263 ltsf (CGEN_FPU
* fpu
, SF x
, SF y
)
268 sim_fpu_32to (&op1
, x
);
269 sim_fpu_32to (&op2
, y
);
270 return sim_fpu_is_lt (&op1
, &op2
);
274 lesf (CGEN_FPU
* fpu
, SF x
, SF y
)
279 sim_fpu_32to (&op1
, x
);
280 sim_fpu_32to (&op2
, y
);
281 return sim_fpu_is_le (&op1
, &op2
);
285 gtsf (CGEN_FPU
* fpu
, SF x
, SF y
)
290 sim_fpu_32to (&op1
, x
);
291 sim_fpu_32to (&op2
, y
);
292 return sim_fpu_is_gt (&op1
, &op2
);
296 gesf (CGEN_FPU
* fpu
, SF x
, SF y
)
301 sim_fpu_32to (&op1
, x
);
302 sim_fpu_32to (&op2
, y
);
303 return sim_fpu_is_ge (&op1
, &op2
);
307 unorderedsf (CGEN_FPU
* fpu
, SF x
, SF y
)
312 sim_fpu_32to (&op1
, x
);
313 sim_fpu_32to (&op2
, y
);
314 return sim_fpu_is_nan (&op1
) || sim_fpu_is_nan (&op2
);
319 fextsfdf (CGEN_FPU
* fpu
, int how UNUSED
, SF x
)
324 sim_fpu_32to (&op1
, x
);
325 sim_fpu_to64 (&res
, &op1
);
331 ftruncdfsf (CGEN_FPU
* fpu
, int how UNUSED
, DF x
)
336 sim_fpu_64to (&op1
, x
);
337 sim_fpu_to32 (&res
, &op1
);
343 floatsisf (CGEN_FPU
* fpu
, int how UNUSED
, SI x
)
348 sim_fpu_i32to (&ans
, x
, sim_fpu_round_near
);
349 sim_fpu_to32 (&res
, &ans
);
354 floatsidf (CGEN_FPU
* fpu
, int how UNUSED
, SI x
)
359 sim_fpu_i32to (&ans
, x
, sim_fpu_round_near
);
360 sim_fpu_to64 (&res
, &ans
);
365 floatdidf (CGEN_FPU
* fpu
, int how UNUSED
, DI x
)
370 sim_fpu_i64to (&ans
, x
, sim_fpu_round_near
);
371 sim_fpu_to64 (&res
, &ans
);
376 ufloatsisf (CGEN_FPU
* fpu
, int how UNUSED
, USI x
)
381 sim_fpu_u32to (&ans
, x
, sim_fpu_round_near
);
382 sim_fpu_to32 (&res
, &ans
);
387 fixsfsi (CGEN_FPU
* fpu
, int how UNUSED
, SF x
)
392 sim_fpu_32to (&op1
, x
);
393 sim_fpu_to32i (&res
, &op1
, sim_fpu_round_near
);
398 fixdfsi (CGEN_FPU
* fpu
, int how UNUSED
, DF x
)
403 sim_fpu_64to (&op1
, x
);
404 sim_fpu_to32i (&res
, &op1
, sim_fpu_round_near
);
409 fixdfdi (CGEN_FPU
* fpu
, int how UNUSED
, DF x
)
414 sim_fpu_64to (&op1
, x
);
415 sim_fpu_to64i (&res
, &op1
, sim_fpu_round_near
);
420 ufixsfsi (CGEN_FPU
* fpu
, int how UNUSED
, SF x
)
425 sim_fpu_32to (&op1
, x
);
426 sim_fpu_to32u (&res
, &op1
, sim_fpu_round_near
);
430 /* DF mode support */
433 adddf (CGEN_FPU
* fpu
, DF x
, DF y
)
439 sim_fpu_status status
;
441 sim_fpu_64to (&op1
, x
);
442 sim_fpu_64to (&op2
, y
);
443 status
= sim_fpu_add (&ans
, &op1
, &op2
);
445 (*fpu
->ops
->error
) (fpu
, status
);
446 sim_fpu_to64 (&res
, &ans
);
452 subdf (CGEN_FPU
* fpu
, DF x
, DF y
)
458 sim_fpu_status status
;
460 sim_fpu_64to (&op1
, x
);
461 sim_fpu_64to (&op2
, y
);
462 status
= sim_fpu_sub (&ans
, &op1
, &op2
);
464 (*fpu
->ops
->error
) (fpu
, status
);
465 sim_fpu_to64 (&res
, &ans
);
471 muldf (CGEN_FPU
* fpu
, DF x
, DF y
)
477 sim_fpu_status status
;
479 sim_fpu_64to (&op1
, x
);
480 sim_fpu_64to (&op2
, y
);
481 status
= sim_fpu_mul (&ans
, &op1
, &op2
);
483 (*fpu
->ops
->error
) (fpu
, status
);
484 sim_fpu_to64 (&res
, &ans
);
490 divdf (CGEN_FPU
* fpu
, DF x
, DF y
)
496 sim_fpu_status status
;
498 sim_fpu_64to (&op1
, x
);
499 sim_fpu_64to (&op2
, y
);
500 status
= sim_fpu_div (&ans
, &op1
, &op2
);
502 (*fpu
->ops
->error
) (fpu
, status
);
503 sim_fpu_to64 (&res
, &ans
);
509 remdf (CGEN_FPU
* fpu
, DF x
, DF y
)
515 sim_fpu_status status
;
517 sim_fpu_64to (&op1
, x
);
518 sim_fpu_64to (&op2
, y
);
519 status
= sim_fpu_rem (&ans
, &op1
, &op2
);
521 (*fpu
->ops
->error
) (fpu
, status
);
522 sim_fpu_to64(&res
, &ans
);
528 negdf (CGEN_FPU
* fpu
, DF x
)
533 sim_fpu_status status
;
535 sim_fpu_64to (&op1
, x
);
536 status
= sim_fpu_neg (&ans
, &op1
);
538 (*fpu
->ops
->error
) (fpu
, status
);
539 sim_fpu_to64 (&res
, &ans
);
545 absdf (CGEN_FPU
* fpu
, DF x
)
550 sim_fpu_status status
;
552 sim_fpu_64to (&op1
, x
);
553 status
= sim_fpu_abs (&ans
, &op1
);
555 (*fpu
->ops
->error
) (fpu
, status
);
556 sim_fpu_to64 (&res
, &ans
);
562 sqrtdf (CGEN_FPU
* fpu
, DF x
)
567 sim_fpu_status status
;
569 sim_fpu_64to (&op1
, x
);
570 status
= sim_fpu_sqrt (&ans
, &op1
);
572 (*fpu
->ops
->error
) (fpu
, status
);
573 sim_fpu_to64 (&res
, &ans
);
579 invdf (CGEN_FPU
* fpu
, DF x
)
584 sim_fpu_status status
;
586 sim_fpu_64to (&op1
, x
);
587 status
= sim_fpu_inv (&ans
, &op1
);
589 (*fpu
->ops
->error
) (fpu
, status
);
590 sim_fpu_to64 (&res
, &ans
);
596 mindf (CGEN_FPU
* fpu
, DF x
, DF y
)
602 sim_fpu_status status
;
604 sim_fpu_64to (&op1
, x
);
605 sim_fpu_64to (&op2
, y
);
606 status
= sim_fpu_min (&ans
, &op1
, &op2
);
608 (*fpu
->ops
->error
) (fpu
, status
);
609 sim_fpu_to64 (&res
, &ans
);
615 maxdf (CGEN_FPU
* fpu
, DF x
, DF y
)
621 sim_fpu_status status
;
623 sim_fpu_64to (&op1
, x
);
624 sim_fpu_64to (&op2
, y
);
625 status
= sim_fpu_max (&ans
, &op1
, &op2
);
627 (*fpu
->ops
->error
) (fpu
, status
);
628 sim_fpu_to64 (&res
, &ans
);
634 cmpdf (CGEN_FPU
* fpu
, DF x
, DF y
)
639 sim_fpu_64to (&op1
, x
);
640 sim_fpu_64to (&op2
, y
);
642 if (sim_fpu_is_nan (&op1
)
643 || sim_fpu_is_nan (&op2
))
654 eqdf (CGEN_FPU
* fpu
, DF x
, DF y
)
659 sim_fpu_64to (&op1
, x
);
660 sim_fpu_64to (&op2
, y
);
661 return sim_fpu_is_eq (&op1
, &op2
);
665 nedf (CGEN_FPU
* fpu
, DF x
, DF y
)
670 sim_fpu_64to (&op1
, x
);
671 sim_fpu_64to (&op2
, y
);
672 return sim_fpu_is_ne (&op1
, &op2
);
676 ltdf (CGEN_FPU
* fpu
, DF x
, DF y
)
681 sim_fpu_64to (&op1
, x
);
682 sim_fpu_64to (&op2
, y
);
683 return sim_fpu_is_lt (&op1
, &op2
);
687 ledf (CGEN_FPU
* fpu
, DF x
, DF y
)
692 sim_fpu_64to (&op1
, x
);
693 sim_fpu_64to (&op2
, y
);
694 return sim_fpu_is_le (&op1
, &op2
);
698 gtdf (CGEN_FPU
* fpu
, DF x
, DF y
)
703 sim_fpu_64to (&op1
, x
);
704 sim_fpu_64to (&op2
, y
);
705 return sim_fpu_is_gt (&op1
, &op2
);
709 gedf (CGEN_FPU
* fpu
, DF x
, DF y
)
714 sim_fpu_64to (&op1
, x
);
715 sim_fpu_64to (&op2
, y
);
716 return sim_fpu_is_ge (&op1
, &op2
);
720 unordereddf (CGEN_FPU
* fpu
, DF x
, DF y
)
725 sim_fpu_64to (&op1
, x
);
726 sim_fpu_64to (&op2
, y
);
727 return sim_fpu_is_nan (&op1
) || sim_fpu_is_nan (&op2
);
730 /* Initialize FP_OPS to use accurate library. */
733 cgen_init_accurate_fpu (SIM_CPU
* cpu
, CGEN_FPU
* fpu
, CGEN_FPU_ERROR_FN
* error
)
738 /* ??? small memory leak, not freed by sim_close */
739 fpu
->ops
= (CGEN_FP_OPS
*) xmalloc (sizeof (CGEN_FP_OPS
));
742 memset (o
, 0, sizeof (*o
));
764 o
->unorderedsf
= unorderedsf
;
784 o
->unordereddf
= unordereddf
;
785 o
->fextsfdf
= fextsfdf
;
786 o
->ftruncdfsf
= ftruncdfsf
;
787 o
->floatsisf
= floatsisf
;
788 o
->floatsidf
= floatsidf
;
789 o
->floatdidf
= floatdidf
;
790 o
->ufloatsisf
= ufloatsisf
;
791 o
->fixsfsi
= fixsfsi
;
792 o
->fixdfsi
= fixdfsi
;
793 o
->fixdfdi
= fixdfdi
;
794 o
->ufixsfsi
= ufixsfsi
;
This page took 0.051134 seconds and 4 git commands to generate.