common/
[deliverable/binutils-gdb.git] / sim / common / cgen-accfp.c
CommitLineData
3535ad49
JM
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#include "sim-main.h"
15#include "sim-fpu.h"
16
17/* SF mode support */
18
19static SF
20addsf (CGEN_FPU* fpu, SF x, SF y)
21{
22 sim_fpu op1;
23 sim_fpu op2;
24 sim_fpu ans;
25 unsigned32 res;
26 sim_fpu_status status;
27
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);
34
35 return res;
36}
37
38static SF
39subsf (CGEN_FPU* fpu, SF x, SF y)
40{
41 sim_fpu op1;
42 sim_fpu op2;
43 sim_fpu ans;
44 unsigned32 res;
c2d11a7d 45 sim_fpu_status status;
3535ad49
JM
46
47 sim_fpu_32to (&op1, x);
48 sim_fpu_32to (&op2, y);
c2d11a7d
JM
49 status = sim_fpu_sub (&ans, &op1, &op2);
50 if (status != 0)
51 (*fpu->ops->error) (fpu, status);
3535ad49
JM
52 sim_fpu_to32 (&res, &ans);
53
54 return res;
55}
56
57static SF
58mulsf (CGEN_FPU* fpu, SF x, SF y)
59{
60 sim_fpu op1;
61 sim_fpu op2;
62 sim_fpu ans;
63 unsigned32 res;
c2d11a7d 64 sim_fpu_status status;
3535ad49
JM
65
66 sim_fpu_32to (&op1, x);
67 sim_fpu_32to (&op2, y);
c2d11a7d
JM
68 status = sim_fpu_mul (&ans, &op1, &op2);
69 if (status != 0)
70 (*fpu->ops->error) (fpu, status);
3535ad49
JM
71 sim_fpu_to32 (&res, &ans);
72
73 return res;
74}
75
76static SF
77divsf (CGEN_FPU* fpu, SF x, SF y)
78{
79 sim_fpu op1;
80 sim_fpu op2;
81 sim_fpu ans;
82 unsigned32 res;
917317f4 83 sim_fpu_status status;
3535ad49
JM
84
85 sim_fpu_32to (&op1, x);
86 sim_fpu_32to (&op2, y);
917317f4
JM
87 status = sim_fpu_div (&ans, &op1, &op2);
88 if (status != 0)
89 (*fpu->ops->error) (fpu, status);
3535ad49
JM
90 sim_fpu_to32 (&res, &ans);
91
92 return res;
93}
94
95static SF
96negsf (CGEN_FPU* fpu, SF x)
97{
98 sim_fpu op1;
99 sim_fpu ans;
100 unsigned32 res;
c2d11a7d 101 sim_fpu_status status;
3535ad49
JM
102
103 sim_fpu_32to (&op1, x);
c2d11a7d
JM
104 status = sim_fpu_neg (&ans, &op1);
105 if (status != 0)
106 (*fpu->ops->error) (fpu, status);
3535ad49
JM
107 sim_fpu_to32 (&res, &ans);
108
109 return res;
110}
111
112static SF
113abssf (CGEN_FPU* fpu, SF x)
114{
115 sim_fpu op1;
116 sim_fpu ans;
117 unsigned32 res;
c2d11a7d 118 sim_fpu_status status;
3535ad49
JM
119
120 sim_fpu_32to (&op1, x);
c2d11a7d
JM
121 status = sim_fpu_abs (&ans, &op1);
122 if (status != 0)
123 (*fpu->ops->error) (fpu, status);
3535ad49
JM
124 sim_fpu_to32 (&res, &ans);
125
126 return res;
127}
128
129static SF
130sqrtsf (CGEN_FPU* fpu, SF x)
131{
132 sim_fpu op1;
133 sim_fpu ans;
134 unsigned32 res;
c2d11a7d 135 sim_fpu_status status;
3535ad49
JM
136
137 sim_fpu_32to (&op1, x);
c2d11a7d
JM
138 status = sim_fpu_sqrt (&ans, &op1);
139 if (status != 0)
140 (*fpu->ops->error) (fpu, status);
3535ad49
JM
141 sim_fpu_to32 (&res, &ans);
142
143 return res;
144}
145
146static SF
147invsf (CGEN_FPU* fpu, SF x)
148{
149 sim_fpu op1;
150 sim_fpu ans;
151 unsigned32 res;
c2d11a7d 152 sim_fpu_status status;
3535ad49
JM
153
154 sim_fpu_32to (&op1, x);
c2d11a7d
JM
155 status = sim_fpu_inv (&ans, &op1);
156 if (status != 0)
157 (*fpu->ops->error) (fpu, status);
3535ad49
JM
158 sim_fpu_to32 (&res, &ans);
159
160 return res;
161}
162
163static SF
164minsf (CGEN_FPU* fpu, SF x, SF y)
165{
166 sim_fpu op1;
167 sim_fpu op2;
168 sim_fpu ans;
169 unsigned32 res;
c2d11a7d 170 sim_fpu_status status;
3535ad49
JM
171
172 sim_fpu_32to (&op1, x);
173 sim_fpu_32to (&op2, y);
c2d11a7d
JM
174 status = sim_fpu_min (&ans, &op1, &op2);
175 if (status != 0)
176 (*fpu->ops->error) (fpu, status);
3535ad49
JM
177 sim_fpu_to32 (&res, &ans);
178
179 return res;
180}
181
182static SF
183maxsf (CGEN_FPU* fpu, SF x, SF y)
184{
185 sim_fpu op1;
186 sim_fpu op2;
187 sim_fpu ans;
188 unsigned32 res;
c2d11a7d 189 sim_fpu_status status;
3535ad49
JM
190
191 sim_fpu_32to (&op1, x);
192 sim_fpu_32to (&op2, y);
c2d11a7d
JM
193 status = sim_fpu_max (&ans, &op1, &op2);
194 if (status != 0)
195 (*fpu->ops->error) (fpu, status);
3535ad49
JM
196 sim_fpu_to32 (&res, &ans);
197
198 return res;
199}
200
201static CGEN_FP_CMP
202cmpsf (CGEN_FPU* fpu, SF x, SF y)
203{
204 sim_fpu op1;
205 sim_fpu op2;
206
207 sim_fpu_32to (&op1, x);
208 sim_fpu_32to (&op2, y);
209
210 if (sim_fpu_is_nan (&op1)
211 || sim_fpu_is_nan (&op2))
212 return FP_CMP_NAN;
213
214 if (x < y)
215 return FP_CMP_LT;
216 if (x > y)
217 return FP_CMP_GT;
218 return FP_CMP_EQ;
219}
220
221static int
222eqsf (CGEN_FPU* fpu, SF x, SF y)
223{
224 sim_fpu op1;
225 sim_fpu op2;
226
227 sim_fpu_32to (&op1, x);
228 sim_fpu_32to (&op2, y);
229 return sim_fpu_is_eq (&op1, &op2);
230}
231
232static int
233nesf (CGEN_FPU* fpu, SF x, SF y)
234{
235 sim_fpu op1;
236 sim_fpu op2;
237
238 sim_fpu_32to (&op1, x);
239 sim_fpu_32to (&op2, y);
240 return sim_fpu_is_ne (&op1, &op2);
241}
242
243static int
244ltsf (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_lt (&op1, &op2);
252}
253
254static int
255lesf (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_le (&op1, &op2);
263}
264
265static int
266gtsf (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_gt (&op1, &op2);
274}
275
276static int
277gesf (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_ge (&op1, &op2);
285}
286
f8603f2f 287static DF
d2c7a1a6 288fextsfdf (CGEN_FPU* fpu, int how UNUSED, SF x)
f8603f2f
DB
289{
290 sim_fpu op1;
291 unsigned64 res;
292
293 sim_fpu_32to (&op1, x);
294 sim_fpu_to64 (&res, &op1);
295
296 return res;
297}
298
299static SF
d2c7a1a6 300ftruncdfsf (CGEN_FPU* fpu, int how UNUSED, DF x)
f8603f2f
DB
301{
302 sim_fpu op1;
303 unsigned32 res;
304
305 sim_fpu_64to (&op1, x);
306 sim_fpu_to32 (&res, &op1);
307
308 return res;
309}
310
3535ad49 311static SF
d2c7a1a6 312floatsisf (CGEN_FPU* fpu, int how UNUSED, SI x)
3535ad49
JM
313{
314 sim_fpu ans;
315 unsigned32 res;
316
317 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
318 sim_fpu_to32 (&res, &ans);
319 return res;
320}
321
9846de1b 322static DF
d2c7a1a6 323floatsidf (CGEN_FPU* fpu, int how UNUSED, SI x)
9846de1b
JM
324{
325 sim_fpu ans;
326 unsigned64 res;
327
328 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
329 sim_fpu_to64 (&res, &ans);
330 return res;
331}
332
3535ad49 333static SF
d2c7a1a6 334ufloatsisf (CGEN_FPU* fpu, int how UNUSED, USI x)
3535ad49
JM
335{
336 sim_fpu ans;
337 unsigned32 res;
338
339 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
340 sim_fpu_to32 (&res, &ans);
341 return res;
342}
343
344static SI
d2c7a1a6 345fixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
3535ad49
JM
346{
347 sim_fpu op1;
348 unsigned32 res;
349
350 sim_fpu_32to (&op1, x);
351 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
352 return res;
353}
354
9846de1b 355static SI
d2c7a1a6 356fixdfsi (CGEN_FPU* fpu, int how UNUSED, DF x)
9846de1b
JM
357{
358 sim_fpu op1;
359 unsigned32 res;
360
361 sim_fpu_64to (&op1, x);
362 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
363 return res;
364}
365
3535ad49 366static USI
d2c7a1a6 367ufixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x)
3535ad49
JM
368{
369 sim_fpu op1;
370 unsigned32 res;
371
372 sim_fpu_32to (&op1, x);
373 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
374 return res;
375}
376\f
377/* DF mode support */
378
379static DF
380adddf (CGEN_FPU* fpu, DF x, DF y)
381{
382 sim_fpu op1;
383 sim_fpu op2;
384 sim_fpu ans;
385 unsigned64 res;
386 sim_fpu_status status;
387
388 sim_fpu_64to (&op1, x);
389 sim_fpu_64to (&op2, y);
390 status = sim_fpu_add (&ans, &op1, &op2);
391 if (status != 0)
392 (*fpu->ops->error) (fpu, status);
393 sim_fpu_to64 (&res, &ans);
394
395 return res;
396}
397
398static DF
399subdf (CGEN_FPU* fpu, DF x, DF y)
400{
401 sim_fpu op1;
402 sim_fpu op2;
403 sim_fpu ans;
404 unsigned64 res;
c2d11a7d 405 sim_fpu_status status;
3535ad49
JM
406
407 sim_fpu_64to (&op1, x);
408 sim_fpu_64to (&op2, y);
c2d11a7d
JM
409 status = sim_fpu_sub (&ans, &op1, &op2);
410 if (status != 0)
411 (*fpu->ops->error) (fpu, status);
3535ad49
JM
412 sim_fpu_to64 (&res, &ans);
413
414 return res;
415}
416
417static DF
418muldf (CGEN_FPU* fpu, DF x, DF y)
419{
420 sim_fpu op1;
421 sim_fpu op2;
422 sim_fpu ans;
423 unsigned64 res;
c2d11a7d 424 sim_fpu_status status;
3535ad49
JM
425
426 sim_fpu_64to (&op1, x);
427 sim_fpu_64to (&op2, y);
c2d11a7d
JM
428 status = sim_fpu_mul (&ans, &op1, &op2);
429 if (status != 0)
430 (*fpu->ops->error) (fpu, status);
3535ad49
JM
431 sim_fpu_to64 (&res, &ans);
432
433 return res;
434}
435
436static DF
437divdf (CGEN_FPU* fpu, DF x, DF y)
438{
439 sim_fpu op1;
440 sim_fpu op2;
441 sim_fpu ans;
442 unsigned64 res;
c2d11a7d 443 sim_fpu_status status;
3535ad49
JM
444
445 sim_fpu_64to (&op1, x);
446 sim_fpu_64to (&op2, y);
c2d11a7d
JM
447 status = sim_fpu_div (&ans, &op1, &op2);
448 if (status != 0)
449 (*fpu->ops->error) (fpu, status);
3535ad49
JM
450 sim_fpu_to64 (&res, &ans);
451
452 return res;
453}
454
455static DF
456negdf (CGEN_FPU* fpu, DF x)
457{
458 sim_fpu op1;
459 sim_fpu ans;
460 unsigned64 res;
c2d11a7d 461 sim_fpu_status status;
3535ad49
JM
462
463 sim_fpu_64to (&op1, x);
c2d11a7d
JM
464 status = sim_fpu_neg (&ans, &op1);
465 if (status != 0)
466 (*fpu->ops->error) (fpu, status);
3535ad49
JM
467 sim_fpu_to64 (&res, &ans);
468
469 return res;
470}
471
472static DF
473absdf (CGEN_FPU* fpu, DF x)
474{
475 sim_fpu op1;
476 sim_fpu ans;
477 unsigned64 res;
c2d11a7d 478 sim_fpu_status status;
3535ad49
JM
479
480 sim_fpu_64to (&op1, x);
c2d11a7d
JM
481 status = sim_fpu_abs (&ans, &op1);
482 if (status != 0)
483 (*fpu->ops->error) (fpu, status);
3535ad49
JM
484 sim_fpu_to64 (&res, &ans);
485
486 return res;
487}
488
489static DF
490sqrtdf (CGEN_FPU* fpu, DF x)
491{
492 sim_fpu op1;
493 sim_fpu ans;
494 unsigned64 res;
c2d11a7d 495 sim_fpu_status status;
3535ad49
JM
496
497 sim_fpu_64to (&op1, x);
c2d11a7d
JM
498 status = sim_fpu_sqrt (&ans, &op1);
499 if (status != 0)
500 (*fpu->ops->error) (fpu, status);
3535ad49
JM
501 sim_fpu_to64 (&res, &ans);
502
503 return res;
504}
505
506static DF
507invdf (CGEN_FPU* fpu, DF x)
508{
509 sim_fpu op1;
510 sim_fpu ans;
511 unsigned64 res;
c2d11a7d 512 sim_fpu_status status;
3535ad49
JM
513
514 sim_fpu_64to (&op1, x);
c2d11a7d
JM
515 status = sim_fpu_inv (&ans, &op1);
516 if (status != 0)
517 (*fpu->ops->error) (fpu, status);
3535ad49
JM
518 sim_fpu_to64 (&res, &ans);
519
520 return res;
521}
522
523static DF
524mindf (CGEN_FPU* fpu, DF x, DF y)
525{
526 sim_fpu op1;
527 sim_fpu op2;
528 sim_fpu ans;
529 unsigned64 res;
c2d11a7d 530 sim_fpu_status status;
3535ad49
JM
531
532 sim_fpu_64to (&op1, x);
533 sim_fpu_64to (&op2, y);
c2d11a7d
JM
534 status = sim_fpu_min (&ans, &op1, &op2);
535 if (status != 0)
536 (*fpu->ops->error) (fpu, status);
3535ad49
JM
537 sim_fpu_to64 (&res, &ans);
538
539 return res;
540}
541
542static DF
543maxdf (CGEN_FPU* fpu, DF x, DF y)
544{
545 sim_fpu op1;
546 sim_fpu op2;
547 sim_fpu ans;
548 unsigned64 res;
c2d11a7d 549 sim_fpu_status status;
3535ad49
JM
550
551 sim_fpu_64to (&op1, x);
552 sim_fpu_64to (&op2, y);
c2d11a7d
JM
553 status = sim_fpu_max (&ans, &op1, &op2);
554 if (status != 0)
555 (*fpu->ops->error) (fpu, status);
3535ad49
JM
556 sim_fpu_to64 (&res, &ans);
557
558 return res;
559}
560
561static CGEN_FP_CMP
562cmpdf (CGEN_FPU* fpu, DF x, DF y)
563{
564 sim_fpu op1;
565 sim_fpu op2;
566
567 sim_fpu_64to (&op1, x);
568 sim_fpu_64to (&op2, y);
569
570 if (sim_fpu_is_nan (&op1)
571 || sim_fpu_is_nan (&op2))
572 return FP_CMP_NAN;
573
574 if (x < y)
575 return FP_CMP_LT;
576 if (x > y)
577 return FP_CMP_GT;
578 return FP_CMP_EQ;
579}
580
581static int
582eqdf (CGEN_FPU* fpu, DF x, DF y)
583{
584 sim_fpu op1;
585 sim_fpu op2;
586
587 sim_fpu_64to (&op1, x);
588 sim_fpu_64to (&op2, y);
589 return sim_fpu_is_eq (&op1, &op2);
590}
591
592static int
593nedf (CGEN_FPU* fpu, DF x, DF y)
594{
595 sim_fpu op1;
596 sim_fpu op2;
597
598 sim_fpu_64to (&op1, x);
599 sim_fpu_64to (&op2, y);
600 return sim_fpu_is_ne (&op1, &op2);
601}
602
603static int
604ltdf (CGEN_FPU* fpu, DF x, DF y)
605{
606 sim_fpu op1;
607 sim_fpu op2;
608
609 sim_fpu_64to (&op1, x);
610 sim_fpu_64to (&op2, y);
611 return sim_fpu_is_lt (&op1, &op2);
612}
613
614static int
615ledf (CGEN_FPU* fpu, DF x, DF y)
616{
617 sim_fpu op1;
618 sim_fpu op2;
619
620 sim_fpu_64to (&op1, x);
621 sim_fpu_64to (&op2, y);
622 return sim_fpu_is_le (&op1, &op2);
623}
624
625static int
626gtdf (CGEN_FPU* fpu, DF x, DF y)
627{
628 sim_fpu op1;
629 sim_fpu op2;
630
631 sim_fpu_64to (&op1, x);
632 sim_fpu_64to (&op2, y);
633 return sim_fpu_is_gt (&op1, &op2);
634}
635
636static int
637gedf (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 return sim_fpu_is_ge (&op1, &op2);
645}
646\f
647/* Initialize FP_OPS to use accurate library. */
648
649void
650cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
651{
652 CGEN_FP_OPS* o;
653
654 fpu->owner = cpu;
655 /* ??? small memory leak, not freed by sim_close */
656 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
657
658 o = fpu->ops;
659 memset (o, 0, sizeof (*o));
660
661 o->error = error;
662
663 o->addsf = addsf;
664 o->subsf = subsf;
665 o->mulsf = mulsf;
666 o->divsf = divsf;
667 o->negsf = negsf;
668 o->abssf = abssf;
669 o->sqrtsf = sqrtsf;
670 o->invsf = invsf;
671 o->minsf = minsf;
672 o->maxsf = maxsf;
673 o->cmpsf = cmpsf;
674 o->eqsf = eqsf;
675 o->nesf = nesf;
676 o->ltsf = ltsf;
677 o->lesf = lesf;
678 o->gtsf = gtsf;
679 o->gesf = gesf;
680
681 o->adddf = adddf;
682 o->subdf = subdf;
683 o->muldf = muldf;
684 o->divdf = divdf;
685 o->negdf = negdf;
686 o->absdf = absdf;
687 o->sqrtdf = sqrtdf;
688 o->invdf = invdf;
689 o->mindf = mindf;
690 o->maxdf = maxdf;
691 o->cmpdf = cmpdf;
692 o->eqdf = eqdf;
693 o->nedf = nedf;
694 o->ltdf = ltdf;
695 o->ledf = ledf;
696 o->gtdf = gtdf;
697 o->gedf = gedf;
f8603f2f
DB
698 o->fextsfdf = fextsfdf;
699 o->ftruncdfsf = ftruncdfsf;
3535ad49 700 o->floatsisf = floatsisf;
9846de1b 701 o->floatsidf = floatsidf;
3535ad49
JM
702 o->ufloatsisf = ufloatsisf;
703 o->fixsfsi = fixsfsi;
9846de1b 704 o->fixdfsi = fixdfsi;
3535ad49
JM
705 o->ufixsfsi = ufixsfsi;
706}
This page took 0.473007 seconds and 4 git commands to generate.