sim: fully merge sim_state_base into sim_state
[deliverable/binutils-gdb.git] / sim / common / cgen-accfp.c
1 /* Accurate fp support for CGEN-based simulators.
2 Copyright (C) 1999 Cygnus Solutions.
3
4 This implemention assumes:
5 typedef USI SF;
6 typedef UDI DF;
7
8 TODO:
9 - lazy encoding/decoding
10 - checking return code (say by callback)
11 - proper rounding
12 */
13
14 /* This must come before any other includes. */
15 #include "defs.h"
16
17 #include "sim-main.h"
18 #include "sim-fpu.h"
19
20 /* SF mode support */
21
22 static SF
23 addsf (CGEN_FPU* fpu, SF x, SF y)
24 {
25 sim_fpu op1;
26 sim_fpu op2;
27 sim_fpu ans;
28 unsigned32 res;
29 sim_fpu_status status;
30
31 sim_fpu_32to (&op1, x);
32 sim_fpu_32to (&op2, y);
33 status = sim_fpu_add (&ans, &op1, &op2);
34 if (status != 0)
35 (*fpu->ops->error) (fpu, status);
36 sim_fpu_to32 (&res, &ans);
37
38 return res;
39 }
40
41 static SF
42 subsf (CGEN_FPU* fpu, SF x, SF y)
43 {
44 sim_fpu op1;
45 sim_fpu op2;
46 sim_fpu ans;
47 unsigned32 res;
48 sim_fpu_status status;
49
50 sim_fpu_32to (&op1, x);
51 sim_fpu_32to (&op2, y);
52 status = sim_fpu_sub (&ans, &op1, &op2);
53 if (status != 0)
54 (*fpu->ops->error) (fpu, status);
55 sim_fpu_to32 (&res, &ans);
56
57 return res;
58 }
59
60 static SF
61 mulsf (CGEN_FPU* fpu, SF x, SF y)
62 {
63 sim_fpu op1;
64 sim_fpu op2;
65 sim_fpu ans;
66 unsigned32 res;
67 sim_fpu_status status;
68
69 sim_fpu_32to (&op1, x);
70 sim_fpu_32to (&op2, y);
71 status = sim_fpu_mul (&ans, &op1, &op2);
72 if (status != 0)
73 (*fpu->ops->error) (fpu, status);
74 sim_fpu_to32 (&res, &ans);
75
76 return res;
77 }
78
79 static SF
80 divsf (CGEN_FPU* fpu, SF x, SF y)
81 {
82 sim_fpu op1;
83 sim_fpu op2;
84 sim_fpu ans;
85 unsigned32 res;
86 sim_fpu_status status;
87
88 sim_fpu_32to (&op1, x);
89 sim_fpu_32to (&op2, y);
90 status = sim_fpu_div (&ans, &op1, &op2);
91 if (status != 0)
92 (*fpu->ops->error) (fpu, status);
93 sim_fpu_to32 (&res, &ans);
94
95 return res;
96 }
97
98 static SF
99 remsf (CGEN_FPU* fpu, SF x, SF y)
100 {
101 sim_fpu op1;
102 sim_fpu op2;
103 sim_fpu ans;
104 unsigned32 res;
105 sim_fpu_status status;
106
107 sim_fpu_32to (&op1, x);
108 sim_fpu_32to (&op2, y);
109 status = sim_fpu_rem (&ans, &op1, &op2);
110 if (status != 0)
111 (*fpu->ops->error) (fpu, status);
112 sim_fpu_to32 (&res, &ans);
113
114 return res;
115 }
116
117 static SF
118 negsf (CGEN_FPU* fpu, SF x)
119 {
120 sim_fpu op1;
121 sim_fpu ans;
122 unsigned32 res;
123 sim_fpu_status status;
124
125 sim_fpu_32to (&op1, x);
126 status = sim_fpu_neg (&ans, &op1);
127 if (status != 0)
128 (*fpu->ops->error) (fpu, status);
129 sim_fpu_to32 (&res, &ans);
130
131 return res;
132 }
133
134 static SF
135 abssf (CGEN_FPU* fpu, SF x)
136 {
137 sim_fpu op1;
138 sim_fpu ans;
139 unsigned32 res;
140 sim_fpu_status status;
141
142 sim_fpu_32to (&op1, x);
143 status = sim_fpu_abs (&ans, &op1);
144 if (status != 0)
145 (*fpu->ops->error) (fpu, status);
146 sim_fpu_to32 (&res, &ans);
147
148 return res;
149 }
150
151 static SF
152 sqrtsf (CGEN_FPU* fpu, SF x)
153 {
154 sim_fpu op1;
155 sim_fpu ans;
156 unsigned32 res;
157 sim_fpu_status status;
158
159 sim_fpu_32to (&op1, x);
160 status = sim_fpu_sqrt (&ans, &op1);
161 if (status != 0)
162 (*fpu->ops->error) (fpu, status);
163 sim_fpu_to32 (&res, &ans);
164
165 return res;
166 }
167
168 static SF
169 invsf (CGEN_FPU* fpu, SF x)
170 {
171 sim_fpu op1;
172 sim_fpu ans;
173 unsigned32 res;
174 sim_fpu_status status;
175
176 sim_fpu_32to (&op1, x);
177 status = sim_fpu_inv (&ans, &op1);
178 if (status != 0)
179 (*fpu->ops->error) (fpu, status);
180 sim_fpu_to32 (&res, &ans);
181
182 return res;
183 }
184
185 static SF
186 minsf (CGEN_FPU* fpu, SF x, SF y)
187 {
188 sim_fpu op1;
189 sim_fpu op2;
190 sim_fpu ans;
191 unsigned32 res;
192 sim_fpu_status status;
193
194 sim_fpu_32to (&op1, x);
195 sim_fpu_32to (&op2, y);
196 status = sim_fpu_min (&ans, &op1, &op2);
197 if (status != 0)
198 (*fpu->ops->error) (fpu, status);
199 sim_fpu_to32 (&res, &ans);
200
201 return res;
202 }
203
204 static SF
205 maxsf (CGEN_FPU* fpu, SF x, SF y)
206 {
207 sim_fpu op1;
208 sim_fpu op2;
209 sim_fpu ans;
210 unsigned32 res;
211 sim_fpu_status status;
212
213 sim_fpu_32to (&op1, x);
214 sim_fpu_32to (&op2, y);
215 status = sim_fpu_max (&ans, &op1, &op2);
216 if (status != 0)
217 (*fpu->ops->error) (fpu, status);
218 sim_fpu_to32 (&res, &ans);
219
220 return res;
221 }
222
223 static CGEN_FP_CMP
224 cmpsf (CGEN_FPU* fpu, SF x, SF y)
225 {
226 sim_fpu op1;
227 sim_fpu op2;
228
229 sim_fpu_32to (&op1, x);
230 sim_fpu_32to (&op2, y);
231
232 if (sim_fpu_is_nan (&op1)
233 || sim_fpu_is_nan (&op2))
234 return FP_CMP_NAN;
235
236 if (x < y)
237 return FP_CMP_LT;
238 if (x > y)
239 return FP_CMP_GT;
240 return FP_CMP_EQ;
241 }
242
243 static int
244 eqsf (CGEN_FPU* fpu, SF x, SF y)
245 {
246 sim_fpu op1;
247 sim_fpu op2;
248
249 sim_fpu_32to (&op1, x);
250 sim_fpu_32to (&op2, y);
251 return sim_fpu_is_eq (&op1, &op2);
252 }
253
254 static int
255 nesf (CGEN_FPU* fpu, SF x, SF y)
256 {
257 sim_fpu op1;
258 sim_fpu op2;
259
260 sim_fpu_32to (&op1, x);
261 sim_fpu_32to (&op2, y);
262 return sim_fpu_is_ne (&op1, &op2);
263 }
264
265 static int
266 ltsf (CGEN_FPU* fpu, SF x, SF y)
267 {
268 sim_fpu op1;
269 sim_fpu op2;
270
271 sim_fpu_32to (&op1, x);
272 sim_fpu_32to (&op2, y);
273 return sim_fpu_is_lt (&op1, &op2);
274 }
275
276 static int
277 lesf (CGEN_FPU* fpu, SF x, SF y)
278 {
279 sim_fpu op1;
280 sim_fpu op2;
281
282 sim_fpu_32to (&op1, x);
283 sim_fpu_32to (&op2, y);
284 return sim_fpu_is_le (&op1, &op2);
285 }
286
287 static int
288 gtsf (CGEN_FPU* fpu, SF x, SF y)
289 {
290 sim_fpu op1;
291 sim_fpu op2;
292
293 sim_fpu_32to (&op1, x);
294 sim_fpu_32to (&op2, y);
295 return sim_fpu_is_gt (&op1, &op2);
296 }
297
298 static int
299 gesf (CGEN_FPU* fpu, SF x, SF y)
300 {
301 sim_fpu op1;
302 sim_fpu op2;
303
304 sim_fpu_32to (&op1, x);
305 sim_fpu_32to (&op2, y);
306 return sim_fpu_is_ge (&op1, &op2);
307 }
308
309 static int
310 unorderedsf (CGEN_FPU* fpu, SF x, SF y)
311 {
312 sim_fpu op1;
313 sim_fpu op2;
314
315 sim_fpu_32to (&op1, x);
316 sim_fpu_32to (&op2, y);
317 return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2);
318 }
319
320
321 static DF
322 fextsfdf (CGEN_FPU* fpu, int how UNUSED, SF x)
323 {
324 sim_fpu op1;
325 unsigned64 res;
326
327 sim_fpu_32to (&op1, x);
328 sim_fpu_to64 (&res, &op1);
329
330 return res;
331 }
332
333 static SF
334 ftruncdfsf (CGEN_FPU* fpu, int how UNUSED, DF x)
335 {
336 sim_fpu op1;
337 unsigned32 res;
338
339 sim_fpu_64to (&op1, x);
340 sim_fpu_to32 (&res, &op1);
341
342 return res;
343 }
344
345 static SF
346 floatsisf (CGEN_FPU* fpu, int how UNUSED, SI x)
347 {
348 sim_fpu ans;
349 unsigned32 res;
350
351 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
352 sim_fpu_to32 (&res, &ans);
353 return res;
354 }
355
356 static DF
357 floatsidf (CGEN_FPU* fpu, int how UNUSED, SI x)
358 {
359 sim_fpu ans;
360 unsigned64 res;
361
362 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
363 sim_fpu_to64 (&res, &ans);
364 return res;
365 }
366
367 static DF
368 floatdidf (CGEN_FPU* fpu, int how UNUSED, DI x)
369 {
370 sim_fpu ans;
371 unsigned64 res;
372
373 sim_fpu_i64to (&ans, x, sim_fpu_round_near);
374 sim_fpu_to64 (&res, &ans);
375 return res;
376 }
377
378 static SF
379 ufloatsisf (CGEN_FPU* fpu, int how UNUSED, USI x)
380 {
381 sim_fpu ans;
382 unsigned32 res;
383
384 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
385 sim_fpu_to32 (&res, &ans);
386 return res;
387 }
388
389 static SI
390 fixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
391 {
392 sim_fpu op1;
393 signed32 res;
394
395 sim_fpu_32to (&op1, x);
396 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
397 return res;
398 }
399
400 static SI
401 fixdfsi (CGEN_FPU* fpu, int how UNUSED, DF x)
402 {
403 sim_fpu op1;
404 signed32 res;
405
406 sim_fpu_64to (&op1, x);
407 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
408 return res;
409 }
410
411 static DI
412 fixdfdi (CGEN_FPU* fpu, int how UNUSED, DF x)
413 {
414 sim_fpu op1;
415 signed64 res;
416
417 sim_fpu_64to (&op1, x);
418 sim_fpu_to64i (&res, &op1, sim_fpu_round_near);
419 return res;
420 }
421
422 static USI
423 ufixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
424 {
425 sim_fpu op1;
426 unsigned32 res;
427
428 sim_fpu_32to (&op1, x);
429 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
430 return res;
431 }
432 \f
433 /* DF mode support */
434
435 static DF
436 adddf (CGEN_FPU* fpu, DF x, DF y)
437 {
438 sim_fpu op1;
439 sim_fpu op2;
440 sim_fpu ans;
441 unsigned64 res;
442 sim_fpu_status status;
443
444 sim_fpu_64to (&op1, x);
445 sim_fpu_64to (&op2, y);
446 status = sim_fpu_add (&ans, &op1, &op2);
447 if (status != 0)
448 (*fpu->ops->error) (fpu, status);
449 sim_fpu_to64 (&res, &ans);
450
451 return res;
452 }
453
454 static DF
455 subdf (CGEN_FPU* fpu, DF x, DF y)
456 {
457 sim_fpu op1;
458 sim_fpu op2;
459 sim_fpu ans;
460 unsigned64 res;
461 sim_fpu_status status;
462
463 sim_fpu_64to (&op1, x);
464 sim_fpu_64to (&op2, y);
465 status = sim_fpu_sub (&ans, &op1, &op2);
466 if (status != 0)
467 (*fpu->ops->error) (fpu, status);
468 sim_fpu_to64 (&res, &ans);
469
470 return res;
471 }
472
473 static DF
474 muldf (CGEN_FPU* fpu, DF x, DF y)
475 {
476 sim_fpu op1;
477 sim_fpu op2;
478 sim_fpu ans;
479 unsigned64 res;
480 sim_fpu_status status;
481
482 sim_fpu_64to (&op1, x);
483 sim_fpu_64to (&op2, y);
484 status = sim_fpu_mul (&ans, &op1, &op2);
485 if (status != 0)
486 (*fpu->ops->error) (fpu, status);
487 sim_fpu_to64 (&res, &ans);
488
489 return res;
490 }
491
492 static DF
493 divdf (CGEN_FPU* fpu, DF x, DF y)
494 {
495 sim_fpu op1;
496 sim_fpu op2;
497 sim_fpu ans;
498 unsigned64 res;
499 sim_fpu_status status;
500
501 sim_fpu_64to (&op1, x);
502 sim_fpu_64to (&op2, y);
503 status = sim_fpu_div (&ans, &op1, &op2);
504 if (status != 0)
505 (*fpu->ops->error) (fpu, status);
506 sim_fpu_to64 (&res, &ans);
507
508 return res;
509 }
510
511 static DF
512 remdf (CGEN_FPU* fpu, DF x, DF y)
513 {
514 sim_fpu op1;
515 sim_fpu op2;
516 sim_fpu ans;
517 unsigned64 res;
518 sim_fpu_status status;
519
520 sim_fpu_64to (&op1, x);
521 sim_fpu_64to (&op2, y);
522 status = sim_fpu_rem (&ans, &op1, &op2);
523 if (status != 0)
524 (*fpu->ops->error) (fpu, status);
525 sim_fpu_to64(&res, &ans);
526
527 return res;
528 }
529
530 static DF
531 negdf (CGEN_FPU* fpu, DF x)
532 {
533 sim_fpu op1;
534 sim_fpu ans;
535 unsigned64 res;
536 sim_fpu_status status;
537
538 sim_fpu_64to (&op1, x);
539 status = sim_fpu_neg (&ans, &op1);
540 if (status != 0)
541 (*fpu->ops->error) (fpu, status);
542 sim_fpu_to64 (&res, &ans);
543
544 return res;
545 }
546
547 static DF
548 absdf (CGEN_FPU* fpu, DF x)
549 {
550 sim_fpu op1;
551 sim_fpu ans;
552 unsigned64 res;
553 sim_fpu_status status;
554
555 sim_fpu_64to (&op1, x);
556 status = sim_fpu_abs (&ans, &op1);
557 if (status != 0)
558 (*fpu->ops->error) (fpu, status);
559 sim_fpu_to64 (&res, &ans);
560
561 return res;
562 }
563
564 static DF
565 sqrtdf (CGEN_FPU* fpu, DF x)
566 {
567 sim_fpu op1;
568 sim_fpu ans;
569 unsigned64 res;
570 sim_fpu_status status;
571
572 sim_fpu_64to (&op1, x);
573 status = sim_fpu_sqrt (&ans, &op1);
574 if (status != 0)
575 (*fpu->ops->error) (fpu, status);
576 sim_fpu_to64 (&res, &ans);
577
578 return res;
579 }
580
581 static DF
582 invdf (CGEN_FPU* fpu, DF x)
583 {
584 sim_fpu op1;
585 sim_fpu ans;
586 unsigned64 res;
587 sim_fpu_status status;
588
589 sim_fpu_64to (&op1, x);
590 status = sim_fpu_inv (&ans, &op1);
591 if (status != 0)
592 (*fpu->ops->error) (fpu, status);
593 sim_fpu_to64 (&res, &ans);
594
595 return res;
596 }
597
598 static DF
599 mindf (CGEN_FPU* fpu, DF x, DF y)
600 {
601 sim_fpu op1;
602 sim_fpu op2;
603 sim_fpu ans;
604 unsigned64 res;
605 sim_fpu_status status;
606
607 sim_fpu_64to (&op1, x);
608 sim_fpu_64to (&op2, y);
609 status = sim_fpu_min (&ans, &op1, &op2);
610 if (status != 0)
611 (*fpu->ops->error) (fpu, status);
612 sim_fpu_to64 (&res, &ans);
613
614 return res;
615 }
616
617 static DF
618 maxdf (CGEN_FPU* fpu, DF x, DF y)
619 {
620 sim_fpu op1;
621 sim_fpu op2;
622 sim_fpu ans;
623 unsigned64 res;
624 sim_fpu_status status;
625
626 sim_fpu_64to (&op1, x);
627 sim_fpu_64to (&op2, y);
628 status = sim_fpu_max (&ans, &op1, &op2);
629 if (status != 0)
630 (*fpu->ops->error) (fpu, status);
631 sim_fpu_to64 (&res, &ans);
632
633 return res;
634 }
635
636 static CGEN_FP_CMP
637 cmpdf (CGEN_FPU* fpu, DF x, DF y)
638 {
639 sim_fpu op1;
640 sim_fpu op2;
641
642 sim_fpu_64to (&op1, x);
643 sim_fpu_64to (&op2, y);
644
645 if (sim_fpu_is_nan (&op1)
646 || sim_fpu_is_nan (&op2))
647 return FP_CMP_NAN;
648
649 if (x < y)
650 return FP_CMP_LT;
651 if (x > y)
652 return FP_CMP_GT;
653 return FP_CMP_EQ;
654 }
655
656 static int
657 eqdf (CGEN_FPU* fpu, DF x, DF y)
658 {
659 sim_fpu op1;
660 sim_fpu op2;
661
662 sim_fpu_64to (&op1, x);
663 sim_fpu_64to (&op2, y);
664 return sim_fpu_is_eq (&op1, &op2);
665 }
666
667 static int
668 nedf (CGEN_FPU* fpu, DF x, DF y)
669 {
670 sim_fpu op1;
671 sim_fpu op2;
672
673 sim_fpu_64to (&op1, x);
674 sim_fpu_64to (&op2, y);
675 return sim_fpu_is_ne (&op1, &op2);
676 }
677
678 static int
679 ltdf (CGEN_FPU* fpu, DF x, DF y)
680 {
681 sim_fpu op1;
682 sim_fpu op2;
683
684 sim_fpu_64to (&op1, x);
685 sim_fpu_64to (&op2, y);
686 return sim_fpu_is_lt (&op1, &op2);
687 }
688
689 static int
690 ledf (CGEN_FPU* fpu, DF x, DF y)
691 {
692 sim_fpu op1;
693 sim_fpu op2;
694
695 sim_fpu_64to (&op1, x);
696 sim_fpu_64to (&op2, y);
697 return sim_fpu_is_le (&op1, &op2);
698 }
699
700 static int
701 gtdf (CGEN_FPU* fpu, DF x, DF y)
702 {
703 sim_fpu op1;
704 sim_fpu op2;
705
706 sim_fpu_64to (&op1, x);
707 sim_fpu_64to (&op2, y);
708 return sim_fpu_is_gt (&op1, &op2);
709 }
710
711 static int
712 gedf (CGEN_FPU* fpu, DF x, DF y)
713 {
714 sim_fpu op1;
715 sim_fpu op2;
716
717 sim_fpu_64to (&op1, x);
718 sim_fpu_64to (&op2, y);
719 return sim_fpu_is_ge (&op1, &op2);
720 }
721
722 static int
723 unordereddf (CGEN_FPU* fpu, DF x, DF y)
724 {
725 sim_fpu op1;
726 sim_fpu op2;
727
728 sim_fpu_64to (&op1, x);
729 sim_fpu_64to (&op2, y);
730 return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2);
731 }
732 \f
733 /* Initialize FP_OPS to use accurate library. */
734
735 void
736 cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
737 {
738 CGEN_FP_OPS* o;
739
740 fpu->owner = cpu;
741 /* ??? small memory leak, not freed by sim_close */
742 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
743
744 o = fpu->ops;
745 memset (o, 0, sizeof (*o));
746
747 o->error = error;
748
749 o->addsf = addsf;
750 o->subsf = subsf;
751 o->mulsf = mulsf;
752 o->divsf = divsf;
753 o->remsf = remsf;
754 o->negsf = negsf;
755 o->abssf = abssf;
756 o->sqrtsf = sqrtsf;
757 o->invsf = invsf;
758 o->minsf = minsf;
759 o->maxsf = maxsf;
760 o->cmpsf = cmpsf;
761 o->eqsf = eqsf;
762 o->nesf = nesf;
763 o->ltsf = ltsf;
764 o->lesf = lesf;
765 o->gtsf = gtsf;
766 o->gesf = gesf;
767 o->unorderedsf = unorderedsf;
768
769 o->adddf = adddf;
770 o->subdf = subdf;
771 o->muldf = muldf;
772 o->divdf = divdf;
773 o->remdf = remdf;
774 o->negdf = negdf;
775 o->absdf = absdf;
776 o->sqrtdf = sqrtdf;
777 o->invdf = invdf;
778 o->mindf = mindf;
779 o->maxdf = maxdf;
780 o->cmpdf = cmpdf;
781 o->eqdf = eqdf;
782 o->nedf = nedf;
783 o->ltdf = ltdf;
784 o->ledf = ledf;
785 o->gtdf = gtdf;
786 o->gedf = gedf;
787 o->unordereddf = unordereddf;
788 o->fextsfdf = fextsfdf;
789 o->ftruncdfsf = ftruncdfsf;
790 o->floatsisf = floatsisf;
791 o->floatsidf = floatsidf;
792 o->floatdidf = floatdidf;
793 o->ufloatsisf = ufloatsisf;
794 o->fixsfsi = fixsfsi;
795 o->fixdfsi = fixdfsi;
796 o->fixdfdi = fixdfdi;
797 o->ufixsfsi = ufixsfsi;
798 }
This page took 0.073119 seconds and 4 git commands to generate.