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 floatsisf (CGEN_FPU* fpu, SI x)
293 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
294 sim_fpu_to32 (&res, &ans);
299 floatsidf (CGEN_FPU* fpu, SI x)
304 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
305 sim_fpu_to64 (&res, &ans);
310 ufloatsisf (CGEN_FPU* fpu, USI x)
315 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
316 sim_fpu_to32 (&res, &ans);
321 fixsfsi (CGEN_FPU* fpu, SF x)
326 sim_fpu_32to (&op1, x);
327 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
332 fixdfsi (CGEN_FPU* fpu, DF x)
337 sim_fpu_64to (&op1, x);
338 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
343 ufixsfsi (CGEN_FPU* fpu, SF x)
348 sim_fpu_32to (&op1, x);
349 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
353 /* DF mode support */
356 adddf (CGEN_FPU* fpu, DF x, DF y)
362 sim_fpu_status status;
364 sim_fpu_64to (&op1, x);
365 sim_fpu_64to (&op2, y);
366 status = sim_fpu_add (&ans, &op1, &op2);
368 (*fpu->ops->error) (fpu, status);
369 sim_fpu_to64 (&res, &ans);
375 subdf (CGEN_FPU* fpu, DF x, DF y)
381 sim_fpu_status status;
383 sim_fpu_64to (&op1, x);
384 sim_fpu_64to (&op2, y);
385 status = sim_fpu_sub (&ans, &op1, &op2);
387 (*fpu->ops->error) (fpu, status);
388 sim_fpu_to64 (&res, &ans);
394 muldf (CGEN_FPU* fpu, DF x, DF y)
400 sim_fpu_status status;
402 sim_fpu_64to (&op1, x);
403 sim_fpu_64to (&op2, y);
404 status = sim_fpu_mul (&ans, &op1, &op2);
406 (*fpu->ops->error) (fpu, status);
407 sim_fpu_to64 (&res, &ans);
413 divdf (CGEN_FPU* fpu, DF x, DF y)
419 sim_fpu_status status;
421 sim_fpu_64to (&op1, x);
422 sim_fpu_64to (&op2, y);
423 status = sim_fpu_div (&ans, &op1, &op2);
425 (*fpu->ops->error) (fpu, status);
426 sim_fpu_to64 (&res, &ans);
432 negdf (CGEN_FPU* fpu, DF x)
437 sim_fpu_status status;
439 sim_fpu_64to (&op1, x);
440 status = sim_fpu_neg (&ans, &op1);
442 (*fpu->ops->error) (fpu, status);
443 sim_fpu_to64 (&res, &ans);
449 absdf (CGEN_FPU* fpu, DF x)
454 sim_fpu_status status;
456 sim_fpu_64to (&op1, x);
457 status = sim_fpu_abs (&ans, &op1);
459 (*fpu->ops->error) (fpu, status);
460 sim_fpu_to64 (&res, &ans);
466 sqrtdf (CGEN_FPU* fpu, DF x)
471 sim_fpu_status status;
473 sim_fpu_64to (&op1, x);
474 status = sim_fpu_sqrt (&ans, &op1);
476 (*fpu->ops->error) (fpu, status);
477 sim_fpu_to64 (&res, &ans);
483 invdf (CGEN_FPU* fpu, DF x)
488 sim_fpu_status status;
490 sim_fpu_64to (&op1, x);
491 status = sim_fpu_inv (&ans, &op1);
493 (*fpu->ops->error) (fpu, status);
494 sim_fpu_to64 (&res, &ans);
500 mindf (CGEN_FPU* fpu, DF x, DF y)
506 sim_fpu_status status;
508 sim_fpu_64to (&op1, x);
509 sim_fpu_64to (&op2, y);
510 status = sim_fpu_min (&ans, &op1, &op2);
512 (*fpu->ops->error) (fpu, status);
513 sim_fpu_to64 (&res, &ans);
519 maxdf (CGEN_FPU* fpu, DF x, DF y)
525 sim_fpu_status status;
527 sim_fpu_64to (&op1, x);
528 sim_fpu_64to (&op2, y);
529 status = sim_fpu_max (&ans, &op1, &op2);
531 (*fpu->ops->error) (fpu, status);
532 sim_fpu_to64 (&res, &ans);
538 cmpdf (CGEN_FPU* fpu, DF x, DF y)
543 sim_fpu_64to (&op1, x);
544 sim_fpu_64to (&op2, y);
546 if (sim_fpu_is_nan (&op1)
547 || sim_fpu_is_nan (&op2))
558 eqdf (CGEN_FPU* fpu, DF x, DF y)
563 sim_fpu_64to (&op1, x);
564 sim_fpu_64to (&op2, y);
565 return sim_fpu_is_eq (&op1, &op2);
569 nedf (CGEN_FPU* fpu, DF x, DF y)
574 sim_fpu_64to (&op1, x);
575 sim_fpu_64to (&op2, y);
576 return sim_fpu_is_ne (&op1, &op2);
580 ltdf (CGEN_FPU* fpu, DF x, DF y)
585 sim_fpu_64to (&op1, x);
586 sim_fpu_64to (&op2, y);
587 return sim_fpu_is_lt (&op1, &op2);
591 ledf (CGEN_FPU* fpu, DF x, DF y)
596 sim_fpu_64to (&op1, x);
597 sim_fpu_64to (&op2, y);
598 return sim_fpu_is_le (&op1, &op2);
602 gtdf (CGEN_FPU* fpu, DF x, DF y)
607 sim_fpu_64to (&op1, x);
608 sim_fpu_64to (&op2, y);
609 return sim_fpu_is_gt (&op1, &op2);
613 gedf (CGEN_FPU* fpu, DF x, DF y)
618 sim_fpu_64to (&op1, x);
619 sim_fpu_64to (&op2, y);
620 return sim_fpu_is_ge (&op1, &op2);
623 /* Initialize FP_OPS to use accurate library. */
626 cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
631 /* ??? small memory leak, not freed by sim_close */
632 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
635 memset (o, 0, sizeof (*o));
674 o->floatsisf = floatsisf;
675 o->floatsidf = floatsidf;
676 o->ufloatsisf = ufloatsisf;
677 o->fixsfsi = fixsfsi;
678 o->fixdfsi = fixdfsi;
679 o->ufixsfsi = ufixsfsi;