[binutils, ARM, 5/16] BF insns infrastructure with new global reloc R_ARM_THM_BF16
[binutils-gdb.git] / sim / common / cgen-accfp.c
blob5d600c6e418a2ac4503a8a33e6bed582905c43e4
1 /* Accurate fp support for CGEN-based simulators.
2 Copyright (C) 1999 Cygnus Solutions.
4 This implemention assumes:
5 typedef USI SF;
6 typedef UDI DF;
8 TODO:
9 - lazy encoding/decoding
10 - checking return code (say by callback)
11 - proper rounding
14 #include "sim-main.h"
15 #include "sim-fpu.h"
17 /* SF mode support */
19 static SF
20 addsf (CGEN_FPU* fpu, SF x, SF y)
22 sim_fpu op1;
23 sim_fpu op2;
24 sim_fpu ans;
25 unsigned32 res;
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);
31 if (status != 0)
32 (*fpu->ops->error) (fpu, status);
33 sim_fpu_to32 (&res, &ans);
35 return res;
38 static SF
39 subsf (CGEN_FPU* fpu, SF x, SF y)
41 sim_fpu op1;
42 sim_fpu op2;
43 sim_fpu ans;
44 unsigned32 res;
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);
50 if (status != 0)
51 (*fpu->ops->error) (fpu, status);
52 sim_fpu_to32 (&res, &ans);
54 return res;
57 static SF
58 mulsf (CGEN_FPU* fpu, SF x, SF y)
60 sim_fpu op1;
61 sim_fpu op2;
62 sim_fpu ans;
63 unsigned32 res;
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);
69 if (status != 0)
70 (*fpu->ops->error) (fpu, status);
71 sim_fpu_to32 (&res, &ans);
73 return res;
76 static SF
77 divsf (CGEN_FPU* fpu, SF x, SF y)
79 sim_fpu op1;
80 sim_fpu op2;
81 sim_fpu ans;
82 unsigned32 res;
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);
88 if (status != 0)
89 (*fpu->ops->error) (fpu, status);
90 sim_fpu_to32 (&res, &ans);
92 return res;
95 static SF
96 remsf (CGEN_FPU* fpu, SF x, SF y)
98 sim_fpu op1;
99 sim_fpu op2;
100 sim_fpu ans;
101 unsigned32 res;
102 sim_fpu_status status;
104 sim_fpu_32to (&op1, x);
105 sim_fpu_32to (&op2, y);
106 status = sim_fpu_rem (&ans, &op1, &op2);
107 if (status != 0)
108 (*fpu->ops->error) (fpu, status);
109 sim_fpu_to32 (&res, &ans);
111 return res;
114 static SF
115 negsf (CGEN_FPU* fpu, SF x)
117 sim_fpu op1;
118 sim_fpu ans;
119 unsigned32 res;
120 sim_fpu_status status;
122 sim_fpu_32to (&op1, x);
123 status = sim_fpu_neg (&ans, &op1);
124 if (status != 0)
125 (*fpu->ops->error) (fpu, status);
126 sim_fpu_to32 (&res, &ans);
128 return res;
131 static SF
132 abssf (CGEN_FPU* fpu, SF x)
134 sim_fpu op1;
135 sim_fpu ans;
136 unsigned32 res;
137 sim_fpu_status status;
139 sim_fpu_32to (&op1, x);
140 status = sim_fpu_abs (&ans, &op1);
141 if (status != 0)
142 (*fpu->ops->error) (fpu, status);
143 sim_fpu_to32 (&res, &ans);
145 return res;
148 static SF
149 sqrtsf (CGEN_FPU* fpu, SF x)
151 sim_fpu op1;
152 sim_fpu ans;
153 unsigned32 res;
154 sim_fpu_status status;
156 sim_fpu_32to (&op1, x);
157 status = sim_fpu_sqrt (&ans, &op1);
158 if (status != 0)
159 (*fpu->ops->error) (fpu, status);
160 sim_fpu_to32 (&res, &ans);
162 return res;
165 static SF
166 invsf (CGEN_FPU* fpu, SF x)
168 sim_fpu op1;
169 sim_fpu ans;
170 unsigned32 res;
171 sim_fpu_status status;
173 sim_fpu_32to (&op1, x);
174 status = sim_fpu_inv (&ans, &op1);
175 if (status != 0)
176 (*fpu->ops->error) (fpu, status);
177 sim_fpu_to32 (&res, &ans);
179 return res;
182 static SF
183 minsf (CGEN_FPU* fpu, SF x, SF y)
185 sim_fpu op1;
186 sim_fpu op2;
187 sim_fpu ans;
188 unsigned32 res;
189 sim_fpu_status status;
191 sim_fpu_32to (&op1, x);
192 sim_fpu_32to (&op2, y);
193 status = sim_fpu_min (&ans, &op1, &op2);
194 if (status != 0)
195 (*fpu->ops->error) (fpu, status);
196 sim_fpu_to32 (&res, &ans);
198 return res;
201 static SF
202 maxsf (CGEN_FPU* fpu, SF x, SF y)
204 sim_fpu op1;
205 sim_fpu op2;
206 sim_fpu ans;
207 unsigned32 res;
208 sim_fpu_status status;
210 sim_fpu_32to (&op1, x);
211 sim_fpu_32to (&op2, y);
212 status = sim_fpu_max (&ans, &op1, &op2);
213 if (status != 0)
214 (*fpu->ops->error) (fpu, status);
215 sim_fpu_to32 (&res, &ans);
217 return res;
220 static CGEN_FP_CMP
221 cmpsf (CGEN_FPU* fpu, SF x, SF y)
223 sim_fpu op1;
224 sim_fpu op2;
226 sim_fpu_32to (&op1, x);
227 sim_fpu_32to (&op2, y);
229 if (sim_fpu_is_nan (&op1)
230 || sim_fpu_is_nan (&op2))
231 return FP_CMP_NAN;
233 if (x < y)
234 return FP_CMP_LT;
235 if (x > y)
236 return FP_CMP_GT;
237 return FP_CMP_EQ;
240 static int
241 eqsf (CGEN_FPU* fpu, SF x, SF y)
243 sim_fpu op1;
244 sim_fpu op2;
246 sim_fpu_32to (&op1, x);
247 sim_fpu_32to (&op2, y);
248 return sim_fpu_is_eq (&op1, &op2);
251 static int
252 nesf (CGEN_FPU* fpu, SF x, SF y)
254 sim_fpu op1;
255 sim_fpu op2;
257 sim_fpu_32to (&op1, x);
258 sim_fpu_32to (&op2, y);
259 return sim_fpu_is_ne (&op1, &op2);
262 static int
263 ltsf (CGEN_FPU* fpu, SF x, SF y)
265 sim_fpu op1;
266 sim_fpu op2;
268 sim_fpu_32to (&op1, x);
269 sim_fpu_32to (&op2, y);
270 return sim_fpu_is_lt (&op1, &op2);
273 static int
274 lesf (CGEN_FPU* fpu, SF x, SF y)
276 sim_fpu op1;
277 sim_fpu op2;
279 sim_fpu_32to (&op1, x);
280 sim_fpu_32to (&op2, y);
281 return sim_fpu_is_le (&op1, &op2);
284 static int
285 gtsf (CGEN_FPU* fpu, SF x, SF y)
287 sim_fpu op1;
288 sim_fpu op2;
290 sim_fpu_32to (&op1, x);
291 sim_fpu_32to (&op2, y);
292 return sim_fpu_is_gt (&op1, &op2);
295 static int
296 gesf (CGEN_FPU* fpu, SF x, SF y)
298 sim_fpu op1;
299 sim_fpu op2;
301 sim_fpu_32to (&op1, x);
302 sim_fpu_32to (&op2, y);
303 return sim_fpu_is_ge (&op1, &op2);
306 static DF
307 fextsfdf (CGEN_FPU* fpu, int how UNUSED, SF x)
309 sim_fpu op1;
310 unsigned64 res;
312 sim_fpu_32to (&op1, x);
313 sim_fpu_to64 (&res, &op1);
315 return res;
318 static SF
319 ftruncdfsf (CGEN_FPU* fpu, int how UNUSED, DF x)
321 sim_fpu op1;
322 unsigned32 res;
324 sim_fpu_64to (&op1, x);
325 sim_fpu_to32 (&res, &op1);
327 return res;
330 static SF
331 floatsisf (CGEN_FPU* fpu, int how UNUSED, SI x)
333 sim_fpu ans;
334 unsigned32 res;
336 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
337 sim_fpu_to32 (&res, &ans);
338 return res;
341 static DF
342 floatsidf (CGEN_FPU* fpu, int how UNUSED, SI x)
344 sim_fpu ans;
345 unsigned64 res;
347 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
348 sim_fpu_to64 (&res, &ans);
349 return res;
352 static SF
353 ufloatsisf (CGEN_FPU* fpu, int how UNUSED, USI x)
355 sim_fpu ans;
356 unsigned32 res;
358 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
359 sim_fpu_to32 (&res, &ans);
360 return res;
363 static SI
364 fixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
366 sim_fpu op1;
367 unsigned32 res;
369 sim_fpu_32to (&op1, x);
370 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
371 return res;
374 static SI
375 fixdfsi (CGEN_FPU* fpu, int how UNUSED, DF x)
377 sim_fpu op1;
378 unsigned32 res;
380 sim_fpu_64to (&op1, x);
381 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
382 return res;
385 static USI
386 ufixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
388 sim_fpu op1;
389 unsigned32 res;
391 sim_fpu_32to (&op1, x);
392 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
393 return res;
396 /* DF mode support */
398 static DF
399 adddf (CGEN_FPU* fpu, DF x, DF y)
401 sim_fpu op1;
402 sim_fpu op2;
403 sim_fpu ans;
404 unsigned64 res;
405 sim_fpu_status status;
407 sim_fpu_64to (&op1, x);
408 sim_fpu_64to (&op2, y);
409 status = sim_fpu_add (&ans, &op1, &op2);
410 if (status != 0)
411 (*fpu->ops->error) (fpu, status);
412 sim_fpu_to64 (&res, &ans);
414 return res;
417 static DF
418 subdf (CGEN_FPU* fpu, DF x, DF y)
420 sim_fpu op1;
421 sim_fpu op2;
422 sim_fpu ans;
423 unsigned64 res;
424 sim_fpu_status status;
426 sim_fpu_64to (&op1, x);
427 sim_fpu_64to (&op2, y);
428 status = sim_fpu_sub (&ans, &op1, &op2);
429 if (status != 0)
430 (*fpu->ops->error) (fpu, status);
431 sim_fpu_to64 (&res, &ans);
433 return res;
436 static DF
437 muldf (CGEN_FPU* fpu, DF x, DF y)
439 sim_fpu op1;
440 sim_fpu op2;
441 sim_fpu ans;
442 unsigned64 res;
443 sim_fpu_status status;
445 sim_fpu_64to (&op1, x);
446 sim_fpu_64to (&op2, y);
447 status = sim_fpu_mul (&ans, &op1, &op2);
448 if (status != 0)
449 (*fpu->ops->error) (fpu, status);
450 sim_fpu_to64 (&res, &ans);
452 return res;
455 static DF
456 divdf (CGEN_FPU* fpu, DF x, DF y)
458 sim_fpu op1;
459 sim_fpu op2;
460 sim_fpu ans;
461 unsigned64 res;
462 sim_fpu_status status;
464 sim_fpu_64to (&op1, x);
465 sim_fpu_64to (&op2, y);
466 status = sim_fpu_div (&ans, &op1, &op2);
467 if (status != 0)
468 (*fpu->ops->error) (fpu, status);
469 sim_fpu_to64 (&res, &ans);
471 return res;
474 static DF
475 remdf (CGEN_FPU* fpu, DF x, DF y)
477 sim_fpu op1;
478 sim_fpu op2;
479 sim_fpu ans;
480 unsigned64 res;
481 sim_fpu_status status;
483 sim_fpu_64to (&op1, x);
484 sim_fpu_64to (&op2, y);
485 status = sim_fpu_rem (&ans, &op1, &op2);
486 if (status != 0)
487 (*fpu->ops->error) (fpu, status);
488 sim_fpu_to64(&res, &ans);
490 return res;
493 static DF
494 negdf (CGEN_FPU* fpu, DF x)
496 sim_fpu op1;
497 sim_fpu ans;
498 unsigned64 res;
499 sim_fpu_status status;
501 sim_fpu_64to (&op1, x);
502 status = sim_fpu_neg (&ans, &op1);
503 if (status != 0)
504 (*fpu->ops->error) (fpu, status);
505 sim_fpu_to64 (&res, &ans);
507 return res;
510 static DF
511 absdf (CGEN_FPU* fpu, DF x)
513 sim_fpu op1;
514 sim_fpu ans;
515 unsigned64 res;
516 sim_fpu_status status;
518 sim_fpu_64to (&op1, x);
519 status = sim_fpu_abs (&ans, &op1);
520 if (status != 0)
521 (*fpu->ops->error) (fpu, status);
522 sim_fpu_to64 (&res, &ans);
524 return res;
527 static DF
528 sqrtdf (CGEN_FPU* fpu, DF x)
530 sim_fpu op1;
531 sim_fpu ans;
532 unsigned64 res;
533 sim_fpu_status status;
535 sim_fpu_64to (&op1, x);
536 status = sim_fpu_sqrt (&ans, &op1);
537 if (status != 0)
538 (*fpu->ops->error) (fpu, status);
539 sim_fpu_to64 (&res, &ans);
541 return res;
544 static DF
545 invdf (CGEN_FPU* fpu, DF x)
547 sim_fpu op1;
548 sim_fpu ans;
549 unsigned64 res;
550 sim_fpu_status status;
552 sim_fpu_64to (&op1, x);
553 status = sim_fpu_inv (&ans, &op1);
554 if (status != 0)
555 (*fpu->ops->error) (fpu, status);
556 sim_fpu_to64 (&res, &ans);
558 return res;
561 static DF
562 mindf (CGEN_FPU* fpu, DF x, DF y)
564 sim_fpu op1;
565 sim_fpu op2;
566 sim_fpu ans;
567 unsigned64 res;
568 sim_fpu_status status;
570 sim_fpu_64to (&op1, x);
571 sim_fpu_64to (&op2, y);
572 status = sim_fpu_min (&ans, &op1, &op2);
573 if (status != 0)
574 (*fpu->ops->error) (fpu, status);
575 sim_fpu_to64 (&res, &ans);
577 return res;
580 static DF
581 maxdf (CGEN_FPU* fpu, DF x, DF y)
583 sim_fpu op1;
584 sim_fpu op2;
585 sim_fpu ans;
586 unsigned64 res;
587 sim_fpu_status status;
589 sim_fpu_64to (&op1, x);
590 sim_fpu_64to (&op2, y);
591 status = sim_fpu_max (&ans, &op1, &op2);
592 if (status != 0)
593 (*fpu->ops->error) (fpu, status);
594 sim_fpu_to64 (&res, &ans);
596 return res;
599 static CGEN_FP_CMP
600 cmpdf (CGEN_FPU* fpu, DF x, DF y)
602 sim_fpu op1;
603 sim_fpu op2;
605 sim_fpu_64to (&op1, x);
606 sim_fpu_64to (&op2, y);
608 if (sim_fpu_is_nan (&op1)
609 || sim_fpu_is_nan (&op2))
610 return FP_CMP_NAN;
612 if (x < y)
613 return FP_CMP_LT;
614 if (x > y)
615 return FP_CMP_GT;
616 return FP_CMP_EQ;
619 static int
620 eqdf (CGEN_FPU* fpu, DF x, DF y)
622 sim_fpu op1;
623 sim_fpu op2;
625 sim_fpu_64to (&op1, x);
626 sim_fpu_64to (&op2, y);
627 return sim_fpu_is_eq (&op1, &op2);
630 static int
631 nedf (CGEN_FPU* fpu, DF x, DF y)
633 sim_fpu op1;
634 sim_fpu op2;
636 sim_fpu_64to (&op1, x);
637 sim_fpu_64to (&op2, y);
638 return sim_fpu_is_ne (&op1, &op2);
641 static int
642 ltdf (CGEN_FPU* fpu, DF x, DF y)
644 sim_fpu op1;
645 sim_fpu op2;
647 sim_fpu_64to (&op1, x);
648 sim_fpu_64to (&op2, y);
649 return sim_fpu_is_lt (&op1, &op2);
652 static int
653 ledf (CGEN_FPU* fpu, DF x, DF y)
655 sim_fpu op1;
656 sim_fpu op2;
658 sim_fpu_64to (&op1, x);
659 sim_fpu_64to (&op2, y);
660 return sim_fpu_is_le (&op1, &op2);
663 static int
664 gtdf (CGEN_FPU* fpu, DF x, DF y)
666 sim_fpu op1;
667 sim_fpu op2;
669 sim_fpu_64to (&op1, x);
670 sim_fpu_64to (&op2, y);
671 return sim_fpu_is_gt (&op1, &op2);
674 static int
675 gedf (CGEN_FPU* fpu, DF x, DF y)
677 sim_fpu op1;
678 sim_fpu op2;
680 sim_fpu_64to (&op1, x);
681 sim_fpu_64to (&op2, y);
682 return sim_fpu_is_ge (&op1, &op2);
685 /* Initialize FP_OPS to use accurate library. */
687 void
688 cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
690 CGEN_FP_OPS* o;
692 fpu->owner = cpu;
693 /* ??? small memory leak, not freed by sim_close */
694 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
696 o = fpu->ops;
697 memset (o, 0, sizeof (*o));
699 o->error = error;
701 o->addsf = addsf;
702 o->subsf = subsf;
703 o->mulsf = mulsf;
704 o->divsf = divsf;
705 o->remsf = remsf;
706 o->negsf = negsf;
707 o->abssf = abssf;
708 o->sqrtsf = sqrtsf;
709 o->invsf = invsf;
710 o->minsf = minsf;
711 o->maxsf = maxsf;
712 o->cmpsf = cmpsf;
713 o->eqsf = eqsf;
714 o->nesf = nesf;
715 o->ltsf = ltsf;
716 o->lesf = lesf;
717 o->gtsf = gtsf;
718 o->gesf = gesf;
720 o->adddf = adddf;
721 o->subdf = subdf;
722 o->muldf = muldf;
723 o->divdf = divdf;
724 o->remdf = remdf;
725 o->negdf = negdf;
726 o->absdf = absdf;
727 o->sqrtdf = sqrtdf;
728 o->invdf = invdf;
729 o->mindf = mindf;
730 o->maxdf = maxdf;
731 o->cmpdf = cmpdf;
732 o->eqdf = eqdf;
733 o->nedf = nedf;
734 o->ltdf = ltdf;
735 o->ledf = ledf;
736 o->gtdf = gtdf;
737 o->gedf = gedf;
738 o->fextsfdf = fextsfdf;
739 o->ftruncdfsf = ftruncdfsf;
740 o->floatsisf = floatsisf;
741 o->floatsidf = floatsidf;
742 o->ufloatsisf = ufloatsisf;
743 o->fixsfsi = fixsfsi;
744 o->fixdfsi = fixdfsi;
745 o->ufixsfsi = ufixsfsi;