From: James S. <jsi...@us...> - 2001-11-21 22:15:30
|
Update of /cvsroot/linux-mips/linux/arch/mips/math-emu In directory usw-pr-cvs1:/tmp/cvs-serv7922 Modified Files: dp_tlong.c ieee754dp.c ieee754sp.c Log Message: More math emulation fixes. Index: dp_tlong.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/math-emu/dp_tlong.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- dp_tlong.c 2001/10/11 21:59:07 1.1 +++ dp_tlong.c 2001/11/21 22:15:28 1.2 @@ -95,7 +95,7 @@ if ((xm >> 63) != 0) { /* This can happen after rounding */ SETCX(IEEE754_INVALID_OPERATION); - return ieee754si_xcpt(ieee754di_indef(), "dp_tlong", x); + return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); } if (round || sticky) SETCX(IEEE754_INEXACT); Index: ieee754dp.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/math-emu/ieee754dp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- ieee754dp.c 2001/10/04 16:22:33 1.1 +++ ieee754dp.c 2001/11/21 22:15:28 1.2 @@ -98,6 +98,32 @@ } +static unsigned long long get_rounding(int sn, unsigned long long xm) +{ + /* inexact must round of 3 bits + */ + if (xm & (DP_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 @@ -136,37 +162,37 @@ } } - /* sticky right shift es bits - */ - xm = XDPSRS(xm, es); - xe += es; - - assert((xm & (DP_HIDDEN_BIT << 3)) == 0); - assert(xe == DP_EMIN); + if (get_rounding(sn, xm) >> (DP_MBITS + 1 + 3)) { + /* Not tiny after rounding */ + SETCX(IEEE754_INEXACT); + xm = get_rounding(sn, xm); + xm >>= 1; + /* Clear grs bits */ + xm &= ~(DP_MBIT(3) - 1); + xe++; + } + else { + /* sticky right shift es bits + */ + xm = XDPSRS(xm, es); + xe += es; + assert((xm & (DP_HIDDEN_BIT << 3)) == 0); + assert(xe == DP_EMIN); + } } if (xm & (DP_MBIT(3) - 1)) { SETCX(IEEE754_INEXACT); + if ((xm & (DP_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 >> (DP_MBITS + 3 + 1)) { /* add causes mantissa overflow */ + if (xm >> (DP_MBITS + 3 + 1)) { + /* add causes mantissa overflow */ xm >>= 1; xe++; } @@ -203,7 +229,8 @@ if ((xm & DP_HIDDEN_BIT) == 0) { /* we underflow (tiny/zero) */ assert(xe == DP_EMIN); - SETCX(IEEE754_UNDERFLOW); + if (ieee754_csr.mx & IEEE754_UNDERFLOW) + SETCX(IEEE754_UNDERFLOW); return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm); } else { assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */ Index: ieee754sp.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/math-emu/ieee754sp.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- ieee754sp.c 2001/10/11 21:57:54 1.2 +++ ieee754sp.c 2001/11/21 22:15:28 1.3 @@ -99,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 @@ -116,57 +142,57 @@ int es = SP_EMIN - xe; if (ieee754_csr.nod) { - SETCX(IEEE754_UNDERFLOW); - SETCX(IEEE754_INEXACT); + SETCX(IEEE754_UNDERFLOW); + SETCX(IEEE754_INEXACT); - switch(ieee754_csr.rm) { + switch(ieee754_csr.rm) { case IEEE754_RN: - return ieee754sp_zero(sn); + return ieee754sp_zero(sn); case IEEE754_RZ: - return ieee754sp_zero(sn); + return ieee754sp_zero(sn); case IEEE754_RU: /* toward +Infinity */ - if(sn == 0) - return ieee754sp_min(0); - else - return ieee754sp_zero(1); + 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); - } + if(sn == 0) + return ieee754sp_zero(0); + else + return ieee754sp_min(1); + } } - /* sticky right shift es bits - */ - SPXSRSXn(es); - - assert((xm & (SP_HIDDEN_BIT << 3)) == 0); - assert(xe == SP_EMIN); + if (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++; } @@ -203,25 +229,8 @@ if ((xm & SP_HIDDEN_BIT) == 0) { /* we underflow (tiny/zero) */ assert(xe == SP_EMIN); - SETCX(IEEE754_UNDERFLOW); - if (!xm) { - 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_mind(0); - else - return ieee754sp_zero(1); - case IEEE754_RD: /* toward -Infinity */ - if(sn == 0) - return ieee754sp_zero(0); - else - return ieee754sp_mind(1); - } - } + 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 */ |