patch-2.4.19 linux-2.4.19/arch/mips/math-emu/ieee754sp.c
Next file: linux-2.4.19/arch/mips/math-emu/kernel_linkage.c
Previous file: linux-2.4.19/arch/mips/math-emu/ieee754int.h
Back to the patch index
Back to the overall index
- Lines: 160
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/mips/math-emu/ieee754sp.c
- Orig date:
Fri Apr 13 20:26:07 2001
diff -urN linux-2.4.18/arch/mips/math-emu/ieee754sp.c linux-2.4.19/arch/mips/math-emu/ieee754sp.c
@@ -42,9 +42,7 @@
int ieee754sp_issnan(ieee754sp x)
{
assert(ieee754sp_isnan(x));
- if (ieee754_csr.noq)
- return 1;
- return !(SPMANT(x) & SP_MBIT(SP_MBITS - 1));
+ return (SPMANT(x) & SP_MBIT(SP_MBITS-1));
}
@@ -74,10 +72,11 @@
if (!SETCX(IEEE754_INVALID_OPERATION)) {
/* not enabled convert to a quiet NaN */
- if (ieee754_csr.noq)
+ SPMANT(r) &= (~SP_MBIT(SP_MBITS-1));
+ if (ieee754sp_isnan(r))
return r;
- SPMANT(r) |= SP_MBIT(SP_MBITS - 1);
- return r;
+ else
+ return ieee754sp_indef();
}
ax.op = op;
@@ -100,6 +99,32 @@
}
+static unsigned get_rounding(int sn, unsigned xm)
+{
+ /* inexact must round of 3 bits
+ */
+ if (xm & (SP_MBIT(3) - 1)) {
+ switch (ieee754_csr.rm) {
+ case IEEE754_RZ:
+ break;
+ case IEEE754_RN:
+ xm += 0x3 + ((xm >> 3) & 1);
+ /* xm += (xm&0x8)?0x4:0x3 */
+ break;
+ case IEEE754_RU: /* toward +Infinity */
+ if (!sn) /* ?? */
+ xm += 0x8;
+ break;
+ case IEEE754_RD: /* toward -Infinity */
+ if (sn) /* ?? */
+ xm += 0x8;
+ break;
+ }
+ }
+ return xm;
+}
+
+
/* generate a normal/denormal number with over,under handeling
* sn is sign
* xe is an unbiased exponent
@@ -118,39 +143,58 @@
if (ieee754_csr.nod) {
SETCX(IEEE754_UNDERFLOW);
- return ieee754sp_zero(sn);
- }
+ SETCX(IEEE754_INEXACT);
- /* sticky right shift es bits
- */
- SPXSRSXn(es);
+ switch(ieee754_csr.rm) {
+ case IEEE754_RN:
+ return ieee754sp_zero(sn);
+ case IEEE754_RZ:
+ return ieee754sp_zero(sn);
+ case IEEE754_RU: /* toward +Infinity */
+ if(sn == 0)
+ return ieee754sp_min(0);
+ else
+ return ieee754sp_zero(1);
+ case IEEE754_RD: /* toward -Infinity */
+ if(sn == 0)
+ return ieee754sp_zero(0);
+ else
+ return ieee754sp_min(1);
+ }
+ }
- assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
- assert(xe == SP_EMIN);
+ if (xe == SP_EMIN - 1
+ && get_rounding(sn, xm) >> (SP_MBITS + 1 + 3))
+ {
+ /* Not tiny after rounding */
+ SETCX(IEEE754_INEXACT);
+ xm = get_rounding(sn, xm);
+ xm >>= 1;
+ /* Clear grs bits */
+ xm &= ~(SP_MBIT(3) - 1);
+ xe++;
+ }
+ else {
+ /* sticky right shift es bits
+ */
+ SPXSRSXn(es);
+ assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
+ assert(xe == SP_EMIN);
+ }
}
if (xm & (SP_MBIT(3) - 1)) {
SETCX(IEEE754_INEXACT);
+ if ((xm & (SP_HIDDEN_BIT << 3)) == 0) {
+ SETCX(IEEE754_UNDERFLOW);
+ }
+
/* inexact must round of 3 bits
*/
- switch (ieee754_csr.rm) {
- case IEEE754_RZ:
- break;
- case IEEE754_RN:
- xm += 0x3 + ((xm >> 3) & 1);
- /* xm += (xm&0x8)?0x4:0x3 */
- break;
- case IEEE754_RU: /* toward +Infinity */
- if (!sn) /* ?? */
- xm += 0x8;
- break;
- case IEEE754_RD: /* toward -Infinity */
- if (sn) /* ?? */
- xm += 0x8;
- break;
- }
+ xm = get_rounding(sn, xm);
/* adjust exponent for rounding add overflowing
*/
- if (xm >> (SP_MBITS + 1 + 3)) { /* add causes mantissa overflow */
+ if (xm >> (SP_MBITS + 1 + 3)) {
+ /* add causes mantissa overflow */
xm >>= 1;
xe++;
}
@@ -163,6 +207,7 @@
if (xe > SP_EMAX) {
SETCX(IEEE754_OVERFLOW);
+ SETCX(IEEE754_INEXACT);
/* -O can be table indexed by (rm,sn) */
switch (ieee754_csr.rm) {
case IEEE754_RN:
@@ -186,7 +231,8 @@
if ((xm & SP_HIDDEN_BIT) == 0) {
/* we underflow (tiny/zero) */
assert(xe == SP_EMIN);
- SETCX(IEEE754_UNDERFLOW);
+ if (ieee754_csr.mx & IEEE754_UNDERFLOW)
+ SETCX(IEEE754_UNDERFLOW);
return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm);
} else {
assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)