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 negsf (CGEN_FPU* fpu, SF x)
101 sim_fpu_status status;
103 sim_fpu_32to (&op1, x);
104 status = sim_fpu_neg (&ans, &op1);
106 (*fpu->ops->error) (fpu, status);
107 sim_fpu_to32 (&res, &ans);
113 abssf (CGEN_FPU* fpu, SF x)
118 sim_fpu_status status;
120 sim_fpu_32to (&op1, x);
121 status = sim_fpu_abs (&ans, &op1);
123 (*fpu->ops->error) (fpu, status);
124 sim_fpu_to32 (&res, &ans);
130 sqrtsf (CGEN_FPU* fpu, SF x)
135 sim_fpu_status status;
137 sim_fpu_32to (&op1, x);
138 status = sim_fpu_sqrt (&ans, &op1);
140 (*fpu->ops->error) (fpu, status);
141 sim_fpu_to32 (&res, &ans);
147 invsf (CGEN_FPU* fpu, SF x)
152 sim_fpu_status status;
154 sim_fpu_32to (&op1, x);
155 status = sim_fpu_inv (&ans, &op1);
157 (*fpu->ops->error) (fpu, status);
158 sim_fpu_to32 (&res, &ans);
164 minsf (CGEN_FPU* fpu, SF x, SF y)
170 sim_fpu_status status;
172 sim_fpu_32to (&op1, x);
173 sim_fpu_32to (&op2, y);
174 status = sim_fpu_min (&ans, &op1, &op2);
176 (*fpu->ops->error) (fpu, status);
177 sim_fpu_to32 (&res, &ans);
183 maxsf (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_max (&ans, &op1, &op2);
195 (*fpu->ops->error) (fpu, status);
196 sim_fpu_to32 (&res, &ans);
202 cmpsf (CGEN_FPU* fpu, SF x, SF y)
207 sim_fpu_32to (&op1, x);
208 sim_fpu_32to (&op2, y);
210 if (sim_fpu_is_nan (&op1)
211 || sim_fpu_is_nan (&op2))
222 eqsf (CGEN_FPU* fpu, SF x, SF y)
227 sim_fpu_32to (&op1, x);
228 sim_fpu_32to (&op2, y);
229 return sim_fpu_is_eq (&op1, &op2);
233 nesf (CGEN_FPU* fpu, SF x, SF y)
238 sim_fpu_32to (&op1, x);
239 sim_fpu_32to (&op2, y);
240 return sim_fpu_is_ne (&op1, &op2);
244 ltsf (CGEN_FPU* fpu, SF x, SF y)
249 sim_fpu_32to (&op1, x);
250 sim_fpu_32to (&op2, y);
251 return sim_fpu_is_lt (&op1, &op2);
255 lesf (CGEN_FPU* fpu, SF x, SF y)
260 sim_fpu_32to (&op1, x);
261 sim_fpu_32to (&op2, y);
262 return sim_fpu_is_le (&op1, &op2);
266 gtsf (CGEN_FPU* fpu, SF x, SF y)
271 sim_fpu_32to (&op1, x);
272 sim_fpu_32to (&op2, y);
273 return sim_fpu_is_gt (&op1, &op2);
277 gesf (CGEN_FPU* fpu, SF x, SF y)
282 sim_fpu_32to (&op1, x);
283 sim_fpu_32to (&op2, y);
284 return sim_fpu_is_ge (&op1, &op2);
288 fextsfdf (CGEN_FPU* fpu, int how UNUSED, SF x)
293 sim_fpu_32to (&op1, x);
294 sim_fpu_to64 (&res, &op1);
300 ftruncdfsf (CGEN_FPU* fpu, int how UNUSED, DF x)
305 sim_fpu_64to (&op1, x);
306 sim_fpu_to32 (&res, &op1);
312 floatsisf (CGEN_FPU* fpu, int how UNUSED, SI x)
317 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
318 sim_fpu_to32 (&res, &ans);
323 floatsidf (CGEN_FPU* fpu, int how UNUSED, SI x)
328 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
329 sim_fpu_to64 (&res, &ans);
334 ufloatsisf (CGEN_FPU* fpu, int how UNUSED, USI x)
339 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
340 sim_fpu_to32 (&res, &ans);
345 fixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
350 sim_fpu_32to (&op1, x);
351 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
356 fixdfsi (CGEN_FPU* fpu, int how UNUSED, DF x)
361 sim_fpu_64to (&op1, x);
362 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
367 ufixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
372 sim_fpu_32to (&op1, x);
373 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
377 /* DF mode support */
380 adddf (CGEN_FPU* fpu, DF x, DF y)
386 sim_fpu_status status;
388 sim_fpu_64to (&op1, x);
389 sim_fpu_64to (&op2, y);
390 status = sim_fpu_add (&ans, &op1, &op2);
392 (*fpu->ops->error) (fpu, status);
393 sim_fpu_to64 (&res, &ans);
399 subdf (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_sub (&ans, &op1, &op2);
411 (*fpu->ops->error) (fpu, status);
412 sim_fpu_to64 (&res, &ans);
418 muldf (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_mul (&ans, &op1, &op2);
430 (*fpu->ops->error) (fpu, status);
431 sim_fpu_to64 (&res, &ans);
437 divdf (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_div (&ans, &op1, &op2);
449 (*fpu->ops->error) (fpu, status);
450 sim_fpu_to64 (&res, &ans);
456 negdf (CGEN_FPU* fpu, DF x)
461 sim_fpu_status status;
463 sim_fpu_64to (&op1, x);
464 status = sim_fpu_neg (&ans, &op1);
466 (*fpu->ops->error) (fpu, status);
467 sim_fpu_to64 (&res, &ans);
473 absdf (CGEN_FPU* fpu, DF x)
478 sim_fpu_status status;
480 sim_fpu_64to (&op1, x);
481 status = sim_fpu_abs (&ans, &op1);
483 (*fpu->ops->error) (fpu, status);
484 sim_fpu_to64 (&res, &ans);
490 sqrtdf (CGEN_FPU* fpu, DF x)
495 sim_fpu_status status;
497 sim_fpu_64to (&op1, x);
498 status = sim_fpu_sqrt (&ans, &op1);
500 (*fpu->ops->error) (fpu, status);
501 sim_fpu_to64 (&res, &ans);
507 invdf (CGEN_FPU* fpu, DF x)
512 sim_fpu_status status;
514 sim_fpu_64to (&op1, x);
515 status = sim_fpu_inv (&ans, &op1);
517 (*fpu->ops->error) (fpu, status);
518 sim_fpu_to64 (&res, &ans);
524 mindf (CGEN_FPU* fpu, DF x, DF y)
530 sim_fpu_status status;
532 sim_fpu_64to (&op1, x);
533 sim_fpu_64to (&op2, y);
534 status = sim_fpu_min (&ans, &op1, &op2);
536 (*fpu->ops->error) (fpu, status);
537 sim_fpu_to64 (&res, &ans);
543 maxdf (CGEN_FPU* fpu, DF x, DF y)
549 sim_fpu_status status;
551 sim_fpu_64to (&op1, x);
552 sim_fpu_64to (&op2, y);
553 status = sim_fpu_max (&ans, &op1, &op2);
555 (*fpu->ops->error) (fpu, status);
556 sim_fpu_to64 (&res, &ans);
562 cmpdf (CGEN_FPU* fpu, DF x, DF y)
567 sim_fpu_64to (&op1, x);
568 sim_fpu_64to (&op2, y);
570 if (sim_fpu_is_nan (&op1)
571 || sim_fpu_is_nan (&op2))
582 eqdf (CGEN_FPU* fpu, DF x, DF y)
587 sim_fpu_64to (&op1, x);
588 sim_fpu_64to (&op2, y);
589 return sim_fpu_is_eq (&op1, &op2);
593 nedf (CGEN_FPU* fpu, DF x, DF y)
598 sim_fpu_64to (&op1, x);
599 sim_fpu_64to (&op2, y);
600 return sim_fpu_is_ne (&op1, &op2);
604 ltdf (CGEN_FPU* fpu, DF x, DF y)
609 sim_fpu_64to (&op1, x);
610 sim_fpu_64to (&op2, y);
611 return sim_fpu_is_lt (&op1, &op2);
615 ledf (CGEN_FPU* fpu, DF x, DF y)
620 sim_fpu_64to (&op1, x);
621 sim_fpu_64to (&op2, y);
622 return sim_fpu_is_le (&op1, &op2);
626 gtdf (CGEN_FPU* fpu, DF x, DF y)
631 sim_fpu_64to (&op1, x);
632 sim_fpu_64to (&op2, y);
633 return sim_fpu_is_gt (&op1, &op2);
637 gedf (CGEN_FPU* fpu, DF x, DF y)
642 sim_fpu_64to (&op1, x);
643 sim_fpu_64to (&op2, y);
644 return sim_fpu_is_ge (&op1, &op2);
647 /* Initialize FP_OPS to use accurate library. */
650 cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
655 /* ??? small memory leak, not freed by sim_close */
656 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
659 memset (o, 0, sizeof (*o));
698 o->fextsfdf = fextsfdf;
699 o->ftruncdfsf = ftruncdfsf;
700 o->floatsisf = floatsisf;
701 o->floatsidf = floatsidf;
702 o->ufloatsisf = ufloatsisf;
703 o->fixsfsi = fixsfsi;
704 o->fixdfsi = fixdfsi;
705 o->ufixsfsi = ufixsfsi;