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). Paired-single operation support
6 and MIPS-3D support contributed by Broadcom Corporation (SiByte).
8 This file is part of GDB, the GNU debugger.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License along
21 with this program; if not, write to the Free Software Foundation, Inc.,
22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 /* XXX: The following notice should be removed as soon as is practical: */
25 /* Floating Point Support for gdb MIPS simulators
27 This file is part of the MIPS sim
29 THIS SOFTWARE IS NOT COPYRIGHTED
32 Cygnus offers the following for use in the public domain. Cygnus
33 makes no warranty with regard to the software or it's performance
34 and the user accepts the software "AS IS" with all faults.
36 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
37 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
38 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
40 (Originally, this code was in interp.c)
45 /* Within cp1.c we refer to sim_cpu directly. */
47 #define SD CPU_STATE(cpu)
49 /*-- FPU support routines ---------------------------------------------------*/
51 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
52 formats conform to ANSI/IEEE Std 754-1985.
54 SINGLE precision floating:
55 seeeeeeeefffffffffffffffffffffff
60 SINGLE precision fixed:
61 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
65 DOUBLE precision floating:
66 seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
71 DOUBLE precision fixed:
72 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
76 PAIRED SINGLE precision floating:
77 seeeeeeeefffffffffffffffffffffffseeeeeeeefffffffffffffffffffffff
82 Note: upper = [63..32], lower = [31..0]
85 /* Extract packed single values: */
86 #define FP_PS_upper(v) (((v) >> 32) & (unsigned)0xFFFFFFFF)
87 #define FP_PS_lower(v) ((v) & (unsigned)0xFFFFFFFF)
88 #define FP_PS_cat(u,l) (((unsigned64)((u) & (unsigned)0xFFFFFFFF) << 32) \
89 | (unsigned64)((l) & 0xFFFFFFFF))
91 /* Explicit QNaN values. */
92 #define FPQNaN_SINGLE (0x7FBFFFFF)
93 #define FPQNaN_WORD (0x7FFFFFFF)
94 #define FPQNaN_DOUBLE (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))
95 #define FPQNaN_LONG (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))
96 #define FPQNaN_PS (FP_PS_cat (FPQNaN_SINGLE, FPQNaN_SINGLE))
98 static const char *fpu_format_name (FP_formats fmt);
100 static const char *fpu_rounding_mode_name (int rm);
104 value_fpr (sim_cpu *cpu,
112 /* Treat unused register values, as fixed-point 64bit values. */
113 if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
116 /* If request to read data as "uninterpreted", then use the current
118 fmt = FPR_STATE[fpr];
124 /* For values not yet accessed, set to the desired format. */
125 if (FPR_STATE[fpr] == fmt_uninterpreted)
127 FPR_STATE[fpr] = fmt;
129 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
130 fpu_format_name (fmt));
133 if (fmt != FPR_STATE[fpr])
135 sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
136 fpr, fpu_format_name (FPR_STATE[fpr]),
137 fpu_format_name (fmt), pr_addr (cia));
138 FPR_STATE[fpr] = fmt_unknown;
141 if (FPR_STATE[fpr] == fmt_unknown)
143 /* Set QNaN value: */
146 case fmt_single: value = FPQNaN_SINGLE; break;
147 case fmt_double: value = FPQNaN_DOUBLE; break;
148 case fmt_word: value = FPQNaN_WORD; break;
149 case fmt_long: value = FPQNaN_LONG; break;
150 case fmt_ps: value = FPQNaN_PS; break;
151 default: err = -1; break;
154 else if (SizeFGR () == 64)
160 value = (FGR[fpr] & 0xFFFFFFFF);
163 case fmt_uninterpreted:
181 value = (FGR[fpr] & 0xFFFFFFFF);
184 case fmt_uninterpreted:
189 /* Even register numbers only. */
191 printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
192 fpr + 1, pr_uword64 ((uword64) FGR[fpr+1]),
193 fpr, pr_uword64 ((uword64) FGR[fpr]));
195 value = ((((uword64) FGR[fpr+1]) << 32)
196 | (FGR[fpr] & 0xFFFFFFFF));
200 SignalException (ReservedInstruction, 0);
205 SignalException (ReservedInstruction, 0);
215 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
218 printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",
219 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
227 store_fpr (sim_cpu *cpu,
236 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
237 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
241 if (SizeFGR () == 64)
245 case fmt_uninterpreted_32:
246 fmt = fmt_uninterpreted;
249 if (STATE_VERBOSE_P (SD))
251 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
253 FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
254 FPR_STATE[fpr] = fmt;
257 case fmt_uninterpreted_64:
258 fmt = fmt_uninterpreted;
259 case fmt_uninterpreted:
264 FPR_STATE[fpr] = fmt;
268 FPR_STATE[fpr] = fmt_unknown;
277 case fmt_uninterpreted_32:
278 fmt = fmt_uninterpreted;
281 FGR[fpr] = (value & 0xFFFFFFFF);
282 FPR_STATE[fpr] = fmt;
285 case fmt_uninterpreted_64:
286 fmt = fmt_uninterpreted;
287 case fmt_uninterpreted:
292 /* Even register numbers only. */
293 FGR[fpr+1] = (value >> 32);
294 FGR[fpr] = (value & 0xFFFFFFFF);
295 FPR_STATE[fpr + 1] = fmt;
296 FPR_STATE[fpr] = fmt;
300 FPR_STATE[fpr] = fmt_unknown;
301 FPR_STATE[fpr + 1] = fmt_unknown;
302 SignalException (ReservedInstruction, 0);
307 FPR_STATE[fpr] = fmt_unknown;
308 SignalException (ReservedInstruction, 0);
312 FPR_STATE[fpr] = fmt_unknown;
319 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
322 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
323 fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));
330 /* CP1 control/status register access functions. */
333 test_fcsr (sim_cpu *cpu,
338 cause = (FCSR & fcsr_CAUSE_mask) >> fcsr_CAUSE_shift;
339 if ((cause & ((FCSR & fcsr_ENABLES_mask) >> fcsr_ENABLES_shift)) != 0
340 || (cause & (1 << UO)))
342 SignalExceptionFPE();
347 value_fcr(sim_cpu *cpu,
351 unsigned32 value = 0;
355 case 0: /* FP Implementation and Revision Register. */
358 case 25: /* FP Condition Codes Register (derived from FCSR). */
359 value = (FCR31 & fcsr_FCC_mask) >> fcsr_FCC_shift;
360 value = (value & 0x1) | (value >> 1); /* Close FCC gap. */
362 case 26: /* FP Exceptions Register (derived from FCSR). */
363 value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);
365 case 28: /* FP Enables Register (derived from FCSR). */
366 value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);
367 if ((FCR31 & fcsr_FS) != 0)
370 case 31: /* FP Control/Status Register (FCSR). */
371 value = FCR31 & ~fcsr_ZERO_mask;
375 return (EXTEND32 (value));
379 store_fcr(sim_cpu *cpu,
389 case 25: /* FP Condition Codes Register (stored into FCSR). */
390 v = (v << 1) | (v & 0x1); /* Adjust for FCC gap. */
391 FCR31 &= ~fcsr_FCC_mask;
392 FCR31 |= ((v << fcsr_FCC_shift) & fcsr_FCC_mask);
394 case 26: /* FP Exceptions Register (stored into FCSR). */
395 FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);
396 FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));
399 case 28: /* FP Enables Register (stored into FCSR). */
400 if ((v & fenr_FS) != 0)
404 FCR31 &= (fcsr_FCC_mask | fcsr_CAUSE_mask | fcsr_FLAGS_mask);
405 FCR31 |= (v & (fcsr_FS | fcsr_ENABLES_mask | fcsr_RM_mask));
408 case 31: /* FP Control/Status Register (FCSR). */
409 FCR31 = v & ~fcsr_ZERO_mask;
416 update_fcsr (sim_cpu *cpu,
418 sim_fpu_status status)
420 FCSR &= ~fcsr_CAUSE_mask;
424 unsigned int cause = 0;
426 /* map between sim_fpu codes and MIPS FCSR */
427 if (status & (sim_fpu_status_invalid_snan
428 | sim_fpu_status_invalid_isi
429 | sim_fpu_status_invalid_idi
430 | sim_fpu_status_invalid_zdz
431 | sim_fpu_status_invalid_imz
432 | sim_fpu_status_invalid_cmp
433 | sim_fpu_status_invalid_sqrt
434 | sim_fpu_status_invalid_cvi))
436 if (status & sim_fpu_status_invalid_div0)
438 if (status & sim_fpu_status_overflow)
440 if (status & sim_fpu_status_underflow)
442 if (status & sim_fpu_status_inexact)
445 /* Implicit clearing of other bits by unimplemented done by callers. */
446 if (status & sim_fpu_status_unimplemented)
450 FCSR |= (cause << fcsr_CAUSE_shift);
451 test_fcsr (cpu, cia);
452 FCSR |= ((cause & ~(1 << UO)) << fcsr_FLAGS_shift);
458 rounding_mode(int rm)
465 /* Round result to nearest representable value. When two
466 representable values are equally near, round to the value
467 that has a least significant bit of zero (i.e. is even). */
468 round = sim_fpu_round_near;
471 /* Round result to the value closest to, and not greater in
472 magnitude than, the result. */
473 round = sim_fpu_round_zero;
476 /* Round result to the value closest to, and not less than,
478 round = sim_fpu_round_up;
481 /* Round result to the value closest to, and not greater than,
483 round = sim_fpu_round_down;
487 fprintf (stderr, "Bad switch\n");
493 /* When the FS bit is set, MIPS processors return zero for
494 denormalized results and optionally replace denormalized inputs
495 with zero. When FS is clear, some implementation trap on input
496 and/or output, while other perform the operation in hardware. */
497 static sim_fpu_denorm
498 denorm_mode(sim_cpu *cpu)
500 sim_fpu_denorm denorm;
502 /* XXX: FIXME: Eventually should be CPU model dependent. */
504 denorm = sim_fpu_denorm_zero;
511 /* Comparison operations. */
513 static sim_fpu_status
514 fp_test(unsigned64 op1,
523 sim_fpu_status status = 0;
524 int less, equal, unordered;
526 /* The format type has already been checked: */
531 sim_fpu_32to (&wop1, op1);
532 sim_fpu_32to (&wop2, op2);
537 sim_fpu_64to (&wop1, op1);
538 sim_fpu_64to (&wop2, op2);
542 fprintf (stderr, "Bad switch\n");
546 if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
548 if ((cond & (1 << 3)) ||
549 sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
550 status = sim_fpu_status_invalid_snan;
559 status |= sim_fpu_abs (&wop1, &wop1);
560 status |= sim_fpu_abs (&wop2, &wop2);
562 equal = sim_fpu_is_eq (&wop1, &wop2);
563 less = !equal && sim_fpu_is_lt (&wop1, &wop2);
566 *condition = (((cond & (1 << 2)) && less)
567 || ((cond & (1 << 1)) && equal)
568 || ((cond & (1 << 0)) && unordered));
582 sim_fpu_status status = 0;
584 /* The format type should already have been checked. The FCSR is
585 updated before the condition codes so that any exceptions will
586 be signalled before the condition codes are changed. */
593 status = fp_test(op1, op2, fmt, abs, cond, &result);
594 update_fcsr (cpu, cia, status);
600 int result0, result1;
601 status = fp_test(FP_PS_lower (op1), FP_PS_lower (op2), fmt_single,
602 abs, cond, &result0);
603 status |= fp_test(FP_PS_upper (op1), FP_PS_upper (op2), fmt_single,
604 abs, cond, &result1);
605 update_fcsr (cpu, cia, status);
606 SETFCC (cc, result0);
607 SETFCC (cc+1, result1);
611 sim_io_eprintf (SD, "Bad switch\n");
617 /* Basic arithmetic operations. */
620 fp_unary(sim_cpu *cpu,
622 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
628 sim_fpu_round round = rounding_mode (GETRM());
629 sim_fpu_denorm denorm = denorm_mode (cpu);
630 sim_fpu_status status = 0;
631 unsigned64 result = 0;
633 /* The format type has already been checked: */
639 sim_fpu_32to (&wop, op);
640 status |= (*sim_fpu_op) (&ans, &wop);
641 status |= sim_fpu_round_32 (&ans, round, denorm);
642 sim_fpu_to32 (&res, &ans);
649 sim_fpu_64to (&wop, op);
650 status |= (*sim_fpu_op) (&ans, &wop);
651 status |= sim_fpu_round_64 (&ans, round, denorm);
652 sim_fpu_to64 (&res, &ans);
658 int status_u = 0, status_l = 0;
659 unsigned32 res_u, res_l;
660 sim_fpu_32to (&wop, FP_PS_upper(op));
661 status_u |= (*sim_fpu_op) (&ans, &wop);
662 sim_fpu_to32 (&res_u, &ans);
663 sim_fpu_32to (&wop, FP_PS_lower(op));
664 status_l |= (*sim_fpu_op) (&ans, &wop);
665 sim_fpu_to32 (&res_l, &ans);
666 result = FP_PS_cat(res_u, res_l);
667 status = status_u | status_l;
671 sim_io_eprintf (SD, "Bad switch\n");
675 update_fcsr (cpu, cia, status);
680 fp_binary(sim_cpu *cpu,
682 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
690 sim_fpu_round round = rounding_mode (GETRM());
691 sim_fpu_denorm denorm = denorm_mode (cpu);
692 sim_fpu_status status = 0;
693 unsigned64 result = 0;
695 /* The format type has already been checked: */
701 sim_fpu_32to (&wop1, op1);
702 sim_fpu_32to (&wop2, op2);
703 status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
704 status |= sim_fpu_round_32 (&ans, round, denorm);
705 sim_fpu_to32 (&res, &ans);
712 sim_fpu_64to (&wop1, op1);
713 sim_fpu_64to (&wop2, op2);
714 status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
715 status |= sim_fpu_round_64 (&ans, round, denorm);
716 sim_fpu_to64 (&res, &ans);
722 int status_u = 0, status_l = 0;
723 unsigned32 res_u, res_l;
724 sim_fpu_32to (&wop1, FP_PS_upper(op1));
725 sim_fpu_32to (&wop2, FP_PS_upper(op2));
726 status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
727 sim_fpu_to32 (&res_u, &ans);
728 sim_fpu_32to (&wop1, FP_PS_lower(op1));
729 sim_fpu_32to (&wop2, FP_PS_lower(op2));
730 status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
731 sim_fpu_to32 (&res_l, &ans);
732 result = FP_PS_cat(res_u, res_l);
733 status = status_u | status_l;
737 sim_io_eprintf (SD, "Bad switch\n");
741 update_fcsr (cpu, cia, status);
745 /* Common MAC code for single operands (.s or .d), defers setting FCSR. */
746 static sim_fpu_status
747 inner_mac(int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
755 sim_fpu_denorm denorm,
761 sim_fpu_status status = 0;
762 sim_fpu_status op_status;
770 sim_fpu_32to (&wop1, op1);
771 sim_fpu_32to (&wop2, op2);
772 status |= sim_fpu_mul (&ans, &wop1, &wop2);
773 if (scale != 0 && sim_fpu_is_number (&ans)) /* number or denorm */
774 ans.normal_exp += scale;
775 status |= sim_fpu_round_32 (&ans, round, denorm);
778 sim_fpu_32to (&wop2, op3);
779 op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
780 op_status |= sim_fpu_round_32 (&ans, round, denorm);
785 op_status = sim_fpu_neg (&ans, &wop1);
786 op_status |= sim_fpu_round_32 (&ans, round, denorm);
789 sim_fpu_to32 (&res, &ans);
796 sim_fpu_64to (&wop1, op1);
797 sim_fpu_64to (&wop2, op2);
798 status |= sim_fpu_mul (&ans, &wop1, &wop2);
799 if (scale != 0 && sim_fpu_is_number (&ans)) /* number or denorm */
800 ans.normal_exp += scale;
801 status |= sim_fpu_round_64 (&ans, round, denorm);
804 sim_fpu_64to (&wop2, op3);
805 op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
806 op_status |= sim_fpu_round_64 (&ans, round, denorm);
811 op_status = sim_fpu_neg (&ans, &wop1);
812 op_status |= sim_fpu_round_64 (&ans, round, denorm);
815 sim_fpu_to64 (&res, &ans);
820 fprintf (stderr, "Bad switch\n");
827 /* Common implementation of madd, nmadd, msub, nmsub that does
828 intermediate rounding per spec. Also used for recip2 and rsqrt2,
829 which are transformed into equivalent nmsub operations. The scale
830 argument is an adjustment to the exponent of the intermediate
831 product op1*op2. It is currently non-zero for rsqrt2 (-1), which
832 requires an effective division by 2. */
836 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
844 sim_fpu_round round = rounding_mode (GETRM());
845 sim_fpu_denorm denorm = denorm_mode (cpu);
846 sim_fpu_status status = 0;
847 unsigned64 result = 0;
849 /* The format type has already been checked: */
854 status = inner_mac(sim_fpu_op, op1, op2, op3, scale,
855 negate, fmt, round, denorm, &result);
859 int status_u, status_l;
860 unsigned64 result_u, result_l;
861 status_u = inner_mac(sim_fpu_op, FP_PS_upper(op1), FP_PS_upper(op2),
862 FP_PS_upper(op3), scale, negate, fmt_single,
863 round, denorm, &result_u);
864 status_l = inner_mac(sim_fpu_op, FP_PS_lower(op1), FP_PS_lower(op2),
865 FP_PS_lower(op3), scale, negate, fmt_single,
866 round, denorm, &result_l);
867 result = FP_PS_cat(result_u, result_l);
868 status = status_u | status_l;
872 sim_io_eprintf (SD, "Bad switch\n");
876 update_fcsr (cpu, cia, status);
880 /* Common rsqrt code for single operands (.s or .d), intermediate rounding. */
881 static sim_fpu_status
882 inner_rsqrt(unsigned64 op1,
885 sim_fpu_denorm denorm,
890 sim_fpu_status status = 0;
891 sim_fpu_status op_status;
899 sim_fpu_32to (&wop1, op1);
900 status |= sim_fpu_sqrt (&ans, &wop1);
901 status |= sim_fpu_round_32 (&ans, status, round);
903 op_status = sim_fpu_inv (&ans, &wop1);
904 op_status |= sim_fpu_round_32 (&ans, round, denorm);
905 sim_fpu_to32 (&res, &ans);
913 sim_fpu_64to (&wop1, op1);
914 status |= sim_fpu_sqrt (&ans, &wop1);
915 status |= sim_fpu_round_64 (&ans, round, denorm);
917 op_status = sim_fpu_inv (&ans, &wop1);
918 op_status |= sim_fpu_round_64 (&ans, round, denorm);
919 sim_fpu_to64 (&res, &ans);
925 fprintf (stderr, "Bad switch\n");
933 fp_inv_sqrt(sim_cpu *cpu,
938 sim_fpu_round round = rounding_mode (GETRM());
939 sim_fpu_round denorm = denorm_mode (cpu);
940 sim_fpu_status status = 0;
941 unsigned64 result = 0;
943 /* The format type has already been checked: */
948 status = inner_rsqrt (op1, fmt, round, denorm, &result);
952 int status_u, status_l;
953 unsigned64 result_u, result_l;
954 status_u = inner_rsqrt (FP_PS_upper(op1), fmt_single, round, denorm,
956 status_l = inner_rsqrt (FP_PS_lower(op1), fmt_single, round, denorm,
958 result = FP_PS_cat(result_u, result_l);
959 status = status_u | status_l;
963 sim_io_eprintf (SD, "Bad switch\n");
967 update_fcsr (cpu, cia, status);
978 return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
987 return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
997 return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
1001 fp_sub(sim_cpu *cpu,
1007 return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
1011 fp_mul(sim_cpu *cpu,
1017 return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
1021 fp_div(sim_cpu *cpu,
1027 return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
1031 fp_recip(sim_cpu *cpu,
1036 return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
1040 fp_sqrt(sim_cpu *cpu,
1045 return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
1049 fp_rsqrt(sim_cpu *cpu,
1054 return fp_inv_sqrt(cpu, cia, op, fmt);
1058 fp_madd(sim_cpu *cpu,
1065 return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 0, fmt);
1069 fp_msub(sim_cpu *cpu,
1076 return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 0, fmt);
1080 fp_nmadd(sim_cpu *cpu,
1087 return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 1, fmt);
1091 fp_nmsub(sim_cpu *cpu,
1098 return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 1, fmt);
1102 /* MIPS-3D ASE operations. */
1104 /* Variant of fp_binary for *r.ps MIPS-3D operations. */
1106 fp_binary_r(sim_cpu *cpu,
1108 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
1115 sim_fpu_round round = rounding_mode (GETRM ());
1116 sim_fpu_denorm denorm = denorm_mode (cpu);
1117 sim_fpu_status status_u, status_l;
1119 unsigned32 res_u, res_l;
1121 /* The format must be fmt_ps. */
1123 sim_fpu_32to (&wop1, FP_PS_upper (op1));
1124 sim_fpu_32to (&wop2, FP_PS_lower (op1));
1125 status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
1126 status_u |= sim_fpu_round_32 (&ans, round, denorm);
1127 sim_fpu_to32 (&res_u, &ans);
1129 sim_fpu_32to (&wop1, FP_PS_upper (op2));
1130 sim_fpu_32to (&wop2, FP_PS_lower (op2));
1131 status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
1132 status_l |= sim_fpu_round_32 (&ans, round, denorm);
1133 sim_fpu_to32 (&res_l, &ans);
1134 result = FP_PS_cat (res_u, res_l);
1136 update_fcsr (cpu, cia, status_u | status_l);
1141 fp_add_r(sim_cpu *cpu,
1147 return fp_binary_r (cpu, cia, &sim_fpu_add, op1, op2);
1151 fp_mul_r(sim_cpu *cpu,
1157 return fp_binary_r (cpu, cia, &sim_fpu_mul, op1, op2);
1160 #define NR_FRAC_GUARD (60)
1161 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
1164 fpu_inv1(sim_fpu *f, const sim_fpu *l)
1166 static const sim_fpu sim_fpu_one = {
1167 sim_fpu_class_number, 0, IMPLICIT_1, 0
1172 if (sim_fpu_is_zero (l))
1176 return sim_fpu_status_invalid_div0;
1178 if (sim_fpu_is_infinity (l))
1184 status |= sim_fpu_div (f, &sim_fpu_one, l);
1189 fpu_inv1_32(sim_fpu *f, const sim_fpu *l)
1191 if (sim_fpu_is_zero (l))
1195 return sim_fpu_status_invalid_div0;
1197 return fpu_inv1 (f, l);
1201 fpu_inv1_64(sim_fpu *f, const sim_fpu *l)
1203 if (sim_fpu_is_zero (l))
1207 return sim_fpu_status_invalid_div0;
1209 return fpu_inv1 (f, l);
1213 fp_recip1(sim_cpu *cpu,
1222 return fp_unary (cpu, cia, &fpu_inv1_32, op, fmt);
1224 return fp_unary (cpu, cia, &fpu_inv1_64, op, fmt);
1230 fp_recip2(sim_cpu *cpu,
1236 static const unsigned64 one_single = UNSIGNED64 (0x3F800000);
1237 static const unsigned64 one_double = UNSIGNED64 (0x3FF0000000000000);
1238 static const unsigned64 one_ps = (UNSIGNED64 (0x3F800000) << 32 | UNSIGNED64 (0x3F800000));
1241 /* Implemented as nmsub fd, 1, fs, ft. */
1244 case fmt_single: one = one_single; break;
1245 case fmt_double: one = one_double; break;
1246 case fmt_ps: one = one_ps; break;
1247 default: one = 0; abort ();
1249 return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, one, 0, 1, fmt);
1253 fpu_inv_sqrt1(sim_fpu *f, const sim_fpu *l)
1255 static const sim_fpu sim_fpu_one = {
1256 sim_fpu_class_number, 0, IMPLICIT_1, 0
1261 if (sim_fpu_is_zero (l))
1265 return sim_fpu_status_invalid_div0;
1267 if (sim_fpu_is_infinity (l))
1271 f->class = sim_fpu_class_zero;
1277 status = sim_fpu_status_invalid_sqrt;
1281 status |= sim_fpu_sqrt (&t, l);
1282 status |= sim_fpu_div (f, &sim_fpu_one, &t);
1287 fpu_inv_sqrt1_32(sim_fpu *f, const sim_fpu *l)
1289 if (sim_fpu_is_zero (l))
1293 return sim_fpu_status_invalid_div0;
1295 return fpu_inv_sqrt1 (f, l);
1299 fpu_inv_sqrt1_64(sim_fpu *f, const sim_fpu *l)
1301 if (sim_fpu_is_zero (l))
1305 return sim_fpu_status_invalid_div0;
1307 return fpu_inv_sqrt1 (f, l);
1311 fp_rsqrt1(sim_cpu *cpu,
1320 return fp_unary (cpu, cia, &fpu_inv_sqrt1_32, op, fmt);
1322 return fp_unary (cpu, cia, &fpu_inv_sqrt1_64, op, fmt);
1328 fp_rsqrt2(sim_cpu *cpu,
1334 static const unsigned64 half_single = UNSIGNED64 (0x3F000000);
1335 static const unsigned64 half_double = UNSIGNED64 (0x3FE0000000000000);
1336 static const unsigned64 half_ps = (UNSIGNED64 (0x3F000000) << 32 | UNSIGNED64 (0x3F000000));
1339 /* Implemented as (nmsub fd, 0.5, fs, ft)/2, where the divide is
1340 done by scaling the exponent during multiply. */
1343 case fmt_single: half = half_single; break;
1344 case fmt_double: half = half_double; break;
1345 case fmt_ps: half = half_ps; break;
1346 default: half = 0; abort ();
1348 return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, half, -1, 1, fmt);
1352 /* Conversion operations. */
1355 convert (sim_cpu *cpu,
1363 sim_fpu_round round = rounding_mode (rm);
1364 sim_fpu_denorm denorm = denorm_mode (cpu);
1365 unsigned32 result32;
1366 unsigned64 result64;
1367 sim_fpu_status status = 0;
1369 /* Convert the input to sim_fpu internal format */
1373 sim_fpu_64to (&wop, op);
1376 sim_fpu_32to (&wop, op);
1379 status = sim_fpu_i32to (&wop, op, round);
1382 status = sim_fpu_i64to (&wop, op, round);
1385 sim_io_eprintf (SD, "Bad switch\n");
1389 /* Convert sim_fpu format into the output */
1390 /* The value WOP is converted to the destination format, rounding
1391 using mode RM. When the destination is a fixed-point format, then
1392 a source value of Infinity, NaN or one which would round to an
1393 integer outside the fixed point range then an IEEE Invalid Operation
1394 condition is raised. Not used if destination format is PS. */
1398 status |= sim_fpu_round_32 (&wop, round, denorm);
1399 /* For a NaN, normalize mantissa bits (cvt.s.d can't preserve them) */
1400 if (sim_fpu_is_qnan (&wop))
1402 sim_fpu_to32 (&result32, &wop);
1403 result64 = result32;
1406 status |= sim_fpu_round_64 (&wop, round, denorm);
1407 /* For a NaN, normalize mantissa bits (make cvt.d.s consistent) */
1408 if (sim_fpu_is_qnan (&wop))
1410 sim_fpu_to64 (&result64, &wop);
1413 status |= sim_fpu_to32i (&result32, &wop, round);
1414 result64 = result32;
1417 status |= sim_fpu_to64i (&result64, &wop, round);
1421 sim_io_eprintf (SD, "Bad switch\n");
1425 update_fcsr (cpu, cia, status);
1430 ps_lower(sim_cpu *cpu,
1434 return FP_PS_lower (op);
1438 ps_upper(sim_cpu *cpu,
1442 return FP_PS_upper(op);
1446 pack_ps(sim_cpu *cpu,
1452 unsigned64 result = 0;
1454 /* The registers must specify FPRs valid for operands of type
1455 "fmt". If they are not valid, the result is undefined. */
1457 /* The format type should already have been checked: */
1463 unsigned32 res_u, res_l;
1464 sim_fpu_32to (&wop, op1);
1465 sim_fpu_to32 (&res_u, &wop);
1466 sim_fpu_32to (&wop, op2);
1467 sim_fpu_to32 (&res_l, &wop);
1468 result = FP_PS_cat(res_u, res_l);
1472 sim_io_eprintf (SD, "Bad switch\n");
1480 convert_ps (sim_cpu *cpu,
1487 sim_fpu wop_u, wop_l;
1488 sim_fpu_round round = rounding_mode (rm);
1489 sim_fpu_denorm denorm = denorm_mode (cpu);
1490 unsigned32 res_u, res_l;
1492 sim_fpu_status status_u = 0, status_l = 0;
1494 /* As convert, but used only for paired values (formats PS, PW) */
1496 /* Convert the input to sim_fpu internal format */
1499 case fmt_word: /* fmt_pw */
1500 sim_fpu_i32to (&wop_u, (op >> 32) & (unsigned)0xFFFFFFFF, round);
1501 sim_fpu_i32to (&wop_l, op & (unsigned)0xFFFFFFFF, round);
1504 sim_fpu_32to (&wop_u, FP_PS_upper(op));
1505 sim_fpu_32to (&wop_l, FP_PS_lower(op));
1508 sim_io_eprintf (SD, "Bad switch\n");
1512 /* Convert sim_fpu format into the output */
1515 case fmt_word: /* fmt_pw */
1516 status_u |= sim_fpu_to32i (&res_u, &wop_u, round);
1517 status_l |= sim_fpu_to32i (&res_l, &wop_l, round);
1518 result = (((unsigned64)res_u) << 32) | (unsigned64)res_l;
1521 status_u |= sim_fpu_round_32 (&wop_u, 0, round);
1522 status_l |= sim_fpu_round_32 (&wop_l, 0, round);
1523 sim_fpu_to32 (&res_u, &wop_u);
1524 sim_fpu_to32 (&res_l, &wop_l);
1525 result = FP_PS_cat(res_u, res_l);
1529 sim_io_eprintf (SD, "Bad switch\n");
1533 update_fcsr (cpu, cia, status_u | status_l);
1538 fpu_format_name (FP_formats fmt)
1554 case fmt_uninterpreted:
1555 return "<uninterpreted>";
1556 case fmt_uninterpreted_32:
1557 return "<uninterpreted_32>";
1558 case fmt_uninterpreted_64:
1559 return "<uninterpreted_64>";
1561 return "<format error>";
1567 fpu_rounding_mode_name (int rm)
1580 return "<rounding mode error>";