d0cf8be8c979d2f8dcd0a83df24c6859aa40ea8d
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 /* Extract sign-bit: */
54 #define FP_S_s(v) (((v) & (((unsigned) 1) << 31)) ? 1 : 0)
55 #define FP_D_s(v) (((v) & (((uword64) 1) << 63)) ? 1 : 0)
56 /* Extract biased exponent: */
57 #define FP_S_be(v) (((v) >> 23) & 0xFF)
58 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
59 /* Extract unbiased Exponent: */
60 #define FP_S_e(v) (FP_S_be (v) - 0x7F)
61 #define FP_D_e(v) (FP_D_be (v) - 0x3FF)
62 /* Extract complete fraction field: */
63 #define FP_S_f(v) ((v) & ~(((unsigned) 0x1FF) << 23))
64 #define FP_D_f(v) ((v) & ~(((uword64) 0xFFF) << 52))
65 /* Extract numbered fraction bit: */
66 #define FP_S_fb(b, v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
67 #define FP_D_fb(b, v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
69 /* Explicit QNaN values used when value required: */
70 #define FPQNaN_SINGLE (0x7FBFFFFF)
71 #define FPQNaN_WORD (0x7FFFFFFF)
72 #define FPQNaN_DOUBLE ((((uword64) 0x7FF7FFFF) << 32) | 0xFFFFFFFF)
73 #define FPQNaN_LONG ((((uword64) 0x7FFFFFFF) << 32) | 0xFFFFFFFF)
75 /* Explicit Infinity values used when required: */
76 #define FPINF_SINGLE (0x7F800000)
77 #define FPINF_DOUBLE ((((uword64) 0x7FF00000) << 32) | 0x00000000)
79 static const char *fpu_format_name (FP_formats fmt
);
81 static const char *fpu_rounding_mode_name (int rm
);
85 value_fpr (SIM_DESC sd
,
94 /* Treat unused register values, as fixed-point 64bit values: */
95 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
98 /* If request to read data as "uninterpreted", then use the current
100 fmt
= FPR_STATE
[fpr
];
106 /* For values not yet accessed, set to the desired format: */
107 if (FPR_STATE
[fpr
] == fmt_uninterpreted
)
109 FPR_STATE
[fpr
] = fmt
;
111 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr
,
112 fpu_format_name (fmt
));
115 if (fmt
!= FPR_STATE
[fpr
])
117 sim_io_eprintf (sd
, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
118 fpr
, fpu_format_name (FPR_STATE
[fpr
]),
119 fpu_format_name (fmt
), pr_addr (cia
));
120 FPR_STATE
[fpr
] = fmt_unknown
;
123 if (FPR_STATE
[fpr
] == fmt_unknown
)
125 /* Set QNaN value: */
129 value
= FPQNaN_SINGLE
;
133 value
= FPQNaN_DOUBLE
;
149 else if (SizeFGR () == 64)
155 value
= (FGR
[fpr
] & 0xFFFFFFFF);
158 case fmt_uninterpreted
:
175 value
= (FGR
[fpr
] & 0xFFFFFFFF);
178 case fmt_uninterpreted
:
183 /* even registers only */
185 printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
186 fpr
+ 1, pr_uword64 ((uword64
) FGR
[fpr
+1]),
187 fpr
, pr_uword64 ((uword64
) FGR
[fpr
]));
189 value
= ((((uword64
) FGR
[fpr
+1]) << 32)
190 | (FGR
[fpr
] & 0xFFFFFFFF));
194 SignalException (ReservedInstruction
, 0);
205 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
208 printf ("DBG: ValueFPR: 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
),
217 store_fpr (SIM_DESC sd
,
227 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
228 fpr
, fpu_format_name (fmt
), pr_uword64 (value
), pr_addr (cia
),
232 if (SizeFGR () == 64)
236 case fmt_uninterpreted_32
:
237 fmt
= fmt_uninterpreted
;
240 if (STATE_VERBOSE_P (SD
))
242 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
244 FGR
[fpr
] = (((uword64
) 0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
245 FPR_STATE
[fpr
] = fmt
;
248 case fmt_uninterpreted_64
:
249 fmt
= fmt_uninterpreted
;
250 case fmt_uninterpreted
:
254 FPR_STATE
[fpr
] = fmt
;
258 FPR_STATE
[fpr
] = fmt_unknown
;
267 case fmt_uninterpreted_32
:
268 fmt
= fmt_uninterpreted
;
271 FGR
[fpr
] = (value
& 0xFFFFFFFF);
272 FPR_STATE
[fpr
] = fmt
;
275 case fmt_uninterpreted_64
:
276 fmt
= fmt_uninterpreted
;
277 case fmt_uninterpreted
:
282 /* even register number only */
283 FGR
[fpr
+1] = (value
>> 32);
284 FGR
[fpr
] = (value
& 0xFFFFFFFF);
285 FPR_STATE
[fpr
+ 1] = fmt
;
286 FPR_STATE
[fpr
] = fmt
;
290 FPR_STATE
[fpr
] = fmt_unknown
;
291 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
292 SignalException (ReservedInstruction
, 0);
297 FPR_STATE
[fpr
] = fmt_unknown
;
302 #if defined(WARN_RESULT)
305 #endif /* WARN_RESULT */
308 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
311 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
312 fpr
, pr_uword64 (FGR
[fpr
]), fpu_format_name (fmt
));
330 sim_fpu_32to (&wop
, op
);
331 boolean
= sim_fpu_is_nan (&wop
);
338 sim_fpu_64to (&wop
, op
);
339 boolean
= sim_fpu_is_nan (&wop
);
343 fprintf (stderr
, "Bad switch\n");
348 printf ("DBG: NaN: returning %d for 0x%s (format = %s)\n",
349 boolean
, pr_addr (op
), fpu_format_name (fmt
));
363 printf ("DBG: Infinity: format %s 0x%s\n",
364 fpu_format_name (fmt
), pr_addr (op
));
372 sim_fpu_32to (&wop
, op
);
373 boolean
= sim_fpu_is_infinity (&wop
);
379 sim_fpu_64to (&wop
, op
);
380 boolean
= sim_fpu_is_infinity (&wop
);
384 printf ("DBG: TODO: unrecognised format (%s) for Infinity check\n",
385 fpu_format_name (fmt
));
390 printf ("DBG: Infinity: returning %d for 0x%s (format = %s)\n",
391 boolean
, pr_addr (op
), fpu_format_name (fmt
));
405 /* Argument checking already performed by the FPCOMPARE code */
408 printf ("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",
409 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
412 /* The format type should already have been checked: */
419 sim_fpu_32to (&wop1
, op1
);
420 sim_fpu_32to (&wop2
, op2
);
421 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
428 sim_fpu_64to (&wop1
, op1
);
429 sim_fpu_64to (&wop2
, op2
);
430 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
434 fprintf (stderr
, "Bad switch\n");
439 printf ("DBG: Less: returning %d (format = %s)\n",
440 boolean
, fpu_format_name (fmt
));
447 Equal (op1
, op2
, fmt
)
454 /* Argument checking already performed by the FPCOMPARE code */
457 printf ("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",
458 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
461 /* The format type should already have been checked: */
468 sim_fpu_32to (&wop1
, op1
);
469 sim_fpu_32to (&wop2
, op2
);
470 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
477 sim_fpu_64to (&wop1
, op1
);
478 sim_fpu_64to (&wop2
, op2
);
479 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
483 fprintf (stderr
, "Bad switch\n");
488 printf ("DBG: Equal: returning %d (format = %s)\n",
489 boolean
, fpu_format_name (fmt
));
496 AbsoluteValue (op
, fmt
)
503 printf ("DBG: AbsoluteValue: %s: op = 0x%s\n",
504 fpu_format_name (fmt
), pr_addr (op
));
507 /* The format type should already have been checked: */
514 sim_fpu_32to (&wop
, op
);
515 sim_fpu_abs (&wop
, &wop
);
516 sim_fpu_to32 (&ans
, &wop
);
524 sim_fpu_64to (&wop
, op
);
525 sim_fpu_abs (&wop
, &wop
);
526 sim_fpu_to64 (&ans
, &wop
);
531 fprintf (stderr
, "Bad switch\n");
546 printf ("DBG: Negate: %s: op = 0x%s\n",
547 fpu_format_name (fmt
), pr_addr (op
));
550 /* The format type should already have been checked: */
557 sim_fpu_32to (&wop
, op
);
558 sim_fpu_neg (&wop
, &wop
);
559 sim_fpu_to32 (&ans
, &wop
);
567 sim_fpu_64to (&wop
, op
);
568 sim_fpu_neg (&wop
, &wop
);
569 sim_fpu_to64 (&ans
, &wop
);
574 fprintf (stderr
, "Bad switch\n");
590 printf ("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",
591 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
594 /* The registers must specify FPRs valid for operands of type
595 "fmt". If they are not valid, the result is undefined. */
597 /* The format type should already have been checked: */
606 sim_fpu_32to (&wop1
, op1
);
607 sim_fpu_32to (&wop2
, op2
);
608 sim_fpu_add (&ans
, &wop1
, &wop2
);
609 sim_fpu_to32 (&res
, &ans
);
619 sim_fpu_64to (&wop1
, op1
);
620 sim_fpu_64to (&wop2
, op2
);
621 sim_fpu_add (&ans
, &wop1
, &wop2
);
622 sim_fpu_to64 (&res
, &ans
);
627 fprintf (stderr
, "Bad switch\n");
632 printf ("DBG: Add: returning 0x%s (format = %s)\n",
633 pr_addr (result
), fpu_format_name (fmt
));
648 printf ("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",
649 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
652 /* The registers must specify FPRs valid for operands of type
653 "fmt". If they are not valid, the result is undefined. */
655 /* The format type should already have been checked: */
664 sim_fpu_32to (&wop1
, op1
);
665 sim_fpu_32to (&wop2
, op2
);
666 sim_fpu_sub (&ans
, &wop1
, &wop2
);
667 sim_fpu_to32 (&res
, &ans
);
677 sim_fpu_64to (&wop1
, op1
);
678 sim_fpu_64to (&wop2
, op2
);
679 sim_fpu_sub (&ans
, &wop1
, &wop2
);
680 sim_fpu_to64 (&res
, &ans
);
685 fprintf (stderr
, "Bad switch\n");
690 printf ("DBG: Sub: returning 0x%s (format = %s)\n",
691 pr_addr (result
), fpu_format_name (fmt
));
698 Multiply (op1
, op2
, fmt
)
706 printf ("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",
707 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
710 /* The registers must specify FPRs valid for operands of type
711 "fmt". If they are not valid, the result is undefined. */
713 /* The format type should already have been checked: */
722 sim_fpu_32to (&wop1
, op1
);
723 sim_fpu_32to (&wop2
, op2
);
724 sim_fpu_mul (&ans
, &wop1
, &wop2
);
725 sim_fpu_to32 (&res
, &ans
);
735 sim_fpu_64to (&wop1
, op1
);
736 sim_fpu_64to (&wop2
, op2
);
737 sim_fpu_mul (&ans
, &wop1
, &wop2
);
738 sim_fpu_to64 (&res
, &ans
);
743 fprintf (stderr
, "Bad switch\n");
748 printf ("DBG: Multiply: returning 0x%s (format = %s)\n",
749 pr_addr (result
), fpu_format_name (fmt
));
756 Divide (op1
, op2
, fmt
)
764 printf ("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",
765 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
768 /* The registers must specify FPRs valid for operands of type
769 "fmt". If they are not valid, the result is undefined. */
771 /* The format type should already have been checked: */
780 sim_fpu_32to (&wop1
, op1
);
781 sim_fpu_32to (&wop2
, op2
);
782 sim_fpu_div (&ans
, &wop1
, &wop2
);
783 sim_fpu_to32 (&res
, &ans
);
793 sim_fpu_64to (&wop1
, op1
);
794 sim_fpu_64to (&wop2
, op2
);
795 sim_fpu_div (&ans
, &wop1
, &wop2
);
796 sim_fpu_to64 (&res
, &ans
);
801 fprintf (stderr
, "Bad switch\n");
806 printf ("DBG: Divide: returning 0x%s (format = %s)\n",
807 pr_addr (result
), fpu_format_name (fmt
));
821 printf ("DBG: Recip: %s: op = 0x%s\n",
822 fpu_format_name (fmt
), pr_addr (op
));
825 /* The registers must specify FPRs valid for operands of type
826 "fmt". If they are not valid, the result is undefined. */
828 /* The format type should already have been checked: */
836 sim_fpu_32to (&wop
, op
);
837 sim_fpu_inv (&ans
, &wop
);
838 sim_fpu_to32 (&res
, &ans
);
847 sim_fpu_64to (&wop
, op
);
848 sim_fpu_inv (&ans
, &wop
);
849 sim_fpu_to64 (&res
, &ans
);
854 fprintf (stderr
, "Bad switch\n");
859 printf ("DBG: Recip: returning 0x%s (format = %s)\n",
860 pr_addr (result
), fpu_format_name (fmt
));
874 printf ("DBG: SquareRoot: %s: op = 0x%s\n",
875 fpu_format_name (fmt
), pr_addr (op
));
878 /* The registers must specify FPRs valid for operands of type
879 "fmt". If they are not valid, the result is undefined. */
881 /* The format type should already have been checked: */
889 sim_fpu_32to (&wop
, op
);
890 sim_fpu_sqrt (&ans
, &wop
);
891 sim_fpu_to32 (&res
, &ans
);
900 sim_fpu_64to (&wop
, op
);
901 sim_fpu_sqrt (&ans
, &wop
);
902 sim_fpu_to64 (&res
, &ans
);
907 fprintf (stderr
, "Bad switch\n");
912 printf ("DBG: SquareRoot: returning 0x%s (format = %s)\n",
913 pr_addr (result
), fpu_format_name (fmt
));
929 printf ("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",
930 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
933 /* The registers must specify FPRs valid for operands of type
934 "fmt". If they are not valid, the result is undefined. */
936 /* The format type should already have been checked: */
943 sim_fpu_32to (&wop1
, op1
);
944 sim_fpu_32to (&wop2
, op2
);
945 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
952 sim_fpu_64to (&wop1
, op1
);
953 sim_fpu_64to (&wop2
, op2
);
954 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
958 fprintf (stderr
, "Bad switch\n");
964 case SIM_FPU_IS_SNAN
:
965 case SIM_FPU_IS_QNAN
:
967 case SIM_FPU_IS_NINF
:
968 case SIM_FPU_IS_NNUMBER
:
969 case SIM_FPU_IS_NDENORM
:
970 case SIM_FPU_IS_NZERO
:
971 result
= op2
; /* op1 - op2 < 0 */
972 case SIM_FPU_IS_PINF
:
973 case SIM_FPU_IS_PNUMBER
:
974 case SIM_FPU_IS_PDENORM
:
975 case SIM_FPU_IS_PZERO
:
976 result
= op1
; /* op1 - op2 > 0 */
978 fprintf (stderr
, "Bad switch\n");
983 printf ("DBG: Max: returning 0x%s (format = %s)\n",
984 pr_addr (result
), fpu_format_name (fmt
));
1001 printf ("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",
1002 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
1005 /* The registers must specify FPRs valid for operands of type
1006 "fmt". If they are not valid, the result is undefined. */
1008 /* The format type should already have been checked: */
1015 sim_fpu_32to (&wop1
, op1
);
1016 sim_fpu_32to (&wop2
, op2
);
1017 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
1024 sim_fpu_64to (&wop1
, op1
);
1025 sim_fpu_64to (&wop2
, op2
);
1026 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
1030 fprintf (stderr
, "Bad switch\n");
1036 case SIM_FPU_IS_SNAN
:
1037 case SIM_FPU_IS_QNAN
:
1039 case SIM_FPU_IS_NINF
:
1040 case SIM_FPU_IS_NNUMBER
:
1041 case SIM_FPU_IS_NDENORM
:
1042 case SIM_FPU_IS_NZERO
:
1043 result
= op1
; /* op1 - op2 < 0 */
1044 case SIM_FPU_IS_PINF
:
1045 case SIM_FPU_IS_PNUMBER
:
1046 case SIM_FPU_IS_PDENORM
:
1047 case SIM_FPU_IS_PZERO
:
1048 result
= op2
; /* op1 - op2 > 0 */
1050 fprintf (stderr
, "Bad switch\n");
1055 printf ("DBG: Min: returning 0x%s (format = %s)\n",
1056 pr_addr (result
), fpu_format_name (fmt
));
1064 convert (SIM_DESC sd
,
1073 sim_fpu_round round
;
1074 unsigned32 result32
;
1075 unsigned64 result64
;
1078 #if 0 /* FIXME: doesn't compile */
1079 printf ("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",
1080 fpu_rounding_mode_name (rm
), pr_addr (op
), fpu_format_name (from
),
1081 fpu_format_name (to
), pr_addr (IPC
));
1088 /* Round result to nearest representable value. When two
1089 representable values are equally near, round to the value
1090 that has a least significant bit of zero (i.e. is even). */
1091 round
= sim_fpu_round_near
;
1094 /* Round result to the value closest to, and not greater in
1095 magnitude than, the result. */
1096 round
= sim_fpu_round_zero
;
1099 /* Round result to the value closest to, and not less than,
1101 round
= sim_fpu_round_up
;
1105 /* Round result to the value closest to, and not greater than,
1107 round
= sim_fpu_round_down
;
1111 fprintf (stderr
, "Bad switch\n");
1115 /* Convert the input to sim_fpu internal format */
1119 sim_fpu_64to (&wop
, op
);
1122 sim_fpu_32to (&wop
, op
);
1125 sim_fpu_i32to (&wop
, op
, round
);
1128 sim_fpu_i64to (&wop
, op
, round
);
1131 fprintf (stderr
, "Bad switch\n");
1135 /* Convert sim_fpu format into the output */
1136 /* The value WOP is converted to the destination format, rounding
1137 using mode RM. When the destination is a fixed-point format, then
1138 a source value of Infinity, NaN or one which would round to an
1139 integer outside the fixed point range then an IEEE Invalid
1140 Operation condition is raised. */
1144 sim_fpu_round_32 (&wop
, round
, 0);
1145 sim_fpu_to32 (&result32
, &wop
);
1146 result64
= result32
;
1149 sim_fpu_round_64 (&wop
, round
, 0);
1150 sim_fpu_to64 (&result64
, &wop
);
1153 sim_fpu_to32i (&result32
, &wop
, round
);
1154 result64
= result32
;
1157 sim_fpu_to64i (&result64
, &wop
, round
);
1161 fprintf (stderr
, "Bad switch\n");
1166 printf ("DBG: Convert: returning 0x%s (to format = %s)\n",
1167 pr_addr (result64
), fpu_format_name (to
));
1174 fpu_format_name (FP_formats fmt
)
1188 case fmt_uninterpreted
:
1189 return "<uninterpreted>";
1190 case fmt_uninterpreted_32
:
1191 return "<uninterpreted_32>";
1192 case fmt_uninterpreted_64
:
1193 return "<uninterpreted_64>";
1195 return "<format error>";
1201 fpu_rounding_mode_name (int rm
)
1214 return "<rounding mode error>";
This page took 0.053153 seconds and 4 git commands to generate.