summaryrefslogtreecommitdiffstats
path: root/lib/libc/sparc64/fpu/fpu_implode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/sparc64/fpu/fpu_implode.c')
-rw-r--r--lib/libc/sparc64/fpu/fpu_implode.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/lib/libc/sparc64/fpu/fpu_implode.c b/lib/libc/sparc64/fpu/fpu_implode.c
index 5287d2b..2a2a9d0 100644
--- a/lib/libc/sparc64/fpu/fpu_implode.c
+++ b/lib/libc/sparc64/fpu/fpu_implode.c
@@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
+#ifdef FPU_DEBUG
+#include <stdio.h>
+#endif
+
#include <machine/frame.h>
#include <machine/fp.h>
#include <machine/fsr.h>
@@ -198,7 +202,6 @@ __fpu_ftoi(fe, fp)
sign = fp->fp_sign;
switch (fp->fp_class) {
-
case FPC_ZERO:
return (0);
@@ -248,10 +251,9 @@ __fpu_ftox(fe, fp, res)
sign = fp->fp_sign;
switch (fp->fp_class) {
-
case FPC_ZERO:
- res[1] = 0;
- return (0);
+ i = 0;
+ goto done;
case FPC_NUM:
/*
@@ -275,15 +277,17 @@ __fpu_ftox(fe, fp, res)
break;
if (sign)
i = -i;
- res[1] = (int)i;
- return (i >> 32);
+ goto done;
default: /* Inf, qNaN, sNaN */
break;
}
/* overflow: replace any inexact exception with invalid */
fe->fe_cx = (fe->fe_cx & ~FSR_NX) | FSR_NV;
- return (0x7fffffffffffffffLL + sign);
+ i = 0x7fffffffffffffffLL + sign;
+done:
+ res[1] = i & 0xffffffff;
+ return (i >> 32);
}
/*
@@ -325,8 +329,9 @@ __fpu_ftos(fe, fp)
* right to introduce leading zeroes. Rounding then acts
* differently for normals and subnormals: the largest subnormal
* may round to the smallest normal (1.0 x 2^minexp), or may
- * remain subnormal. In the latter case, signal an underflow
- * if the result was inexact or if underflow traps are enabled.
+ * remain subnormal. A number that is subnormal before rounding
+ * will signal an underflow if the result is inexact or if underflow
+ * traps are enabled.
*
* Rounding a normal, on the other hand, always produces another
* normal (although either way the result might be too big for
@@ -341,8 +346,10 @@ __fpu_ftos(fe, fp)
if ((exp = fp->fp_exp + SNG_EXP_BIAS) <= 0) { /* subnormal */
/* -NG for g,r; -SNG_FRACBITS-exp for fraction */
(void) __fpu_shr(fp, FP_NMANT - FP_NG - SNG_FRACBITS - exp);
- if (fpround(fe, fp) && fp->fp_mant[3] == SNG_EXP(1))
+ if (fpround(fe, fp) && fp->fp_mant[3] == SNG_EXP(1)) {
+ fe->fe_cx |= FSR_UF;
return (sign | SNG_EXP(1) | 0);
+ }
if ((fe->fe_cx & FSR_NX) ||
(fe->fe_fsr & (FSR_UF << FSR_TEM_SHIFT)))
fe->fe_cx |= FSR_UF;
@@ -403,6 +410,7 @@ zero: res[1] = 0;
if ((exp = fp->fp_exp + DBL_EXP_BIAS) <= 0) {
(void) __fpu_shr(fp, FP_NMANT - FP_NG - DBL_FRACBITS - exp);
if (fpround(fe, fp) && fp->fp_mant[2] == DBL_EXP(1)) {
+ fe->fe_cx |= FSR_UF;
res[1] = 0;
return (sign | DBL_EXP(1) | 0);
}
@@ -422,7 +430,7 @@ zero: res[1] = 0;
return (sign | DBL_EXP(DBL_EXP_INFNAN) | 0);
}
res[1] = ~0;
- return (sign | DBL_EXP(DBL_EXP_INFNAN) | DBL_MASK);
+ return (sign | DBL_EXP(DBL_EXP_INFNAN - 1) | DBL_MASK);
}
done:
res[1] = fp->fp_mant[3];
@@ -464,6 +472,7 @@ zero: res[1] = res[2] = res[3] = 0;
if ((exp = fp->fp_exp + EXT_EXP_BIAS) <= 0) {
(void) __fpu_shr(fp, FP_NMANT - FP_NG - EXT_FRACBITS - exp);
if (fpround(fe, fp) && fp->fp_mant[0] == EXT_EXP(1)) {
+ fe->fe_cx |= FSR_UF;
res[1] = res[2] = res[3] = 0;
return (sign | EXT_EXP(1) | 0);
}
@@ -483,7 +492,7 @@ zero: res[1] = res[2] = res[3] = 0;
return (sign | EXT_EXP(EXT_EXP_INFNAN) | 0);
}
res[1] = res[2] = res[3] = ~0;
- return (sign | EXT_EXP(EXT_EXP_INFNAN) | EXT_MASK);
+ return (sign | EXT_EXP(EXT_EXP_INFNAN - 1) | EXT_MASK);
}
done:
res[1] = fp->fp_mant[1];
@@ -504,7 +513,6 @@ __fpu_implode(fe, fp, type, space)
{
switch (type) {
-
case FTYPE_LNG:
space[0] = __fpu_ftox(fe, fp, space);
break;
OpenPOWER on IntegriCloud