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 ufloatsisf (CGEN_FPU* fpu, int how UNUSED, USI x)
358 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
359 sim_fpu_to32 (&res, &ans);
364 fixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
369 sim_fpu_32to (&op1, x);
370 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
375 fixdfsi (CGEN_FPU* fpu, int how UNUSED, DF x)
380 sim_fpu_64to (&op1, x);
381 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
386 ufixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
391 sim_fpu_32to (&op1, x);
392 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
396 /* DF mode support */
399 adddf (CGEN_FPU* fpu, DF x, DF y)
405 sim_fpu_status status;
407 sim_fpu_64to (&op1, x);
408 sim_fpu_64to (&op2, y);
409 status = sim_fpu_add (&ans, &op1, &op2);
411 (*fpu->ops->error) (fpu, status);
412 sim_fpu_to64 (&res, &ans);
418 subdf (CGEN_FPU* fpu, DF x, DF y)
424 sim_fpu_status status;
426 sim_fpu_64to (&op1, x);
427 sim_fpu_64to (&op2, y);
428 status = sim_fpu_sub (&ans, &op1, &op2);
430 (*fpu->ops->error) (fpu, status);
431 sim_fpu_to64 (&res, &ans);
437 muldf (CGEN_FPU* fpu, DF x, DF y)
443 sim_fpu_status status;
445 sim_fpu_64to (&op1, x);
446 sim_fpu_64to (&op2, y);
447 status = sim_fpu_mul (&ans, &op1, &op2);
449 (*fpu->ops->error) (fpu, status);
450 sim_fpu_to64 (&res, &ans);
456 divdf (CGEN_FPU* fpu, DF x, DF y)
462 sim_fpu_status status;
464 sim_fpu_64to (&op1, x);
465 sim_fpu_64to (&op2, y);
466 status = sim_fpu_div (&ans, &op1, &op2);
468 (*fpu->ops->error) (fpu, status);
469 sim_fpu_to64 (&res, &ans);
475 remdf (CGEN_FPU* fpu, DF x, DF y)
481 sim_fpu_status status;
483 sim_fpu_64to (&op1, x);
484 sim_fpu_64to (&op2, y);
485 status = sim_fpu_rem (&ans, &op1, &op2);
487 (*fpu->ops->error) (fpu, status);
488 sim_fpu_to64(&res, &ans);
494 negdf (CGEN_FPU* fpu, DF x)
499 sim_fpu_status status;
501 sim_fpu_64to (&op1, x);
502 status = sim_fpu_neg (&ans, &op1);
504 (*fpu->ops->error) (fpu, status);
505 sim_fpu_to64 (&res, &ans);
511 absdf (CGEN_FPU* fpu, DF x)
516 sim_fpu_status status;
518 sim_fpu_64to (&op1, x);
519 status = sim_fpu_abs (&ans, &op1);
521 (*fpu->ops->error) (fpu, status);
522 sim_fpu_to64 (&res, &ans);
528 sqrtdf (CGEN_FPU* fpu, DF x)
533 sim_fpu_status status;
535 sim_fpu_64to (&op1, x);
536 status = sim_fpu_sqrt (&ans, &op1);
538 (*fpu->ops->error) (fpu, status);
539 sim_fpu_to64 (&res, &ans);
545 invdf (CGEN_FPU* fpu, DF x)
550 sim_fpu_status status;
552 sim_fpu_64to (&op1, x);
553 status = sim_fpu_inv (&ans, &op1);
555 (*fpu->ops->error) (fpu, status);
556 sim_fpu_to64 (&res, &ans);
562 mindf (CGEN_FPU* fpu, DF x, DF y)
568 sim_fpu_status status;
570 sim_fpu_64to (&op1, x);
571 sim_fpu_64to (&op2, y);
572 status = sim_fpu_min (&ans, &op1, &op2);
574 (*fpu->ops->error) (fpu, status);
575 sim_fpu_to64 (&res, &ans);
581 maxdf (CGEN_FPU* fpu, DF x, DF y)
587 sim_fpu_status status;
589 sim_fpu_64to (&op1, x);
590 sim_fpu_64to (&op2, y);
591 status = sim_fpu_max (&ans, &op1, &op2);
593 (*fpu->ops->error) (fpu, status);
594 sim_fpu_to64 (&res, &ans);
600 cmpdf (CGEN_FPU* fpu, DF x, DF y)
605 sim_fpu_64to (&op1, x);
606 sim_fpu_64to (&op2, y);
608 if (sim_fpu_is_nan (&op1)
609 || sim_fpu_is_nan (&op2))
620 eqdf (CGEN_FPU* fpu, DF x, DF y)
625 sim_fpu_64to (&op1, x);
626 sim_fpu_64to (&op2, y);
627 return sim_fpu_is_eq (&op1, &op2);
631 nedf (CGEN_FPU* fpu, DF x, DF y)
636 sim_fpu_64to (&op1, x);
637 sim_fpu_64to (&op2, y);
638 return sim_fpu_is_ne (&op1, &op2);
642 ltdf (CGEN_FPU* fpu, DF x, DF y)
647 sim_fpu_64to (&op1, x);
648 sim_fpu_64to (&op2, y);
649 return sim_fpu_is_lt (&op1, &op2);
653 ledf (CGEN_FPU* fpu, DF x, DF y)
658 sim_fpu_64to (&op1, x);
659 sim_fpu_64to (&op2, y);
660 return sim_fpu_is_le (&op1, &op2);
664 gtdf (CGEN_FPU* fpu, DF x, DF y)
669 sim_fpu_64to (&op1, x);
670 sim_fpu_64to (&op2, y);
671 return sim_fpu_is_gt (&op1, &op2);
675 gedf (CGEN_FPU* fpu, DF x, DF y)
680 sim_fpu_64to (&op1, x);
681 sim_fpu_64to (&op2, y);
682 return sim_fpu_is_ge (&op1, &op2);
685 /* Initialize FP_OPS to use accurate library. */
688 cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
693 /* ??? small memory leak, not freed by sim_close */
694 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
697 memset (o, 0, sizeof (*o));
738 o->fextsfdf = fextsfdf;
739 o->ftruncdfsf = ftruncdfsf;
740 o->floatsisf = floatsisf;
741 o->floatsidf = floatsidf;
742 o->ufloatsisf = ufloatsisf;
743 o->fixsfsi = fixsfsi;
744 o->fixdfsi = fixdfsi;
745 o->ufixsfsi = ufixsfsi;