3b1cac2faaf35c5fab5a577f3df134fd5242107e
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.
31 SINGLE precision floating:
32 seeeeeeeefffffffffffffffffffffff
37 SINGLE precision fixed:
38 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
42 DOUBLE precision floating:
43 seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
48 DOUBLE precision fixed:
49 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
54 /* Explicit QNaN values used when value required: */
55 #define FPQNaN_SINGLE (0x7FBFFFFF)
56 #define FPQNaN_WORD (0x7FFFFFFF)
57 #define FPQNaN_DOUBLE (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))
58 #define FPQNaN_LONG (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))
60 static const char *fpu_format_name (FP_formats fmt
);
62 static const char *fpu_rounding_mode_name (int rm
);
66 value_fpr (SIM_DESC sd
,
75 /* Treat unused register values, as fixed-point 64bit values: */
76 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
79 /* If request to read data as "uninterpreted", then use the current
87 /* For values not yet accessed, set to the desired format: */
88 if (FPR_STATE
[fpr
] == fmt_uninterpreted
)
92 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr
,
93 fpu_format_name (fmt
));
96 if (fmt
!= FPR_STATE
[fpr
])
98 sim_io_eprintf (sd
, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
99 fpr
, fpu_format_name (FPR_STATE
[fpr
]),
100 fpu_format_name (fmt
), pr_addr (cia
));
101 FPR_STATE
[fpr
] = fmt_unknown
;
104 if (FPR_STATE
[fpr
] == fmt_unknown
)
106 /* Set QNaN value: */
110 value
= FPQNaN_SINGLE
;
114 value
= FPQNaN_DOUBLE
;
130 else if (SizeFGR () == 64)
136 value
= (FGR
[fpr
] & 0xFFFFFFFF);
139 case fmt_uninterpreted
:
156 value
= (FGR
[fpr
] & 0xFFFFFFFF);
159 case fmt_uninterpreted
:
164 /* even registers only */
166 printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
167 fpr
+ 1, pr_uword64 ((uword64
) FGR
[fpr
+1]),
168 fpr
, pr_uword64 ((uword64
) FGR
[fpr
]));
170 value
= ((((uword64
) FGR
[fpr
+1]) << 32)
171 | (FGR
[fpr
] & 0xFFFFFFFF));
175 SignalException (ReservedInstruction
, 0);
186 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
189 printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",
190 fpr
, fpu_format_name (fmt
), pr_uword64 (value
), pr_addr (cia
),
198 store_fpr (SIM_DESC sd
,
208 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
209 fpr
, fpu_format_name (fmt
), pr_uword64 (value
), pr_addr (cia
),
213 if (SizeFGR () == 64)
217 case fmt_uninterpreted_32
:
218 fmt
= fmt_uninterpreted
;
221 if (STATE_VERBOSE_P (SD
))
223 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
225 FGR
[fpr
] = (((uword64
) 0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
226 FPR_STATE
[fpr
] = fmt
;
229 case fmt_uninterpreted_64
:
230 fmt
= fmt_uninterpreted
;
231 case fmt_uninterpreted
:
235 FPR_STATE
[fpr
] = fmt
;
239 FPR_STATE
[fpr
] = fmt_unknown
;
248 case fmt_uninterpreted_32
:
249 fmt
= fmt_uninterpreted
;
252 FGR
[fpr
] = (value
& 0xFFFFFFFF);
253 FPR_STATE
[fpr
] = fmt
;
256 case fmt_uninterpreted_64
:
257 fmt
= fmt_uninterpreted
;
258 case fmt_uninterpreted
:
263 /* even register number only */
264 FGR
[fpr
+1] = (value
>> 32);
265 FGR
[fpr
] = (value
& 0xFFFFFFFF);
266 FPR_STATE
[fpr
+ 1] = fmt
;
267 FPR_STATE
[fpr
] = fmt
;
271 FPR_STATE
[fpr
] = fmt_unknown
;
272 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
273 SignalException (ReservedInstruction
, 0);
278 FPR_STATE
[fpr
] = fmt_unknown
;
285 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
288 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
289 fpr
, pr_uword64 (FGR
[fpr
]), fpu_format_name (fmt
));
307 sim_fpu_32to (&wop
, op
);
308 boolean
= sim_fpu_is_nan (&wop
);
315 sim_fpu_64to (&wop
, op
);
316 boolean
= sim_fpu_is_nan (&wop
);
320 fprintf (stderr
, "Bad switch\n");
325 printf ("DBG: NaN: returning %d for 0x%s (format = %s)\n",
326 boolean
, pr_addr (op
), fpu_format_name (fmt
));
340 printf ("DBG: Infinity: format %s 0x%s\n",
341 fpu_format_name (fmt
), pr_addr (op
));
349 sim_fpu_32to (&wop
, op
);
350 boolean
= sim_fpu_is_infinity (&wop
);
356 sim_fpu_64to (&wop
, op
);
357 boolean
= sim_fpu_is_infinity (&wop
);
361 printf ("DBG: TODO: unrecognised format (%s) for Infinity check\n",
362 fpu_format_name (fmt
));
367 printf ("DBG: Infinity: returning %d for 0x%s (format = %s)\n",
368 boolean
, pr_addr (op
), fpu_format_name (fmt
));
382 /* Argument checking already performed by the FPCOMPARE code */
385 printf ("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",
386 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
389 /* The format type should already have been checked: */
396 sim_fpu_32to (&wop1
, op1
);
397 sim_fpu_32to (&wop2
, op2
);
398 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
405 sim_fpu_64to (&wop1
, op1
);
406 sim_fpu_64to (&wop2
, op2
);
407 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
411 fprintf (stderr
, "Bad switch\n");
416 printf ("DBG: Less: returning %d (format = %s)\n",
417 boolean
, fpu_format_name (fmt
));
424 Equal (op1
, op2
, fmt
)
431 /* Argument checking already performed by the FPCOMPARE code */
434 printf ("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",
435 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
438 /* The format type should already have been checked: */
445 sim_fpu_32to (&wop1
, op1
);
446 sim_fpu_32to (&wop2
, op2
);
447 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
454 sim_fpu_64to (&wop1
, op1
);
455 sim_fpu_64to (&wop2
, op2
);
456 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
460 fprintf (stderr
, "Bad switch\n");
465 printf ("DBG: Equal: returning %d (format = %s)\n",
466 boolean
, fpu_format_name (fmt
));
473 AbsoluteValue (op
, fmt
)
480 printf ("DBG: AbsoluteValue: %s: op = 0x%s\n",
481 fpu_format_name (fmt
), pr_addr (op
));
484 /* The format type should already have been checked: */
491 sim_fpu_32to (&wop
, op
);
492 sim_fpu_abs (&wop
, &wop
);
493 sim_fpu_to32 (&ans
, &wop
);
501 sim_fpu_64to (&wop
, op
);
502 sim_fpu_abs (&wop
, &wop
);
503 sim_fpu_to64 (&ans
, &wop
);
508 fprintf (stderr
, "Bad switch\n");
523 printf ("DBG: Negate: %s: op = 0x%s\n",
524 fpu_format_name (fmt
), pr_addr (op
));
527 /* The format type should already have been checked: */
534 sim_fpu_32to (&wop
, op
);
535 sim_fpu_neg (&wop
, &wop
);
536 sim_fpu_to32 (&ans
, &wop
);
544 sim_fpu_64to (&wop
, op
);
545 sim_fpu_neg (&wop
, &wop
);
546 sim_fpu_to64 (&ans
, &wop
);
551 fprintf (stderr
, "Bad switch\n");
567 printf ("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",
568 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
571 /* The registers must specify FPRs valid for operands of type
572 "fmt". If they are not valid, the result is undefined. */
574 /* The format type should already have been checked: */
583 sim_fpu_32to (&wop1
, op1
);
584 sim_fpu_32to (&wop2
, op2
);
585 sim_fpu_add (&ans
, &wop1
, &wop2
);
586 sim_fpu_to32 (&res
, &ans
);
596 sim_fpu_64to (&wop1
, op1
);
597 sim_fpu_64to (&wop2
, op2
);
598 sim_fpu_add (&ans
, &wop1
, &wop2
);
599 sim_fpu_to64 (&res
, &ans
);
604 fprintf (stderr
, "Bad switch\n");
609 printf ("DBG: Add: returning 0x%s (format = %s)\n",
610 pr_addr (result
), fpu_format_name (fmt
));
625 printf ("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",
626 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
629 /* The registers must specify FPRs valid for operands of type
630 "fmt". If they are not valid, the result is undefined. */
632 /* The format type should already have been checked: */
641 sim_fpu_32to (&wop1
, op1
);
642 sim_fpu_32to (&wop2
, op2
);
643 sim_fpu_sub (&ans
, &wop1
, &wop2
);
644 sim_fpu_to32 (&res
, &ans
);
654 sim_fpu_64to (&wop1
, op1
);
655 sim_fpu_64to (&wop2
, op2
);
656 sim_fpu_sub (&ans
, &wop1
, &wop2
);
657 sim_fpu_to64 (&res
, &ans
);
662 fprintf (stderr
, "Bad switch\n");
667 printf ("DBG: Sub: returning 0x%s (format = %s)\n",
668 pr_addr (result
), fpu_format_name (fmt
));
675 Multiply (op1
, op2
, fmt
)
683 printf ("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",
684 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
687 /* The registers must specify FPRs valid for operands of type
688 "fmt". If they are not valid, the result is undefined. */
690 /* The format type should already have been checked: */
699 sim_fpu_32to (&wop1
, op1
);
700 sim_fpu_32to (&wop2
, op2
);
701 sim_fpu_mul (&ans
, &wop1
, &wop2
);
702 sim_fpu_to32 (&res
, &ans
);
712 sim_fpu_64to (&wop1
, op1
);
713 sim_fpu_64to (&wop2
, op2
);
714 sim_fpu_mul (&ans
, &wop1
, &wop2
);
715 sim_fpu_to64 (&res
, &ans
);
720 fprintf (stderr
, "Bad switch\n");
725 printf ("DBG: Multiply: returning 0x%s (format = %s)\n",
726 pr_addr (result
), fpu_format_name (fmt
));
733 Divide (op1
, op2
, fmt
)
741 printf ("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",
742 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
745 /* The registers must specify FPRs valid for operands of type
746 "fmt". If they are not valid, the result is undefined. */
748 /* The format type should already have been checked: */
757 sim_fpu_32to (&wop1
, op1
);
758 sim_fpu_32to (&wop2
, op2
);
759 sim_fpu_div (&ans
, &wop1
, &wop2
);
760 sim_fpu_to32 (&res
, &ans
);
770 sim_fpu_64to (&wop1
, op1
);
771 sim_fpu_64to (&wop2
, op2
);
772 sim_fpu_div (&ans
, &wop1
, &wop2
);
773 sim_fpu_to64 (&res
, &ans
);
778 fprintf (stderr
, "Bad switch\n");
783 printf ("DBG: Divide: returning 0x%s (format = %s)\n",
784 pr_addr (result
), fpu_format_name (fmt
));
798 printf ("DBG: Recip: %s: op = 0x%s\n",
799 fpu_format_name (fmt
), pr_addr (op
));
802 /* The registers must specify FPRs valid for operands of type
803 "fmt". If they are not valid, the result is undefined. */
805 /* The format type should already have been checked: */
813 sim_fpu_32to (&wop
, op
);
814 sim_fpu_inv (&ans
, &wop
);
815 sim_fpu_to32 (&res
, &ans
);
824 sim_fpu_64to (&wop
, op
);
825 sim_fpu_inv (&ans
, &wop
);
826 sim_fpu_to64 (&res
, &ans
);
831 fprintf (stderr
, "Bad switch\n");
836 printf ("DBG: Recip: returning 0x%s (format = %s)\n",
837 pr_addr (result
), fpu_format_name (fmt
));
851 printf ("DBG: SquareRoot: %s: op = 0x%s\n",
852 fpu_format_name (fmt
), pr_addr (op
));
855 /* The registers must specify FPRs valid for operands of type
856 "fmt". If they are not valid, the result is undefined. */
858 /* The format type should already have been checked: */
866 sim_fpu_32to (&wop
, op
);
867 sim_fpu_sqrt (&ans
, &wop
);
868 sim_fpu_to32 (&res
, &ans
);
877 sim_fpu_64to (&wop
, op
);
878 sim_fpu_sqrt (&ans
, &wop
);
879 sim_fpu_to64 (&res
, &ans
);
884 fprintf (stderr
, "Bad switch\n");
889 printf ("DBG: SquareRoot: returning 0x%s (format = %s)\n",
890 pr_addr (result
), fpu_format_name (fmt
));
906 printf ("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",
907 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
910 /* The registers must specify FPRs valid for operands of type
911 "fmt". If they are not valid, the result is undefined. */
913 /* The format type should already have been checked: */
920 sim_fpu_32to (&wop1
, op1
);
921 sim_fpu_32to (&wop2
, op2
);
922 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
929 sim_fpu_64to (&wop1
, op1
);
930 sim_fpu_64to (&wop2
, op2
);
931 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
935 fprintf (stderr
, "Bad switch\n");
941 case SIM_FPU_IS_SNAN
:
942 case SIM_FPU_IS_QNAN
:
944 case SIM_FPU_IS_NINF
:
945 case SIM_FPU_IS_NNUMBER
:
946 case SIM_FPU_IS_NDENORM
:
947 case SIM_FPU_IS_NZERO
:
948 result
= op2
; /* op1 - op2 < 0 */
949 case SIM_FPU_IS_PINF
:
950 case SIM_FPU_IS_PNUMBER
:
951 case SIM_FPU_IS_PDENORM
:
952 case SIM_FPU_IS_PZERO
:
953 result
= op1
; /* op1 - op2 > 0 */
955 fprintf (stderr
, "Bad switch\n");
960 printf ("DBG: Max: returning 0x%s (format = %s)\n",
961 pr_addr (result
), fpu_format_name (fmt
));
978 printf ("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",
979 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
982 /* The registers must specify FPRs valid for operands of type
983 "fmt". If they are not valid, the result is undefined. */
985 /* The format type should already have been checked: */
992 sim_fpu_32to (&wop1
, op1
);
993 sim_fpu_32to (&wop2
, op2
);
994 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
1001 sim_fpu_64to (&wop1
, op1
);
1002 sim_fpu_64to (&wop2
, op2
);
1003 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
1007 fprintf (stderr
, "Bad switch\n");
1013 case SIM_FPU_IS_SNAN
:
1014 case SIM_FPU_IS_QNAN
:
1016 case SIM_FPU_IS_NINF
:
1017 case SIM_FPU_IS_NNUMBER
:
1018 case SIM_FPU_IS_NDENORM
:
1019 case SIM_FPU_IS_NZERO
:
1020 result
= op1
; /* op1 - op2 < 0 */
1021 case SIM_FPU_IS_PINF
:
1022 case SIM_FPU_IS_PNUMBER
:
1023 case SIM_FPU_IS_PDENORM
:
1024 case SIM_FPU_IS_PZERO
:
1025 result
= op2
; /* op1 - op2 > 0 */
1027 fprintf (stderr
, "Bad switch\n");
1032 printf ("DBG: Min: returning 0x%s (format = %s)\n",
1033 pr_addr (result
), fpu_format_name (fmt
));
1041 convert (SIM_DESC sd
,
1050 sim_fpu_round round
;
1051 unsigned32 result32
;
1052 unsigned64 result64
;
1055 #if 0 /* FIXME: doesn't compile */
1056 printf ("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",
1057 fpu_rounding_mode_name (rm
), pr_addr (op
), fpu_format_name (from
),
1058 fpu_format_name (to
), pr_addr (IPC
));
1065 /* Round result to nearest representable value. When two
1066 representable values are equally near, round to the value
1067 that has a least significant bit of zero (i.e. is even). */
1068 round
= sim_fpu_round_near
;
1071 /* Round result to the value closest to, and not greater in
1072 magnitude than, the result. */
1073 round
= sim_fpu_round_zero
;
1076 /* Round result to the value closest to, and not less than,
1078 round
= sim_fpu_round_up
;
1082 /* Round result to the value closest to, and not greater than,
1084 round
= sim_fpu_round_down
;
1088 fprintf (stderr
, "Bad switch\n");
1092 /* Convert the input to sim_fpu internal format */
1096 sim_fpu_64to (&wop
, op
);
1099 sim_fpu_32to (&wop
, op
);
1102 sim_fpu_i32to (&wop
, op
, round
);
1105 sim_fpu_i64to (&wop
, op
, round
);
1108 fprintf (stderr
, "Bad switch\n");
1112 /* Convert sim_fpu format into the output */
1113 /* The value WOP is converted to the destination format, rounding
1114 using mode RM. When the destination is a fixed-point format, then
1115 a source value of Infinity, NaN or one which would round to an
1116 integer outside the fixed point range then an IEEE Invalid
1117 Operation condition is raised. */
1121 sim_fpu_round_32 (&wop
, round
, 0);
1122 sim_fpu_to32 (&result32
, &wop
);
1123 result64
= result32
;
1126 sim_fpu_round_64 (&wop
, round
, 0);
1127 sim_fpu_to64 (&result64
, &wop
);
1130 sim_fpu_to32i (&result32
, &wop
, round
);
1131 result64
= result32
;
1134 sim_fpu_to64i (&result64
, &wop
, round
);
1138 fprintf (stderr
, "Bad switch\n");
1143 printf ("DBG: Convert: returning 0x%s (to format = %s)\n",
1144 pr_addr (result64
), fpu_format_name (to
));
1151 fpu_format_name (FP_formats fmt
)
1165 case fmt_uninterpreted
:
1166 return "<uninterpreted>";
1167 case fmt_uninterpreted_32
:
1168 return "<uninterpreted_32>";
1169 case fmt_uninterpreted_64
:
1170 return "<uninterpreted_64>";
1172 return "<format error>";
1178 fpu_rounding_mode_name (int rm
)
1191 return "<rounding mode error>";
This page took 0.105102 seconds and 4 git commands to generate.