/* IEEE754 floating point arithmetic1* single precision square root2*/3/*4* MIPS floating point support5* Copyright (C) 1994-2000 Algorithmics Ltd.6*7* ########################################################################8*9* This program is free software; you can distribute it and/or modify it10* under the terms of the GNU General Public License (Version 2) as11* published by the Free Software Foundation.12*13* This program is distributed in the hope it will be useful, but WITHOUT14* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or15* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License16* for more details.17*18* You should have received a copy of the GNU General Public License along19* with this program; if not, write to the Free Software Foundation, Inc.,20* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.21*22* ########################################################################23*/242526#include "ieee754sp.h"2728ieee754sp ieee754sp_sqrt(ieee754sp x)29{30int ix, s, q, m, t, i;31unsigned int r;32COMPXSP;3334/* take care of Inf and NaN */3536EXPLODEXSP;37CLEARCX;38FLUSHXSP;3940/* x == INF or NAN? */41switch (xc) {42case IEEE754_CLASS_QNAN:43/* sqrt(Nan) = Nan */44return ieee754sp_nanxcpt(x, "sqrt");45case IEEE754_CLASS_SNAN:46SETCX(IEEE754_INVALID_OPERATION);47return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");48case IEEE754_CLASS_ZERO:49/* sqrt(0) = 0 */50return x;51case IEEE754_CLASS_INF:52if (xs) {53/* sqrt(-Inf) = Nan */54SETCX(IEEE754_INVALID_OPERATION);55return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");56}57/* sqrt(+Inf) = Inf */58return x;59case IEEE754_CLASS_DNORM:60case IEEE754_CLASS_NORM:61if (xs) {62/* sqrt(-x) = Nan */63SETCX(IEEE754_INVALID_OPERATION);64return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");65}66break;67}6869ix = x.bits;7071/* normalize x */72m = (ix >> 23);73if (m == 0) { /* subnormal x */74for (i = 0; (ix & 0x00800000) == 0; i++)75ix <<= 1;76m -= i - 1;77}78m -= 127; /* unbias exponent */79ix = (ix & 0x007fffff) | 0x00800000;80if (m & 1) /* odd m, double x to make it even */81ix += ix;82m >>= 1; /* m = [m/2] */8384/* generate sqrt(x) bit by bit */85ix += ix;86q = s = 0; /* q = sqrt(x) */87r = 0x01000000; /* r = moving bit from right to left */8889while (r != 0) {90t = s + r;91if (t <= ix) {92s = t + r;93ix -= t;94q += r;95}96ix += ix;97r >>= 1;98}99100if (ix != 0) {101SETCX(IEEE754_INEXACT);102switch (ieee754_csr.rm) {103case IEEE754_RP:104q += 2;105break;106case IEEE754_RN:107q += (q & 1);108break;109}110}111ix = (q >> 1) + 0x3f000000;112ix += (m << 23);113x.bits = ix;114return x;115}116117118