]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/mips/cp1.c
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
;
284 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
287 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
288 fpr
, pr_uword64 (FGR
[fpr
]), fpu_format_name (fmt
));
306 sim_fpu_32to (&wop
, op
);
307 boolean
= sim_fpu_is_nan (&wop
);
314 sim_fpu_64to (&wop
, op
);
315 boolean
= sim_fpu_is_nan (&wop
);
319 fprintf (stderr
, "Bad switch\n");
324 printf ("DBG: NaN: returning %d for 0x%s (format = %s)\n",
325 boolean
, pr_addr (op
), fpu_format_name (fmt
));
339 printf ("DBG: Infinity: format %s 0x%s\n",
340 fpu_format_name (fmt
), pr_addr (op
));
348 sim_fpu_32to (&wop
, op
);
349 boolean
= sim_fpu_is_infinity (&wop
);
355 sim_fpu_64to (&wop
, op
);
356 boolean
= sim_fpu_is_infinity (&wop
);
360 printf ("DBG: TODO: unrecognised format (%s) for Infinity check\n",
361 fpu_format_name (fmt
));
366 printf ("DBG: Infinity: returning %d for 0x%s (format = %s)\n",
367 boolean
, pr_addr (op
), fpu_format_name (fmt
));
381 /* Argument checking already performed by the FPCOMPARE code */
384 printf ("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",
385 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
388 /* The format type should already have been checked: */
395 sim_fpu_32to (&wop1
, op1
);
396 sim_fpu_32to (&wop2
, op2
);
397 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
404 sim_fpu_64to (&wop1
, op1
);
405 sim_fpu_64to (&wop2
, op2
);
406 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
410 fprintf (stderr
, "Bad switch\n");
415 printf ("DBG: Less: returning %d (format = %s)\n",
416 boolean
, fpu_format_name (fmt
));
423 Equal (op1
, op2
, fmt
)
430 /* Argument checking already performed by the FPCOMPARE code */
433 printf ("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",
434 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
437 /* The format type should already have been checked: */
444 sim_fpu_32to (&wop1
, op1
);
445 sim_fpu_32to (&wop2
, op2
);
446 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
453 sim_fpu_64to (&wop1
, op1
);
454 sim_fpu_64to (&wop2
, op2
);
455 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
459 fprintf (stderr
, "Bad switch\n");
464 printf ("DBG: Equal: returning %d (format = %s)\n",
465 boolean
, fpu_format_name (fmt
));
472 AbsoluteValue (op
, fmt
)
479 printf ("DBG: AbsoluteValue: %s: op = 0x%s\n",
480 fpu_format_name (fmt
), pr_addr (op
));
483 /* The format type should already have been checked: */
490 sim_fpu_32to (&wop
, op
);
491 sim_fpu_abs (&wop
, &wop
);
492 sim_fpu_to32 (&ans
, &wop
);
500 sim_fpu_64to (&wop
, op
);
501 sim_fpu_abs (&wop
, &wop
);
502 sim_fpu_to64 (&ans
, &wop
);
507 fprintf (stderr
, "Bad switch\n");
522 printf ("DBG: Negate: %s: op = 0x%s\n",
523 fpu_format_name (fmt
), pr_addr (op
));
526 /* The format type should already have been checked: */
533 sim_fpu_32to (&wop
, op
);
534 sim_fpu_neg (&wop
, &wop
);
535 sim_fpu_to32 (&ans
, &wop
);
543 sim_fpu_64to (&wop
, op
);
544 sim_fpu_neg (&wop
, &wop
);
545 sim_fpu_to64 (&ans
, &wop
);
550 fprintf (stderr
, "Bad switch\n");
566 printf ("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",
567 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
570 /* The registers must specify FPRs valid for operands of type
571 "fmt". If they are not valid, the result is undefined. */
573 /* The format type should already have been checked: */
582 sim_fpu_32to (&wop1
, op1
);
583 sim_fpu_32to (&wop2
, op2
);
584 sim_fpu_add (&ans
, &wop1
, &wop2
);
585 sim_fpu_to32 (&res
, &ans
);
595 sim_fpu_64to (&wop1
, op1
);
596 sim_fpu_64to (&wop2
, op2
);
597 sim_fpu_add (&ans
, &wop1
, &wop2
);
598 sim_fpu_to64 (&res
, &ans
);
603 fprintf (stderr
, "Bad switch\n");
608 printf ("DBG: Add: returning 0x%s (format = %s)\n",
609 pr_addr (result
), fpu_format_name (fmt
));
624 printf ("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",
625 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
628 /* The registers must specify FPRs valid for operands of type
629 "fmt". If they are not valid, the result is undefined. */
631 /* The format type should already have been checked: */
640 sim_fpu_32to (&wop1
, op1
);
641 sim_fpu_32to (&wop2
, op2
);
642 sim_fpu_sub (&ans
, &wop1
, &wop2
);
643 sim_fpu_to32 (&res
, &ans
);
653 sim_fpu_64to (&wop1
, op1
);
654 sim_fpu_64to (&wop2
, op2
);
655 sim_fpu_sub (&ans
, &wop1
, &wop2
);
656 sim_fpu_to64 (&res
, &ans
);
661 fprintf (stderr
, "Bad switch\n");
666 printf ("DBG: Sub: returning 0x%s (format = %s)\n",
667 pr_addr (result
), fpu_format_name (fmt
));
674 Multiply (op1
, op2
, fmt
)
682 printf ("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",
683 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
686 /* The registers must specify FPRs valid for operands of type
687 "fmt". If they are not valid, the result is undefined. */
689 /* The format type should already have been checked: */
698 sim_fpu_32to (&wop1
, op1
);
699 sim_fpu_32to (&wop2
, op2
);
700 sim_fpu_mul (&ans
, &wop1
, &wop2
);
701 sim_fpu_to32 (&res
, &ans
);
711 sim_fpu_64to (&wop1
, op1
);
712 sim_fpu_64to (&wop2
, op2
);
713 sim_fpu_mul (&ans
, &wop1
, &wop2
);
714 sim_fpu_to64 (&res
, &ans
);
719 fprintf (stderr
, "Bad switch\n");
724 printf ("DBG: Multiply: returning 0x%s (format = %s)\n",
725 pr_addr (result
), fpu_format_name (fmt
));
732 Divide (op1
, op2
, fmt
)
740 printf ("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",
741 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
744 /* The registers must specify FPRs valid for operands of type
745 "fmt". If they are not valid, the result is undefined. */
747 /* The format type should already have been checked: */
756 sim_fpu_32to (&wop1
, op1
);
757 sim_fpu_32to (&wop2
, op2
);
758 sim_fpu_div (&ans
, &wop1
, &wop2
);
759 sim_fpu_to32 (&res
, &ans
);
769 sim_fpu_64to (&wop1
, op1
);
770 sim_fpu_64to (&wop2
, op2
);
771 sim_fpu_div (&ans
, &wop1
, &wop2
);
772 sim_fpu_to64 (&res
, &ans
);
777 fprintf (stderr
, "Bad switch\n");
782 printf ("DBG: Divide: returning 0x%s (format = %s)\n",
783 pr_addr (result
), fpu_format_name (fmt
));
797 printf ("DBG: Recip: %s: op = 0x%s\n",
798 fpu_format_name (fmt
), pr_addr (op
));
801 /* The registers must specify FPRs valid for operands of type
802 "fmt". If they are not valid, the result is undefined. */
804 /* The format type should already have been checked: */
812 sim_fpu_32to (&wop
, op
);
813 sim_fpu_inv (&ans
, &wop
);
814 sim_fpu_to32 (&res
, &ans
);
823 sim_fpu_64to (&wop
, op
);
824 sim_fpu_inv (&ans
, &wop
);
825 sim_fpu_to64 (&res
, &ans
);
830 fprintf (stderr
, "Bad switch\n");
835 printf ("DBG: Recip: returning 0x%s (format = %s)\n",
836 pr_addr (result
), fpu_format_name (fmt
));
850 printf ("DBG: SquareRoot: %s: op = 0x%s\n",
851 fpu_format_name (fmt
), pr_addr (op
));
854 /* The registers must specify FPRs valid for operands of type
855 "fmt". If they are not valid, the result is undefined. */
857 /* The format type should already have been checked: */
865 sim_fpu_32to (&wop
, op
);
866 sim_fpu_sqrt (&ans
, &wop
);
867 sim_fpu_to32 (&res
, &ans
);
876 sim_fpu_64to (&wop
, op
);
877 sim_fpu_sqrt (&ans
, &wop
);
878 sim_fpu_to64 (&res
, &ans
);
883 fprintf (stderr
, "Bad switch\n");
888 printf ("DBG: SquareRoot: returning 0x%s (format = %s)\n",
889 pr_addr (result
), fpu_format_name (fmt
));
905 printf ("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",
906 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
909 /* The registers must specify FPRs valid for operands of type
910 "fmt". If they are not valid, the result is undefined. */
912 /* The format type should already have been checked: */
919 sim_fpu_32to (&wop1
, op1
);
920 sim_fpu_32to (&wop2
, op2
);
921 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
928 sim_fpu_64to (&wop1
, op1
);
929 sim_fpu_64to (&wop2
, op2
);
930 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
934 fprintf (stderr
, "Bad switch\n");
940 case SIM_FPU_IS_SNAN
:
941 case SIM_FPU_IS_QNAN
:
943 case SIM_FPU_IS_NINF
:
944 case SIM_FPU_IS_NNUMBER
:
945 case SIM_FPU_IS_NDENORM
:
946 case SIM_FPU_IS_NZERO
:
947 result
= op2
; /* op1 - op2 < 0 */
948 case SIM_FPU_IS_PINF
:
949 case SIM_FPU_IS_PNUMBER
:
950 case SIM_FPU_IS_PDENORM
:
951 case SIM_FPU_IS_PZERO
:
952 result
= op1
; /* op1 - op2 > 0 */
954 fprintf (stderr
, "Bad switch\n");
959 printf ("DBG: Max: returning 0x%s (format = %s)\n",
960 pr_addr (result
), fpu_format_name (fmt
));
977 printf ("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",
978 fpu_format_name (fmt
), pr_addr (op1
), pr_addr (op2
));
981 /* The registers must specify FPRs valid for operands of type
982 "fmt". If they are not valid, the result is undefined. */
984 /* The format type should already have been checked: */
991 sim_fpu_32to (&wop1
, op1
);
992 sim_fpu_32to (&wop2
, op2
);
993 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
1000 sim_fpu_64to (&wop1
, op1
);
1001 sim_fpu_64to (&wop2
, op2
);
1002 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
1006 fprintf (stderr
, "Bad switch\n");
1012 case SIM_FPU_IS_SNAN
:
1013 case SIM_FPU_IS_QNAN
:
1015 case SIM_FPU_IS_NINF
:
1016 case SIM_FPU_IS_NNUMBER
:
1017 case SIM_FPU_IS_NDENORM
:
1018 case SIM_FPU_IS_NZERO
:
1019 result
= op1
; /* op1 - op2 < 0 */
1020 case SIM_FPU_IS_PINF
:
1021 case SIM_FPU_IS_PNUMBER
:
1022 case SIM_FPU_IS_PDENORM
:
1023 case SIM_FPU_IS_PZERO
:
1024 result
= op2
; /* op1 - op2 > 0 */
1026 fprintf (stderr
, "Bad switch\n");
1031 printf ("DBG: Min: returning 0x%s (format = %s)\n",
1032 pr_addr (result
), fpu_format_name (fmt
));
1040 convert (SIM_DESC sd
,
1049 sim_fpu_round round
;
1050 unsigned32 result32
;
1051 unsigned64 result64
;
1054 #if 0 /* FIXME: doesn't compile */
1055 printf ("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",
1056 fpu_rounding_mode_name (rm
), pr_addr (op
), fpu_format_name (from
),
1057 fpu_format_name (to
), pr_addr (IPC
));
1064 /* Round result to nearest representable value. When two
1065 representable values are equally near, round to the value
1066 that has a least significant bit of zero (i.e. is even). */
1067 round
= sim_fpu_round_near
;
1070 /* Round result to the value closest to, and not greater in
1071 magnitude than, the result. */
1072 round
= sim_fpu_round_zero
;
1075 /* Round result to the value closest to, and not less than,
1077 round
= sim_fpu_round_up
;
1081 /* Round result to the value closest to, and not greater than,
1083 round
= sim_fpu_round_down
;
1087 fprintf (stderr
, "Bad switch\n");
1091 /* Convert the input to sim_fpu internal format */
1095 sim_fpu_64to (&wop
, op
);
1098 sim_fpu_32to (&wop
, op
);
1101 sim_fpu_i32to (&wop
, op
, round
);
1104 sim_fpu_i64to (&wop
, op
, round
);
1107 fprintf (stderr
, "Bad switch\n");
1111 /* Convert sim_fpu format into the output */
1112 /* The value WOP is converted to the destination format, rounding
1113 using mode RM. When the destination is a fixed-point format, then
1114 a source value of Infinity, NaN or one which would round to an
1115 integer outside the fixed point range then an IEEE Invalid
1116 Operation condition is raised. */
1120 sim_fpu_round_32 (&wop
, round
, 0);
1121 sim_fpu_to32 (&result32
, &wop
);
1122 result64
= result32
;
1125 sim_fpu_round_64 (&wop
, round
, 0);
1126 sim_fpu_to64 (&result64
, &wop
);
1129 sim_fpu_to32i (&result32
, &wop
, round
);
1130 result64
= result32
;
1133 sim_fpu_to64i (&result64
, &wop
, round
);
1137 fprintf (stderr
, "Bad switch\n");
1142 printf ("DBG: Convert: returning 0x%s (to format = %s)\n",
1143 pr_addr (result64
), fpu_format_name (to
));
1150 fpu_format_name (FP_formats fmt
)
1164 case fmt_uninterpreted
:
1165 return "<uninterpreted>";
1166 case fmt_uninterpreted_32
:
1167 return "<uninterpreted_32>";
1168 case fmt_uninterpreted_64
:
1169 return "<uninterpreted_64>";
1171 return "<format error>";
1177 fpu_rounding_mode_name (int rm
)
1190 return "<rounding mode error>";