123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- /* IEEE754 floating point arithmetic
- * single precision square root
- */
- /*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
- #include "ieee754sp.h"
- ieee754sp ieee754sp_sqrt(ieee754sp x)
- {
- int ix, s, q, m, t, i;
- unsigned int r;
- COMPXSP;
- /* take care of Inf and NaN */
- EXPLODEXSP;
- CLEARCX;
- FLUSHXSP;
- /* x == INF or NAN? */
- switch (xc) {
- case IEEE754_CLASS_QNAN:
- /* sqrt(Nan) = Nan */
- return ieee754sp_nanxcpt(x, "sqrt");
- case IEEE754_CLASS_SNAN:
- SETCX(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
- case IEEE754_CLASS_ZERO:
- /* sqrt(0) = 0 */
- return x;
- case IEEE754_CLASS_INF:
- if (xs) {
- /* sqrt(-Inf) = Nan */
- SETCX(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
- }
- /* sqrt(+Inf) = Inf */
- return x;
- case IEEE754_CLASS_DNORM:
- case IEEE754_CLASS_NORM:
- if (xs) {
- /* sqrt(-x) = Nan */
- SETCX(IEEE754_INVALID_OPERATION);
- return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
- }
- break;
- }
- ix = x.bits;
- /* normalize x */
- m = (ix >> 23);
- if (m == 0) { /* subnormal x */
- for (i = 0; (ix & 0x00800000) == 0; i++)
- ix <<= 1;
- m -= i - 1;
- }
- m -= 127; /* unbias exponent */
- ix = (ix & 0x007fffff) | 0x00800000;
- if (m & 1) /* odd m, double x to make it even */
- ix += ix;
- m >>= 1; /* m = [m/2] */
- /* generate sqrt(x) bit by bit */
- ix += ix;
- q = s = 0; /* q = sqrt(x) */
- r = 0x01000000; /* r = moving bit from right to left */
- while (r != 0) {
- t = s + r;
- if (t <= ix) {
- s = t + r;
- ix -= t;
- q += r;
- }
- ix += ix;
- r >>= 1;
- }
- if (ix != 0) {
- SETCX(IEEE754_INEXACT);
- switch (ieee754_csr.rm) {
- case IEEE754_RP:
- q += 2;
- break;
- case IEEE754_RN:
- q += (q & 1);
- break;
- }
- }
- ix = (q >> 1) + 0x3f000000;
- ix += (m << 23);
- x.bits = ix;
- return x;
- }
|