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)
14 /* This must come before any other includes. */
23 addsf (CGEN_FPU* fpu, SF x, SF y)
29 sim_fpu_status status;
31 sim_fpu_32to (&op1, x);
32 sim_fpu_32to (&op2, y);
33 status = sim_fpu_add (&ans, &op1, &op2);
35 (*fpu->ops->error) (fpu, status);
36 sim_fpu_to32 (&res, &ans);
42 subsf (CGEN_FPU* fpu, SF x, SF y)
48 sim_fpu_status status;
50 sim_fpu_32to (&op1, x);
51 sim_fpu_32to (&op2, y);
52 status = sim_fpu_sub (&ans, &op1, &op2);
54 (*fpu->ops->error) (fpu, status);
55 sim_fpu_to32 (&res, &ans);
61 mulsf (CGEN_FPU* fpu, SF x, SF y)
67 sim_fpu_status status;
69 sim_fpu_32to (&op1, x);
70 sim_fpu_32to (&op2, y);
71 status = sim_fpu_mul (&ans, &op1, &op2);
73 (*fpu->ops->error) (fpu, status);
74 sim_fpu_to32 (&res, &ans);
80 divsf (CGEN_FPU* fpu, SF x, SF y)
86 sim_fpu_status status;
88 sim_fpu_32to (&op1, x);
89 sim_fpu_32to (&op2, y);
90 status = sim_fpu_div (&ans, &op1, &op2);
92 (*fpu->ops->error) (fpu, status);
93 sim_fpu_to32 (&res, &ans);
99 remsf (CGEN_FPU* fpu, SF x, SF y)
105 sim_fpu_status status;
107 sim_fpu_32to (&op1, x);
108 sim_fpu_32to (&op2, y);
109 status = sim_fpu_rem (&ans, &op1, &op2);
111 (*fpu->ops->error) (fpu, status);
112 sim_fpu_to32 (&res, &ans);
118 negsf (CGEN_FPU* fpu, SF x)
123 sim_fpu_status status;
125 sim_fpu_32to (&op1, x);
126 status = sim_fpu_neg (&ans, &op1);
128 (*fpu->ops->error) (fpu, status);
129 sim_fpu_to32 (&res, &ans);
135 abssf (CGEN_FPU* fpu, SF x)
140 sim_fpu_status status;
142 sim_fpu_32to (&op1, x);
143 status = sim_fpu_abs (&ans, &op1);
145 (*fpu->ops->error) (fpu, status);
146 sim_fpu_to32 (&res, &ans);
152 sqrtsf (CGEN_FPU* fpu, SF x)
157 sim_fpu_status status;
159 sim_fpu_32to (&op1, x);
160 status = sim_fpu_sqrt (&ans, &op1);
162 (*fpu->ops->error) (fpu, status);
163 sim_fpu_to32 (&res, &ans);
169 invsf (CGEN_FPU* fpu, SF x)
174 sim_fpu_status status;
176 sim_fpu_32to (&op1, x);
177 status = sim_fpu_inv (&ans, &op1);
179 (*fpu->ops->error) (fpu, status);
180 sim_fpu_to32 (&res, &ans);
186 minsf (CGEN_FPU* fpu, SF x, SF y)
192 sim_fpu_status status;
194 sim_fpu_32to (&op1, x);
195 sim_fpu_32to (&op2, y);
196 status = sim_fpu_min (&ans, &op1, &op2);
198 (*fpu->ops->error) (fpu, status);
199 sim_fpu_to32 (&res, &ans);
205 maxsf (CGEN_FPU* fpu, SF x, SF y)
211 sim_fpu_status status;
213 sim_fpu_32to (&op1, x);
214 sim_fpu_32to (&op2, y);
215 status = sim_fpu_max (&ans, &op1, &op2);
217 (*fpu->ops->error) (fpu, status);
218 sim_fpu_to32 (&res, &ans);
224 cmpsf (CGEN_FPU* fpu, SF x, SF y)
229 sim_fpu_32to (&op1, x);
230 sim_fpu_32to (&op2, y);
232 if (sim_fpu_is_nan (&op1)
233 || sim_fpu_is_nan (&op2))
244 eqsf (CGEN_FPU* fpu, SF x, SF y)
249 sim_fpu_32to (&op1, x);
250 sim_fpu_32to (&op2, y);
251 return sim_fpu_is_eq (&op1, &op2);
255 nesf (CGEN_FPU* fpu, SF x, SF y)
260 sim_fpu_32to (&op1, x);
261 sim_fpu_32to (&op2, y);
262 return sim_fpu_is_ne (&op1, &op2);
266 ltsf (CGEN_FPU* fpu, SF x, SF y)
271 sim_fpu_32to (&op1, x);
272 sim_fpu_32to (&op2, y);
273 return sim_fpu_is_lt (&op1, &op2);
277 lesf (CGEN_FPU* fpu, SF x, SF y)
282 sim_fpu_32to (&op1, x);
283 sim_fpu_32to (&op2, y);
284 return sim_fpu_is_le (&op1, &op2);
288 gtsf (CGEN_FPU* fpu, SF x, SF y)
293 sim_fpu_32to (&op1, x);
294 sim_fpu_32to (&op2, y);
295 return sim_fpu_is_gt (&op1, &op2);
299 gesf (CGEN_FPU* fpu, SF x, SF y)
304 sim_fpu_32to (&op1, x);
305 sim_fpu_32to (&op2, y);
306 return sim_fpu_is_ge (&op1, &op2);
310 unorderedsf (CGEN_FPU* fpu, SF x, SF y)
315 sim_fpu_32to (&op1, x);
316 sim_fpu_32to (&op2, y);
317 return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2);
322 fextsfdf (CGEN_FPU* fpu, int how UNUSED, SF x)
327 sim_fpu_32to (&op1, x);
328 sim_fpu_to64 (&res, &op1);
334 ftruncdfsf (CGEN_FPU* fpu, int how UNUSED, DF x)
339 sim_fpu_64to (&op1, x);
340 sim_fpu_to32 (&res, &op1);
346 floatsisf (CGEN_FPU* fpu, int how UNUSED, SI x)
351 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
352 sim_fpu_to32 (&res, &ans);
357 floatsidf (CGEN_FPU* fpu, int how UNUSED, SI x)
362 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
363 sim_fpu_to64 (&res, &ans);
368 floatdidf (CGEN_FPU* fpu, int how UNUSED, DI x)
373 sim_fpu_i64to (&ans, x, sim_fpu_round_near);
374 sim_fpu_to64 (&res, &ans);
379 ufloatsisf (CGEN_FPU* fpu, int how UNUSED, USI x)
384 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
385 sim_fpu_to32 (&res, &ans);
390 fixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
395 sim_fpu_32to (&op1, x);
396 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
401 fixdfsi (CGEN_FPU* fpu, int how UNUSED, DF x)
406 sim_fpu_64to (&op1, x);
407 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
412 fixdfdi (CGEN_FPU* fpu, int how UNUSED, DF x)
417 sim_fpu_64to (&op1, x);
418 sim_fpu_to64i (&res, &op1, sim_fpu_round_near);
423 ufixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
428 sim_fpu_32to (&op1, x);
429 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
433 /* DF mode support */
436 adddf (CGEN_FPU* fpu, DF x, DF y)
442 sim_fpu_status status;
444 sim_fpu_64to (&op1, x);
445 sim_fpu_64to (&op2, y);
446 status = sim_fpu_add (&ans, &op1, &op2);
448 (*fpu->ops->error) (fpu, status);
449 sim_fpu_to64 (&res, &ans);
455 subdf (CGEN_FPU* fpu, DF x, DF y)
461 sim_fpu_status status;
463 sim_fpu_64to (&op1, x);
464 sim_fpu_64to (&op2, y);
465 status = sim_fpu_sub (&ans, &op1, &op2);
467 (*fpu->ops->error) (fpu, status);
468 sim_fpu_to64 (&res, &ans);
474 muldf (CGEN_FPU* fpu, DF x, DF y)
480 sim_fpu_status status;
482 sim_fpu_64to (&op1, x);
483 sim_fpu_64to (&op2, y);
484 status = sim_fpu_mul (&ans, &op1, &op2);
486 (*fpu->ops->error) (fpu, status);
487 sim_fpu_to64 (&res, &ans);
493 divdf (CGEN_FPU* fpu, DF x, DF y)
499 sim_fpu_status status;
501 sim_fpu_64to (&op1, x);
502 sim_fpu_64to (&op2, y);
503 status = sim_fpu_div (&ans, &op1, &op2);
505 (*fpu->ops->error) (fpu, status);
506 sim_fpu_to64 (&res, &ans);
512 remdf (CGEN_FPU* fpu, DF x, DF y)
518 sim_fpu_status status;
520 sim_fpu_64to (&op1, x);
521 sim_fpu_64to (&op2, y);
522 status = sim_fpu_rem (&ans, &op1, &op2);
524 (*fpu->ops->error) (fpu, status);
525 sim_fpu_to64(&res, &ans);
531 negdf (CGEN_FPU* fpu, DF x)
536 sim_fpu_status status;
538 sim_fpu_64to (&op1, x);
539 status = sim_fpu_neg (&ans, &op1);
541 (*fpu->ops->error) (fpu, status);
542 sim_fpu_to64 (&res, &ans);
548 absdf (CGEN_FPU* fpu, DF x)
553 sim_fpu_status status;
555 sim_fpu_64to (&op1, x);
556 status = sim_fpu_abs (&ans, &op1);
558 (*fpu->ops->error) (fpu, status);
559 sim_fpu_to64 (&res, &ans);
565 sqrtdf (CGEN_FPU* fpu, DF x)
570 sim_fpu_status status;
572 sim_fpu_64to (&op1, x);
573 status = sim_fpu_sqrt (&ans, &op1);
575 (*fpu->ops->error) (fpu, status);
576 sim_fpu_to64 (&res, &ans);
582 invdf (CGEN_FPU* fpu, DF x)
587 sim_fpu_status status;
589 sim_fpu_64to (&op1, x);
590 status = sim_fpu_inv (&ans, &op1);
592 (*fpu->ops->error) (fpu, status);
593 sim_fpu_to64 (&res, &ans);
599 mindf (CGEN_FPU* fpu, DF x, DF y)
605 sim_fpu_status status;
607 sim_fpu_64to (&op1, x);
608 sim_fpu_64to (&op2, y);
609 status = sim_fpu_min (&ans, &op1, &op2);
611 (*fpu->ops->error) (fpu, status);
612 sim_fpu_to64 (&res, &ans);
618 maxdf (CGEN_FPU* fpu, DF x, DF y)
624 sim_fpu_status status;
626 sim_fpu_64to (&op1, x);
627 sim_fpu_64to (&op2, y);
628 status = sim_fpu_max (&ans, &op1, &op2);
630 (*fpu->ops->error) (fpu, status);
631 sim_fpu_to64 (&res, &ans);
637 cmpdf (CGEN_FPU* fpu, DF x, DF y)
642 sim_fpu_64to (&op1, x);
643 sim_fpu_64to (&op2, y);
645 if (sim_fpu_is_nan (&op1)
646 || sim_fpu_is_nan (&op2))
657 eqdf (CGEN_FPU* fpu, DF x, DF y)
662 sim_fpu_64to (&op1, x);
663 sim_fpu_64to (&op2, y);
664 return sim_fpu_is_eq (&op1, &op2);
668 nedf (CGEN_FPU* fpu, DF x, DF y)
673 sim_fpu_64to (&op1, x);
674 sim_fpu_64to (&op2, y);
675 return sim_fpu_is_ne (&op1, &op2);
679 ltdf (CGEN_FPU* fpu, DF x, DF y)
684 sim_fpu_64to (&op1, x);
685 sim_fpu_64to (&op2, y);
686 return sim_fpu_is_lt (&op1, &op2);
690 ledf (CGEN_FPU* fpu, DF x, DF y)
695 sim_fpu_64to (&op1, x);
696 sim_fpu_64to (&op2, y);
697 return sim_fpu_is_le (&op1, &op2);
701 gtdf (CGEN_FPU* fpu, DF x, DF y)
706 sim_fpu_64to (&op1, x);
707 sim_fpu_64to (&op2, y);
708 return sim_fpu_is_gt (&op1, &op2);
712 gedf (CGEN_FPU* fpu, DF x, DF y)
717 sim_fpu_64to (&op1, x);
718 sim_fpu_64to (&op2, y);
719 return sim_fpu_is_ge (&op1, &op2);
723 unordereddf (CGEN_FPU* fpu, DF x, DF y)
728 sim_fpu_64to (&op1, x);
729 sim_fpu_64to (&op2, y);
730 return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2);
733 /* Initialize FP_OPS to use accurate library. */
736 cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
741 /* ??? small memory leak, not freed by sim_close */
742 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
745 memset (o, 0, sizeof (*o));
767 o->unorderedsf = unorderedsf;
787 o->unordereddf = unordereddf;
788 o->fextsfdf = fextsfdf;
789 o->ftruncdfsf = ftruncdfsf;
790 o->floatsisf = floatsisf;
791 o->floatsidf = floatsidf;
792 o->floatdidf = floatdidf;
793 o->ufloatsisf = ufloatsisf;
794 o->fixsfsi = fixsfsi;
795 o->fixdfsi = fixdfsi;
796 o->fixdfdi = fixdfdi;
797 o->ufixsfsi = ufixsfsi;