import gdb-1999-12-06 snapshot
[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
287static SF
288floatsisf (CGEN_FPU* fpu, SI x)
289{
290 sim_fpu ans;
291 unsigned32 res;
292
293 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
294 sim_fpu_to32 (&res, &ans);
295 return res;
296}
297
9846de1b
JM
298static DF
299floatsidf (CGEN_FPU* fpu, SI x)
300{
301 sim_fpu ans;
302 unsigned64 res;
303
304 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
305 sim_fpu_to64 (&res, &ans);
306 return res;
307}
308
3535ad49
JM
309static SF
310ufloatsisf (CGEN_FPU* fpu, USI x)
311{
312 sim_fpu ans;
313 unsigned32 res;
314
315 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
316 sim_fpu_to32 (&res, &ans);
317 return res;
318}
319
320static SI
321fixsfsi (CGEN_FPU* fpu, SF x)
322{
323 sim_fpu op1;
324 unsigned32 res;
325
326 sim_fpu_32to (&op1, x);
327 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
328 return res;
329}
330
9846de1b
JM
331static SI
332fixdfsi (CGEN_FPU* fpu, DF x)
333{
334 sim_fpu op1;
335 unsigned32 res;
336
337 sim_fpu_64to (&op1, x);
338 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
339 return res;
340}
341
3535ad49
JM
342static USI
343ufixsfsi (CGEN_FPU* fpu, SF x)
344{
345 sim_fpu op1;
346 unsigned32 res;
347
348 sim_fpu_32to (&op1, x);
349 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
350 return res;
351}
352\f
353/* DF mode support */
354
355static DF
356adddf (CGEN_FPU* fpu, DF x, DF y)
357{
358 sim_fpu op1;
359 sim_fpu op2;
360 sim_fpu ans;
361 unsigned64 res;
362 sim_fpu_status status;
363
364 sim_fpu_64to (&op1, x);
365 sim_fpu_64to (&op2, y);
366 status = sim_fpu_add (&ans, &op1, &op2);
367 if (status != 0)
368 (*fpu->ops->error) (fpu, status);
369 sim_fpu_to64 (&res, &ans);
370
371 return res;
372}
373
374static DF
375subdf (CGEN_FPU* fpu, DF x, DF y)
376{
377 sim_fpu op1;
378 sim_fpu op2;
379 sim_fpu ans;
380 unsigned64 res;
c2d11a7d 381 sim_fpu_status status;
3535ad49
JM
382
383 sim_fpu_64to (&op1, x);
384 sim_fpu_64to (&op2, y);
c2d11a7d
JM
385 status = sim_fpu_sub (&ans, &op1, &op2);
386 if (status != 0)
387 (*fpu->ops->error) (fpu, status);
3535ad49
JM
388 sim_fpu_to64 (&res, &ans);
389
390 return res;
391}
392
393static DF
394muldf (CGEN_FPU* fpu, DF x, DF y)
395{
396 sim_fpu op1;
397 sim_fpu op2;
398 sim_fpu ans;
399 unsigned64 res;
c2d11a7d 400 sim_fpu_status status;
3535ad49
JM
401
402 sim_fpu_64to (&op1, x);
403 sim_fpu_64to (&op2, y);
c2d11a7d
JM
404 status = sim_fpu_mul (&ans, &op1, &op2);
405 if (status != 0)
406 (*fpu->ops->error) (fpu, status);
3535ad49
JM
407 sim_fpu_to64 (&res, &ans);
408
409 return res;
410}
411
412static DF
413divdf (CGEN_FPU* fpu, DF x, DF y)
414{
415 sim_fpu op1;
416 sim_fpu op2;
417 sim_fpu ans;
418 unsigned64 res;
c2d11a7d 419 sim_fpu_status status;
3535ad49
JM
420
421 sim_fpu_64to (&op1, x);
422 sim_fpu_64to (&op2, y);
c2d11a7d
JM
423 status = sim_fpu_div (&ans, &op1, &op2);
424 if (status != 0)
425 (*fpu->ops->error) (fpu, status);
3535ad49
JM
426 sim_fpu_to64 (&res, &ans);
427
428 return res;
429}
430
431static DF
432negdf (CGEN_FPU* fpu, DF x)
433{
434 sim_fpu op1;
435 sim_fpu ans;
436 unsigned64 res;
c2d11a7d 437 sim_fpu_status status;
3535ad49
JM
438
439 sim_fpu_64to (&op1, x);
c2d11a7d
JM
440 status = sim_fpu_neg (&ans, &op1);
441 if (status != 0)
442 (*fpu->ops->error) (fpu, status);
3535ad49
JM
443 sim_fpu_to64 (&res, &ans);
444
445 return res;
446}
447
448static DF
449absdf (CGEN_FPU* fpu, DF x)
450{
451 sim_fpu op1;
452 sim_fpu ans;
453 unsigned64 res;
c2d11a7d 454 sim_fpu_status status;
3535ad49
JM
455
456 sim_fpu_64to (&op1, x);
c2d11a7d
JM
457 status = sim_fpu_abs (&ans, &op1);
458 if (status != 0)
459 (*fpu->ops->error) (fpu, status);
3535ad49
JM
460 sim_fpu_to64 (&res, &ans);
461
462 return res;
463}
464
465static DF
466sqrtdf (CGEN_FPU* fpu, DF x)
467{
468 sim_fpu op1;
469 sim_fpu ans;
470 unsigned64 res;
c2d11a7d 471 sim_fpu_status status;
3535ad49
JM
472
473 sim_fpu_64to (&op1, x);
c2d11a7d
JM
474 status = sim_fpu_sqrt (&ans, &op1);
475 if (status != 0)
476 (*fpu->ops->error) (fpu, status);
3535ad49
JM
477 sim_fpu_to64 (&res, &ans);
478
479 return res;
480}
481
482static DF
483invdf (CGEN_FPU* fpu, DF x)
484{
485 sim_fpu op1;
486 sim_fpu ans;
487 unsigned64 res;
c2d11a7d 488 sim_fpu_status status;
3535ad49
JM
489
490 sim_fpu_64to (&op1, x);
c2d11a7d
JM
491 status = sim_fpu_inv (&ans, &op1);
492 if (status != 0)
493 (*fpu->ops->error) (fpu, status);
3535ad49
JM
494 sim_fpu_to64 (&res, &ans);
495
496 return res;
497}
498
499static DF
500mindf (CGEN_FPU* fpu, DF x, DF y)
501{
502 sim_fpu op1;
503 sim_fpu op2;
504 sim_fpu ans;
505 unsigned64 res;
c2d11a7d 506 sim_fpu_status status;
3535ad49
JM
507
508 sim_fpu_64to (&op1, x);
509 sim_fpu_64to (&op2, y);
c2d11a7d
JM
510 status = sim_fpu_min (&ans, &op1, &op2);
511 if (status != 0)
512 (*fpu->ops->error) (fpu, status);
3535ad49
JM
513 sim_fpu_to64 (&res, &ans);
514
515 return res;
516}
517
518static DF
519maxdf (CGEN_FPU* fpu, DF x, DF y)
520{
521 sim_fpu op1;
522 sim_fpu op2;
523 sim_fpu ans;
524 unsigned64 res;
c2d11a7d 525 sim_fpu_status status;
3535ad49
JM
526
527 sim_fpu_64to (&op1, x);
528 sim_fpu_64to (&op2, y);
c2d11a7d
JM
529 status = sim_fpu_max (&ans, &op1, &op2);
530 if (status != 0)
531 (*fpu->ops->error) (fpu, status);
3535ad49
JM
532 sim_fpu_to64 (&res, &ans);
533
534 return res;
535}
536
537static CGEN_FP_CMP
538cmpdf (CGEN_FPU* fpu, DF x, DF y)
539{
540 sim_fpu op1;
541 sim_fpu op2;
542
543 sim_fpu_64to (&op1, x);
544 sim_fpu_64to (&op2, y);
545
546 if (sim_fpu_is_nan (&op1)
547 || sim_fpu_is_nan (&op2))
548 return FP_CMP_NAN;
549
550 if (x < y)
551 return FP_CMP_LT;
552 if (x > y)
553 return FP_CMP_GT;
554 return FP_CMP_EQ;
555}
556
557static int
558eqdf (CGEN_FPU* fpu, DF x, DF y)
559{
560 sim_fpu op1;
561 sim_fpu op2;
562
563 sim_fpu_64to (&op1, x);
564 sim_fpu_64to (&op2, y);
565 return sim_fpu_is_eq (&op1, &op2);
566}
567
568static int
569nedf (CGEN_FPU* fpu, DF x, DF y)
570{
571 sim_fpu op1;
572 sim_fpu op2;
573
574 sim_fpu_64to (&op1, x);
575 sim_fpu_64to (&op2, y);
576 return sim_fpu_is_ne (&op1, &op2);
577}
578
579static int
580ltdf (CGEN_FPU* fpu, DF x, DF y)
581{
582 sim_fpu op1;
583 sim_fpu op2;
584
585 sim_fpu_64to (&op1, x);
586 sim_fpu_64to (&op2, y);
587 return sim_fpu_is_lt (&op1, &op2);
588}
589
590static int
591ledf (CGEN_FPU* fpu, DF x, DF y)
592{
593 sim_fpu op1;
594 sim_fpu op2;
595
596 sim_fpu_64to (&op1, x);
597 sim_fpu_64to (&op2, y);
598 return sim_fpu_is_le (&op1, &op2);
599}
600
601static int
602gtdf (CGEN_FPU* fpu, DF x, DF y)
603{
604 sim_fpu op1;
605 sim_fpu op2;
606
607 sim_fpu_64to (&op1, x);
608 sim_fpu_64to (&op2, y);
609 return sim_fpu_is_gt (&op1, &op2);
610}
611
612static int
613gedf (CGEN_FPU* fpu, DF x, DF y)
614{
615 sim_fpu op1;
616 sim_fpu op2;
617
618 sim_fpu_64to (&op1, x);
619 sim_fpu_64to (&op2, y);
620 return sim_fpu_is_ge (&op1, &op2);
621}
622\f
623/* Initialize FP_OPS to use accurate library. */
624
625void
626cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
627{
628 CGEN_FP_OPS* o;
629
630 fpu->owner = cpu;
631 /* ??? small memory leak, not freed by sim_close */
632 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
633
634 o = fpu->ops;
635 memset (o, 0, sizeof (*o));
636
637 o->error = error;
638
639 o->addsf = addsf;
640 o->subsf = subsf;
641 o->mulsf = mulsf;
642 o->divsf = divsf;
643 o->negsf = negsf;
644 o->abssf = abssf;
645 o->sqrtsf = sqrtsf;
646 o->invsf = invsf;
647 o->minsf = minsf;
648 o->maxsf = maxsf;
649 o->cmpsf = cmpsf;
650 o->eqsf = eqsf;
651 o->nesf = nesf;
652 o->ltsf = ltsf;
653 o->lesf = lesf;
654 o->gtsf = gtsf;
655 o->gesf = gesf;
656
657 o->adddf = adddf;
658 o->subdf = subdf;
659 o->muldf = muldf;
660 o->divdf = divdf;
661 o->negdf = negdf;
662 o->absdf = absdf;
663 o->sqrtdf = sqrtdf;
664 o->invdf = invdf;
665 o->mindf = mindf;
666 o->maxdf = maxdf;
667 o->cmpdf = cmpdf;
668 o->eqdf = eqdf;
669 o->nedf = nedf;
670 o->ltdf = ltdf;
671 o->ledf = ledf;
672 o->gtdf = gtdf;
673 o->gedf = gedf;
674 o->floatsisf = floatsisf;
9846de1b 675 o->floatsidf = floatsidf;
3535ad49
JM
676 o->ufloatsisf = ufloatsisf;
677 o->fixsfsi = fixsfsi;
9846de1b 678 o->fixdfsi = fixdfsi;
3535ad49
JM
679 o->ufixsfsi = ufixsfsi;
680}
This page took 0.055047 seconds and 4 git commands to generate.