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))
97 /* If request to read data as "uninterpreted", then use the current
104 /* For values not yet accessed, set to the desired format: */
105 if (FPR_STATE[fpr] == fmt_uninterpreted) {
106 FPR_STATE[fpr] = fmt;
108 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr, fpu_format_name (fmt));
111 if (fmt != FPR_STATE[fpr]) {
112 sim_io_eprintf(sd,"FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",fpr, fpu_format_name (FPR_STATE[fpr]), fpu_format_name (fmt),pr_addr(cia));
113 FPR_STATE[fpr] = fmt_unknown;
116 if (FPR_STATE[fpr] == fmt_unknown) {
117 /* Set QNaN value: */
120 value = FPQNaN_SINGLE;
124 value = FPQNaN_DOUBLE;
139 } else if (SizeFGR() == 64) {
143 value = (FGR[fpr] & 0xFFFFFFFF);
146 case fmt_uninterpreted:
160 value = (FGR[fpr] & 0xFFFFFFFF);
163 case fmt_uninterpreted:
166 if ((fpr & 1) == 0) { /* even registers only */
168 printf("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
169 fpr+1, pr_uword64( (uword64) FGR[fpr+1] ),
170 fpr, pr_uword64( (uword64) FGR[fpr] ));
172 value = ((((uword64)FGR[fpr+1]) << 32) | (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",fpr, fpu_format_name (fmt),pr_uword64(value),pr_addr(cia),SizeFGR());
195 store_fpr (SIM_DESC sd,
205 printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d,\n",fpr, fpu_format_name (fmt),pr_uword64(value),pr_addr(cia),SizeFGR());
208 if (SizeFGR() == 64) {
210 case fmt_uninterpreted_32:
211 fmt = fmt_uninterpreted;
214 if (STATE_VERBOSE_P(SD))
215 sim_io_eprintf (SD, "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
217 FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
218 FPR_STATE[fpr] = fmt;
221 case fmt_uninterpreted_64:
222 fmt = fmt_uninterpreted;
223 case fmt_uninterpreted:
227 FPR_STATE[fpr] = fmt;
231 FPR_STATE[fpr] = fmt_unknown;
237 case fmt_uninterpreted_32:
238 fmt = fmt_uninterpreted;
241 FGR[fpr] = (value & 0xFFFFFFFF);
242 FPR_STATE[fpr] = fmt;
245 case fmt_uninterpreted_64:
246 fmt = fmt_uninterpreted;
247 case fmt_uninterpreted:
250 if ((fpr & 1) == 0) { /* even register number only */
251 FGR[fpr+1] = (value >> 32);
252 FGR[fpr] = (value & 0xFFFFFFFF);
253 FPR_STATE[fpr + 1] = fmt;
254 FPR_STATE[fpr] = fmt;
256 FPR_STATE[fpr] = fmt_unknown;
257 FPR_STATE[fpr + 1] = fmt_unknown;
258 SignalException(ReservedInstruction,0);
263 FPR_STATE[fpr] = fmt_unknown;
268 #if defined(WARN_RESULT)
271 #endif /* WARN_RESULT */
274 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
277 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_uword64(FGR[fpr]), fpu_format_name (fmt));
294 sim_fpu_32to (&wop, op);
295 boolean = sim_fpu_is_nan (&wop);
302 sim_fpu_64to (&wop, op);
303 boolean = sim_fpu_is_nan (&wop);
307 fprintf (stderr, "Bad switch\n");
312 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op), fpu_format_name (fmt));
326 printf("DBG: Infinity: format %s 0x%s\n", fpu_format_name (fmt),pr_addr(op));
333 sim_fpu_32to (&wop, op);
334 boolean = sim_fpu_is_infinity (&wop);
340 sim_fpu_64to (&wop, op);
341 boolean = sim_fpu_is_infinity (&wop);
345 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n", fpu_format_name (fmt));
350 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op), fpu_format_name (fmt));
364 /* Argument checking already performed by the FPCOMPARE code */
367 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2));
370 /* The format type should already have been checked: */
376 sim_fpu_32to (&wop1, op1);
377 sim_fpu_32to (&wop2, op2);
378 boolean = sim_fpu_is_lt (&wop1, &wop2);
385 sim_fpu_64to (&wop1, op1);
386 sim_fpu_64to (&wop2, op2);
387 boolean = sim_fpu_is_lt (&wop1, &wop2);
391 fprintf (stderr, "Bad switch\n");
396 printf("DBG: Less: returning %d (format = %s)\n",boolean, fpu_format_name (fmt));
410 /* Argument checking already performed by the FPCOMPARE code */
413 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2));
416 /* The format type should already have been checked: */
422 sim_fpu_32to (&wop1, op1);
423 sim_fpu_32to (&wop2, op2);
424 boolean = sim_fpu_is_eq (&wop1, &wop2);
431 sim_fpu_64to (&wop1, op1);
432 sim_fpu_64to (&wop2, op2);
433 boolean = sim_fpu_is_eq (&wop1, &wop2);
437 fprintf (stderr, "Bad switch\n");
442 printf("DBG: Equal: returning %d (format = %s)\n",boolean, fpu_format_name (fmt));
449 AbsoluteValue(op,fmt)
456 printf("DBG: AbsoluteValue: %s: op = 0x%s\n", fpu_format_name (fmt),pr_addr(op));
459 /* The format type should already have been checked: */
465 sim_fpu_32to (&wop, op);
466 sim_fpu_abs (&wop, &wop);
467 sim_fpu_to32 (&ans, &wop);
475 sim_fpu_64to (&wop, op);
476 sim_fpu_abs (&wop, &wop);
477 sim_fpu_to64 (&ans, &wop);
482 fprintf (stderr, "Bad switch\n");
497 printf("DBG: Negate: %s: op = 0x%s\n", fpu_format_name (fmt),pr_addr(op));
500 /* The format type should already have been checked: */
506 sim_fpu_32to (&wop, op);
507 sim_fpu_neg (&wop, &wop);
508 sim_fpu_to32 (&ans, &wop);
516 sim_fpu_64to (&wop, op);
517 sim_fpu_neg (&wop, &wop);
518 sim_fpu_to64 (&ans, &wop);
523 fprintf (stderr, "Bad switch\n");
539 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2));
542 /* The registers must specify FPRs valid for operands of type
543 "fmt". If they are not valid, the result is undefined. */
545 /* The format type should already have been checked: */
553 sim_fpu_32to (&wop1, op1);
554 sim_fpu_32to (&wop2, op2);
555 sim_fpu_add (&ans, &wop1, &wop2);
556 sim_fpu_to32 (&res, &ans);
566 sim_fpu_64to (&wop1, op1);
567 sim_fpu_64to (&wop2, op2);
568 sim_fpu_add (&ans, &wop1, &wop2);
569 sim_fpu_to64 (&res, &ans);
574 fprintf (stderr, "Bad switch\n");
579 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt));
594 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2));
597 /* The registers must specify FPRs valid for operands of type
598 "fmt". If they are not valid, the result is undefined. */
600 /* The format type should already have been checked: */
608 sim_fpu_32to (&wop1, op1);
609 sim_fpu_32to (&wop2, op2);
610 sim_fpu_sub (&ans, &wop1, &wop2);
611 sim_fpu_to32 (&res, &ans);
621 sim_fpu_64to (&wop1, op1);
622 sim_fpu_64to (&wop2, op2);
623 sim_fpu_sub (&ans, &wop1, &wop2);
624 sim_fpu_to64 (&res, &ans);
629 fprintf (stderr, "Bad switch\n");
634 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt));
641 Multiply(op1,op2,fmt)
649 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n", 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: */
663 sim_fpu_32to (&wop1, op1);
664 sim_fpu_32to (&wop2, op2);
665 sim_fpu_mul (&ans, &wop1, &wop2);
666 sim_fpu_to32 (&res, &ans);
676 sim_fpu_64to (&wop1, op1);
677 sim_fpu_64to (&wop2, op2);
678 sim_fpu_mul (&ans, &wop1, &wop2);
679 sim_fpu_to64 (&res, &ans);
684 fprintf (stderr, "Bad switch\n");
689 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt));
704 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2));
707 /* The registers must specify FPRs valid for operands of type
708 "fmt". If they are not valid, the result is undefined. */
710 /* The format type should already have been checked: */
718 sim_fpu_32to (&wop1, op1);
719 sim_fpu_32to (&wop2, op2);
720 sim_fpu_div (&ans, &wop1, &wop2);
721 sim_fpu_to32 (&res, &ans);
731 sim_fpu_64to (&wop1, op1);
732 sim_fpu_64to (&wop2, op2);
733 sim_fpu_div (&ans, &wop1, &wop2);
734 sim_fpu_to64 (&res, &ans);
739 fprintf (stderr, "Bad switch\n");
744 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt));
758 printf("DBG: Recip: %s: op = 0x%s\n", fpu_format_name (fmt),pr_addr(op));
761 /* The registers must specify FPRs valid for operands of type
762 "fmt". If they are not valid, the result is undefined. */
764 /* The format type should already have been checked: */
771 sim_fpu_32to (&wop, op);
772 sim_fpu_inv (&ans, &wop);
773 sim_fpu_to32 (&res, &ans);
782 sim_fpu_64to (&wop, op);
783 sim_fpu_inv (&ans, &wop);
784 sim_fpu_to64 (&res, &ans);
789 fprintf (stderr, "Bad switch\n");
794 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt));
808 printf("DBG: SquareRoot: %s: op = 0x%s\n", fpu_format_name (fmt),pr_addr(op));
811 /* The registers must specify FPRs valid for operands of type
812 "fmt". If they are not valid, the result is undefined. */
814 /* The format type should already have been checked: */
821 sim_fpu_32to (&wop, op);
822 sim_fpu_sqrt (&ans, &wop);
823 sim_fpu_to32 (&res, &ans);
832 sim_fpu_64to (&wop, op);
833 sim_fpu_sqrt (&ans, &wop);
834 sim_fpu_to64 (&res, &ans);
839 fprintf (stderr, "Bad switch\n");
844 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt));
860 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2));
863 /* The registers must specify FPRs valid for operands of type
864 "fmt". If they are not valid, the result is undefined. */
866 /* The format type should already have been checked: */
873 sim_fpu_32to (&wop1, op1);
874 sim_fpu_32to (&wop2, op2);
875 cmp = sim_fpu_cmp (&wop1, &wop2);
882 sim_fpu_64to (&wop1, op1);
883 sim_fpu_64to (&wop2, op2);
884 cmp = sim_fpu_cmp (&wop1, &wop2);
888 fprintf (stderr, "Bad switch\n");
894 case SIM_FPU_IS_SNAN:
895 case SIM_FPU_IS_QNAN:
897 case SIM_FPU_IS_NINF:
898 case SIM_FPU_IS_NNUMBER:
899 case SIM_FPU_IS_NDENORM:
900 case SIM_FPU_IS_NZERO:
901 result = op2; /* op1 - op2 < 0 */
902 case SIM_FPU_IS_PINF:
903 case SIM_FPU_IS_PNUMBER:
904 case SIM_FPU_IS_PDENORM:
905 case SIM_FPU_IS_PZERO:
906 result = op1; /* op1 - op2 > 0 */
908 fprintf (stderr, "Bad switch\n");
913 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt));
930 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n", 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 = op1; /* 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 = op2; /* op1 - op2 > 0 */
978 fprintf (stderr, "Bad switch\n");
983 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt));
991 convert (SIM_DESC sd,
1000 sim_fpu_round round;
1001 unsigned32 result32;
1002 unsigned64 result64;
1005 #if 0 /* FIXME: doesn't compile */
1006 printf("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n", fpu_rounding_mode_name (rm),pr_addr(op), fpu_format_name (from), fpu_format_name (to),pr_addr(IPC));
1013 /* Round result to nearest representable value. When two
1014 representable values are equally near, round to the value
1015 that has a least significant bit of zero (i.e. is even). */
1016 round = sim_fpu_round_near;
1019 /* Round result to the value closest to, and not greater in
1020 magnitude than, the result. */
1021 round = sim_fpu_round_zero;
1024 /* Round result to the value closest to, and not less than,
1026 round = sim_fpu_round_up;
1030 /* Round result to the value closest to, and not greater than,
1032 round = sim_fpu_round_down;
1036 fprintf (stderr, "Bad switch\n");
1040 /* Convert the input to sim_fpu internal format */
1044 sim_fpu_64to (&wop, op);
1047 sim_fpu_32to (&wop, op);
1050 sim_fpu_i32to (&wop, op, round);
1053 sim_fpu_i64to (&wop, op, round);
1056 fprintf (stderr, "Bad switch\n");
1060 /* Convert sim_fpu format into the output */
1061 /* The value WOP is converted to the destination format, rounding
1062 using mode RM. When the destination is a fixed-point format, then
1063 a source value of Infinity, NaN or one which would round to an
1064 integer outside the fixed point range then an IEEE Invalid
1065 Operation condition is raised. */
1069 sim_fpu_round_32 (&wop, round, 0);
1070 sim_fpu_to32 (&result32, &wop);
1071 result64 = result32;
1074 sim_fpu_round_64 (&wop, round, 0);
1075 sim_fpu_to64 (&result64, &wop);
1078 sim_fpu_to32i (&result32, &wop, round);
1079 result64 = result32;
1082 sim_fpu_to64i (&result64, &wop, round);
1086 fprintf (stderr, "Bad switch\n");
1091 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64), fpu_format_name (to));
1098 fpu_format_name (FP_formats fmt)
1112 case fmt_uninterpreted:
1113 return "<uninterpreted>";
1114 case fmt_uninterpreted_32:
1115 return "<uninterpreted_32>";
1116 case fmt_uninterpreted_64:
1117 return "<uninterpreted_64>";
1119 return "<format error>";
1125 fpu_rounding_mode_name (int rm)
1138 return "<rounding mode error>";