2 /* MIPS Simulator FPU (CoProcessor 1) support.
3 Copyright (C) 2002 Free Software Foundation, Inc.
4 Originally created by Cygnus Solutions. Extensive modifications,
5 including paired-single operation support and MIPS-3D support
6 contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom
9 This file is part of GDB, the GNU debugger.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License along
22 with this program; if not, write to the Free Software Foundation, Inc.,
23 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 /* XXX: The following notice should be removed as soon as is practical: */
26 /* Floating Point Support for gdb MIPS simulators
28 This file is part of the MIPS sim
30 THIS SOFTWARE IS NOT COPYRIGHTED
33 Cygnus offers the following for use in the public domain. Cygnus
34 makes no warranty with regard to the software or it's performance
35 and the user accepts the software "AS IS" with all faults.
37 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
38 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
41 (Originally, this code was in interp.c)
46 /* Within cp1.c we refer to sim_cpu directly. */
48 #define SD CPU_STATE(cpu)
50 /*-- FPU support routines ---------------------------------------------------*/
52 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
53 formats conform to ANSI/IEEE Std 754-1985.
55 SINGLE precision floating:
56 seeeeeeeefffffffffffffffffffffff
61 SINGLE precision fixed:
62 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
66 DOUBLE precision floating:
67 seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
72 DOUBLE precision fixed:
73 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
77 PAIRED SINGLE precision floating:
78 seeeeeeeefffffffffffffffffffffffseeeeeeeefffffffffffffffffffffff
83 Note: upper = [63..32], lower = [31..0]
86 /* Extract packed single values: */
87 #define FP_PS_upper(v) (((v) >> 32) & (unsigned)0xFFFFFFFF)
88 #define FP_PS_lower(v) ((v) & (unsigned)0xFFFFFFFF)
89 #define FP_PS_cat(u,l) (((unsigned64)((u) & (unsigned)0xFFFFFFFF) << 32) \
90 | (unsigned64)((l) & 0xFFFFFFFF))
92 /* Explicit QNaN values. */
93 #define FPQNaN_SINGLE (0x7FBFFFFF)
94 #define FPQNaN_WORD (0x7FFFFFFF)
95 #define FPQNaN_DOUBLE (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))
96 #define FPQNaN_LONG (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))
97 #define FPQNaN_PS (FP_PS_cat (FPQNaN_SINGLE, FPQNaN_SINGLE))
99 static const char *fpu_format_name (FP_formats fmt
);
101 static const char *fpu_rounding_mode_name (int rm
);
105 value_fpr (sim_cpu
*cpu
,
113 /* Treat unused register values, as fixed-point 64bit values. */
114 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
117 /* If request to read data as "uninterpreted", then use the current
119 fmt
= FPR_STATE
[fpr
];
125 /* For values not yet accessed, set to the desired format. */
126 if (FPR_STATE
[fpr
] == fmt_uninterpreted
)
128 FPR_STATE
[fpr
] = fmt
;
130 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr
,
131 fpu_format_name (fmt
));
134 if (fmt
!= FPR_STATE
[fpr
])
136 sim_io_eprintf (SD
, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
137 fpr
, fpu_format_name (FPR_STATE
[fpr
]),
138 fpu_format_name (fmt
), pr_addr (cia
));
139 FPR_STATE
[fpr
] = fmt_unknown
;
142 if (FPR_STATE
[fpr
] == fmt_unknown
)
144 /* Set QNaN value: */
147 case fmt_single
: value
= FPQNaN_SINGLE
; break;
148 case fmt_double
: value
= FPQNaN_DOUBLE
; break;
149 case fmt_word
: value
= FPQNaN_WORD
; break;
150 case fmt_long
: value
= FPQNaN_LONG
; break;
151 case fmt_ps
: value
= FPQNaN_PS
; break;
152 default: err
= -1; break;
155 else if (SizeFGR () == 64)
161 value
= (FGR
[fpr
] & 0xFFFFFFFF);
164 case fmt_uninterpreted
:
182 value
= (FGR
[fpr
] & 0xFFFFFFFF);
185 case fmt_uninterpreted
:
190 /* Even register numbers only. */
192 printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
193 fpr
+ 1, pr_uword64 ((uword64
) FGR
[fpr
+1]),
194 fpr
, pr_uword64 ((uword64
) FGR
[fpr
]));
196 value
= ((((uword64
) FGR
[fpr
+1]) << 32)
197 | (FGR
[fpr
] & 0xFFFFFFFF));
201 SignalException (ReservedInstruction
, 0);
206 SignalException (ReservedInstruction
, 0);
216 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
219 printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",
220 fpr
, fpu_format_name (fmt
), pr_uword64 (value
), pr_addr (cia
),
228 store_fpr (sim_cpu
*cpu
,
237 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
238 fpr
, fpu_format_name (fmt
), pr_uword64 (value
), pr_addr (cia
),
242 if (SizeFGR () == 64)
246 case fmt_uninterpreted_32
:
247 fmt
= fmt_uninterpreted
;
250 if (STATE_VERBOSE_P (SD
))
252 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
254 FGR
[fpr
] = (((uword64
) 0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
255 FPR_STATE
[fpr
] = fmt
;
258 case fmt_uninterpreted_64
:
259 fmt
= fmt_uninterpreted
;
260 case fmt_uninterpreted
:
265 FPR_STATE
[fpr
] = fmt
;
269 FPR_STATE
[fpr
] = fmt_unknown
;
278 case fmt_uninterpreted_32
:
279 fmt
= fmt_uninterpreted
;
282 FGR
[fpr
] = (value
& 0xFFFFFFFF);
283 FPR_STATE
[fpr
] = fmt
;
286 case fmt_uninterpreted_64
:
287 fmt
= fmt_uninterpreted
;
288 case fmt_uninterpreted
:
293 /* Even register numbers only. */
294 FGR
[fpr
+1] = (value
>> 32);
295 FGR
[fpr
] = (value
& 0xFFFFFFFF);
296 FPR_STATE
[fpr
+ 1] = fmt
;
297 FPR_STATE
[fpr
] = fmt
;
301 FPR_STATE
[fpr
] = fmt_unknown
;
302 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
303 SignalException (ReservedInstruction
, 0);
308 FPR_STATE
[fpr
] = fmt_unknown
;
309 SignalException (ReservedInstruction
, 0);
313 FPR_STATE
[fpr
] = fmt_unknown
;
320 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
323 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
324 fpr
, pr_uword64 (FGR
[fpr
]), fpu_format_name (fmt
));
331 /* CP1 control/status register access functions. */
334 test_fcsr (sim_cpu
*cpu
,
339 cause
= (FCSR
& fcsr_CAUSE_mask
) >> fcsr_CAUSE_shift
;
340 if ((cause
& ((FCSR
& fcsr_ENABLES_mask
) >> fcsr_ENABLES_shift
)) != 0
341 || (cause
& (1 << UO
)))
343 SignalExceptionFPE();
348 value_fcr(sim_cpu
*cpu
,
352 unsigned32 value
= 0;
356 case 0: /* FP Implementation and Revision Register. */
359 case 25: /* FP Condition Codes Register (derived from FCSR). */
360 value
= (FCR31
& fcsr_FCC_mask
) >> fcsr_FCC_shift
;
361 value
= (value
& 0x1) | (value
>> 1); /* Close FCC gap. */
363 case 26: /* FP Exceptions Register (derived from FCSR). */
364 value
= FCR31
& (fcsr_CAUSE_mask
| fcsr_FLAGS_mask
);
366 case 28: /* FP Enables Register (derived from FCSR). */
367 value
= FCR31
& (fcsr_ENABLES_mask
| fcsr_RM_mask
);
368 if ((FCR31
& fcsr_FS
) != 0)
371 case 31: /* FP Control/Status Register (FCSR). */
372 value
= FCR31
& ~fcsr_ZERO_mask
;
376 return (EXTEND32 (value
));
380 store_fcr(sim_cpu
*cpu
,
390 case 25: /* FP Condition Codes Register (stored into FCSR). */
391 v
= (v
<< 1) | (v
& 0x1); /* Adjust for FCC gap. */
392 FCR31
&= ~fcsr_FCC_mask
;
393 FCR31
|= ((v
<< fcsr_FCC_shift
) & fcsr_FCC_mask
);
395 case 26: /* FP Exceptions Register (stored into FCSR). */
396 FCR31
&= ~(fcsr_CAUSE_mask
| fcsr_FLAGS_mask
);
397 FCR31
|= (v
& (fcsr_CAUSE_mask
| fcsr_FLAGS_mask
));
400 case 28: /* FP Enables Register (stored into FCSR). */
401 if ((v
& fenr_FS
) != 0)
405 FCR31
&= (fcsr_FCC_mask
| fcsr_CAUSE_mask
| fcsr_FLAGS_mask
);
406 FCR31
|= (v
& (fcsr_FS
| fcsr_ENABLES_mask
| fcsr_RM_mask
));
409 case 31: /* FP Control/Status Register (FCSR). */
410 FCR31
= v
& ~fcsr_ZERO_mask
;
417 update_fcsr (sim_cpu
*cpu
,
419 sim_fpu_status status
)
421 FCSR
&= ~fcsr_CAUSE_mask
;
425 unsigned int cause
= 0;
427 /* map between sim_fpu codes and MIPS FCSR */
428 if (status
& (sim_fpu_status_invalid_snan
429 | sim_fpu_status_invalid_isi
430 | sim_fpu_status_invalid_idi
431 | sim_fpu_status_invalid_zdz
432 | sim_fpu_status_invalid_imz
433 | sim_fpu_status_invalid_cmp
434 | sim_fpu_status_invalid_sqrt
435 | sim_fpu_status_invalid_cvi
))
437 if (status
& sim_fpu_status_invalid_div0
)
439 if (status
& sim_fpu_status_overflow
)
441 if (status
& sim_fpu_status_underflow
)
443 if (status
& sim_fpu_status_inexact
)
446 /* Implicit clearing of other bits by unimplemented done by callers. */
447 if (status
& sim_fpu_status_unimplemented
)
451 FCSR
|= (cause
<< fcsr_CAUSE_shift
);
452 test_fcsr (cpu
, cia
);
453 FCSR
|= ((cause
& ~(1 << UO
)) << fcsr_FLAGS_shift
);
459 rounding_mode(int rm
)
466 /* Round result to nearest representable value. When two
467 representable values are equally near, round to the value
468 that has a least significant bit of zero (i.e. is even). */
469 round
= sim_fpu_round_near
;
472 /* Round result to the value closest to, and not greater in
473 magnitude than, the result. */
474 round
= sim_fpu_round_zero
;
477 /* Round result to the value closest to, and not less than,
479 round
= sim_fpu_round_up
;
482 /* Round result to the value closest to, and not greater than,
484 round
= sim_fpu_round_down
;
488 fprintf (stderr
, "Bad switch\n");
494 /* When the FS bit is set, MIPS processors return zero for
495 denormalized results and optionally replace denormalized inputs
496 with zero. When FS is clear, some implementation trap on input
497 and/or output, while other perform the operation in hardware. */
498 static sim_fpu_denorm
499 denorm_mode(sim_cpu
*cpu
)
501 sim_fpu_denorm denorm
;
503 /* XXX: FIXME: Eventually should be CPU model dependent. */
505 denorm
= sim_fpu_denorm_zero
;
512 /* Comparison operations. */
514 static sim_fpu_status
515 fp_test(unsigned64 op1
,
524 sim_fpu_status status
= 0;
525 int less
, equal
, unordered
;
527 /* The format type has already been checked: */
532 sim_fpu_32to (&wop1
, op1
);
533 sim_fpu_32to (&wop2
, op2
);
538 sim_fpu_64to (&wop1
, op1
);
539 sim_fpu_64to (&wop2
, op2
);
543 fprintf (stderr
, "Bad switch\n");
547 if (sim_fpu_is_nan (&wop1
) || sim_fpu_is_nan (&wop2
))
549 if ((cond
& (1 << 3)) ||
550 sim_fpu_is_snan (&wop1
) || sim_fpu_is_snan (&wop2
))
551 status
= sim_fpu_status_invalid_snan
;
560 status
|= sim_fpu_abs (&wop1
, &wop1
);
561 status
|= sim_fpu_abs (&wop2
, &wop2
);
563 equal
= sim_fpu_is_eq (&wop1
, &wop2
);
564 less
= !equal
&& sim_fpu_is_lt (&wop1
, &wop2
);
567 *condition
= (((cond
& (1 << 2)) && less
)
568 || ((cond
& (1 << 1)) && equal
)
569 || ((cond
& (1 << 0)) && unordered
));
583 sim_fpu_status status
= 0;
585 /* The format type should already have been checked. The FCSR is
586 updated before the condition codes so that any exceptions will
587 be signalled before the condition codes are changed. */
594 status
= fp_test(op1
, op2
, fmt
, abs
, cond
, &result
);
595 update_fcsr (cpu
, cia
, status
);
601 int result0
, result1
;
602 status
= fp_test(FP_PS_lower (op1
), FP_PS_lower (op2
), fmt_single
,
603 abs
, cond
, &result0
);
604 status
|= fp_test(FP_PS_upper (op1
), FP_PS_upper (op2
), fmt_single
,
605 abs
, cond
, &result1
);
606 update_fcsr (cpu
, cia
, status
);
607 SETFCC (cc
, result0
);
608 SETFCC (cc
+1, result1
);
612 sim_io_eprintf (SD
, "Bad switch\n");
618 /* Basic arithmetic operations. */
621 fp_unary(sim_cpu
*cpu
,
623 int (*sim_fpu_op
)(sim_fpu
*, const sim_fpu
*),
629 sim_fpu_round round
= rounding_mode (GETRM());
630 sim_fpu_denorm denorm
= denorm_mode (cpu
);
631 sim_fpu_status status
= 0;
632 unsigned64 result
= 0;
634 /* The format type has already been checked: */
640 sim_fpu_32to (&wop
, op
);
641 status
|= (*sim_fpu_op
) (&ans
, &wop
);
642 status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
643 sim_fpu_to32 (&res
, &ans
);
650 sim_fpu_64to (&wop
, op
);
651 status
|= (*sim_fpu_op
) (&ans
, &wop
);
652 status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
653 sim_fpu_to64 (&res
, &ans
);
659 int status_u
= 0, status_l
= 0;
660 unsigned32 res_u
, res_l
;
661 sim_fpu_32to (&wop
, FP_PS_upper(op
));
662 status_u
|= (*sim_fpu_op
) (&ans
, &wop
);
663 sim_fpu_to32 (&res_u
, &ans
);
664 sim_fpu_32to (&wop
, FP_PS_lower(op
));
665 status_l
|= (*sim_fpu_op
) (&ans
, &wop
);
666 sim_fpu_to32 (&res_l
, &ans
);
667 result
= FP_PS_cat(res_u
, res_l
);
668 status
= status_u
| status_l
;
672 sim_io_eprintf (SD
, "Bad switch\n");
676 update_fcsr (cpu
, cia
, status
);
681 fp_binary(sim_cpu
*cpu
,
683 int (*sim_fpu_op
)(sim_fpu
*, const sim_fpu
*, const sim_fpu
*),
691 sim_fpu_round round
= rounding_mode (GETRM());
692 sim_fpu_denorm denorm
= denorm_mode (cpu
);
693 sim_fpu_status status
= 0;
694 unsigned64 result
= 0;
696 /* The format type has already been checked: */
702 sim_fpu_32to (&wop1
, op1
);
703 sim_fpu_32to (&wop2
, op2
);
704 status
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
705 status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
706 sim_fpu_to32 (&res
, &ans
);
713 sim_fpu_64to (&wop1
, op1
);
714 sim_fpu_64to (&wop2
, op2
);
715 status
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
716 status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
717 sim_fpu_to64 (&res
, &ans
);
723 int status_u
= 0, status_l
= 0;
724 unsigned32 res_u
, res_l
;
725 sim_fpu_32to (&wop1
, FP_PS_upper(op1
));
726 sim_fpu_32to (&wop2
, FP_PS_upper(op2
));
727 status_u
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
728 sim_fpu_to32 (&res_u
, &ans
);
729 sim_fpu_32to (&wop1
, FP_PS_lower(op1
));
730 sim_fpu_32to (&wop2
, FP_PS_lower(op2
));
731 status_l
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
732 sim_fpu_to32 (&res_l
, &ans
);
733 result
= FP_PS_cat(res_u
, res_l
);
734 status
= status_u
| status_l
;
738 sim_io_eprintf (SD
, "Bad switch\n");
742 update_fcsr (cpu
, cia
, status
);
746 /* Common MAC code for single operands (.s or .d), defers setting FCSR. */
747 static sim_fpu_status
748 inner_mac(int (*sim_fpu_op
)(sim_fpu
*, const sim_fpu
*, const sim_fpu
*),
756 sim_fpu_denorm denorm
,
762 sim_fpu_status status
= 0;
763 sim_fpu_status op_status
;
771 sim_fpu_32to (&wop1
, op1
);
772 sim_fpu_32to (&wop2
, op2
);
773 status
|= sim_fpu_mul (&ans
, &wop1
, &wop2
);
774 if (scale
!= 0 && sim_fpu_is_number (&ans
)) /* number or denorm */
775 ans
.normal_exp
+= scale
;
776 status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
779 sim_fpu_32to (&wop2
, op3
);
780 op_status
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
781 op_status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
786 op_status
= sim_fpu_neg (&ans
, &wop1
);
787 op_status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
790 sim_fpu_to32 (&res
, &ans
);
797 sim_fpu_64to (&wop1
, op1
);
798 sim_fpu_64to (&wop2
, op2
);
799 status
|= sim_fpu_mul (&ans
, &wop1
, &wop2
);
800 if (scale
!= 0 && sim_fpu_is_number (&ans
)) /* number or denorm */
801 ans
.normal_exp
+= scale
;
802 status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
805 sim_fpu_64to (&wop2
, op3
);
806 op_status
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
807 op_status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
812 op_status
= sim_fpu_neg (&ans
, &wop1
);
813 op_status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
816 sim_fpu_to64 (&res
, &ans
);
821 fprintf (stderr
, "Bad switch\n");
828 /* Common implementation of madd, nmadd, msub, nmsub that does
829 intermediate rounding per spec. Also used for recip2 and rsqrt2,
830 which are transformed into equivalent nmsub operations. The scale
831 argument is an adjustment to the exponent of the intermediate
832 product op1*op2. It is currently non-zero for rsqrt2 (-1), which
833 requires an effective division by 2. */
837 int (*sim_fpu_op
)(sim_fpu
*, const sim_fpu
*, const sim_fpu
*),
845 sim_fpu_round round
= rounding_mode (GETRM());
846 sim_fpu_denorm denorm
= denorm_mode (cpu
);
847 sim_fpu_status status
= 0;
848 unsigned64 result
= 0;
850 /* The format type has already been checked: */
855 status
= inner_mac(sim_fpu_op
, op1
, op2
, op3
, scale
,
856 negate
, fmt
, round
, denorm
, &result
);
860 int status_u
, status_l
;
861 unsigned64 result_u
, result_l
;
862 status_u
= inner_mac(sim_fpu_op
, FP_PS_upper(op1
), FP_PS_upper(op2
),
863 FP_PS_upper(op3
), scale
, negate
, fmt_single
,
864 round
, denorm
, &result_u
);
865 status_l
= inner_mac(sim_fpu_op
, FP_PS_lower(op1
), FP_PS_lower(op2
),
866 FP_PS_lower(op3
), scale
, negate
, fmt_single
,
867 round
, denorm
, &result_l
);
868 result
= FP_PS_cat(result_u
, result_l
);
869 status
= status_u
| status_l
;
873 sim_io_eprintf (SD
, "Bad switch\n");
877 update_fcsr (cpu
, cia
, status
);
881 /* Common rsqrt code for single operands (.s or .d), intermediate rounding. */
882 static sim_fpu_status
883 inner_rsqrt(unsigned64 op1
,
886 sim_fpu_denorm denorm
,
891 sim_fpu_status status
= 0;
892 sim_fpu_status op_status
;
900 sim_fpu_32to (&wop1
, op1
);
901 status
|= sim_fpu_sqrt (&ans
, &wop1
);
902 status
|= sim_fpu_round_32 (&ans
, status
, round
);
904 op_status
= sim_fpu_inv (&ans
, &wop1
);
905 op_status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
906 sim_fpu_to32 (&res
, &ans
);
914 sim_fpu_64to (&wop1
, op1
);
915 status
|= sim_fpu_sqrt (&ans
, &wop1
);
916 status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
918 op_status
= sim_fpu_inv (&ans
, &wop1
);
919 op_status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
920 sim_fpu_to64 (&res
, &ans
);
926 fprintf (stderr
, "Bad switch\n");
934 fp_inv_sqrt(sim_cpu
*cpu
,
939 sim_fpu_round round
= rounding_mode (GETRM());
940 sim_fpu_round denorm
= denorm_mode (cpu
);
941 sim_fpu_status status
= 0;
942 unsigned64 result
= 0;
944 /* The format type has already been checked: */
949 status
= inner_rsqrt (op1
, fmt
, round
, denorm
, &result
);
953 int status_u
, status_l
;
954 unsigned64 result_u
, result_l
;
955 status_u
= inner_rsqrt (FP_PS_upper(op1
), fmt_single
, round
, denorm
,
957 status_l
= inner_rsqrt (FP_PS_lower(op1
), fmt_single
, round
, denorm
,
959 result
= FP_PS_cat(result_u
, result_l
);
960 status
= status_u
| status_l
;
964 sim_io_eprintf (SD
, "Bad switch\n");
968 update_fcsr (cpu
, cia
, status
);
979 return fp_unary(cpu
, cia
, &sim_fpu_abs
, op
, fmt
);
988 return fp_unary(cpu
, cia
, &sim_fpu_neg
, op
, fmt
);
998 return fp_binary(cpu
, cia
, &sim_fpu_add
, op1
, op2
, fmt
);
1002 fp_sub(sim_cpu
*cpu
,
1008 return fp_binary(cpu
, cia
, &sim_fpu_sub
, op1
, op2
, fmt
);
1012 fp_mul(sim_cpu
*cpu
,
1018 return fp_binary(cpu
, cia
, &sim_fpu_mul
, op1
, op2
, fmt
);
1022 fp_div(sim_cpu
*cpu
,
1028 return fp_binary(cpu
, cia
, &sim_fpu_div
, op1
, op2
, fmt
);
1032 fp_recip(sim_cpu
*cpu
,
1037 return fp_unary(cpu
, cia
, &sim_fpu_inv
, op
, fmt
);
1041 fp_sqrt(sim_cpu
*cpu
,
1046 return fp_unary(cpu
, cia
, &sim_fpu_sqrt
, op
, fmt
);
1050 fp_rsqrt(sim_cpu
*cpu
,
1055 return fp_inv_sqrt(cpu
, cia
, op
, fmt
);
1059 fp_madd(sim_cpu
*cpu
,
1066 return fp_mac(cpu
, cia
, &sim_fpu_add
, op1
, op2
, op3
, 0, 0, fmt
);
1070 fp_msub(sim_cpu
*cpu
,
1077 return fp_mac(cpu
, cia
, &sim_fpu_sub
, op1
, op2
, op3
, 0, 0, fmt
);
1081 fp_nmadd(sim_cpu
*cpu
,
1088 return fp_mac(cpu
, cia
, &sim_fpu_add
, op1
, op2
, op3
, 0, 1, fmt
);
1092 fp_nmsub(sim_cpu
*cpu
,
1099 return fp_mac(cpu
, cia
, &sim_fpu_sub
, op1
, op2
, op3
, 0, 1, fmt
);
1103 /* MIPS-3D ASE operations. */
1105 /* Variant of fp_binary for *r.ps MIPS-3D operations. */
1107 fp_binary_r(sim_cpu
*cpu
,
1109 int (*sim_fpu_op
)(sim_fpu
*, const sim_fpu
*, const sim_fpu
*),
1116 sim_fpu_round round
= rounding_mode (GETRM ());
1117 sim_fpu_denorm denorm
= denorm_mode (cpu
);
1118 sim_fpu_status status_u
, status_l
;
1120 unsigned32 res_u
, res_l
;
1122 /* The format must be fmt_ps. */
1124 sim_fpu_32to (&wop1
, FP_PS_upper (op1
));
1125 sim_fpu_32to (&wop2
, FP_PS_lower (op1
));
1126 status_u
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
1127 status_u
|= sim_fpu_round_32 (&ans
, round
, denorm
);
1128 sim_fpu_to32 (&res_u
, &ans
);
1130 sim_fpu_32to (&wop1
, FP_PS_upper (op2
));
1131 sim_fpu_32to (&wop2
, FP_PS_lower (op2
));
1132 status_l
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
1133 status_l
|= sim_fpu_round_32 (&ans
, round
, denorm
);
1134 sim_fpu_to32 (&res_l
, &ans
);
1135 result
= FP_PS_cat (res_u
, res_l
);
1137 update_fcsr (cpu
, cia
, status_u
| status_l
);
1142 fp_add_r(sim_cpu
*cpu
,
1148 return fp_binary_r (cpu
, cia
, &sim_fpu_add
, op1
, op2
);
1152 fp_mul_r(sim_cpu
*cpu
,
1158 return fp_binary_r (cpu
, cia
, &sim_fpu_mul
, op1
, op2
);
1161 #define NR_FRAC_GUARD (60)
1162 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
1165 fpu_inv1(sim_fpu
*f
, const sim_fpu
*l
)
1167 static const sim_fpu sim_fpu_one
= {
1168 sim_fpu_class_number
, 0, IMPLICIT_1
, 0
1173 if (sim_fpu_is_zero (l
))
1177 return sim_fpu_status_invalid_div0
;
1179 if (sim_fpu_is_infinity (l
))
1185 status
|= sim_fpu_div (f
, &sim_fpu_one
, l
);
1190 fpu_inv1_32(sim_fpu
*f
, const sim_fpu
*l
)
1192 if (sim_fpu_is_zero (l
))
1196 return sim_fpu_status_invalid_div0
;
1198 return fpu_inv1 (f
, l
);
1202 fpu_inv1_64(sim_fpu
*f
, const sim_fpu
*l
)
1204 if (sim_fpu_is_zero (l
))
1208 return sim_fpu_status_invalid_div0
;
1210 return fpu_inv1 (f
, l
);
1214 fp_recip1(sim_cpu
*cpu
,
1223 return fp_unary (cpu
, cia
, &fpu_inv1_32
, op
, fmt
);
1225 return fp_unary (cpu
, cia
, &fpu_inv1_64
, op
, fmt
);
1231 fp_recip2(sim_cpu
*cpu
,
1237 static const unsigned64 one_single
= UNSIGNED64 (0x3F800000);
1238 static const unsigned64 one_double
= UNSIGNED64 (0x3FF0000000000000);
1239 static const unsigned64 one_ps
= (UNSIGNED64 (0x3F800000) << 32 | UNSIGNED64 (0x3F800000));
1242 /* Implemented as nmsub fd, 1, fs, ft. */
1245 case fmt_single
: one
= one_single
; break;
1246 case fmt_double
: one
= one_double
; break;
1247 case fmt_ps
: one
= one_ps
; break;
1248 default: one
= 0; abort ();
1250 return fp_mac (cpu
, cia
, &sim_fpu_sub
, op1
, op2
, one
, 0, 1, fmt
);
1254 fpu_inv_sqrt1(sim_fpu
*f
, const sim_fpu
*l
)
1256 static const sim_fpu sim_fpu_one
= {
1257 sim_fpu_class_number
, 0, IMPLICIT_1
, 0
1262 if (sim_fpu_is_zero (l
))
1266 return sim_fpu_status_invalid_div0
;
1268 if (sim_fpu_is_infinity (l
))
1272 f
->class = sim_fpu_class_zero
;
1278 status
= sim_fpu_status_invalid_sqrt
;
1282 status
|= sim_fpu_sqrt (&t
, l
);
1283 status
|= sim_fpu_div (f
, &sim_fpu_one
, &t
);
1288 fpu_inv_sqrt1_32(sim_fpu
*f
, const sim_fpu
*l
)
1290 if (sim_fpu_is_zero (l
))
1294 return sim_fpu_status_invalid_div0
;
1296 return fpu_inv_sqrt1 (f
, l
);
1300 fpu_inv_sqrt1_64(sim_fpu
*f
, const sim_fpu
*l
)
1302 if (sim_fpu_is_zero (l
))
1306 return sim_fpu_status_invalid_div0
;
1308 return fpu_inv_sqrt1 (f
, l
);
1312 fp_rsqrt1(sim_cpu
*cpu
,
1321 return fp_unary (cpu
, cia
, &fpu_inv_sqrt1_32
, op
, fmt
);
1323 return fp_unary (cpu
, cia
, &fpu_inv_sqrt1_64
, op
, fmt
);
1329 fp_rsqrt2(sim_cpu
*cpu
,
1335 static const unsigned64 half_single
= UNSIGNED64 (0x3F000000);
1336 static const unsigned64 half_double
= UNSIGNED64 (0x3FE0000000000000);
1337 static const unsigned64 half_ps
= (UNSIGNED64 (0x3F000000) << 32 | UNSIGNED64 (0x3F000000));
1340 /* Implemented as (nmsub fd, 0.5, fs, ft)/2, where the divide is
1341 done by scaling the exponent during multiply. */
1344 case fmt_single
: half
= half_single
; break;
1345 case fmt_double
: half
= half_double
; break;
1346 case fmt_ps
: half
= half_ps
; break;
1347 default: half
= 0; abort ();
1349 return fp_mac (cpu
, cia
, &sim_fpu_sub
, op1
, op2
, half
, -1, 1, fmt
);
1353 /* Conversion operations. */
1356 convert (sim_cpu
*cpu
,
1364 sim_fpu_round round
= rounding_mode (rm
);
1365 sim_fpu_denorm denorm
= denorm_mode (cpu
);
1366 unsigned32 result32
;
1367 unsigned64 result64
;
1368 sim_fpu_status status
= 0;
1370 /* Convert the input to sim_fpu internal format */
1374 sim_fpu_64to (&wop
, op
);
1377 sim_fpu_32to (&wop
, op
);
1380 status
= sim_fpu_i32to (&wop
, op
, round
);
1383 status
= sim_fpu_i64to (&wop
, op
, round
);
1386 sim_io_eprintf (SD
, "Bad switch\n");
1390 /* Convert sim_fpu format into the output */
1391 /* The value WOP is converted to the destination format, rounding
1392 using mode RM. When the destination is a fixed-point format, then
1393 a source value of Infinity, NaN or one which would round to an
1394 integer outside the fixed point range then an IEEE Invalid Operation
1395 condition is raised. Not used if destination format is PS. */
1399 status
|= sim_fpu_round_32 (&wop
, round
, denorm
);
1400 /* For a NaN, normalize mantissa bits (cvt.s.d can't preserve them) */
1401 if (sim_fpu_is_qnan (&wop
))
1403 sim_fpu_to32 (&result32
, &wop
);
1404 result64
= result32
;
1407 status
|= sim_fpu_round_64 (&wop
, round
, denorm
);
1408 /* For a NaN, normalize mantissa bits (make cvt.d.s consistent) */
1409 if (sim_fpu_is_qnan (&wop
))
1411 sim_fpu_to64 (&result64
, &wop
);
1414 status
|= sim_fpu_to32i (&result32
, &wop
, round
);
1415 result64
= result32
;
1418 status
|= sim_fpu_to64i (&result64
, &wop
, round
);
1422 sim_io_eprintf (SD
, "Bad switch\n");
1426 update_fcsr (cpu
, cia
, status
);
1431 ps_lower(sim_cpu
*cpu
,
1435 return FP_PS_lower (op
);
1439 ps_upper(sim_cpu
*cpu
,
1443 return FP_PS_upper(op
);
1447 pack_ps(sim_cpu
*cpu
,
1453 unsigned64 result
= 0;
1455 /* The registers must specify FPRs valid for operands of type
1456 "fmt". If they are not valid, the result is undefined. */
1458 /* The format type should already have been checked: */
1464 unsigned32 res_u
, res_l
;
1465 sim_fpu_32to (&wop
, op1
);
1466 sim_fpu_to32 (&res_u
, &wop
);
1467 sim_fpu_32to (&wop
, op2
);
1468 sim_fpu_to32 (&res_l
, &wop
);
1469 result
= FP_PS_cat(res_u
, res_l
);
1473 sim_io_eprintf (SD
, "Bad switch\n");
1481 convert_ps (sim_cpu
*cpu
,
1488 sim_fpu wop_u
, wop_l
;
1489 sim_fpu_round round
= rounding_mode (rm
);
1490 sim_fpu_denorm denorm
= denorm_mode (cpu
);
1491 unsigned32 res_u
, res_l
;
1493 sim_fpu_status status_u
= 0, status_l
= 0;
1495 /* As convert, but used only for paired values (formats PS, PW) */
1497 /* Convert the input to sim_fpu internal format */
1500 case fmt_word
: /* fmt_pw */
1501 sim_fpu_i32to (&wop_u
, (op
>> 32) & (unsigned)0xFFFFFFFF, round
);
1502 sim_fpu_i32to (&wop_l
, op
& (unsigned)0xFFFFFFFF, round
);
1505 sim_fpu_32to (&wop_u
, FP_PS_upper(op
));
1506 sim_fpu_32to (&wop_l
, FP_PS_lower(op
));
1509 sim_io_eprintf (SD
, "Bad switch\n");
1513 /* Convert sim_fpu format into the output */
1516 case fmt_word
: /* fmt_pw */
1517 status_u
|= sim_fpu_to32i (&res_u
, &wop_u
, round
);
1518 status_l
|= sim_fpu_to32i (&res_l
, &wop_l
, round
);
1519 result
= (((unsigned64
)res_u
) << 32) | (unsigned64
)res_l
;
1522 status_u
|= sim_fpu_round_32 (&wop_u
, 0, round
);
1523 status_l
|= sim_fpu_round_32 (&wop_l
, 0, round
);
1524 sim_fpu_to32 (&res_u
, &wop_u
);
1525 sim_fpu_to32 (&res_l
, &wop_l
);
1526 result
= FP_PS_cat(res_u
, res_l
);
1530 sim_io_eprintf (SD
, "Bad switch\n");
1534 update_fcsr (cpu
, cia
, status_u
| status_l
);
1539 fpu_format_name (FP_formats fmt
)
1555 case fmt_uninterpreted
:
1556 return "<uninterpreted>";
1557 case fmt_uninterpreted_32
:
1558 return "<uninterpreted_32>";
1559 case fmt_uninterpreted_64
:
1560 return "<uninterpreted_64>";
1562 return "<format error>";
1568 fpu_rounding_mode_name (int rm
)
1581 return "<rounding mode error>";