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 fextsfdf (CGEN_FPU
* fpu
, int how UNUSED
, SF x
)
312 sim_fpu_32to (&op1
, x
);
313 sim_fpu_to64 (&res
, &op1
);
319 ftruncdfsf (CGEN_FPU
* fpu
, int how UNUSED
, DF x
)
324 sim_fpu_64to (&op1
, x
);
325 sim_fpu_to32 (&res
, &op1
);
331 floatsisf (CGEN_FPU
* fpu
, int how UNUSED
, SI x
)
336 sim_fpu_i32to (&ans
, x
, sim_fpu_round_near
);
337 sim_fpu_to32 (&res
, &ans
);
342 floatsidf (CGEN_FPU
* fpu
, int how UNUSED
, SI x
)
347 sim_fpu_i32to (&ans
, x
, sim_fpu_round_near
);
348 sim_fpu_to64 (&res
, &ans
);
353 floatdidf (CGEN_FPU
* fpu
, int how UNUSED
, DI x
)
358 sim_fpu_i64to (&ans
, x
, sim_fpu_round_near
);
359 sim_fpu_to64 (&res
, &ans
);
364 ufloatsisf (CGEN_FPU
* fpu
, int how UNUSED
, USI x
)
369 sim_fpu_u32to (&ans
, x
, sim_fpu_round_near
);
370 sim_fpu_to32 (&res
, &ans
);
375 fixsfsi (CGEN_FPU
* fpu
, int how UNUSED
, SF x
)
380 sim_fpu_32to (&op1
, x
);
381 sim_fpu_to32i (&res
, &op1
, sim_fpu_round_near
);
386 fixdfsi (CGEN_FPU
* fpu
, int how UNUSED
, DF x
)
391 sim_fpu_64to (&op1
, x
);
392 sim_fpu_to32i (&res
, &op1
, sim_fpu_round_near
);
397 fixdfdi (CGEN_FPU
* fpu
, int how UNUSED
, DF x
)
402 sim_fpu_64to (&op1
, x
);
403 sim_fpu_to64i (&res
, &op1
, sim_fpu_round_near
);
408 ufixsfsi (CGEN_FPU
* fpu
, int how UNUSED
, SF x
)
413 sim_fpu_32to (&op1
, x
);
414 sim_fpu_to32u (&res
, &op1
, sim_fpu_round_near
);
418 /* DF mode support */
421 adddf (CGEN_FPU
* fpu
, DF x
, DF y
)
427 sim_fpu_status status
;
429 sim_fpu_64to (&op1
, x
);
430 sim_fpu_64to (&op2
, y
);
431 status
= sim_fpu_add (&ans
, &op1
, &op2
);
433 (*fpu
->ops
->error
) (fpu
, status
);
434 sim_fpu_to64 (&res
, &ans
);
440 subdf (CGEN_FPU
* fpu
, DF x
, DF y
)
446 sim_fpu_status status
;
448 sim_fpu_64to (&op1
, x
);
449 sim_fpu_64to (&op2
, y
);
450 status
= sim_fpu_sub (&ans
, &op1
, &op2
);
452 (*fpu
->ops
->error
) (fpu
, status
);
453 sim_fpu_to64 (&res
, &ans
);
459 muldf (CGEN_FPU
* fpu
, DF x
, DF y
)
465 sim_fpu_status status
;
467 sim_fpu_64to (&op1
, x
);
468 sim_fpu_64to (&op2
, y
);
469 status
= sim_fpu_mul (&ans
, &op1
, &op2
);
471 (*fpu
->ops
->error
) (fpu
, status
);
472 sim_fpu_to64 (&res
, &ans
);
478 divdf (CGEN_FPU
* fpu
, DF x
, DF y
)
484 sim_fpu_status status
;
486 sim_fpu_64to (&op1
, x
);
487 sim_fpu_64to (&op2
, y
);
488 status
= sim_fpu_div (&ans
, &op1
, &op2
);
490 (*fpu
->ops
->error
) (fpu
, status
);
491 sim_fpu_to64 (&res
, &ans
);
497 remdf (CGEN_FPU
* fpu
, DF x
, DF y
)
503 sim_fpu_status status
;
505 sim_fpu_64to (&op1
, x
);
506 sim_fpu_64to (&op2
, y
);
507 status
= sim_fpu_rem (&ans
, &op1
, &op2
);
509 (*fpu
->ops
->error
) (fpu
, status
);
510 sim_fpu_to64(&res
, &ans
);
516 negdf (CGEN_FPU
* fpu
, DF x
)
521 sim_fpu_status status
;
523 sim_fpu_64to (&op1
, x
);
524 status
= sim_fpu_neg (&ans
, &op1
);
526 (*fpu
->ops
->error
) (fpu
, status
);
527 sim_fpu_to64 (&res
, &ans
);
533 absdf (CGEN_FPU
* fpu
, DF x
)
538 sim_fpu_status status
;
540 sim_fpu_64to (&op1
, x
);
541 status
= sim_fpu_abs (&ans
, &op1
);
543 (*fpu
->ops
->error
) (fpu
, status
);
544 sim_fpu_to64 (&res
, &ans
);
550 sqrtdf (CGEN_FPU
* fpu
, DF x
)
555 sim_fpu_status status
;
557 sim_fpu_64to (&op1
, x
);
558 status
= sim_fpu_sqrt (&ans
, &op1
);
560 (*fpu
->ops
->error
) (fpu
, status
);
561 sim_fpu_to64 (&res
, &ans
);
567 invdf (CGEN_FPU
* fpu
, DF x
)
572 sim_fpu_status status
;
574 sim_fpu_64to (&op1
, x
);
575 status
= sim_fpu_inv (&ans
, &op1
);
577 (*fpu
->ops
->error
) (fpu
, status
);
578 sim_fpu_to64 (&res
, &ans
);
584 mindf (CGEN_FPU
* fpu
, DF x
, DF y
)
590 sim_fpu_status status
;
592 sim_fpu_64to (&op1
, x
);
593 sim_fpu_64to (&op2
, y
);
594 status
= sim_fpu_min (&ans
, &op1
, &op2
);
596 (*fpu
->ops
->error
) (fpu
, status
);
597 sim_fpu_to64 (&res
, &ans
);
603 maxdf (CGEN_FPU
* fpu
, DF x
, DF y
)
609 sim_fpu_status status
;
611 sim_fpu_64to (&op1
, x
);
612 sim_fpu_64to (&op2
, y
);
613 status
= sim_fpu_max (&ans
, &op1
, &op2
);
615 (*fpu
->ops
->error
) (fpu
, status
);
616 sim_fpu_to64 (&res
, &ans
);
622 cmpdf (CGEN_FPU
* fpu
, DF x
, DF y
)
627 sim_fpu_64to (&op1
, x
);
628 sim_fpu_64to (&op2
, y
);
630 if (sim_fpu_is_nan (&op1
)
631 || sim_fpu_is_nan (&op2
))
642 eqdf (CGEN_FPU
* fpu
, DF x
, DF y
)
647 sim_fpu_64to (&op1
, x
);
648 sim_fpu_64to (&op2
, y
);
649 return sim_fpu_is_eq (&op1
, &op2
);
653 nedf (CGEN_FPU
* fpu
, DF x
, DF y
)
658 sim_fpu_64to (&op1
, x
);
659 sim_fpu_64to (&op2
, y
);
660 return sim_fpu_is_ne (&op1
, &op2
);
664 ltdf (CGEN_FPU
* fpu
, DF x
, DF y
)
669 sim_fpu_64to (&op1
, x
);
670 sim_fpu_64to (&op2
, y
);
671 return sim_fpu_is_lt (&op1
, &op2
);
675 ledf (CGEN_FPU
* fpu
, DF x
, DF y
)
680 sim_fpu_64to (&op1
, x
);
681 sim_fpu_64to (&op2
, y
);
682 return sim_fpu_is_le (&op1
, &op2
);
686 gtdf (CGEN_FPU
* fpu
, DF x
, DF y
)
691 sim_fpu_64to (&op1
, x
);
692 sim_fpu_64to (&op2
, y
);
693 return sim_fpu_is_gt (&op1
, &op2
);
697 gedf (CGEN_FPU
* fpu
, DF x
, DF y
)
702 sim_fpu_64to (&op1
, x
);
703 sim_fpu_64to (&op2
, y
);
704 return sim_fpu_is_ge (&op1
, &op2
);
707 /* Initialize FP_OPS to use accurate library. */
710 cgen_init_accurate_fpu (SIM_CPU
* cpu
, CGEN_FPU
* fpu
, CGEN_FPU_ERROR_FN
* error
)
715 /* ??? small memory leak, not freed by sim_close */
716 fpu
->ops
= (CGEN_FP_OPS
*) xmalloc (sizeof (CGEN_FP_OPS
));
719 memset (o
, 0, sizeof (*o
));
760 o
->fextsfdf
= fextsfdf
;
761 o
->ftruncdfsf
= ftruncdfsf
;
762 o
->floatsisf
= floatsisf
;
763 o
->floatsidf
= floatsidf
;
764 o
->floatdidf
= floatdidf
;
765 o
->ufloatsisf
= ufloatsisf
;
766 o
->fixsfsi
= fixsfsi
;
767 o
->fixdfsi
= fixdfsi
;
768 o
->fixdfdi
= fixdfdi
;
769 o
->ufixsfsi
= ufixsfsi
;
This page took 0.04576 seconds and 5 git commands to generate.