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).
7 This file is part of GDB, the GNU debugger.
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)
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.
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. */
23 /* XXX: The following notice should be removed as soon as is practical: */
24 /* Floating Point Support for gdb MIPS simulators
26 This file is part of the MIPS sim
28 THIS SOFTWARE IS NOT COPYRIGHTED
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.
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.
39 (Originally, this code was in interp.c)
44 /* Within cp1.c we refer to sim_cpu directly. */
46 #define SD CPU_STATE(cpu)
48 /*-- FPU support routines ---------------------------------------------------*/
50 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
51 formats conform to ANSI/IEEE Std 754-1985.
53 SINGLE precision floating:
54 seeeeeeeefffffffffffffffffffffff
59 SINGLE precision fixed:
60 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
64 DOUBLE precision floating:
65 seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
70 DOUBLE precision fixed:
71 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
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))
82 static const char *fpu_format_name (FP_formats fmt);
84 static const char *fpu_rounding_mode_name (int rm);
88 value_fpr (sim_cpu *cpu,
96 /* Treat unused register values, as fixed-point 64bit values: */
97 if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
100 /* If request to read data as "uninterpreted", then use the current
102 fmt = FPR_STATE[fpr];
108 /* For values not yet accessed, set to the desired format: */
109 if (FPR_STATE[fpr] == fmt_uninterpreted)
111 FPR_STATE[fpr] = fmt;
113 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
114 fpu_format_name (fmt));
117 if (fmt != FPR_STATE[fpr])
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;
125 if (FPR_STATE[fpr] == fmt_unknown)
127 /* Set QNaN value: */
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;
137 else if (SizeFGR () == 64)
143 value = (FGR[fpr] & 0xFFFFFFFF);
146 case fmt_uninterpreted:
163 value = (FGR[fpr] & 0xFFFFFFFF);
166 case fmt_uninterpreted:
171 /* Even registers numbers only. */
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]));
177 value = ((((uword64) FGR[fpr+1]) << 32)
178 | (FGR[fpr] & 0xFFFFFFFF));
182 SignalException (ReservedInstruction, 0);
193 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
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),
205 store_fpr (sim_cpu *cpu,
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),
219 if (SizeFGR () == 64)
223 case fmt_uninterpreted_32:
224 fmt = fmt_uninterpreted;
227 if (STATE_VERBOSE_P (SD))
229 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
231 FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
232 FPR_STATE[fpr] = fmt;
235 case fmt_uninterpreted_64:
236 fmt = fmt_uninterpreted;
237 case fmt_uninterpreted:
241 FPR_STATE[fpr] = fmt;
245 FPR_STATE[fpr] = fmt_unknown;
254 case fmt_uninterpreted_32:
255 fmt = fmt_uninterpreted;
258 FGR[fpr] = (value & 0xFFFFFFFF);
259 FPR_STATE[fpr] = fmt;
262 case fmt_uninterpreted_64:
263 fmt = fmt_uninterpreted;
264 case fmt_uninterpreted:
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;
277 FPR_STATE[fpr] = fmt_unknown;
278 FPR_STATE[fpr + 1] = fmt_unknown;
279 SignalException (ReservedInstruction, 0);
284 FPR_STATE[fpr] = fmt_unknown;
291 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
294 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
295 fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));
302 /* CP1 control/status registers */
305 test_fcsr (sim_cpu *cpu,
310 cause = (FCSR & fcsr_CAUSE_mask) >> fcsr_CAUSE_shift;
311 if ((cause & ((FCSR & fcsr_ENABLES_mask) >> fcsr_ENABLES_shift)) != 0
312 || (cause & (1 << UO)))
314 SignalExceptionFPE();
319 value_fcr(sim_cpu *cpu,
323 unsigned32 value = 0;
327 case 0: /* FP Implementation and Revision Register */
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 */
334 case 26: /* FP Exceptions Register */
335 value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);
337 case 28: /* FP Enables Register */
338 value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);
340 value |= 0x4; /* nonstandard FS bit */
342 case 31: /* FP Control/Status Register */
343 value = FCR31 & ~fcsr_ZERO_mask;
347 return (EXTEND32 (value));
351 store_fcr(sim_cpu *cpu,
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);
366 case 26: /* FP Exceptions Register */
367 FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);
368 FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));
371 case 28: /* FP Enables Register */
372 if (v & 0x4) /* nonstandard FS bit */
376 FCR31 &= (fcsr_FCC_mask | fcsr_CAUSE_mask | fcsr_FLAGS_mask);
377 FCR31 |= (v & (fcsr_FS | fcsr_ENABLES_mask | fcsr_RM_mask));
380 case 31: /* FP Control/Status Register */
381 FCR31 = v & ~fcsr_ZERO_mask;
388 update_fcsr (sim_cpu *cpu,
390 sim_fpu_status status)
392 FCSR &= ~fcsr_CAUSE_mask;
396 unsigned int cause = 0;
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))
408 if (status & sim_fpu_status_invalid_div0)
410 if (status & sim_fpu_status_overflow)
412 if (status & sim_fpu_status_underflow)
414 if (status & sim_fpu_status_inexact)
417 /* Implicit clearing of other bits by unimplemented done by callers. */
418 if (status & sim_fpu_status_unimplemented)
422 FCSR |= (cause << fcsr_CAUSE_shift);
423 test_fcsr (cpu, cia);
424 FCSR |= ((cause & ~(1 << UO)) << fcsr_FLAGS_shift);
430 /* Comparison operations. */
432 static sim_fpu_status
433 fp_test(unsigned64 op1,
442 sim_fpu_status status = 0;
443 int less, equal, unordered;
445 /* The format type has already been checked: */
450 sim_fpu_32to (&wop1, op1);
451 sim_fpu_32to (&wop2, op2);
456 sim_fpu_64to (&wop1, op1);
457 sim_fpu_64to (&wop2, op2);
461 fprintf (stderr, "Bad switch\n");
465 if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
467 if ((cond & (1 << 3)) ||
468 sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
469 status = sim_fpu_status_invalid_snan;
478 status |= sim_fpu_abs (&wop1, &wop1);
479 status |= sim_fpu_abs (&wop2, &wop2);
481 equal = sim_fpu_is_eq (&wop1, &wop2);
482 less = !equal && sim_fpu_is_lt (&wop1, &wop2);
485 *condition = (((cond & (1 << 2)) && less)
486 || ((cond & (1 << 1)) && equal)
487 || ((cond & (1 << 0)) && unordered));
501 sim_fpu_status status = 0;
503 /* The format type should already have been checked: */
510 status = fp_test(op1, op2, fmt, abs, cond, &result);
511 update_fcsr (cpu, cia, status);
516 sim_io_eprintf (SD, "Bad switch\n");
522 /* Basic arithmetic operations. */
525 fp_unary(sim_cpu *cpu,
527 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
533 unsigned64 result = 0;
535 /* The format type has already been checked: */
541 sim_fpu_32to (&wop, op);
542 (*sim_fpu_op) (&ans, &wop);
543 sim_fpu_to32 (&res, &ans);
550 sim_fpu_64to (&wop, op);
551 (*sim_fpu_op) (&ans, &wop);
552 sim_fpu_to64 (&res, &ans);
557 sim_io_eprintf (SD, "Bad switch\n");
565 fp_binary(sim_cpu *cpu,
567 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
575 unsigned64 result = 0;
577 /* The format type has already been checked: */
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);
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);
601 sim_io_eprintf (SD, "Bad switch\n");
615 return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
624 return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
634 return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
644 return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
654 return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
664 return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
668 fp_recip(sim_cpu *cpu,
673 return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
677 fp_sqrt(sim_cpu *cpu,
682 return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
686 /* Conversion operations. */
689 convert (sim_cpu *cpu,
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));
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;
718 /* Round result to the value closest to, and not greater in
719 magnitude than, the result. */
720 round = sim_fpu_round_zero;
723 /* Round result to the value closest to, and not less than,
725 round = sim_fpu_round_up;
729 /* Round result to the value closest to, and not greater than,
731 round = sim_fpu_round_down;
735 fprintf (stderr, "Bad switch\n");
739 /* Convert the input to sim_fpu internal format */
743 sim_fpu_64to (&wop, op);
746 sim_fpu_32to (&wop, op);
749 sim_fpu_i32to (&wop, op, round);
752 sim_fpu_i64to (&wop, op, round);
755 fprintf (stderr, "Bad switch\n");
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. */
768 sim_fpu_round_32 (&wop, round, 0);
769 sim_fpu_to32 (&result32, &wop);
773 sim_fpu_round_64 (&wop, round, 0);
774 sim_fpu_to64 (&result64, &wop);
777 sim_fpu_to32i (&result32, &wop, round);
781 sim_fpu_to64i (&result64, &wop, round);
785 fprintf (stderr, "Bad switch\n");
790 printf ("DBG: Convert: returning 0x%s (to format = %s)\n",
791 pr_addr (result64), fpu_format_name (to));
798 fpu_format_name (FP_formats fmt)
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>";
819 return "<format error>";
825 fpu_rounding_mode_name (int rm)
838 return "<rounding mode error>";