2 /* Floating Point Support for gdb MIPS simulators
4 This file is part of the MIPS sim
6 THIS SOFTWARE IS NOT COPYRIGHTED
8 Cygnus offers the following for use in the public domain. Cygnus
9 makes no warranty with regard to the software or it's performance
10 and the user accepts the software "AS IS" with all faults.
12 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
13 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 (Originally, this code was in interp.c)
22 /* Within cp1.c we refer to sim_cpu directly. */
24 #define SD CPU_STATE(cpu)
26 /*-- FPU support routines ---------------------------------------------------*/
28 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
29 formats conform to ANSI/IEEE Std 754-1985.
31 SINGLE precision floating:
32 seeeeeeeefffffffffffffffffffffff
37 SINGLE precision fixed:
38 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
42 DOUBLE precision floating:
43 seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
48 DOUBLE precision fixed:
49 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
54 /* Explicit QNaN values used when value required: */
55 #define FPQNaN_SINGLE (0x7FBFFFFF)
56 #define FPQNaN_WORD (0x7FFFFFFF)
57 #define FPQNaN_DOUBLE (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))
58 #define FPQNaN_LONG (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))
60 static const char *fpu_format_name (FP_formats fmt);
62 static const char *fpu_rounding_mode_name (int rm);
66 value_fpr (sim_cpu *cpu,
74 /* Treat unused register values, as fixed-point 64bit values: */
75 if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
78 /* If request to read data as "uninterpreted", then use the current
86 /* For values not yet accessed, set to the desired format: */
87 if (FPR_STATE[fpr] == fmt_uninterpreted)
91 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
92 fpu_format_name (fmt));
95 if (fmt != FPR_STATE[fpr])
97 sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
98 fpr, fpu_format_name (FPR_STATE[fpr]),
99 fpu_format_name (fmt), pr_addr (cia));
100 FPR_STATE[fpr] = fmt_unknown;
103 if (FPR_STATE[fpr] == fmt_unknown)
105 /* Set QNaN value: */
109 value = FPQNaN_SINGLE;
113 value = FPQNaN_DOUBLE;
129 else if (SizeFGR () == 64)
135 value = (FGR[fpr] & 0xFFFFFFFF);
138 case fmt_uninterpreted:
155 value = (FGR[fpr] & 0xFFFFFFFF);
158 case fmt_uninterpreted:
163 /* even registers only */
165 printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
166 fpr + 1, pr_uword64 ((uword64) FGR[fpr+1]),
167 fpr, pr_uword64 ((uword64) FGR[fpr]));
169 value = ((((uword64) FGR[fpr+1]) << 32)
170 | (FGR[fpr] & 0xFFFFFFFF));
174 SignalException (ReservedInstruction, 0);
185 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
188 printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",
189 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
197 store_fpr (sim_cpu *cpu,
206 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
207 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
211 if (SizeFGR () == 64)
215 case fmt_uninterpreted_32:
216 fmt = fmt_uninterpreted;
219 if (STATE_VERBOSE_P (SD))
221 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
223 FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
224 FPR_STATE[fpr] = fmt;
227 case fmt_uninterpreted_64:
228 fmt = fmt_uninterpreted;
229 case fmt_uninterpreted:
233 FPR_STATE[fpr] = fmt;
237 FPR_STATE[fpr] = fmt_unknown;
246 case fmt_uninterpreted_32:
247 fmt = fmt_uninterpreted;
250 FGR[fpr] = (value & 0xFFFFFFFF);
251 FPR_STATE[fpr] = fmt;
254 case fmt_uninterpreted_64:
255 fmt = fmt_uninterpreted;
256 case fmt_uninterpreted:
261 /* even register number only */
262 FGR[fpr+1] = (value >> 32);
263 FGR[fpr] = (value & 0xFFFFFFFF);
264 FPR_STATE[fpr + 1] = fmt;
265 FPR_STATE[fpr] = fmt;
269 FPR_STATE[fpr] = fmt_unknown;
270 FPR_STATE[fpr + 1] = fmt_unknown;
271 SignalException (ReservedInstruction, 0);
276 FPR_STATE[fpr] = fmt_unknown;
283 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
286 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
287 fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));
305 sim_fpu_32to (&wop, op);
306 boolean = sim_fpu_is_nan (&wop);
313 sim_fpu_64to (&wop, op);
314 boolean = sim_fpu_is_nan (&wop);
318 fprintf (stderr, "Bad switch\n");
323 printf ("DBG: NaN: returning %d for 0x%s (format = %s)\n",
324 boolean, pr_addr (op), fpu_format_name (fmt));
338 /* Argument checking already performed by the FPCOMPARE code */
341 printf ("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",
342 fpu_format_name (fmt), pr_addr (op1), pr_addr (op2));
345 /* The format type should already have been checked: */
352 sim_fpu_32to (&wop1, op1);
353 sim_fpu_32to (&wop2, op2);
354 boolean = sim_fpu_is_lt (&wop1, &wop2);
361 sim_fpu_64to (&wop1, op1);
362 sim_fpu_64to (&wop2, op2);
363 boolean = sim_fpu_is_lt (&wop1, &wop2);
367 fprintf (stderr, "Bad switch\n");
372 printf ("DBG: Less: returning %d (format = %s)\n",
373 boolean, fpu_format_name (fmt));
380 Equal (op1, op2, fmt)
387 /* Argument checking already performed by the FPCOMPARE code */
390 printf ("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",
391 fpu_format_name (fmt), pr_addr (op1), pr_addr (op2));
394 /* The format type should already have been checked: */
401 sim_fpu_32to (&wop1, op1);
402 sim_fpu_32to (&wop2, op2);
403 boolean = sim_fpu_is_eq (&wop1, &wop2);
410 sim_fpu_64to (&wop1, op1);
411 sim_fpu_64to (&wop2, op2);
412 boolean = sim_fpu_is_eq (&wop1, &wop2);
416 fprintf (stderr, "Bad switch\n");
421 printf ("DBG: Equal: returning %d (format = %s)\n",
422 boolean, fpu_format_name (fmt));
429 /* Basic arithmetic operations. */
432 fp_unary(sim_cpu *cpu,
434 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
440 unsigned64 result = 0;
442 /* The format type has already been checked: */
448 sim_fpu_32to (&wop, op);
449 (*sim_fpu_op) (&ans, &wop);
450 sim_fpu_to32 (&res, &ans);
457 sim_fpu_64to (&wop, op);
458 (*sim_fpu_op) (&ans, &wop);
459 sim_fpu_to64 (&res, &ans);
464 sim_io_eprintf (SD, "Bad switch\n");
472 fp_binary(sim_cpu *cpu,
474 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
482 unsigned64 result = 0;
484 /* The format type has already been checked: */
490 sim_fpu_32to (&wop1, op1);
491 sim_fpu_32to (&wop2, op2);
492 (*sim_fpu_op) (&ans, &wop1, &wop2);
493 sim_fpu_to32 (&res, &ans);
500 sim_fpu_64to (&wop1, op1);
501 sim_fpu_64to (&wop2, op2);
502 (*sim_fpu_op) (&ans, &wop1, &wop2);
503 sim_fpu_to64 (&res, &ans);
508 sim_io_eprintf (SD, "Bad switch\n");
522 return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
531 return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
541 return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
551 return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
561 return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
571 return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
575 fp_recip(sim_cpu *cpu,
580 return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
584 fp_sqrt(sim_cpu *cpu,
589 return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
594 convert (sim_cpu *cpu,
607 #if 0 /* FIXME: doesn't compile */
608 printf ("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",
609 fpu_rounding_mode_name (rm), pr_addr (op), fpu_format_name (from),
610 fpu_format_name (to), pr_addr (IPC));
617 /* Round result to nearest representable value. When two
618 representable values are equally near, round to the value
619 that has a least significant bit of zero (i.e. is even). */
620 round = sim_fpu_round_near;
623 /* Round result to the value closest to, and not greater in
624 magnitude than, the result. */
625 round = sim_fpu_round_zero;
628 /* Round result to the value closest to, and not less than,
630 round = sim_fpu_round_up;
634 /* Round result to the value closest to, and not greater than,
636 round = sim_fpu_round_down;
640 fprintf (stderr, "Bad switch\n");
644 /* Convert the input to sim_fpu internal format */
648 sim_fpu_64to (&wop, op);
651 sim_fpu_32to (&wop, op);
654 sim_fpu_i32to (&wop, op, round);
657 sim_fpu_i64to (&wop, op, round);
660 fprintf (stderr, "Bad switch\n");
664 /* Convert sim_fpu format into the output */
665 /* The value WOP is converted to the destination format, rounding
666 using mode RM. When the destination is a fixed-point format, then
667 a source value of Infinity, NaN or one which would round to an
668 integer outside the fixed point range then an IEEE Invalid
669 Operation condition is raised. */
673 sim_fpu_round_32 (&wop, round, 0);
674 sim_fpu_to32 (&result32, &wop);
678 sim_fpu_round_64 (&wop, round, 0);
679 sim_fpu_to64 (&result64, &wop);
682 sim_fpu_to32i (&result32, &wop, round);
686 sim_fpu_to64i (&result64, &wop, round);
690 fprintf (stderr, "Bad switch\n");
695 printf ("DBG: Convert: returning 0x%s (to format = %s)\n",
696 pr_addr (result64), fpu_format_name (to));
703 fpu_format_name (FP_formats fmt)
717 case fmt_uninterpreted:
718 return "<uninterpreted>";
719 case fmt_uninterpreted_32:
720 return "<uninterpreted_32>";
721 case fmt_uninterpreted_64:
722 return "<uninterpreted_64>";
724 return "<format error>";
730 fpu_rounding_mode_name (int rm)
743 return "<rounding mode error>";