* config/tc-mips.c: Add define for $zero register.
[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 static sim_fpu_round
430 rounding_mode(int rm)
431 {
432 sim_fpu_round round;
433
434 switch (rm)
435 {
436 case FP_RM_NEAREST:
437 /* Round result to nearest representable value. When two
438 representable values are equally near, round to the value
439 that has a least significant bit of zero (i.e. is even). */
440 round = sim_fpu_round_near;
441 break;
442 case FP_RM_TOZERO:
443 /* Round result to the value closest to, and not greater in
444 magnitude than, the result. */
445 round = sim_fpu_round_zero;
446 break;
447 case FP_RM_TOPINF:
448 /* Round result to the value closest to, and not less than,
449 the result. */
450 round = sim_fpu_round_up;
451 break;
452 case FP_RM_TOMINF:
453 /* Round result to the value closest to, and not greater than,
454 the result. */
455 round = sim_fpu_round_down;
456 break;
457 default:
458 round = 0;
459 fprintf (stderr, "Bad switch\n");
460 abort ();
461 }
462 return round;
463 }
464
465
466 /* Comparison operations. */
467
468 static sim_fpu_status
469 fp_test(unsigned64 op1,
470 unsigned64 op2,
471 FP_formats fmt,
472 int abs,
473 int cond,
474 int *condition)
475 {
476 sim_fpu wop1;
477 sim_fpu wop2;
478 sim_fpu_status status = 0;
479 int less, equal, unordered;
480
481 /* The format type has already been checked: */
482 switch (fmt)
483 {
484 case fmt_single:
485 {
486 sim_fpu_32to (&wop1, op1);
487 sim_fpu_32to (&wop2, op2);
488 break;
489 }
490 case fmt_double:
491 {
492 sim_fpu_64to (&wop1, op1);
493 sim_fpu_64to (&wop2, op2);
494 break;
495 }
496 default:
497 fprintf (stderr, "Bad switch\n");
498 abort ();
499 }
500
501 if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
502 {
503 if ((cond & (1 << 3)) ||
504 sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
505 status = sim_fpu_status_invalid_snan;
506 less = 0;
507 equal = 0;
508 unordered = 1;
509 }
510 else
511 {
512 if (abs)
513 {
514 status |= sim_fpu_abs (&wop1, &wop1);
515 status |= sim_fpu_abs (&wop2, &wop2);
516 }
517 equal = sim_fpu_is_eq (&wop1, &wop2);
518 less = !equal && sim_fpu_is_lt (&wop1, &wop2);
519 unordered = 0;
520 }
521 *condition = (((cond & (1 << 2)) && less)
522 || ((cond & (1 << 1)) && equal)
523 || ((cond & (1 << 0)) && unordered));
524 return status;
525 }
526
527 void
528 fp_cmp(sim_cpu *cpu,
529 address_word cia,
530 unsigned64 op1,
531 unsigned64 op2,
532 FP_formats fmt,
533 int abs,
534 int cond,
535 int cc)
536 {
537 sim_fpu_status status = 0;
538
539 /* The format type should already have been checked: */
540 switch (fmt)
541 {
542 case fmt_single:
543 case fmt_double:
544 {
545 int result;
546 status = fp_test(op1, op2, fmt, abs, cond, &result);
547 update_fcsr (cpu, cia, status);
548 SETFCC (cc, result);
549 break;
550 }
551 default:
552 sim_io_eprintf (SD, "Bad switch\n");
553 abort ();
554 }
555 }
556
557
558 /* Basic arithmetic operations. */
559
560 static unsigned64
561 fp_unary(sim_cpu *cpu,
562 address_word cia,
563 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
564 unsigned64 op,
565 FP_formats fmt)
566 {
567 sim_fpu wop;
568 sim_fpu ans;
569 unsigned64 result = 0;
570
571 /* The format type has already been checked: */
572 switch (fmt)
573 {
574 case fmt_single:
575 {
576 unsigned32 res;
577 sim_fpu_32to (&wop, op);
578 (*sim_fpu_op) (&ans, &wop);
579 sim_fpu_to32 (&res, &ans);
580 result = res;
581 break;
582 }
583 case fmt_double:
584 {
585 unsigned64 res;
586 sim_fpu_64to (&wop, op);
587 (*sim_fpu_op) (&ans, &wop);
588 sim_fpu_to64 (&res, &ans);
589 result = res;
590 break;
591 }
592 default:
593 sim_io_eprintf (SD, "Bad switch\n");
594 abort ();
595 }
596
597 return result;
598 }
599
600 static unsigned64
601 fp_binary(sim_cpu *cpu,
602 address_word cia,
603 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
604 unsigned64 op1,
605 unsigned64 op2,
606 FP_formats fmt)
607 {
608 sim_fpu wop1;
609 sim_fpu wop2;
610 sim_fpu ans;
611 unsigned64 result = 0;
612
613 /* The format type has already been checked: */
614 switch (fmt)
615 {
616 case fmt_single:
617 {
618 unsigned32 res;
619 sim_fpu_32to (&wop1, op1);
620 sim_fpu_32to (&wop2, op2);
621 (*sim_fpu_op) (&ans, &wop1, &wop2);
622 sim_fpu_to32 (&res, &ans);
623 result = res;
624 break;
625 }
626 case fmt_double:
627 {
628 unsigned64 res;
629 sim_fpu_64to (&wop1, op1);
630 sim_fpu_64to (&wop2, op2);
631 (*sim_fpu_op) (&ans, &wop1, &wop2);
632 sim_fpu_to64 (&res, &ans);
633 result = res;
634 break;
635 }
636 default:
637 sim_io_eprintf (SD, "Bad switch\n");
638 abort ();
639 }
640
641 return result;
642 }
643
644
645 unsigned64
646 fp_abs(sim_cpu *cpu,
647 address_word cia,
648 unsigned64 op,
649 FP_formats fmt)
650 {
651 return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
652 }
653
654 unsigned64
655 fp_neg(sim_cpu *cpu,
656 address_word cia,
657 unsigned64 op,
658 FP_formats fmt)
659 {
660 return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
661 }
662
663 unsigned64
664 fp_add(sim_cpu *cpu,
665 address_word cia,
666 unsigned64 op1,
667 unsigned64 op2,
668 FP_formats fmt)
669 {
670 return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
671 }
672
673 unsigned64
674 fp_sub(sim_cpu *cpu,
675 address_word cia,
676 unsigned64 op1,
677 unsigned64 op2,
678 FP_formats fmt)
679 {
680 return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
681 }
682
683 unsigned64
684 fp_mul(sim_cpu *cpu,
685 address_word cia,
686 unsigned64 op1,
687 unsigned64 op2,
688 FP_formats fmt)
689 {
690 return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
691 }
692
693 unsigned64
694 fp_div(sim_cpu *cpu,
695 address_word cia,
696 unsigned64 op1,
697 unsigned64 op2,
698 FP_formats fmt)
699 {
700 return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
701 }
702
703 unsigned64
704 fp_recip(sim_cpu *cpu,
705 address_word cia,
706 unsigned64 op,
707 FP_formats fmt)
708 {
709 return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
710 }
711
712 unsigned64
713 fp_sqrt(sim_cpu *cpu,
714 address_word cia,
715 unsigned64 op,
716 FP_formats fmt)
717 {
718 return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
719 }
720
721
722 /* Conversion operations. */
723
724 uword64
725 convert (sim_cpu *cpu,
726 address_word cia,
727 int rm,
728 uword64 op,
729 FP_formats from,
730 FP_formats to)
731 {
732 sim_fpu wop;
733 sim_fpu_round round = rounding_mode (rm);
734 unsigned32 result32;
735 unsigned64 result64;
736
737 /* Convert the input to sim_fpu internal format */
738 switch (from)
739 {
740 case fmt_double:
741 sim_fpu_64to (&wop, op);
742 break;
743 case fmt_single:
744 sim_fpu_32to (&wop, op);
745 break;
746 case fmt_word:
747 sim_fpu_i32to (&wop, op, round);
748 break;
749 case fmt_long:
750 sim_fpu_i64to (&wop, op, round);
751 break;
752 default:
753 fprintf (stderr, "Bad switch\n");
754 abort ();
755 }
756
757 /* Convert sim_fpu format into the output */
758 /* The value WOP is converted to the destination format, rounding
759 using mode RM. When the destination is a fixed-point format, then
760 a source value of Infinity, NaN or one which would round to an
761 integer outside the fixed point range then an IEEE Invalid
762 Operation condition is raised. */
763 switch (to)
764 {
765 case fmt_single:
766 sim_fpu_round_32 (&wop, round, 0);
767 sim_fpu_to32 (&result32, &wop);
768 result64 = result32;
769 break;
770 case fmt_double:
771 sim_fpu_round_64 (&wop, round, 0);
772 sim_fpu_to64 (&result64, &wop);
773 break;
774 case fmt_word:
775 sim_fpu_to32i (&result32, &wop, round);
776 result64 = result32;
777 break;
778 case fmt_long:
779 sim_fpu_to64i (&result64, &wop, round);
780 break;
781 default:
782 result64 = 0;
783 fprintf (stderr, "Bad switch\n");
784 abort ();
785 }
786
787 #ifdef DEBUG
788 printf ("DBG: Convert: returning 0x%s (to format = %s)\n",
789 pr_addr (result64), fpu_format_name (to));
790 #endif /* DEBUG */
791
792 return (result64);
793 }
794
795 static const char *
796 fpu_format_name (FP_formats fmt)
797 {
798 switch (fmt)
799 {
800 case fmt_single:
801 return "single";
802 case fmt_double:
803 return "double";
804 case fmt_word:
805 return "word";
806 case fmt_long:
807 return "long";
808 case fmt_unknown:
809 return "<unknown>";
810 case fmt_uninterpreted:
811 return "<uninterpreted>";
812 case fmt_uninterpreted_32:
813 return "<uninterpreted_32>";
814 case fmt_uninterpreted_64:
815 return "<uninterpreted_64>";
816 default:
817 return "<format error>";
818 }
819 }
820
821 #ifdef DEBUG
822 static const char *
823 fpu_rounding_mode_name (int rm)
824 {
825 switch (rm)
826 {
827 case FP_RM_NEAREST:
828 return "Round";
829 case FP_RM_TOZERO:
830 return "Trunc";
831 case FP_RM_TOPINF:
832 return "Ceil";
833 case FP_RM_TOMINF:
834 return "Floor";
835 default:
836 return "<rounding mode error>";
837 }
838 }
839 #endif /* DEBUG */
This page took 0.048197 seconds and 5 git commands to generate.