]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/cgen-accfp.c
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
;