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)
46 sim_fpu_32to (&op1, x);
47 sim_fpu_32to (&op2, y);
48 sim_fpu_sub (&ans, &op1, &op2);
49 sim_fpu_to32 (&res, &ans);
55 mulsf (CGEN_FPU* fpu, SF x, SF y)
62 sim_fpu_32to (&op1, x);
63 sim_fpu_32to (&op2, y);
64 sim_fpu_mul (&ans, &op1, &op2);
65 sim_fpu_to32 (&res, &ans);
71 divsf (CGEN_FPU* fpu, SF x, SF y)
78 sim_fpu_32to (&op1, x);
79 sim_fpu_32to (&op2, y);
80 sim_fpu_div (&ans, &op1, &op2);
81 sim_fpu_to32 (&res, &ans);
87 negsf (CGEN_FPU* fpu, SF x)
93 sim_fpu_32to (&op1, x);
94 sim_fpu_neg (&ans, &op1);
95 sim_fpu_to32 (&res, &ans);
101 abssf (CGEN_FPU* fpu, SF x)
107 sim_fpu_32to (&op1, x);
108 sim_fpu_abs (&ans, &op1);
109 sim_fpu_to32 (&res, &ans);
115 sqrtsf (CGEN_FPU* fpu, SF x)
121 sim_fpu_32to (&op1, x);
122 sim_fpu_sqrt (&ans, &op1);
123 sim_fpu_to32 (&res, &ans);
129 invsf (CGEN_FPU* fpu, SF x)
135 sim_fpu_32to (&op1, x);
136 sim_fpu_inv (&ans, &op1);
137 sim_fpu_to32 (&res, &ans);
143 minsf (CGEN_FPU* fpu, SF x, SF y)
150 sim_fpu_32to (&op1, x);
151 sim_fpu_32to (&op2, y);
152 sim_fpu_min (&ans, &op1, &op2);
153 sim_fpu_to32 (&res, &ans);
159 maxsf (CGEN_FPU* fpu, SF x, SF y)
166 sim_fpu_32to (&op1, x);
167 sim_fpu_32to (&op2, y);
168 sim_fpu_max (&ans, &op1, &op2);
169 sim_fpu_to32 (&res, &ans);
175 cmpsf (CGEN_FPU* fpu, SF x, SF y)
180 sim_fpu_32to (&op1, x);
181 sim_fpu_32to (&op2, y);
183 if (sim_fpu_is_nan (&op1)
184 || sim_fpu_is_nan (&op2))
195 eqsf (CGEN_FPU* fpu, SF x, SF y)
200 sim_fpu_32to (&op1, x);
201 sim_fpu_32to (&op2, y);
202 return sim_fpu_is_eq (&op1, &op2);
206 nesf (CGEN_FPU* fpu, SF x, SF y)
211 sim_fpu_32to (&op1, x);
212 sim_fpu_32to (&op2, y);
213 return sim_fpu_is_ne (&op1, &op2);
217 ltsf (CGEN_FPU* fpu, SF x, SF y)
222 sim_fpu_32to (&op1, x);
223 sim_fpu_32to (&op2, y);
224 return sim_fpu_is_lt (&op1, &op2);
228 lesf (CGEN_FPU* fpu, SF x, SF y)
233 sim_fpu_32to (&op1, x);
234 sim_fpu_32to (&op2, y);
235 return sim_fpu_is_le (&op1, &op2);
239 gtsf (CGEN_FPU* fpu, SF x, SF y)
244 sim_fpu_32to (&op1, x);
245 sim_fpu_32to (&op2, y);
246 return sim_fpu_is_gt (&op1, &op2);
250 gesf (CGEN_FPU* fpu, SF x, SF y)
255 sim_fpu_32to (&op1, x);
256 sim_fpu_32to (&op2, y);
257 return sim_fpu_is_ge (&op1, &op2);
261 floatsisf (CGEN_FPU* fpu, SI x)
266 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
267 sim_fpu_to32 (&res, &ans);
272 floatsidf (CGEN_FPU* fpu, SI x)
277 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
278 sim_fpu_to64 (&res, &ans);
283 ufloatsisf (CGEN_FPU* fpu, USI x)
288 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
289 sim_fpu_to32 (&res, &ans);
294 fixsfsi (CGEN_FPU* fpu, SF x)
299 sim_fpu_32to (&op1, x);
300 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
305 fixdfsi (CGEN_FPU* fpu, DF x)
310 sim_fpu_64to (&op1, x);
311 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
316 ufixsfsi (CGEN_FPU* fpu, SF x)
321 sim_fpu_32to (&op1, x);
322 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
326 /* DF mode support */
329 adddf (CGEN_FPU* fpu, DF x, DF y)
335 sim_fpu_status status;
337 sim_fpu_64to (&op1, x);
338 sim_fpu_64to (&op2, y);
339 status = sim_fpu_add (&ans, &op1, &op2);
341 (*fpu->ops->error) (fpu, status);
342 sim_fpu_to64 (&res, &ans);
348 subdf (CGEN_FPU* fpu, DF x, DF y)
355 sim_fpu_64to (&op1, x);
356 sim_fpu_64to (&op2, y);
357 sim_fpu_sub (&ans, &op1, &op2);
358 sim_fpu_to64 (&res, &ans);
364 muldf (CGEN_FPU* fpu, DF x, DF y)
371 sim_fpu_64to (&op1, x);
372 sim_fpu_64to (&op2, y);
373 sim_fpu_mul (&ans, &op1, &op2);
374 sim_fpu_to64 (&res, &ans);
380 divdf (CGEN_FPU* fpu, DF x, DF y)
387 sim_fpu_64to (&op1, x);
388 sim_fpu_64to (&op2, y);
389 sim_fpu_div (&ans, &op1, &op2);
390 sim_fpu_to64 (&res, &ans);
396 negdf (CGEN_FPU* fpu, DF x)
402 sim_fpu_64to (&op1, x);
403 sim_fpu_neg (&ans, &op1);
404 sim_fpu_to64 (&res, &ans);
410 absdf (CGEN_FPU* fpu, DF x)
416 sim_fpu_64to (&op1, x);
417 sim_fpu_abs (&ans, &op1);
418 sim_fpu_to64 (&res, &ans);
424 sqrtdf (CGEN_FPU* fpu, DF x)
430 sim_fpu_64to (&op1, x);
431 sim_fpu_sqrt (&ans, &op1);
432 sim_fpu_to64 (&res, &ans);
438 invdf (CGEN_FPU* fpu, DF x)
444 sim_fpu_64to (&op1, x);
445 sim_fpu_inv (&ans, &op1);
446 sim_fpu_to64 (&res, &ans);
452 mindf (CGEN_FPU* fpu, DF x, DF y)
459 sim_fpu_64to (&op1, x);
460 sim_fpu_64to (&op2, y);
461 sim_fpu_min (&ans, &op1, &op2);
462 sim_fpu_to64 (&res, &ans);
468 maxdf (CGEN_FPU* fpu, DF x, DF y)
475 sim_fpu_64to (&op1, x);
476 sim_fpu_64to (&op2, y);
477 sim_fpu_max (&ans, &op1, &op2);
478 sim_fpu_to64 (&res, &ans);
484 cmpdf (CGEN_FPU* fpu, DF x, DF y)
489 sim_fpu_64to (&op1, x);
490 sim_fpu_64to (&op2, y);
492 if (sim_fpu_is_nan (&op1)
493 || sim_fpu_is_nan (&op2))
504 eqdf (CGEN_FPU* fpu, DF x, DF y)
509 sim_fpu_64to (&op1, x);
510 sim_fpu_64to (&op2, y);
511 return sim_fpu_is_eq (&op1, &op2);
515 nedf (CGEN_FPU* fpu, DF x, DF y)
520 sim_fpu_64to (&op1, x);
521 sim_fpu_64to (&op2, y);
522 return sim_fpu_is_ne (&op1, &op2);
526 ltdf (CGEN_FPU* fpu, DF x, DF y)
531 sim_fpu_64to (&op1, x);
532 sim_fpu_64to (&op2, y);
533 return sim_fpu_is_lt (&op1, &op2);
537 ledf (CGEN_FPU* fpu, DF x, DF y)
542 sim_fpu_64to (&op1, x);
543 sim_fpu_64to (&op2, y);
544 return sim_fpu_is_le (&op1, &op2);
548 gtdf (CGEN_FPU* fpu, DF x, DF y)
553 sim_fpu_64to (&op1, x);
554 sim_fpu_64to (&op2, y);
555 return sim_fpu_is_gt (&op1, &op2);
559 gedf (CGEN_FPU* fpu, DF x, DF y)
564 sim_fpu_64to (&op1, x);
565 sim_fpu_64to (&op2, y);
566 return sim_fpu_is_ge (&op1, &op2);
569 /* Initialize FP_OPS to use accurate library. */
572 cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
577 /* ??? small memory leak, not freed by sim_close */
578 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
581 memset (o, 0, sizeof (*o));
620 o->floatsisf = floatsisf;
621 o->floatsidf = floatsidf;
622 o->ufloatsisf = ufloatsisf;
623 o->fixsfsi = fixsfsi;
624 o->fixdfsi = fixdfsi;
625 o->ufixsfsi = ufixsfsi;