e4bfba2b028a75d5fdda7618c25dc0e9502f6332
[deliverable/binutils-gdb.git] / sim / mips / cp1.c
1 /*> cp1.c <*/
2 /* MIPS Simulator FPU (CoProcessor 1) support.
3 Copyright (C) 2002 Free Software Foundation, Inc.
4 Originally created by Cygnus Solutions, modified substially
5 by Broadcom Corporation (SiByte).
6
7 This file is part of GDB, the GNU debugger.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License along
20 with this program; if not, write to the Free Software Foundation, Inc.,
21 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23 /* XXX: The following notice should be removed as soon as is practical: */
24 /* Floating Point Support for gdb MIPS simulators
25
26 This file is part of the MIPS sim
27
28 THIS SOFTWARE IS NOT COPYRIGHTED
29 (by Cygnus.)
30
31 Cygnus offers the following for use in the public domain. Cygnus
32 makes no warranty with regard to the software or it's performance
33 and the user accepts the software "AS IS" with all faults.
34
35 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
36 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
38
39 (Originally, this code was in interp.c)
40 */
41
42 #include "sim-main.h"
43
44 /* Within cp1.c we refer to sim_cpu directly. */
45 #define CPU cpu
46 #define SD CPU_STATE(cpu)
47
48 /*-- FPU support routines ---------------------------------------------------*/
49
50 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
51 formats conform to ANSI/IEEE Std 754-1985.
52
53 SINGLE precision floating:
54 seeeeeeeefffffffffffffffffffffff
55 s = 1bit = sign
56 e = 8bits = exponent
57 f = 23bits = fraction
58
59 SINGLE precision fixed:
60 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
61 s = 1bit = sign
62 i = 31bits = integer
63
64 DOUBLE precision floating:
65 seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
66 s = 1bit = sign
67 e = 11bits = exponent
68 f = 52bits = fraction
69
70 DOUBLE precision fixed:
71 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
72 s = 1bit = sign
73 i = 63bits = integer
74 */
75
76 /* Explicit QNaN values used when value required: */
77 #define FPQNaN_SINGLE (0x7FBFFFFF)
78 #define FPQNaN_WORD (0x7FFFFFFF)
79 #define FPQNaN_DOUBLE (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))
80 #define FPQNaN_LONG (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))
81
82 static const char *fpu_format_name (FP_formats fmt);
83 #ifdef DEBUG
84 static const char *fpu_rounding_mode_name (int rm);
85 #endif
86
87 uword64
88 value_fpr (sim_cpu *cpu,
89 address_word cia,
90 int fpr,
91 FP_formats fmt)
92 {
93 uword64 value = 0;
94 int err = 0;
95
96 /* Treat unused register values, as fixed-point 64bit values: */
97 if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
98 {
99 #if 1
100 /* If request to read data as "uninterpreted", then use the current
101 encoding: */
102 fmt = FPR_STATE[fpr];
103 #else
104 fmt = fmt_long;
105 #endif
106 }
107
108 /* For values not yet accessed, set to the desired format: */
109 if (FPR_STATE[fpr] == fmt_uninterpreted)
110 {
111 FPR_STATE[fpr] = fmt;
112 #ifdef DEBUG
113 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
114 fpu_format_name (fmt));
115 #endif /* DEBUG */
116 }
117 if (fmt != FPR_STATE[fpr])
118 {
119 sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
120 fpr, fpu_format_name (FPR_STATE[fpr]),
121 fpu_format_name (fmt), pr_addr (cia));
122 FPR_STATE[fpr] = fmt_unknown;
123 }
124
125 if (FPR_STATE[fpr] == fmt_unknown)
126 {
127 /* Set QNaN value: */
128 switch (fmt)
129 {
130 case fmt_single: value = FPQNaN_SINGLE; break;
131 case fmt_double: value = FPQNaN_DOUBLE; break;
132 case fmt_word: value = FPQNaN_WORD; break;
133 case fmt_long: value = FPQNaN_LONG; break;
134 default: err = -1; break;
135 }
136 }
137 else if (SizeFGR () == 64)
138 {
139 switch (fmt)
140 {
141 case fmt_single:
142 case fmt_word:
143 value = (FGR[fpr] & 0xFFFFFFFF);
144 break;
145
146 case fmt_uninterpreted:
147 case fmt_double:
148 case fmt_long:
149 value = FGR[fpr];
150 break;
151
152 default:
153 err = -1;
154 break;
155 }
156 }
157 else
158 {
159 switch (fmt)
160 {
161 case fmt_single:
162 case fmt_word:
163 value = (FGR[fpr] & 0xFFFFFFFF);
164 break;
165
166 case fmt_uninterpreted:
167 case fmt_double:
168 case fmt_long:
169 if ((fpr & 1) == 0)
170 {
171 /* Even registers numbers only. */
172 #ifdef DEBUG
173 printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
174 fpr + 1, pr_uword64 ((uword64) FGR[fpr+1]),
175 fpr, pr_uword64 ((uword64) FGR[fpr]));
176 #endif
177 value = ((((uword64) FGR[fpr+1]) << 32)
178 | (FGR[fpr] & 0xFFFFFFFF));
179 }
180 else
181 {
182 SignalException (ReservedInstruction, 0);
183 }
184 break;
185
186 default:
187 err = -1;
188 break;
189 }
190 }
191
192 if (err)
193 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
194
195 #ifdef DEBUG
196 printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",
197 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
198 SizeFGR ());
199 #endif /* DEBUG */
200
201 return (value);
202 }
203
204 void
205 store_fpr (sim_cpu *cpu,
206 address_word cia,
207 int fpr,
208 FP_formats fmt,
209 uword64 value)
210 {
211 int err = 0;
212
213 #ifdef DEBUG
214 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
215 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
216 SizeFGR ());
217 #endif /* DEBUG */
218
219 if (SizeFGR () == 64)
220 {
221 switch (fmt)
222 {
223 case fmt_uninterpreted_32:
224 fmt = fmt_uninterpreted;
225 case fmt_single:
226 case fmt_word:
227 if (STATE_VERBOSE_P (SD))
228 sim_io_eprintf (SD,
229 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
230 pr_addr (cia));
231 FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
232 FPR_STATE[fpr] = fmt;
233 break;
234
235 case fmt_uninterpreted_64:
236 fmt = fmt_uninterpreted;
237 case fmt_uninterpreted:
238 case fmt_double:
239 case fmt_long:
240 FGR[fpr] = value;
241 FPR_STATE[fpr] = fmt;
242 break;
243
244 default:
245 FPR_STATE[fpr] = fmt_unknown;
246 err = -1;
247 break;
248 }
249 }
250 else
251 {
252 switch (fmt)
253 {
254 case fmt_uninterpreted_32:
255 fmt = fmt_uninterpreted;
256 case fmt_single:
257 case fmt_word:
258 FGR[fpr] = (value & 0xFFFFFFFF);
259 FPR_STATE[fpr] = fmt;
260 break;
261
262 case fmt_uninterpreted_64:
263 fmt = fmt_uninterpreted;
264 case fmt_uninterpreted:
265 case fmt_double:
266 case fmt_long:
267 if ((fpr & 1) == 0)
268 {
269 /* Even register numbers only. */
270 FGR[fpr+1] = (value >> 32);
271 FGR[fpr] = (value & 0xFFFFFFFF);
272 FPR_STATE[fpr + 1] = fmt;
273 FPR_STATE[fpr] = fmt;
274 }
275 else
276 {
277 FPR_STATE[fpr] = fmt_unknown;
278 FPR_STATE[fpr + 1] = fmt_unknown;
279 SignalException (ReservedInstruction, 0);
280 }
281 break;
282
283 default:
284 FPR_STATE[fpr] = fmt_unknown;
285 err = -1;
286 break;
287 }
288 }
289
290 if (err)
291 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
292
293 #ifdef DEBUG
294 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
295 fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));
296 #endif /* DEBUG */
297
298 return;
299 }
300
301
302 /* CP1 control/status registers */
303
304 void
305 test_fcsr (sim_cpu *cpu,
306 address_word cia)
307 {
308 unsigned int cause;
309
310 cause = (FCSR & fcsr_CAUSE_mask) >> fcsr_CAUSE_shift;
311 if ((cause & ((FCSR & fcsr_ENABLES_mask) >> fcsr_ENABLES_shift)) != 0
312 || (cause & (1 << UO)))
313 {
314 SignalExceptionFPE();
315 }
316 }
317
318 unsigned_word
319 value_fcr(sim_cpu *cpu,
320 address_word cia,
321 int fcr)
322 {
323 unsigned32 value = 0;
324
325 switch (fcr)
326 {
327 case 0: /* FP Implementation and Revision Register */
328 value = FCR0;
329 break;
330 case 25: /* FP Condition Codes Register */
331 value = (FCR31 & fcsr_FCC_mask) >> fcsr_FCC_shift;
332 value = (value & 0x1) | (value >> 1); /* close FCC gap */
333 break;
334 case 26: /* FP Exceptions Register */
335 value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);
336 break;
337 case 28: /* FP Enables Register */
338 value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);
339 if (FCR31 & fcsr_FS)
340 value |= 0x4; /* nonstandard FS bit */
341 break;
342 case 31: /* FP Control/Status Register */
343 value = FCR31 & ~fcsr_ZERO_mask;
344 break;
345 }
346
347 return (EXTEND32 (value));
348 }
349
350 void
351 store_fcr(sim_cpu *cpu,
352 address_word cia,
353 int fcr,
354 unsigned_word value)
355 {
356 unsigned32 v;
357
358 v = VL4_8(value);
359 switch (fcr)
360 {
361 case 25: /* FP Condition Codes Register */
362 v = (v << 1) | (v & 0x1); /* adjust for FCC gap */
363 FCR31 &= ~fcsr_FCC_mask;
364 FCR31 |= ((v << fcsr_FCC_shift) & fcsr_FCC_mask);
365 break;
366 case 26: /* FP Exceptions Register */
367 FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);
368 FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));
369 test_fcsr(cpu, cia);
370 break;
371 case 28: /* FP Enables Register */
372 if (v & 0x4) /* nonstandard FS bit */
373 v |= fcsr_FS;
374 else
375 v &= ~fcsr_FS;
376 FCR31 &= (fcsr_FCC_mask | fcsr_CAUSE_mask | fcsr_FLAGS_mask);
377 FCR31 |= (v & (fcsr_FS | fcsr_ENABLES_mask | fcsr_RM_mask));
378 test_fcsr(cpu, cia);
379 break;
380 case 31: /* FP Control/Status Register */
381 FCR31 = v & ~fcsr_ZERO_mask;
382 test_fcsr(cpu, cia);
383 break;
384 }
385 }
386
387 void
388 update_fcsr (sim_cpu *cpu,
389 address_word cia,
390 sim_fpu_status status)
391 {
392 FCSR &= ~fcsr_CAUSE_mask;
393
394 if (status != 0)
395 {
396 unsigned int cause = 0;
397
398 /* map between sim_fpu codes and MIPS FCSR */
399 if (status & (sim_fpu_status_invalid_snan
400 | sim_fpu_status_invalid_isi
401 | sim_fpu_status_invalid_idi
402 | sim_fpu_status_invalid_zdz
403 | sim_fpu_status_invalid_imz
404 | sim_fpu_status_invalid_cmp
405 | sim_fpu_status_invalid_sqrt
406 | sim_fpu_status_invalid_cvi))
407 cause |= (1 << IO);
408 if (status & sim_fpu_status_invalid_div0)
409 cause |= (1 << DZ);
410 if (status & sim_fpu_status_overflow)
411 cause |= (1 << OF);
412 if (status & sim_fpu_status_underflow)
413 cause |= (1 << UF);
414 if (status & sim_fpu_status_inexact)
415 cause |= (1 << IR);
416 #if 0 /* Not yet. */
417 /* Implicit clearing of other bits by unimplemented done by callers. */
418 if (status & sim_fpu_status_unimplemented)
419 cause |= (1 << UO);
420 #endif
421
422 FCSR |= (cause << fcsr_CAUSE_shift);
423 test_fcsr (cpu, cia);
424 FCSR |= ((cause & ~(1 << UO)) << fcsr_FLAGS_shift);
425 }
426 return;
427 }
428
429
430 /* Comparison operations. */
431
432 static sim_fpu_status
433 fp_test(unsigned64 op1,
434 unsigned64 op2,
435 FP_formats fmt,
436 int abs,
437 int cond,
438 int *condition)
439 {
440 sim_fpu wop1;
441 sim_fpu wop2;
442 sim_fpu_status status = 0;
443 int less, equal, unordered;
444
445 /* The format type has already been checked: */
446 switch (fmt)
447 {
448 case fmt_single:
449 {
450 sim_fpu_32to (&wop1, op1);
451 sim_fpu_32to (&wop2, op2);
452 break;
453 }
454 case fmt_double:
455 {
456 sim_fpu_64to (&wop1, op1);
457 sim_fpu_64to (&wop2, op2);
458 break;
459 }
460 default:
461 fprintf (stderr, "Bad switch\n");
462 abort ();
463 }
464
465 if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
466 {
467 if ((cond & (1 << 3)) ||
468 sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
469 status = sim_fpu_status_invalid_snan;
470 less = 0;
471 equal = 0;
472 unordered = 1;
473 }
474 else
475 {
476 if (abs)
477 {
478 status |= sim_fpu_abs (&wop1, &wop1);
479 status |= sim_fpu_abs (&wop2, &wop2);
480 }
481 equal = sim_fpu_is_eq (&wop1, &wop2);
482 less = !equal && sim_fpu_is_lt (&wop1, &wop2);
483 unordered = 0;
484 }
485 *condition = (((cond & (1 << 2)) && less)
486 || ((cond & (1 << 1)) && equal)
487 || ((cond & (1 << 0)) && unordered));
488 return status;
489 }
490
491 void
492 fp_cmp(sim_cpu *cpu,
493 address_word cia,
494 unsigned64 op1,
495 unsigned64 op2,
496 FP_formats fmt,
497 int abs,
498 int cond,
499 int cc)
500 {
501 sim_fpu_status status = 0;
502
503 /* The format type should already have been checked: */
504 switch (fmt)
505 {
506 case fmt_single:
507 case fmt_double:
508 {
509 int result;
510 status = fp_test(op1, op2, fmt, abs, cond, &result);
511 update_fcsr (cpu, cia, status);
512 SETFCC (cc, result);
513 break;
514 }
515 default:
516 sim_io_eprintf (SD, "Bad switch\n");
517 abort ();
518 }
519 }
520
521
522 /* Basic arithmetic operations. */
523
524 static unsigned64
525 fp_unary(sim_cpu *cpu,
526 address_word cia,
527 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
528 unsigned64 op,
529 FP_formats fmt)
530 {
531 sim_fpu wop;
532 sim_fpu ans;
533 unsigned64 result = 0;
534
535 /* The format type has already been checked: */
536 switch (fmt)
537 {
538 case fmt_single:
539 {
540 unsigned32 res;
541 sim_fpu_32to (&wop, op);
542 (*sim_fpu_op) (&ans, &wop);
543 sim_fpu_to32 (&res, &ans);
544 result = res;
545 break;
546 }
547 case fmt_double:
548 {
549 unsigned64 res;
550 sim_fpu_64to (&wop, op);
551 (*sim_fpu_op) (&ans, &wop);
552 sim_fpu_to64 (&res, &ans);
553 result = res;
554 break;
555 }
556 default:
557 sim_io_eprintf (SD, "Bad switch\n");
558 abort ();
559 }
560
561 return result;
562 }
563
564 static unsigned64
565 fp_binary(sim_cpu *cpu,
566 address_word cia,
567 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
568 unsigned64 op1,
569 unsigned64 op2,
570 FP_formats fmt)
571 {
572 sim_fpu wop1;
573 sim_fpu wop2;
574 sim_fpu ans;
575 unsigned64 result = 0;
576
577 /* The format type has already been checked: */
578 switch (fmt)
579 {
580 case fmt_single:
581 {
582 unsigned32 res;
583 sim_fpu_32to (&wop1, op1);
584 sim_fpu_32to (&wop2, op2);
585 (*sim_fpu_op) (&ans, &wop1, &wop2);
586 sim_fpu_to32 (&res, &ans);
587 result = res;
588 break;
589 }
590 case fmt_double:
591 {
592 unsigned64 res;
593 sim_fpu_64to (&wop1, op1);
594 sim_fpu_64to (&wop2, op2);
595 (*sim_fpu_op) (&ans, &wop1, &wop2);
596 sim_fpu_to64 (&res, &ans);
597 result = res;
598 break;
599 }
600 default:
601 sim_io_eprintf (SD, "Bad switch\n");
602 abort ();
603 }
604
605 return result;
606 }
607
608
609 unsigned64
610 fp_abs(sim_cpu *cpu,
611 address_word cia,
612 unsigned64 op,
613 FP_formats fmt)
614 {
615 return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
616 }
617
618 unsigned64
619 fp_neg(sim_cpu *cpu,
620 address_word cia,
621 unsigned64 op,
622 FP_formats fmt)
623 {
624 return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
625 }
626
627 unsigned64
628 fp_add(sim_cpu *cpu,
629 address_word cia,
630 unsigned64 op1,
631 unsigned64 op2,
632 FP_formats fmt)
633 {
634 return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
635 }
636
637 unsigned64
638 fp_sub(sim_cpu *cpu,
639 address_word cia,
640 unsigned64 op1,
641 unsigned64 op2,
642 FP_formats fmt)
643 {
644 return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
645 }
646
647 unsigned64
648 fp_mul(sim_cpu *cpu,
649 address_word cia,
650 unsigned64 op1,
651 unsigned64 op2,
652 FP_formats fmt)
653 {
654 return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
655 }
656
657 unsigned64
658 fp_div(sim_cpu *cpu,
659 address_word cia,
660 unsigned64 op1,
661 unsigned64 op2,
662 FP_formats fmt)
663 {
664 return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
665 }
666
667 unsigned64
668 fp_recip(sim_cpu *cpu,
669 address_word cia,
670 unsigned64 op,
671 FP_formats fmt)
672 {
673 return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
674 }
675
676 unsigned64
677 fp_sqrt(sim_cpu *cpu,
678 address_word cia,
679 unsigned64 op,
680 FP_formats fmt)
681 {
682 return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
683 }
684
685
686 /* Conversion operations. */
687
688 uword64
689 convert (sim_cpu *cpu,
690 address_word cia,
691 int rm,
692 uword64 op,
693 FP_formats from,
694 FP_formats to)
695 {
696 sim_fpu wop;
697 sim_fpu_round round;
698 unsigned32 result32;
699 unsigned64 result64;
700
701 #ifdef DEBUG
702 #if 0 /* FIXME: doesn't compile */
703 printf ("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",
704 fpu_rounding_mode_name (rm), pr_addr (op), fpu_format_name (from),
705 fpu_format_name (to), pr_addr (IPC));
706 #endif
707 #endif /* DEBUG */
708
709 switch (rm)
710 {
711 case FP_RM_NEAREST:
712 /* Round result to nearest representable value. When two
713 representable values are equally near, round to the value
714 that has a least significant bit of zero (i.e. is even). */
715 round = sim_fpu_round_near;
716 break;
717 case FP_RM_TOZERO:
718 /* Round result to the value closest to, and not greater in
719 magnitude than, the result. */
720 round = sim_fpu_round_zero;
721 break;
722 case FP_RM_TOPINF:
723 /* Round result to the value closest to, and not less than,
724 the result. */
725 round = sim_fpu_round_up;
726 break;
727
728 case FP_RM_TOMINF:
729 /* Round result to the value closest to, and not greater than,
730 the result. */
731 round = sim_fpu_round_down;
732 break;
733 default:
734 round = 0;
735 fprintf (stderr, "Bad switch\n");
736 abort ();
737 }
738
739 /* Convert the input to sim_fpu internal format */
740 switch (from)
741 {
742 case fmt_double:
743 sim_fpu_64to (&wop, op);
744 break;
745 case fmt_single:
746 sim_fpu_32to (&wop, op);
747 break;
748 case fmt_word:
749 sim_fpu_i32to (&wop, op, round);
750 break;
751 case fmt_long:
752 sim_fpu_i64to (&wop, op, round);
753 break;
754 default:
755 fprintf (stderr, "Bad switch\n");
756 abort ();
757 }
758
759 /* Convert sim_fpu format into the output */
760 /* The value WOP is converted to the destination format, rounding
761 using mode RM. When the destination is a fixed-point format, then
762 a source value of Infinity, NaN or one which would round to an
763 integer outside the fixed point range then an IEEE Invalid
764 Operation condition is raised. */
765 switch (to)
766 {
767 case fmt_single:
768 sim_fpu_round_32 (&wop, round, 0);
769 sim_fpu_to32 (&result32, &wop);
770 result64 = result32;
771 break;
772 case fmt_double:
773 sim_fpu_round_64 (&wop, round, 0);
774 sim_fpu_to64 (&result64, &wop);
775 break;
776 case fmt_word:
777 sim_fpu_to32i (&result32, &wop, round);
778 result64 = result32;
779 break;
780 case fmt_long:
781 sim_fpu_to64i (&result64, &wop, round);
782 break;
783 default:
784 result64 = 0;
785 fprintf (stderr, "Bad switch\n");
786 abort ();
787 }
788
789 #ifdef DEBUG
790 printf ("DBG: Convert: returning 0x%s (to format = %s)\n",
791 pr_addr (result64), fpu_format_name (to));
792 #endif /* DEBUG */
793
794 return (result64);
795 }
796
797 static const char *
798 fpu_format_name (FP_formats fmt)
799 {
800 switch (fmt)
801 {
802 case fmt_single:
803 return "single";
804 case fmt_double:
805 return "double";
806 case fmt_word:
807 return "word";
808 case fmt_long:
809 return "long";
810 case fmt_unknown:
811 return "<unknown>";
812 case fmt_uninterpreted:
813 return "<uninterpreted>";
814 case fmt_uninterpreted_32:
815 return "<uninterpreted_32>";
816 case fmt_uninterpreted_64:
817 return "<uninterpreted_64>";
818 default:
819 return "<format error>";
820 }
821 }
822
823 #ifdef DEBUG
824 static const char *
825 fpu_rounding_mode_name (int rm)
826 {
827 switch (rm)
828 {
829 case FP_RM_NEAREST:
830 return "Round";
831 case FP_RM_TOZERO:
832 return "Trunc";
833 case FP_RM_TOPINF:
834 return "Ceil";
835 case FP_RM_TOMINF:
836 return "Floor";
837 default:
838 return "<rounding mode error>";
839 }
840 }
841 #endif /* DEBUG */
This page took 0.044922 seconds and 4 git commands to generate.