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. */
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. */
30 /* SINGLE precision floating:
31 * seeeeeeeefffffffffffffffffffffff
33 * e = 8bits = exponent
34 * f = 23bits = fraction
36 /* SINGLE precision fixed:
37 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
39 * i = 31bits = integer
41 /* DOUBLE precision floating:
42 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
44 * e = 11bits = exponent
45 * f = 52bits = fraction
47 /* DOUBLE precision fixed:
48 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
50 * i = 63bits = integer
53 /* Explicit QNaN values used when value required: */
54 #define FPQNaN_SINGLE (0x7FBFFFFF)
55 #define FPQNaN_WORD (0x7FFFFFFF)
56 #define FPQNaN_DOUBLE ((((uword64) 0x7FF7FFFF) << 32) | 0xFFFFFFFF)
57 #define FPQNaN_LONG ((((uword64) 0x7FFFFFFF) << 32) | 0xFFFFFFFF)
59 static const char *fpu_format_name (FP_formats fmt
);
61 static const char *fpu_rounding_mode_name (int rm
);
65 value_fpr (SIM_DESC sd
,
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_DESC sd
,
207 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
208 fpr
, fpu_format_name (fmt
), pr_uword64 (value
), pr_addr (cia
),
212 if (SizeFGR () == 64)
216 case fmt_uninterpreted_32
:
217 fmt
= fmt_uninterpreted
;
220 if (STATE_VERBOSE_P (SD
))
222 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
224 FGR
[fpr
] = (((uword64
) 0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
225 FPR_STATE
[fpr
] = fmt
;
228 case fmt_uninterpreted_64
:
229 fmt
= fmt_uninterpreted
;
230 case fmt_uninterpreted
:
234 FPR_STATE
[fpr
] = fmt
;
238 FPR_STATE
[fpr
] = fmt_unknown
;
247 case fmt_uninterpreted_32
:
248 fmt
= fmt_uninterpreted
;
251 FGR
[fpr
] = (value
& 0xFFFFFFFF);
252 FPR_STATE
[fpr
] = fmt
;
255 case fmt_uninterpreted_64
:
256 fmt
= fmt_uninterpreted
;
257 case fmt_uninterpreted
:
262 /* even register number only */
263 FGR
[fpr
+1] = (value
>> 32);
264 FGR
[fpr
] = (value
& 0xFFFFFFFF);
265 FPR_STATE
[fpr
+ 1] = fmt
;
266 FPR_STATE
[fpr
] = fmt
;
270 FPR_STATE
[fpr
] = fmt_unknown
;
271 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
272 SignalException (ReservedInstruction
, 0);
277 FPR_STATE
[fpr
] = fmt_unknown
;
282 #if defined(WARN_RESULT)
285 #endif /* WARN_RESULT */
288 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
291 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
292 fpr
, pr_uword64 (FGR
[fpr
]), fpu_format_name (fmt
));
310 sim_fpu_32to (&wop
, op
);
311 boolean
= sim_fpu_is_nan (&wop
);
318 sim_fpu_64to (&wop
, op
);
319 boolean
= sim_fpu_is_nan (&wop
);
323 fprintf (stderr
, "Bad switch\n");
328 printf ("DBG: NaN: returning %d for 0x%s (format = %s)\n",
329 boolean
, pr_addr (op
), fpu_format_name (fmt
));
343 printf ("DBG: Infinity: format %s 0x%s\n",
344 fpu_format_name (fmt
), pr_addr (op
));
352 sim_fpu_32to (&wop
, op
);
353 boolean
= sim_fpu_is_infinity (&wop
);
359 sim_fpu_64to (&wop
, op
);
360 boolean
= sim_fpu_is_infinity (&wop
);
364 printf ("DBG: TODO: unrecognised format (%s) for Infinity check\n",
365 fpu_format_name (fmt
));
370 printf ("DBG: Infinity: returning %d for 0x%s (format = %s)\n",
371 boolean
, pr_addr (op
), fpu_format_name (fmt
));
385 /* Argument checking already performed by the FPCOMPARE code */
388 printf ("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",
389 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
392 /* The format type should already have been checked: */
399 sim_fpu_32to (&wop1
, op1
);
400 sim_fpu_32to (&wop2
, op2
);
401 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
408 sim_fpu_64to (&wop1
, op1
);
409 sim_fpu_64to (&wop2
, op2
);
410 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
414 fprintf (stderr
, "Bad switch\n");
419 printf ("DBG: Less: returning %d (format = %s)\n",
420 boolean
, fpu_format_name (fmt
));
427 Equal (op1
, op2
, fmt
)
434 /* Argument checking already performed by the FPCOMPARE code */
437 printf ("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",
438 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
441 /* The format type should already have been checked: */
448 sim_fpu_32to (&wop1
, op1
);
449 sim_fpu_32to (&wop2
, op2
);
450 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
457 sim_fpu_64to (&wop1
, op1
);
458 sim_fpu_64to (&wop2
, op2
);
459 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
463 fprintf (stderr
, "Bad switch\n");
468 printf ("DBG: Equal: returning %d (format = %s)\n",
469 boolean
, fpu_format_name (fmt
));
476 AbsoluteValue (op
, fmt
)
483 printf ("DBG: AbsoluteValue: %s: op = 0x%s\n",
484 fpu_format_name (fmt
), pr_addr (op
));
487 /* The format type should already have been checked: */
494 sim_fpu_32to (&wop
, op
);
495 sim_fpu_abs (&wop
, &wop
);
496 sim_fpu_to32 (&ans
, &wop
);
504 sim_fpu_64to (&wop
, op
);
505 sim_fpu_abs (&wop
, &wop
);
506 sim_fpu_to64 (&ans
, &wop
);
511 fprintf (stderr
, "Bad switch\n");
526 printf ("DBG: Negate: %s: op = 0x%s\n",
527 fpu_format_name (fmt
), pr_addr (op
));
530 /* The format type should already have been checked: */
537 sim_fpu_32to (&wop
, op
);
538 sim_fpu_neg (&wop
, &wop
);
539 sim_fpu_to32 (&ans
, &wop
);
547 sim_fpu_64to (&wop
, op
);
548 sim_fpu_neg (&wop
, &wop
);
549 sim_fpu_to64 (&ans
, &wop
);
554 fprintf (stderr
, "Bad switch\n");
570 printf ("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",
571 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
574 /* The registers must specify FPRs valid for operands of type
575 "fmt". If they are not valid, the result is undefined. */
577 /* The format type should already have been checked: */
586 sim_fpu_32to (&wop1
, op1
);
587 sim_fpu_32to (&wop2
, op2
);
588 sim_fpu_add (&ans
, &wop1
, &wop2
);
589 sim_fpu_to32 (&res
, &ans
);
599 sim_fpu_64to (&wop1
, op1
);
600 sim_fpu_64to (&wop2
, op2
);
601 sim_fpu_add (&ans
, &wop1
, &wop2
);
602 sim_fpu_to64 (&res
, &ans
);
607 fprintf (stderr
, "Bad switch\n");
612 printf ("DBG: Add: returning 0x%s (format = %s)\n",
613 pr_addr (result
), fpu_format_name (fmt
));
628 printf ("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",
629 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
632 /* The registers must specify FPRs valid for operands of type
633 "fmt". If they are not valid, the result is undefined. */
635 /* The format type should already have been checked: */
644 sim_fpu_32to (&wop1
, op1
);
645 sim_fpu_32to (&wop2
, op2
);
646 sim_fpu_sub (&ans
, &wop1
, &wop2
);
647 sim_fpu_to32 (&res
, &ans
);
657 sim_fpu_64to (&wop1
, op1
);
658 sim_fpu_64to (&wop2
, op2
);
659 sim_fpu_sub (&ans
, &wop1
, &wop2
);
660 sim_fpu_to64 (&res
, &ans
);
665 fprintf (stderr
, "Bad switch\n");
670 printf ("DBG: Sub: returning 0x%s (format = %s)\n",
671 pr_addr (result
), fpu_format_name (fmt
));
678 Multiply (op1
, op2
, fmt
)
686 printf ("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",
687 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
690 /* The registers must specify FPRs valid for operands of type
691 "fmt". If they are not valid, the result is undefined. */
693 /* The format type should already have been checked: */
702 sim_fpu_32to (&wop1
, op1
);
703 sim_fpu_32to (&wop2
, op2
);
704 sim_fpu_mul (&ans
, &wop1
, &wop2
);
705 sim_fpu_to32 (&res
, &ans
);
715 sim_fpu_64to (&wop1
, op1
);
716 sim_fpu_64to (&wop2
, op2
);
717 sim_fpu_mul (&ans
, &wop1
, &wop2
);
718 sim_fpu_to64 (&res
, &ans
);
723 fprintf (stderr
, "Bad switch\n");
728 printf ("DBG: Multiply: returning 0x%s (format = %s)\n",
729 pr_addr (result
), fpu_format_name (fmt
));
736 Divide (op1
, op2
, fmt
)
744 printf ("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",
745 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
748 /* The registers must specify FPRs valid for operands of type
749 "fmt". If they are not valid, the result is undefined. */
751 /* The format type should already have been checked: */
760 sim_fpu_32to (&wop1
, op1
);
761 sim_fpu_32to (&wop2
, op2
);
762 sim_fpu_div (&ans
, &wop1
, &wop2
);
763 sim_fpu_to32 (&res
, &ans
);
773 sim_fpu_64to (&wop1
, op1
);
774 sim_fpu_64to (&wop2
, op2
);
775 sim_fpu_div (&ans
, &wop1
, &wop2
);
776 sim_fpu_to64 (&res
, &ans
);
781 fprintf (stderr
, "Bad switch\n");
786 printf ("DBG: Divide: returning 0x%s (format = %s)\n",
787 pr_addr (result
), fpu_format_name (fmt
));
801 printf ("DBG: Recip: %s: op = 0x%s\n",
802 fpu_format_name (fmt
), pr_addr (op
));
805 /* The registers must specify FPRs valid for operands of type
806 "fmt". If they are not valid, the result is undefined. */
808 /* The format type should already have been checked: */
816 sim_fpu_32to (&wop
, op
);
817 sim_fpu_inv (&ans
, &wop
);
818 sim_fpu_to32 (&res
, &ans
);
827 sim_fpu_64to (&wop
, op
);
828 sim_fpu_inv (&ans
, &wop
);
829 sim_fpu_to64 (&res
, &ans
);
834 fprintf (stderr
, "Bad switch\n");
839 printf ("DBG: Recip: returning 0x%s (format = %s)\n",
840 pr_addr (result
), fpu_format_name (fmt
));
854 printf ("DBG: SquareRoot: %s: op = 0x%s\n",
855 fpu_format_name (fmt
), pr_addr (op
));
858 /* The registers must specify FPRs valid for operands of type
859 "fmt". If they are not valid, the result is undefined. */
861 /* The format type should already have been checked: */
869 sim_fpu_32to (&wop
, op
);
870 sim_fpu_sqrt (&ans
, &wop
);
871 sim_fpu_to32 (&res
, &ans
);
880 sim_fpu_64to (&wop
, op
);
881 sim_fpu_sqrt (&ans
, &wop
);
882 sim_fpu_to64 (&res
, &ans
);
887 fprintf (stderr
, "Bad switch\n");
892 printf ("DBG: SquareRoot: returning 0x%s (format = %s)\n",
893 pr_addr (result
), fpu_format_name (fmt
));
909 printf ("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",
910 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
913 /* The registers must specify FPRs valid for operands of type
914 "fmt". If they are not valid, the result is undefined. */
916 /* The format type should already have been checked: */
923 sim_fpu_32to (&wop1
, op1
);
924 sim_fpu_32to (&wop2
, op2
);
925 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
932 sim_fpu_64to (&wop1
, op1
);
933 sim_fpu_64to (&wop2
, op2
);
934 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
938 fprintf (stderr
, "Bad switch\n");
944 case SIM_FPU_IS_SNAN
:
945 case SIM_FPU_IS_QNAN
:
947 case SIM_FPU_IS_NINF
:
948 case SIM_FPU_IS_NNUMBER
:
949 case SIM_FPU_IS_NDENORM
:
950 case SIM_FPU_IS_NZERO
:
951 result
= op2
; /* op1 - op2 < 0 */
952 case SIM_FPU_IS_PINF
:
953 case SIM_FPU_IS_PNUMBER
:
954 case SIM_FPU_IS_PDENORM
:
955 case SIM_FPU_IS_PZERO
:
956 result
= op1
; /* op1 - op2 > 0 */
958 fprintf (stderr
, "Bad switch\n");
963 printf ("DBG: Max: returning 0x%s (format = %s)\n",
964 pr_addr (result
), fpu_format_name (fmt
));
981 printf ("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",
982 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
985 /* The registers must specify FPRs valid for operands of type
986 "fmt". If they are not valid, the result is undefined. */
988 /* The format type should already have been checked: */
995 sim_fpu_32to (&wop1
, op1
);
996 sim_fpu_32to (&wop2
, op2
);
997 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
1004 sim_fpu_64to (&wop1
, op1
);
1005 sim_fpu_64to (&wop2
, op2
);
1006 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
1010 fprintf (stderr
, "Bad switch\n");
1016 case SIM_FPU_IS_SNAN
:
1017 case SIM_FPU_IS_QNAN
:
1019 case SIM_FPU_IS_NINF
:
1020 case SIM_FPU_IS_NNUMBER
:
1021 case SIM_FPU_IS_NDENORM
:
1022 case SIM_FPU_IS_NZERO
:
1023 result
= op1
; /* op1 - op2 < 0 */
1024 case SIM_FPU_IS_PINF
:
1025 case SIM_FPU_IS_PNUMBER
:
1026 case SIM_FPU_IS_PDENORM
:
1027 case SIM_FPU_IS_PZERO
:
1028 result
= op2
; /* op1 - op2 > 0 */
1030 fprintf (stderr
, "Bad switch\n");
1035 printf ("DBG: Min: returning 0x%s (format = %s)\n",
1036 pr_addr (result
), fpu_format_name (fmt
));
1044 convert (SIM_DESC sd
,
1053 sim_fpu_round round
;
1054 unsigned32 result32
;
1055 unsigned64 result64
;
1058 #if 0 /* FIXME: doesn't compile */
1059 printf ("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",
1060 fpu_rounding_mode_name (rm
), pr_addr (op
), fpu_format_name (from
),
1061 fpu_format_name (to
), pr_addr (IPC
));
1068 /* Round result to nearest representable value. When two
1069 representable values are equally near, round to the value
1070 that has a least significant bit of zero (i.e. is even). */
1071 round
= sim_fpu_round_near
;
1074 /* Round result to the value closest to, and not greater in
1075 magnitude than, the result. */
1076 round
= sim_fpu_round_zero
;
1079 /* Round result to the value closest to, and not less than,
1081 round
= sim_fpu_round_up
;
1085 /* Round result to the value closest to, and not greater than,
1087 round
= sim_fpu_round_down
;
1091 fprintf (stderr
, "Bad switch\n");
1095 /* Convert the input to sim_fpu internal format */
1099 sim_fpu_64to (&wop
, op
);
1102 sim_fpu_32to (&wop
, op
);
1105 sim_fpu_i32to (&wop
, op
, round
);
1108 sim_fpu_i64to (&wop
, op
, round
);
1111 fprintf (stderr
, "Bad switch\n");
1115 /* Convert sim_fpu format into the output */
1116 /* The value WOP is converted to the destination format, rounding
1117 using mode RM. When the destination is a fixed-point format, then
1118 a source value of Infinity, NaN or one which would round to an
1119 integer outside the fixed point range then an IEEE Invalid
1120 Operation condition is raised. */
1124 sim_fpu_round_32 (&wop
, round
, 0);
1125 sim_fpu_to32 (&result32
, &wop
);
1126 result64
= result32
;
1129 sim_fpu_round_64 (&wop
, round
, 0);
1130 sim_fpu_to64 (&result64
, &wop
);
1133 sim_fpu_to32i (&result32
, &wop
, round
);
1134 result64
= result32
;
1137 sim_fpu_to64i (&result64
, &wop
, round
);
1141 fprintf (stderr
, "Bad switch\n");
1146 printf ("DBG: Convert: returning 0x%s (to format = %s)\n",
1147 pr_addr (result64
), fpu_format_name (to
));
1154 fpu_format_name (FP_formats fmt
)
1168 case fmt_uninterpreted
:
1169 return "<uninterpreted>";
1170 case fmt_uninterpreted_32
:
1171 return "<uninterpreted_32>";
1172 case fmt_uninterpreted_64
:
1173 return "<uninterpreted_64>";
1175 return "<format error>";
1181 fpu_rounding_mode_name (int rm
)
1194 return "<rounding mode error>";