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)
77 sim_fpu_status status;
79 sim_fpu_32to (&op1, x);
80 sim_fpu_32to (&op2, y);
81 status = sim_fpu_div (&ans, &op1, &op2);
83 (*fpu->ops->error) (fpu, status);
84 sim_fpu_to32 (&res, &ans);
90 negsf (CGEN_FPU* fpu, SF x)
96 sim_fpu_32to (&op1, x);
97 sim_fpu_neg (&ans, &op1);
98 sim_fpu_to32 (&res, &ans);
104 abssf (CGEN_FPU* fpu, SF x)
110 sim_fpu_32to (&op1, x);
111 sim_fpu_abs (&ans, &op1);
112 sim_fpu_to32 (&res, &ans);
118 sqrtsf (CGEN_FPU* fpu, SF x)
124 sim_fpu_32to (&op1, x);
125 sim_fpu_sqrt (&ans, &op1);
126 sim_fpu_to32 (&res, &ans);
132 invsf (CGEN_FPU* fpu, SF x)
138 sim_fpu_32to (&op1, x);
139 sim_fpu_inv (&ans, &op1);
140 sim_fpu_to32 (&res, &ans);
146 minsf (CGEN_FPU* fpu, SF x, SF y)
153 sim_fpu_32to (&op1, x);
154 sim_fpu_32to (&op2, y);
155 sim_fpu_min (&ans, &op1, &op2);
156 sim_fpu_to32 (&res, &ans);
162 maxsf (CGEN_FPU* fpu, SF x, SF y)
169 sim_fpu_32to (&op1, x);
170 sim_fpu_32to (&op2, y);
171 sim_fpu_max (&ans, &op1, &op2);
172 sim_fpu_to32 (&res, &ans);
178 cmpsf (CGEN_FPU* fpu, SF x, SF y)
183 sim_fpu_32to (&op1, x);
184 sim_fpu_32to (&op2, y);
186 if (sim_fpu_is_nan (&op1)
187 || sim_fpu_is_nan (&op2))
198 eqsf (CGEN_FPU* fpu, SF x, SF y)
203 sim_fpu_32to (&op1, x);
204 sim_fpu_32to (&op2, y);
205 return sim_fpu_is_eq (&op1, &op2);
209 nesf (CGEN_FPU* fpu, SF x, SF y)
214 sim_fpu_32to (&op1, x);
215 sim_fpu_32to (&op2, y);
216 return sim_fpu_is_ne (&op1, &op2);
220 ltsf (CGEN_FPU* fpu, SF x, SF y)
225 sim_fpu_32to (&op1, x);
226 sim_fpu_32to (&op2, y);
227 return sim_fpu_is_lt (&op1, &op2);
231 lesf (CGEN_FPU* fpu, SF x, SF y)
236 sim_fpu_32to (&op1, x);
237 sim_fpu_32to (&op2, y);
238 return sim_fpu_is_le (&op1, &op2);
242 gtsf (CGEN_FPU* fpu, SF x, SF y)
247 sim_fpu_32to (&op1, x);
248 sim_fpu_32to (&op2, y);
249 return sim_fpu_is_gt (&op1, &op2);
253 gesf (CGEN_FPU* fpu, SF x, SF y)
258 sim_fpu_32to (&op1, x);
259 sim_fpu_32to (&op2, y);
260 return sim_fpu_is_ge (&op1, &op2);
264 floatsisf (CGEN_FPU* fpu, SI x)
269 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
270 sim_fpu_to32 (&res, &ans);
275 floatsidf (CGEN_FPU* fpu, SI x)
280 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
281 sim_fpu_to64 (&res, &ans);
286 ufloatsisf (CGEN_FPU* fpu, USI x)
291 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
292 sim_fpu_to32 (&res, &ans);
297 fixsfsi (CGEN_FPU* fpu, SF x)
302 sim_fpu_32to (&op1, x);
303 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
308 fixdfsi (CGEN_FPU* fpu, DF x)
313 sim_fpu_64to (&op1, x);
314 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
319 ufixsfsi (CGEN_FPU* fpu, SF x)
324 sim_fpu_32to (&op1, x);
325 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
329 /* DF mode support */
332 adddf (CGEN_FPU* fpu, DF x, DF y)
338 sim_fpu_status status;
340 sim_fpu_64to (&op1, x);
341 sim_fpu_64to (&op2, y);
342 status = sim_fpu_add (&ans, &op1, &op2);
344 (*fpu->ops->error) (fpu, status);
345 sim_fpu_to64 (&res, &ans);
351 subdf (CGEN_FPU* fpu, DF x, DF y)
358 sim_fpu_64to (&op1, x);
359 sim_fpu_64to (&op2, y);
360 sim_fpu_sub (&ans, &op1, &op2);
361 sim_fpu_to64 (&res, &ans);
367 muldf (CGEN_FPU* fpu, DF x, DF y)
374 sim_fpu_64to (&op1, x);
375 sim_fpu_64to (&op2, y);
376 sim_fpu_mul (&ans, &op1, &op2);
377 sim_fpu_to64 (&res, &ans);
383 divdf (CGEN_FPU* fpu, DF x, DF y)
390 sim_fpu_64to (&op1, x);
391 sim_fpu_64to (&op2, y);
392 sim_fpu_div (&ans, &op1, &op2);
393 sim_fpu_to64 (&res, &ans);
399 negdf (CGEN_FPU* fpu, DF x)
405 sim_fpu_64to (&op1, x);
406 sim_fpu_neg (&ans, &op1);
407 sim_fpu_to64 (&res, &ans);
413 absdf (CGEN_FPU* fpu, DF x)
419 sim_fpu_64to (&op1, x);
420 sim_fpu_abs (&ans, &op1);
421 sim_fpu_to64 (&res, &ans);
427 sqrtdf (CGEN_FPU* fpu, DF x)
433 sim_fpu_64to (&op1, x);
434 sim_fpu_sqrt (&ans, &op1);
435 sim_fpu_to64 (&res, &ans);
441 invdf (CGEN_FPU* fpu, DF x)
447 sim_fpu_64to (&op1, x);
448 sim_fpu_inv (&ans, &op1);
449 sim_fpu_to64 (&res, &ans);
455 mindf (CGEN_FPU* fpu, DF x, DF y)
462 sim_fpu_64to (&op1, x);
463 sim_fpu_64to (&op2, y);
464 sim_fpu_min (&ans, &op1, &op2);
465 sim_fpu_to64 (&res, &ans);
471 maxdf (CGEN_FPU* fpu, DF x, DF y)
478 sim_fpu_64to (&op1, x);
479 sim_fpu_64to (&op2, y);
480 sim_fpu_max (&ans, &op1, &op2);
481 sim_fpu_to64 (&res, &ans);
487 cmpdf (CGEN_FPU* fpu, DF x, DF y)
492 sim_fpu_64to (&op1, x);
493 sim_fpu_64to (&op2, y);
495 if (sim_fpu_is_nan (&op1)
496 || sim_fpu_is_nan (&op2))
507 eqdf (CGEN_FPU* fpu, DF x, DF y)
512 sim_fpu_64to (&op1, x);
513 sim_fpu_64to (&op2, y);
514 return sim_fpu_is_eq (&op1, &op2);
518 nedf (CGEN_FPU* fpu, DF x, DF y)
523 sim_fpu_64to (&op1, x);
524 sim_fpu_64to (&op2, y);
525 return sim_fpu_is_ne (&op1, &op2);
529 ltdf (CGEN_FPU* fpu, DF x, DF y)
534 sim_fpu_64to (&op1, x);
535 sim_fpu_64to (&op2, y);
536 return sim_fpu_is_lt (&op1, &op2);
540 ledf (CGEN_FPU* fpu, DF x, DF y)
545 sim_fpu_64to (&op1, x);
546 sim_fpu_64to (&op2, y);
547 return sim_fpu_is_le (&op1, &op2);
551 gtdf (CGEN_FPU* fpu, DF x, DF y)
556 sim_fpu_64to (&op1, x);
557 sim_fpu_64to (&op2, y);
558 return sim_fpu_is_gt (&op1, &op2);
562 gedf (CGEN_FPU* fpu, DF x, DF y)
567 sim_fpu_64to (&op1, x);
568 sim_fpu_64to (&op2, y);
569 return sim_fpu_is_ge (&op1, &op2);
572 /* Initialize FP_OPS to use accurate library. */
575 cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
580 /* ??? small memory leak, not freed by sim_close */
581 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
584 memset (o, 0, sizeof (*o));
623 o->floatsisf = floatsisf;
624 o->floatsidf = floatsidf;
625 o->ufloatsisf = ufloatsisf;
626 o->fixsfsi = fixsfsi;
627 o->fixdfsi = fixdfsi;
628 o->ufixsfsi = ufixsfsi;