2 /* MIPS Simulator FPU (CoProcessor 1) support.
3 Copyright (C) 2002-2023 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 3 of the License, or
14 (at your option) any later version.
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
22 along with this program. If not, see <http://www.gnu.org/licenses/>. */
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)
43 /* This must come before any other includes. */
50 /* Within cp1.c we refer to sim_cpu directly. */
52 #define SD CPU_STATE(cpu)
54 /*-- FPU support routines ---------------------------------------------------*/
56 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
57 formats conform to ANSI/IEEE Std 754-1985.
59 SINGLE precision floating:
60 seeeeeeeefffffffffffffffffffffff
65 SINGLE precision fixed:
66 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
70 DOUBLE precision floating:
71 seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
76 DOUBLE precision fixed:
77 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
81 PAIRED SINGLE precision floating:
82 seeeeeeeefffffffffffffffffffffffseeeeeeeefffffffffffffffffffffff
87 Note: upper = [63..32], lower = [31..0]
90 /* Extract packed single values: */
91 #define FP_PS_upper(v) (((v) >> 32) & (unsigned)0xFFFFFFFF)
92 #define FP_PS_lower(v) ((v) & (unsigned)0xFFFFFFFF)
93 #define FP_PS_cat(u,l) (((uint64_t)((u) & (unsigned)0xFFFFFFFF) << 32) \
94 | (uint64_t)((l) & 0xFFFFFFFF))
96 /* Explicit QNaN values. */
97 #define FPQNaN_SINGLE (0x7FBFFFFF)
98 #define FPQNaN_WORD (0x7FFFFFFF)
99 #define FPQNaN_DOUBLE (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))
100 #define FPQNaN_LONG (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))
101 #define FPQNaN_PS (FP_PS_cat (FPQNaN_SINGLE, FPQNaN_SINGLE))
103 static void update_fcsr (sim_cpu
*, address_word
, sim_fpu_status
);
105 static const char *fpu_format_name (FP_formats fmt
);
107 static const char *fpu_rounding_mode_name (int rm
);
111 value_fpr (sim_cpu
*cpu
,
119 /* Treat unused register values, as fixed-point 64bit values. */
120 if (fmt
== fmt_unknown
)
123 /* If request to read data as "unknown", then use the current
125 fmt
= FPR_STATE
[fpr
];
131 /* For values not yet accessed, set to the desired format. */
132 if (fmt
< fmt_uninterpreted
&& fmt
!= fmt_dc32
)
134 if (FPR_STATE
[fpr
] == fmt_uninterpreted
)
136 FPR_STATE
[fpr
] = fmt
;
138 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr
,
139 fpu_format_name (fmt
));
142 else if (fmt
!= FPR_STATE
[fpr
]
143 && !(fmt
== fmt_single
144 && FPR_STATE
[fpr
] == fmt_double
145 && (FGR
[fpr
] == 0 || FGR
[fpr
] == 0xFFFFFFFF)))
147 sim_io_eprintf (SD
, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
148 fpr
, fpu_format_name (FPR_STATE
[fpr
]),
149 fpu_format_name (fmt
), pr_addr (cia
));
150 FPR_STATE
[fpr
] = fmt_unknown
;
154 if (FPR_STATE
[fpr
] == fmt_unknown
)
156 /* Set QNaN value: */
159 case fmt_single
: value
= FPQNaN_SINGLE
; break;
160 case fmt_double
: value
= FPQNaN_DOUBLE
; break;
161 case fmt_word
: value
= FPQNaN_WORD
; break;
162 case fmt_long
: value
= FPQNaN_LONG
; break;
163 case fmt_ps
: value
= FPQNaN_PS
; break;
164 default: err
= -1; break;
167 else if (SizeFGR () == 64)
171 case fmt_uninterpreted_32
:
175 value
= (FGR
[fpr
] & 0xFFFFFFFF);
178 case fmt_uninterpreted_64
:
179 case fmt_uninterpreted
:
195 case fmt_uninterpreted_32
:
198 value
= (FGR
[fpr
] & 0xFFFFFFFF);
201 case fmt_uninterpreted_64
:
202 case fmt_uninterpreted
:
207 /* Even register numbers only. */
209 printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
210 fpr
+ 1, pr_uword64 ((uword64
) FGR
[fpr
+1]),
211 fpr
, pr_uword64 ((uword64
) FGR
[fpr
]));
213 value
= ((((uword64
) FGR
[fpr
+1]) << 32)
214 | (FGR
[fpr
] & 0xFFFFFFFF));
218 SignalException (ReservedInstruction
, 0);
223 SignalException (ReservedInstruction
, 0);
233 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
236 printf ("DBG: ValueFPR: 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
),
245 store_fpr (sim_cpu
*cpu
,
254 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
255 fpr
, fpu_format_name (fmt
), pr_uword64 (value
), pr_addr (cia
),
259 if (SizeFGR () == 64)
263 case fmt_uninterpreted_32
:
264 fmt
= fmt_uninterpreted
;
267 if (STATE_VERBOSE_P (SD
))
269 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
271 FGR
[fpr
] = (((uword64
) 0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
272 FPR_STATE
[fpr
] = fmt
;
275 case fmt_uninterpreted_64
:
276 fmt
= fmt_uninterpreted
;
277 case fmt_uninterpreted
:
282 FPR_STATE
[fpr
] = fmt
;
286 FPR_STATE
[fpr
] = fmt_unknown
;
295 case fmt_uninterpreted_32
:
296 fmt
= fmt_uninterpreted
;
299 FGR
[fpr
] = (value
& 0xFFFFFFFF);
300 FPR_STATE
[fpr
] = fmt
;
303 case fmt_uninterpreted_64
:
304 fmt
= fmt_uninterpreted
;
305 case fmt_uninterpreted
:
310 /* Even register numbers only. */
311 FGR
[fpr
+1] = (value
>> 32);
312 FGR
[fpr
] = (value
& 0xFFFFFFFF);
313 FPR_STATE
[fpr
+ 1] = fmt
;
314 FPR_STATE
[fpr
] = fmt
;
318 FPR_STATE
[fpr
] = fmt_unknown
;
319 FPR_STATE
[fpr
^ 1] = fmt_unknown
;
320 SignalException (ReservedInstruction
, 0);
325 FPR_STATE
[fpr
] = fmt_unknown
;
326 SignalException (ReservedInstruction
, 0);
330 FPR_STATE
[fpr
] = fmt_unknown
;
337 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
340 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
341 fpr
, pr_uword64 (FGR
[fpr
]), fpu_format_name (fmt
));
348 /* CP1 control/status register access functions. */
351 test_fcsr (sim_cpu
*cpu
,
356 cause
= (FCSR
& fcsr_CAUSE_mask
) >> fcsr_CAUSE_shift
;
357 if ((cause
& ((FCSR
& fcsr_ENABLES_mask
) >> fcsr_ENABLES_shift
)) != 0
358 || (cause
& (1 << UO
)))
360 SignalExceptionFPE();
365 value_fcr(sim_cpu
*cpu
,
373 case 0: /* FP Implementation and Revision Register. */
376 case 25: /* FP Condition Codes Register (derived from FCSR). */
377 value
= (FCR31
& fcsr_FCC_mask
) >> fcsr_FCC_shift
;
378 value
= (value
& 0x1) | (value
>> 1); /* Close FCC gap. */
380 case 26: /* FP Exceptions Register (derived from FCSR). */
381 value
= FCR31
& (fcsr_CAUSE_mask
| fcsr_FLAGS_mask
);
383 case 28: /* FP Enables Register (derived from FCSR). */
384 value
= FCR31
& (fcsr_ENABLES_mask
| fcsr_RM_mask
);
385 if ((FCR31
& fcsr_FS
) != 0)
388 case 31: /* FP Control/Status Register (FCSR). */
389 value
= FCR31
& ~fcsr_ZERO_mask
;
393 return (EXTEND32 (value
));
397 store_fcr(sim_cpu
*cpu
,
407 case 25: /* FP Condition Codes Register (stored into FCSR). */
408 v
= (v
<< 1) | (v
& 0x1); /* Adjust for FCC gap. */
409 FCR31
&= ~fcsr_FCC_mask
;
410 FCR31
|= ((v
<< fcsr_FCC_shift
) & fcsr_FCC_mask
);
412 case 26: /* FP Exceptions Register (stored into FCSR). */
413 FCR31
&= ~(fcsr_CAUSE_mask
| fcsr_FLAGS_mask
);
414 FCR31
|= (v
& (fcsr_CAUSE_mask
| fcsr_FLAGS_mask
));
417 case 28: /* FP Enables Register (stored into FCSR). */
418 if ((v
& fenr_FS
) != 0)
422 FCR31
&= (fcsr_FCC_mask
| fcsr_CAUSE_mask
| fcsr_FLAGS_mask
);
423 FCR31
|= (v
& (fcsr_FS
| fcsr_ENABLES_mask
| fcsr_RM_mask
));
426 case 31: /* FP Control/Status Register (FCSR). */
427 FCR31
= v
& ~fcsr_ZERO_mask
;
434 update_fcsr (sim_cpu
*cpu
,
436 sim_fpu_status status
)
438 FCSR
&= ~fcsr_CAUSE_mask
;
442 unsigned int cause
= 0;
444 /* map between sim_fpu codes and MIPS FCSR */
445 if (status
& (sim_fpu_status_invalid_snan
446 | sim_fpu_status_invalid_isi
447 | sim_fpu_status_invalid_idi
448 | sim_fpu_status_invalid_zdz
449 | sim_fpu_status_invalid_imz
450 | sim_fpu_status_invalid_cmp
451 | sim_fpu_status_invalid_sqrt
452 | sim_fpu_status_invalid_cvi
))
454 if (status
& sim_fpu_status_invalid_div0
)
456 if (status
& sim_fpu_status_overflow
)
458 if (status
& sim_fpu_status_underflow
)
460 if (status
& sim_fpu_status_inexact
)
463 /* Implicit clearing of other bits by unimplemented done by callers. */
464 if (status
& sim_fpu_status_unimplemented
)
468 FCSR
|= (cause
<< fcsr_CAUSE_shift
);
469 test_fcsr (cpu
, cia
);
470 FCSR
|= ((cause
& ~(1 << UO
)) << fcsr_FLAGS_shift
);
476 rounding_mode(int rm
)
483 /* Round result to nearest representable value. When two
484 representable values are equally near, round to the value
485 that has a least significant bit of zero (i.e. is even). */
486 round
= sim_fpu_round_near
;
489 /* Round result to the value closest to, and not greater in
490 magnitude than, the result. */
491 round
= sim_fpu_round_zero
;
494 /* Round result to the value closest to, and not less than,
496 round
= sim_fpu_round_up
;
499 /* Round result to the value closest to, and not greater than,
501 round
= sim_fpu_round_down
;
505 fprintf (stderr
, "Bad switch\n");
511 /* When the FS bit is set, MIPS processors return zero for
512 denormalized results and optionally replace denormalized inputs
513 with zero. When FS is clear, some implementation trap on input
514 and/or output, while other perform the operation in hardware. */
515 static sim_fpu_denorm
516 denorm_mode(sim_cpu
*cpu
)
518 sim_fpu_denorm denorm
;
520 /* XXX: FIXME: Eventually should be CPU model dependent. */
522 denorm
= sim_fpu_denorm_zero
;
529 /* Comparison operations. */
531 static sim_fpu_status
532 fp_test(uint64_t op1
,
541 sim_fpu_status status
= 0;
542 int less
, equal
, unordered
;
544 /* The format type has already been checked: */
549 sim_fpu_32to (&wop1
, op1
);
550 sim_fpu_32to (&wop2
, op2
);
555 sim_fpu_64to (&wop1
, op1
);
556 sim_fpu_64to (&wop2
, op2
);
560 fprintf (stderr
, "Bad switch\n");
564 if (sim_fpu_is_nan (&wop1
) || sim_fpu_is_nan (&wop2
))
566 if ((cond
& (1 << 3))
567 || sim_fpu_is_snan (&wop1
) || sim_fpu_is_snan (&wop2
))
568 status
= sim_fpu_status_invalid_snan
;
577 status
|= sim_fpu_abs (&wop1
, &wop1
);
578 status
|= sim_fpu_abs (&wop2
, &wop2
);
580 equal
= sim_fpu_is_eq (&wop1
, &wop2
);
581 less
= !equal
&& sim_fpu_is_lt (&wop1
, &wop2
);
584 *condition
= (((cond
& (1 << 2)) && less
)
585 || ((cond
& (1 << 1)) && equal
)
586 || ((cond
& (1 << 0)) && unordered
));
590 static const int sim_fpu_class_mips_mapping
[] = {
591 FP_R6CLASS_SNAN
, /* SIM_FPU_IS_SNAN = 1, Noisy not-a-number */
592 FP_R6CLASS_QNAN
, /* SIM_FPU_IS_QNAN = 2, Quiet not-a-number */
593 FP_R6CLASS_NEGINF
, /* SIM_FPU_IS_NINF = 3, -infinity */
594 FP_R6CLASS_POSINF
, /* SIM_FPU_IS_PINF = 4, +infinity */
595 FP_R6CLASS_NEGNORM
, /* SIM_FPU_IS_NNUMBER = 5, -num - [-MAX .. -MIN] */
596 FP_R6CLASS_POSNORM
, /* SIM_FPU_IS_PNUMBER = 6, +num - [+MIN .. +MAX] */
597 FP_R6CLASS_NEGSUB
, /* SIM_FPU_IS_NDENORM = 7, -denorm - (MIN .. 0) */
598 FP_R6CLASS_POSSUB
, /* SIM_FPU_IS_PDENORM = 8, +denorm - (0 .. MIN) */
599 FP_R6CLASS_NEGZERO
, /* SIM_FPU_IS_NZERO = 9, -0 */
600 FP_R6CLASS_POSZERO
/* SIM_FPU_IS_PZERO = 10, +0 */
604 fp_classify (sim_cpu
*cpu
,
614 sim_fpu_32to (&wop
, op
);
617 sim_fpu_64to (&wop
, op
);
620 sim_io_error (SD
, "Bad switch\n");
622 return sim_fpu_class_mips_mapping
[sim_fpu_classify (&wop
) - 1];
626 fp_rint (sim_cpu
*cpu
,
632 sim_fpu wop
= {0}, wtemp
= {0}, wmagic
= {0}, wans
= {0};
633 int64_t intermediate
;
635 sim_fpu_round round
= rounding_mode (GETRM());
640 sim_fpu_32to (&wop
, op
);
641 sim_fpu_32to (&wmagic
, 0x4b000000);
644 sim_fpu_64to (&wop
, op
);
645 sim_fpu_64to (&wmagic
, 0x4330000000000000);
648 sim_io_error (SD
, "Bad switch\n");
651 if (sim_fpu_is_nan (&wop
) || sim_fpu_is_infinity (&wop
))
653 status
= sim_fpu_status_invalid_cvi
;
654 update_fcsr (cpu
, cia
, status
);
661 if (sim_fpu_is_ge (&wop
, &wmagic
))
665 sim_fpu_add (&wtemp
, &wop
, &wmagic
);
666 sim_fpu_round_32 (&wtemp
, round
, sim_fpu_denorm_default
);
667 sim_fpu_sub (&wans
, &wtemp
, &wmagic
);
669 sim_fpu_to32 ((uint32_t *) ans
, &wans
);
672 if (sim_fpu_is_ge (&wop
, &wmagic
))
676 sim_fpu_add (&wtemp
, &wop
, &wmagic
);
677 sim_fpu_round_64 (&wtemp
, round
, sim_fpu_denorm_default
);
678 sim_fpu_sub (&wans
, &wtemp
, &wmagic
);
680 sim_fpu_to64 (ans
, &wans
);
683 sim_io_error (SD
, "Bad switch\n");
686 if (*ans
!= op
&& status
== 0)
687 status
= sim_fpu_status_inexact
;
689 update_fcsr (cpu
, cia
, status
);
703 sim_fpu_status status
= 0;
705 /* The format type should already have been checked. The FCSR is
706 updated before the condition codes so that any exceptions will
707 be signalled before the condition codes are changed. */
714 status
= fp_test(op1
, op2
, fmt
, abs
, cond
, &result
);
715 update_fcsr (cpu
, cia
, status
);
721 int result0
, result1
;
722 status
= fp_test(FP_PS_lower (op1
), FP_PS_lower (op2
), fmt_single
,
723 abs
, cond
, &result0
);
724 status
|= fp_test(FP_PS_upper (op1
), FP_PS_upper (op2
), fmt_single
,
725 abs
, cond
, &result1
);
726 update_fcsr (cpu
, cia
, status
);
727 SETFCC (cc
, result0
);
728 SETFCC (cc
+1, result1
);
732 sim_io_error (SD
, "Bad switch\n");
737 fp_r6_cmp (sim_cpu
*cpu
,
746 int signalling
= cond
& 0x8;
751 sim_fpu_32to (&wop1
, op1
);
752 sim_fpu_32to (&wop2
, op2
);
755 sim_fpu_64to (&wop1
, op1
);
756 sim_fpu_64to (&wop2
, op2
);
759 sim_io_error (SD
, "Bad switch\n");
768 result
= sim_fpu_is_un (&wop1
, &wop2
);
771 result
= sim_fpu_is_or (&wop1
, &wop2
);
774 result
= sim_fpu_is_eq (&wop1
, &wop2
);
777 result
= sim_fpu_is_ne (&wop1
, &wop2
);
780 result
= sim_fpu_is_lt (&wop1
, &wop2
);
783 result
= sim_fpu_is_le (&wop1
, &wop2
);
786 result
= sim_fpu_is_un (&wop1
, &wop2
) || sim_fpu_is_eq (&wop1
, &wop2
);
789 result
= sim_fpu_is_un (&wop1
, &wop2
) || sim_fpu_is_ne (&wop1
, &wop2
);
792 result
= sim_fpu_is_un (&wop1
, &wop2
) || sim_fpu_is_lt (&wop1
, &wop2
);
795 result
= sim_fpu_is_un (&wop1
, &wop2
) || sim_fpu_is_le (&wop1
, &wop2
);
798 update_fcsr (cpu
, cia
, sim_fpu_status_invalid_cmp
);
809 return 0xFFFFFFFFFFFFFFFF;
811 sim_io_error (SD
, "Bad switch\n");
818 /* Basic arithmetic operations. */
821 fp_unary(sim_cpu
*cpu
,
823 int (*sim_fpu_op
)(sim_fpu
*, const sim_fpu
*),
829 sim_fpu_round round
= rounding_mode (GETRM());
830 sim_fpu_denorm denorm
= denorm_mode (cpu
);
831 sim_fpu_status status
= 0;
834 /* The format type has already been checked: */
840 sim_fpu_32to (&wop
, op
);
841 status
|= (*sim_fpu_op
) (&ans
, &wop
);
842 status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
843 sim_fpu_to32 (&res
, &ans
);
850 sim_fpu_64to (&wop
, op
);
851 status
|= (*sim_fpu_op
) (&ans
, &wop
);
852 status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
853 sim_fpu_to64 (&res
, &ans
);
859 int status_u
= 0, status_l
= 0;
860 uint32_t res_u
, res_l
;
861 sim_fpu_32to (&wop
, FP_PS_upper(op
));
862 status_u
|= (*sim_fpu_op
) (&ans
, &wop
);
863 sim_fpu_to32 (&res_u
, &ans
);
864 sim_fpu_32to (&wop
, FP_PS_lower(op
));
865 status_l
|= (*sim_fpu_op
) (&ans
, &wop
);
866 sim_fpu_to32 (&res_l
, &ans
);
867 result
= FP_PS_cat(res_u
, res_l
);
868 status
= status_u
| status_l
;
872 sim_io_error (SD
, "Bad switch\n");
875 update_fcsr (cpu
, cia
, status
);
880 fp_binary(sim_cpu
*cpu
,
882 int (*sim_fpu_op
)(sim_fpu
*, const sim_fpu
*, const sim_fpu
*),
890 sim_fpu_round round
= rounding_mode (GETRM());
891 sim_fpu_denorm denorm
= denorm_mode (cpu
);
892 sim_fpu_status status
= 0;
895 /* The format type has already been checked: */
901 sim_fpu_32to (&wop1
, op1
);
902 sim_fpu_32to (&wop2
, op2
);
903 status
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
904 status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
905 sim_fpu_to32 (&res
, &ans
);
912 sim_fpu_64to (&wop1
, op1
);
913 sim_fpu_64to (&wop2
, op2
);
914 status
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
915 status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
916 sim_fpu_to64 (&res
, &ans
);
922 int status_u
= 0, status_l
= 0;
923 uint32_t res_u
, res_l
;
924 sim_fpu_32to (&wop1
, FP_PS_upper(op1
));
925 sim_fpu_32to (&wop2
, FP_PS_upper(op2
));
926 status_u
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
927 sim_fpu_to32 (&res_u
, &ans
);
928 sim_fpu_32to (&wop1
, FP_PS_lower(op1
));
929 sim_fpu_32to (&wop2
, FP_PS_lower(op2
));
930 status_l
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
931 sim_fpu_to32 (&res_l
, &ans
);
932 result
= FP_PS_cat(res_u
, res_l
);
933 status
= status_u
| status_l
;
937 sim_io_error (SD
, "Bad switch\n");
940 update_fcsr (cpu
, cia
, status
);
944 /* Common MAC code for single operands (.s or .d), defers setting FCSR. */
945 static sim_fpu_status
946 inner_mac(int (*sim_fpu_op
)(sim_fpu
*, const sim_fpu
*, const sim_fpu
*),
954 sim_fpu_denorm denorm
,
960 sim_fpu_status status
= 0;
961 sim_fpu_status op_status
;
969 sim_fpu_32to (&wop1
, op1
);
970 sim_fpu_32to (&wop2
, op2
);
971 status
|= sim_fpu_mul (&ans
, &wop1
, &wop2
);
972 if (scale
!= 0 && sim_fpu_is_number (&ans
)) /* number or denorm */
973 ans
.normal_exp
+= scale
;
974 status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
977 sim_fpu_32to (&wop2
, op3
);
978 op_status
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
979 op_status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
984 op_status
= sim_fpu_neg (&ans
, &wop1
);
985 op_status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
988 sim_fpu_to32 (&res
, &ans
);
995 sim_fpu_64to (&wop1
, op1
);
996 sim_fpu_64to (&wop2
, op2
);
997 status
|= sim_fpu_mul (&ans
, &wop1
, &wop2
);
998 if (scale
!= 0 && sim_fpu_is_number (&ans
)) /* number or denorm */
999 ans
.normal_exp
+= scale
;
1000 status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
1003 sim_fpu_64to (&wop2
, op3
);
1004 op_status
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
1005 op_status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
1006 status
|= op_status
;
1010 op_status
= sim_fpu_neg (&ans
, &wop1
);
1011 op_status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
1012 status
|= op_status
;
1014 sim_fpu_to64 (&res
, &ans
);
1019 fprintf (stderr
, "Bad switch\n");
1026 /* Common implementation of madd, nmadd, msub, nmsub that does
1027 intermediate rounding per spec. Also used for recip2 and rsqrt2,
1028 which are transformed into equivalent nmsub operations. The scale
1029 argument is an adjustment to the exponent of the intermediate
1030 product op1*op2. It is currently non-zero for rsqrt2 (-1), which
1031 requires an effective division by 2. */
1033 fp_mac(sim_cpu
*cpu
,
1035 int (*sim_fpu_op
)(sim_fpu
*, const sim_fpu
*, const sim_fpu
*),
1043 sim_fpu_round round
= rounding_mode (GETRM());
1044 sim_fpu_denorm denorm
= denorm_mode (cpu
);
1045 sim_fpu_status status
= 0;
1046 uint64_t result
= 0;
1048 /* The format type has already been checked: */
1053 status
= inner_mac(sim_fpu_op
, op1
, op2
, op3
, scale
,
1054 negate
, fmt
, round
, denorm
, &result
);
1058 int status_u
, status_l
;
1059 uint64_t result_u
, result_l
;
1060 status_u
= inner_mac(sim_fpu_op
, FP_PS_upper(op1
), FP_PS_upper(op2
),
1061 FP_PS_upper(op3
), scale
, negate
, fmt_single
,
1062 round
, denorm
, &result_u
);
1063 status_l
= inner_mac(sim_fpu_op
, FP_PS_lower(op1
), FP_PS_lower(op2
),
1064 FP_PS_lower(op3
), scale
, negate
, fmt_single
,
1065 round
, denorm
, &result_l
);
1066 result
= FP_PS_cat(result_u
, result_l
);
1067 status
= status_u
| status_l
;
1071 sim_io_error (SD
, "Bad switch\n");
1074 update_fcsr (cpu
, cia
, status
);
1078 /* Common FMAC code for .s, .d. Defers setting FCSR to caller. */
1079 static sim_fpu_status
1080 inner_fmac (sim_cpu
*cpu
,
1081 int (*sim_fpu_op
) (sim_fpu
*, const sim_fpu
*, const sim_fpu
*),
1085 sim_fpu_round round
,
1086 sim_fpu_denorm denorm
,
1090 sim_fpu wop1
, wop2
, ans
;
1091 sim_fpu_status status
= 0;
1092 sim_fpu_status op_status
;
1099 sim_fpu_32to (&wop1
, op1
);
1100 sim_fpu_32to (&wop2
, op2
);
1101 status
|= sim_fpu_mul (&ans
, &wop1
, &wop2
);
1104 sim_fpu_32to (&wop2
, op3
);
1105 op_status
|= (*sim_fpu_op
) (&ans
, &wop2
, &wop1
);
1106 op_status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
1107 status
|= op_status
;
1108 sim_fpu_to32 (&t32
, &ans
);
1112 sim_fpu_64to (&wop1
, op1
);
1113 sim_fpu_64to (&wop2
, op2
);
1114 status
|= sim_fpu_mul (&ans
, &wop1
, &wop2
);
1117 sim_fpu_64to (&wop2
, op3
);
1118 op_status
|= (*sim_fpu_op
) (&ans
, &wop2
, &wop1
);
1119 op_status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
1120 status
|= op_status
;
1121 sim_fpu_to64 (&t64
, &ans
);
1124 sim_io_error (SD
, "Bad switch\n");
1132 fp_fmac (sim_cpu
*cpu
,
1134 int (*sim_fpu_op
) (sim_fpu
*, const sim_fpu
*, const sim_fpu
*),
1140 sim_fpu_round round
= rounding_mode (GETRM());
1141 sim_fpu_denorm denorm
= denorm_mode (cpu
);
1142 sim_fpu_status status
= 0;
1143 uint64_t result
= 0;
1149 status
= inner_fmac (cpu
, sim_fpu_op
, op1
, op2
, op3
,
1150 round
, denorm
, fmt
, &result
);
1153 sim_io_error (SD
, "Bad switch\n");
1156 update_fcsr (cpu
, cia
, status
);
1160 /* Common rsqrt code for single operands (.s or .d), intermediate rounding. */
1161 static sim_fpu_status
1162 inner_rsqrt(uint64_t op1
,
1164 sim_fpu_round round
,
1165 sim_fpu_denorm denorm
,
1170 sim_fpu_status status
= 0;
1171 sim_fpu_status op_status
;
1179 sim_fpu_32to (&wop1
, op1
);
1180 status
|= sim_fpu_sqrt (&ans
, &wop1
);
1181 status
|= sim_fpu_round_32 (&ans
, status
, round
);
1183 op_status
= sim_fpu_inv (&ans
, &wop1
);
1184 op_status
|= sim_fpu_round_32 (&ans
, round
, denorm
);
1185 sim_fpu_to32 (&res
, &ans
);
1187 status
|= op_status
;
1193 sim_fpu_64to (&wop1
, op1
);
1194 status
|= sim_fpu_sqrt (&ans
, &wop1
);
1195 status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
1197 op_status
= sim_fpu_inv (&ans
, &wop1
);
1198 op_status
|= sim_fpu_round_64 (&ans
, round
, denorm
);
1199 sim_fpu_to64 (&res
, &ans
);
1201 status
|= op_status
;
1205 fprintf (stderr
, "Bad switch\n");
1213 fp_inv_sqrt(sim_cpu
*cpu
,
1218 sim_fpu_round round
= rounding_mode (GETRM());
1219 sim_fpu_round denorm
= denorm_mode (cpu
);
1220 sim_fpu_status status
= 0;
1221 uint64_t result
= 0;
1223 /* The format type has already been checked: */
1228 status
= inner_rsqrt (op1
, fmt
, round
, denorm
, &result
);
1232 int status_u
, status_l
;
1233 uint64_t result_u
, result_l
;
1234 status_u
= inner_rsqrt (FP_PS_upper(op1
), fmt_single
, round
, denorm
,
1236 status_l
= inner_rsqrt (FP_PS_lower(op1
), fmt_single
, round
, denorm
,
1238 result
= FP_PS_cat(result_u
, result_l
);
1239 status
= status_u
| status_l
;
1243 sim_io_error (SD
, "Bad switch\n");
1246 update_fcsr (cpu
, cia
, status
);
1252 fp_abs(sim_cpu
*cpu
,
1257 return fp_unary(cpu
, cia
, &sim_fpu_abs
, op
, fmt
);
1261 fp_neg(sim_cpu
*cpu
,
1266 return fp_unary(cpu
, cia
, &sim_fpu_neg
, op
, fmt
);
1270 fp_add(sim_cpu
*cpu
,
1276 return fp_binary(cpu
, cia
, &sim_fpu_add
, op1
, op2
, fmt
);
1280 fp_sub(sim_cpu
*cpu
,
1286 return fp_binary(cpu
, cia
, &sim_fpu_sub
, op1
, op2
, fmt
);
1290 fp_mul(sim_cpu
*cpu
,
1296 return fp_binary(cpu
, cia
, &sim_fpu_mul
, op1
, op2
, fmt
);
1300 fp_div(sim_cpu
*cpu
,
1306 return fp_binary(cpu
, cia
, &sim_fpu_div
, op1
, op2
, fmt
);
1310 fp_min (sim_cpu
*cpu
,
1316 return fp_binary (cpu
, cia
, &sim_fpu_min
, op1
, op2
, fmt
);
1320 fp_max (sim_cpu
*cpu
,
1326 return fp_binary (cpu
, cia
, &sim_fpu_max
, op1
, op2
, fmt
);
1330 fp_mina (sim_cpu
*cpu
,
1337 sim_fpu wop1
= {0}, wop2
= {0}, waop1
, waop2
, wans
;
1338 sim_fpu_status status
= 0;
1343 sim_fpu_32to (&wop1
, op1
);
1344 sim_fpu_32to (&wop2
, op2
);
1347 sim_fpu_64to (&wop1
, op1
);
1348 sim_fpu_64to (&wop2
, op2
);
1351 sim_io_error (SD
, "Bad switch\n");
1354 status
|= sim_fpu_abs (&waop1
, &wop1
);
1355 status
|= sim_fpu_abs (&waop2
, &wop2
);
1356 status
|= sim_fpu_min (&wans
, &waop1
, &waop2
);
1357 ret
= (sim_fpu_is_eq (&wans
, &waop1
)) ? op1
: op2
;
1359 update_fcsr (cpu
, cia
, status
);
1364 fp_maxa (sim_cpu
*cpu
,
1371 sim_fpu wop1
= {0}, wop2
= {0}, waop1
, waop2
, wans
;
1372 sim_fpu_status status
= 0;
1377 sim_fpu_32to (&wop1
, op1
);
1378 sim_fpu_32to (&wop2
, op2
);
1381 sim_fpu_64to (&wop1
, op1
);
1382 sim_fpu_64to (&wop2
, op2
);
1385 sim_io_error (SD
, "Bad switch\n");
1388 status
|= sim_fpu_abs (&waop1
, &wop1
);
1389 status
|= sim_fpu_abs (&waop2
, &wop2
);
1390 status
|= sim_fpu_max (&wans
, &waop1
, &waop2
);
1391 ret
= (sim_fpu_is_eq (&wans
, &waop1
)) ? op1
: op2
;
1393 update_fcsr (cpu
, cia
, status
);
1398 fp_recip(sim_cpu
*cpu
,
1403 return fp_unary(cpu
, cia
, &sim_fpu_inv
, op
, fmt
);
1407 fp_sqrt(sim_cpu
*cpu
,
1412 return fp_unary(cpu
, cia
, &sim_fpu_sqrt
, op
, fmt
);
1416 fp_rsqrt(sim_cpu
*cpu
,
1421 return fp_inv_sqrt(cpu
, cia
, op
, fmt
);
1425 fp_madd(sim_cpu
*cpu
,
1432 return fp_mac(cpu
, cia
, &sim_fpu_add
, op1
, op2
, op3
, 0, 0, fmt
);
1436 fp_msub(sim_cpu
*cpu
,
1443 return fp_mac(cpu
, cia
, &sim_fpu_sub
, op1
, op2
, op3
, 0, 0, fmt
);
1447 fp_fmadd (sim_cpu
*cpu
,
1454 return fp_fmac (cpu
, cia
, &sim_fpu_add
, op1
, op2
, op3
, fmt
);
1458 fp_fmsub (sim_cpu
*cpu
,
1465 return fp_fmac (cpu
, cia
, &sim_fpu_sub
, op1
, op2
, op3
, fmt
);
1469 fp_nmadd(sim_cpu
*cpu
,
1476 return fp_mac(cpu
, cia
, &sim_fpu_add
, op1
, op2
, op3
, 0, 1, fmt
);
1480 fp_nmsub(sim_cpu
*cpu
,
1487 return fp_mac(cpu
, cia
, &sim_fpu_sub
, op1
, op2
, op3
, 0, 1, fmt
);
1491 /* MIPS-3D ASE operations. */
1493 /* Variant of fp_binary for *r.ps MIPS-3D operations. */
1495 fp_binary_r(sim_cpu
*cpu
,
1497 int (*sim_fpu_op
)(sim_fpu
*, const sim_fpu
*, const sim_fpu
*),
1504 sim_fpu_round round
= rounding_mode (GETRM ());
1505 sim_fpu_denorm denorm
= denorm_mode (cpu
);
1506 sim_fpu_status status_u
, status_l
;
1508 uint32_t res_u
, res_l
;
1510 /* The format must be fmt_ps. */
1512 sim_fpu_32to (&wop1
, FP_PS_upper (op1
));
1513 sim_fpu_32to (&wop2
, FP_PS_lower (op1
));
1514 status_u
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
1515 status_u
|= sim_fpu_round_32 (&ans
, round
, denorm
);
1516 sim_fpu_to32 (&res_u
, &ans
);
1518 sim_fpu_32to (&wop1
, FP_PS_upper (op2
));
1519 sim_fpu_32to (&wop2
, FP_PS_lower (op2
));
1520 status_l
|= (*sim_fpu_op
) (&ans
, &wop1
, &wop2
);
1521 status_l
|= sim_fpu_round_32 (&ans
, round
, denorm
);
1522 sim_fpu_to32 (&res_l
, &ans
);
1523 result
= FP_PS_cat (res_u
, res_l
);
1525 update_fcsr (cpu
, cia
, status_u
| status_l
);
1530 fp_add_r(sim_cpu
*cpu
,
1536 return fp_binary_r (cpu
, cia
, &sim_fpu_add
, op1
, op2
);
1540 fp_mul_r(sim_cpu
*cpu
,
1546 return fp_binary_r (cpu
, cia
, &sim_fpu_mul
, op1
, op2
);
1549 #define NR_FRAC_GUARD (60)
1550 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
1553 fpu_inv1(sim_fpu
*f
, const sim_fpu
*l
)
1555 static const sim_fpu sim_fpu_one
= {
1556 sim_fpu_class_number
, 0, IMPLICIT_1
, 0
1561 if (sim_fpu_is_zero (l
))
1565 return sim_fpu_status_invalid_div0
;
1567 if (sim_fpu_is_infinity (l
))
1573 status
|= sim_fpu_div (f
, &sim_fpu_one
, l
);
1578 fpu_inv1_32(sim_fpu
*f
, const sim_fpu
*l
)
1580 if (sim_fpu_is_zero (l
))
1584 return sim_fpu_status_invalid_div0
;
1586 return fpu_inv1 (f
, l
);
1590 fpu_inv1_64(sim_fpu
*f
, const sim_fpu
*l
)
1592 if (sim_fpu_is_zero (l
))
1596 return sim_fpu_status_invalid_div0
;
1598 return fpu_inv1 (f
, l
);
1602 fp_recip1(sim_cpu
*cpu
,
1611 return fp_unary (cpu
, cia
, &fpu_inv1_32
, op
, fmt
);
1613 return fp_unary (cpu
, cia
, &fpu_inv1_64
, op
, fmt
);
1619 fp_recip2(sim_cpu
*cpu
,
1625 static const uint64_t one_single
= UNSIGNED64 (0x3F800000);
1626 static const uint64_t one_double
= UNSIGNED64 (0x3FF0000000000000);
1627 static const uint64_t one_ps
= (UNSIGNED64 (0x3F800000) << 32 | UNSIGNED64 (0x3F800000));
1630 /* Implemented as nmsub fd, 1, fs, ft. */
1633 case fmt_single
: one
= one_single
; break;
1634 case fmt_double
: one
= one_double
; break;
1635 case fmt_ps
: one
= one_ps
; break;
1636 default: one
= 0; abort ();
1638 return fp_mac (cpu
, cia
, &sim_fpu_sub
, op1
, op2
, one
, 0, 1, fmt
);
1642 fpu_inv_sqrt1(sim_fpu
*f
, const sim_fpu
*l
)
1644 static const sim_fpu sim_fpu_one
= {
1645 sim_fpu_class_number
, 0, IMPLICIT_1
, 0
1650 if (sim_fpu_is_zero (l
))
1654 return sim_fpu_status_invalid_div0
;
1656 if (sim_fpu_is_infinity (l
))
1660 f
->class = sim_fpu_class_zero
;
1666 status
= sim_fpu_status_invalid_sqrt
;
1670 status
|= sim_fpu_sqrt (&t
, l
);
1671 status
|= sim_fpu_div (f
, &sim_fpu_one
, &t
);
1676 fpu_inv_sqrt1_32(sim_fpu
*f
, const sim_fpu
*l
)
1678 if (sim_fpu_is_zero (l
))
1682 return sim_fpu_status_invalid_div0
;
1684 return fpu_inv_sqrt1 (f
, l
);
1688 fpu_inv_sqrt1_64(sim_fpu
*f
, const sim_fpu
*l
)
1690 if (sim_fpu_is_zero (l
))
1694 return sim_fpu_status_invalid_div0
;
1696 return fpu_inv_sqrt1 (f
, l
);
1700 fp_rsqrt1(sim_cpu
*cpu
,
1709 return fp_unary (cpu
, cia
, &fpu_inv_sqrt1_32
, op
, fmt
);
1711 return fp_unary (cpu
, cia
, &fpu_inv_sqrt1_64
, op
, fmt
);
1717 fp_rsqrt2(sim_cpu
*cpu
,
1723 static const uint64_t half_single
= UNSIGNED64 (0x3F000000);
1724 static const uint64_t half_double
= UNSIGNED64 (0x3FE0000000000000);
1725 static const uint64_t half_ps
= (UNSIGNED64 (0x3F000000) << 32 | UNSIGNED64 (0x3F000000));
1728 /* Implemented as (nmsub fd, 0.5, fs, ft)/2, where the divide is
1729 done by scaling the exponent during multiply. */
1732 case fmt_single
: half
= half_single
; break;
1733 case fmt_double
: half
= half_double
; break;
1734 case fmt_ps
: half
= half_ps
; break;
1735 default: half
= 0; abort ();
1737 return fp_mac (cpu
, cia
, &sim_fpu_sub
, op1
, op2
, half
, -1, 1, fmt
);
1741 /* Conversion operations. */
1744 convert (sim_cpu
*cpu
,
1752 sim_fpu_round round
= rounding_mode (rm
);
1753 sim_fpu_denorm denorm
= denorm_mode (cpu
);
1756 sim_fpu_status status
= 0;
1758 /* Convert the input to sim_fpu internal format */
1762 sim_fpu_64to (&wop
, op
);
1765 sim_fpu_32to (&wop
, op
);
1768 status
= sim_fpu_i32to (&wop
, op
, round
);
1771 status
= sim_fpu_i64to (&wop
, op
, round
);
1774 sim_io_error (SD
, "Bad switch\n");
1777 /* Convert sim_fpu format into the output */
1778 /* The value WOP is converted to the destination format, rounding
1779 using mode RM. When the destination is a fixed-point format, then
1780 a source value of Infinity, NaN or one which would round to an
1781 integer outside the fixed point range then an IEEE Invalid Operation
1782 condition is raised. Not used if destination format is PS. */
1786 status
|= sim_fpu_round_32 (&wop
, round
, denorm
);
1787 /* For a NaN, normalize mantissa bits (cvt.s.d can't preserve them) */
1788 if (sim_fpu_is_qnan (&wop
))
1790 sim_fpu_to32 (&result32
, &wop
);
1791 result64
= result32
;
1794 status
|= sim_fpu_round_64 (&wop
, round
, denorm
);
1795 /* For a NaN, normalize mantissa bits (make cvt.d.s consistent) */
1796 if (sim_fpu_is_qnan (&wop
))
1798 sim_fpu_to64 (&result64
, &wop
);
1801 status
|= sim_fpu_to32u (&result32
, &wop
, round
);
1802 result64
= result32
;
1805 status
|= sim_fpu_to64u (&result64
, &wop
, round
);
1809 sim_io_error (SD
, "Bad switch\n");
1812 update_fcsr (cpu
, cia
, status
);
1817 ps_lower(sim_cpu
*cpu
,
1821 return FP_PS_lower (op
);
1825 ps_upper(sim_cpu
*cpu
,
1829 return FP_PS_upper(op
);
1833 pack_ps(sim_cpu
*cpu
,
1839 uint64_t result
= 0;
1841 /* The registers must specify FPRs valid for operands of type
1842 "fmt". If they are not valid, the result is undefined. */
1844 /* The format type should already have been checked: */
1850 uint32_t res_u
, res_l
;
1851 sim_fpu_32to (&wop
, op1
);
1852 sim_fpu_to32 (&res_u
, &wop
);
1853 sim_fpu_32to (&wop
, op2
);
1854 sim_fpu_to32 (&res_l
, &wop
);
1855 result
= FP_PS_cat(res_u
, res_l
);
1859 sim_io_error (SD
, "Bad switch\n");
1866 convert_ps (sim_cpu
*cpu
,
1873 sim_fpu wop_u
, wop_l
;
1874 sim_fpu_round round
= rounding_mode (rm
);
1875 sim_fpu_denorm denorm
= denorm_mode (cpu
);
1876 uint32_t res_u
, res_l
;
1878 sim_fpu_status status_u
= 0, status_l
= 0;
1880 /* As convert, but used only for paired values (formats PS, PW) */
1882 /* Convert the input to sim_fpu internal format */
1885 case fmt_word
: /* fmt_pw */
1886 sim_fpu_i32to (&wop_u
, (op
>> 32) & (unsigned)0xFFFFFFFF, round
);
1887 sim_fpu_i32to (&wop_l
, op
& (unsigned)0xFFFFFFFF, round
);
1890 sim_fpu_32to (&wop_u
, FP_PS_upper(op
));
1891 sim_fpu_32to (&wop_l
, FP_PS_lower(op
));
1894 sim_io_error (SD
, "Bad switch\n");
1897 /* Convert sim_fpu format into the output */
1900 case fmt_word
: /* fmt_pw */
1901 status_u
|= sim_fpu_to32u (&res_u
, &wop_u
, round
);
1902 status_l
|= sim_fpu_to32u (&res_l
, &wop_l
, round
);
1903 result
= (((uint64_t)res_u
) << 32) | (uint64_t)res_l
;
1906 status_u
|= sim_fpu_round_32 (&wop_u
, 0, round
);
1907 status_l
|= sim_fpu_round_32 (&wop_l
, 0, round
);
1908 sim_fpu_to32 (&res_u
, &wop_u
);
1909 sim_fpu_to32 (&res_l
, &wop_l
);
1910 result
= FP_PS_cat(res_u
, res_l
);
1914 sim_io_error (SD
, "Bad switch\n");
1917 update_fcsr (cpu
, cia
, status_u
| status_l
);
1922 fpu_format_name (FP_formats fmt
)
1938 case fmt_uninterpreted
:
1939 return "<uninterpreted>";
1940 case fmt_uninterpreted_32
:
1941 return "<uninterpreted_32>";
1942 case fmt_uninterpreted_64
:
1943 return "<uninterpreted_64>";
1945 return "<format error>";
1951 fpu_rounding_mode_name (int rm
)
1964 return "<rounding mode error>";