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. */
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 register 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 register access functions. */
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 (derived from FCSR). */
331 value = (FCR31 & fcsr_FCC_mask) >> fcsr_FCC_shift;
332 value = (value & 0x1) | (value >> 1); /* Close FCC gap. */
334 case 26: /* FP Exceptions Register (derived from FCSR). */
335 value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);
337 case 28: /* FP Enables Register (derived from FCSR). */
338 value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);
339 if ((FCR31 & fcsr_FS) != 0)
342 case 31: /* FP Control/Status Register (FCSR). */
343 value = FCR31 & ~fcsr_ZERO_mask;
347 return (EXTEND32 (value));
351 store_fcr(sim_cpu *cpu,
361 case 25: /* FP Condition Codes Register (stored into FCSR). */
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 (stored into FCSR). */
367 FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);
368 FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));
371 case 28: /* FP Enables Register (stored into FCSR). */
372 if ((v & fenr_FS) != 0)
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 (FCSR). */
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 rounding_mode(int rm)
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;
443 /* Round result to the value closest to, and not greater in
444 magnitude than, the result. */
445 round = sim_fpu_round_zero;
448 /* Round result to the value closest to, and not less than,
450 round = sim_fpu_round_up;
453 /* Round result to the value closest to, and not greater than,
455 round = sim_fpu_round_down;
459 fprintf (stderr, "Bad switch\n");
465 /* When the FS bit is set, MIPS processors return zero for
466 denormalized results and optionally replace denormalized inputs
467 with zero. When FS is clear, some implementation trap on input
468 and/or output, while other perform the operation in hardware. */
469 static sim_fpu_denorm
470 denorm_mode(sim_cpu *cpu)
472 sim_fpu_denorm denorm;
474 /* XXX: FIXME: Eventually should be CPU model dependent. */
476 denorm = sim_fpu_denorm_zero;
483 /* Comparison operations. */
485 static sim_fpu_status
486 fp_test(unsigned64 op1,
495 sim_fpu_status status = 0;
496 int less, equal, unordered;
498 /* The format type has already been checked: */
503 sim_fpu_32to (&wop1, op1);
504 sim_fpu_32to (&wop2, op2);
509 sim_fpu_64to (&wop1, op1);
510 sim_fpu_64to (&wop2, op2);
514 fprintf (stderr, "Bad switch\n");
518 if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
520 if ((cond & (1 << 3)) ||
521 sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
522 status = sim_fpu_status_invalid_snan;
531 status |= sim_fpu_abs (&wop1, &wop1);
532 status |= sim_fpu_abs (&wop2, &wop2);
534 equal = sim_fpu_is_eq (&wop1, &wop2);
535 less = !equal && sim_fpu_is_lt (&wop1, &wop2);
538 *condition = (((cond & (1 << 2)) && less)
539 || ((cond & (1 << 1)) && equal)
540 || ((cond & (1 << 0)) && unordered));
554 sim_fpu_status status = 0;
556 /* The format type should already have been checked. The FCSR is
557 updated before the condition codes so that any exceptions will
558 be signalled before the condition codes are changed. */
565 status = fp_test(op1, op2, fmt, abs, cond, &result);
566 update_fcsr (cpu, cia, status);
571 sim_io_eprintf (SD, "Bad switch\n");
577 /* Basic arithmetic operations. */
580 fp_unary(sim_cpu *cpu,
582 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
588 sim_fpu_round round = rounding_mode (GETRM());
589 sim_fpu_denorm denorm = denorm_mode (cpu);
590 sim_fpu_status status = 0;
591 unsigned64 result = 0;
593 /* The format type has already been checked: */
599 sim_fpu_32to (&wop, op);
600 status |= (*sim_fpu_op) (&ans, &wop);
601 status |= sim_fpu_round_32 (&ans, round, denorm);
602 sim_fpu_to32 (&res, &ans);
609 sim_fpu_64to (&wop, op);
610 status |= (*sim_fpu_op) (&ans, &wop);
611 status |= sim_fpu_round_64 (&ans, round, denorm);
612 sim_fpu_to64 (&res, &ans);
617 sim_io_eprintf (SD, "Bad switch\n");
621 update_fcsr (cpu, cia, status);
626 fp_binary(sim_cpu *cpu,
628 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
636 sim_fpu_round round = rounding_mode (GETRM());
637 sim_fpu_denorm denorm = denorm_mode (cpu);
638 sim_fpu_status status = 0;
639 unsigned64 result = 0;
641 /* The format type has already been checked: */
647 sim_fpu_32to (&wop1, op1);
648 sim_fpu_32to (&wop2, op2);
649 status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
650 status |= sim_fpu_round_32 (&ans, round, denorm);
651 sim_fpu_to32 (&res, &ans);
658 sim_fpu_64to (&wop1, op1);
659 sim_fpu_64to (&wop2, op2);
660 status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
661 status |= sim_fpu_round_64 (&ans, round, denorm);
662 sim_fpu_to64 (&res, &ans);
667 sim_io_eprintf (SD, "Bad switch\n");
671 update_fcsr (cpu, cia, status);
682 return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
691 return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
701 return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
711 return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
721 return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
731 return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
735 fp_recip(sim_cpu *cpu,
740 return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
744 fp_sqrt(sim_cpu *cpu,
749 return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
753 /* Conversion operations. */
756 convert (sim_cpu *cpu,
764 sim_fpu_round round = rounding_mode (rm);
765 sim_fpu_denorm denorm = denorm_mode (cpu);
768 sim_fpu_status status = 0;
770 /* Convert the input to sim_fpu internal format */
774 sim_fpu_64to (&wop, op);
777 sim_fpu_32to (&wop, op);
780 status = sim_fpu_i32to (&wop, op, round);
783 status = sim_fpu_i64to (&wop, op, round);
786 sim_io_eprintf (SD, "Bad switch\n");
790 /* Convert sim_fpu format into the output */
791 /* The value WOP is converted to the destination format, rounding
792 using mode RM. When the destination is a fixed-point format, then
793 a source value of Infinity, NaN or one which would round to an
794 integer outside the fixed point range then an IEEE Invalid
795 Operation condition is raised. */
799 status |= sim_fpu_round_32 (&wop, round, denorm);
800 /* For a NaN, normalize mantissa bits (cvt.s.d can't preserve them) */
801 if (sim_fpu_is_qnan (&wop))
803 sim_fpu_to32 (&result32, &wop);
807 status |= sim_fpu_round_64 (&wop, round, denorm);
808 /* For a NaN, normalize mantissa bits (make cvt.d.s consistent) */
809 if (sim_fpu_is_qnan (&wop))
811 sim_fpu_to64 (&result64, &wop);
814 status |= sim_fpu_to32i (&result32, &wop, round);
818 status |= sim_fpu_to64i (&result64, &wop, round);
822 sim_io_eprintf (SD, "Bad switch\n");
826 update_fcsr (cpu, cia, status);
831 fpu_format_name (FP_formats fmt)
845 case fmt_uninterpreted:
846 return "<uninterpreted>";
847 case fmt_uninterpreted_32:
848 return "<uninterpreted_32>";
849 case fmt_uninterpreted_64:
850 return "<uninterpreted_64>";
852 return "<format error>";
858 fpu_rounding_mode_name (int rm)
871 return "<rounding mode error>";