Merge branch 'for-linus' into test
[sfrench/cifs-2.6.git] / arch / mips / math-emu / sp_sqrt.c
1 /* IEEE754 floating point arithmetic
2  * single precision square root
3  */
4 /*
5  * MIPS floating point support
6  * Copyright (C) 1994-2000 Algorithmics Ltd.
7  *
8  *  This program is free software; you can distribute it and/or modify it
9  *  under the terms of the GNU General Public License (Version 2) as
10  *  published by the Free Software Foundation.
11  *
12  *  This program is distributed in the hope it will be useful, but WITHOUT
13  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  *  for more details.
16  *
17  *  You should have received a copy of the GNU General Public License along
18  *  with this program; if not, write to the Free Software Foundation, Inc.,
19  *  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
20  */
21
22 #include "ieee754sp.h"
23
24 union ieee754sp ieee754sp_sqrt(union ieee754sp x)
25 {
26         int ix, s, q, m, t, i;
27         unsigned int r;
28         COMPXSP;
29
30         /* take care of Inf and NaN */
31
32         EXPLODEXSP;
33         ieee754_clearcx();
34         FLUSHXSP;
35
36         /* x == INF or NAN? */
37         switch (xc) {
38         case IEEE754_CLASS_SNAN:
39                 return ieee754sp_nanxcpt(x);
40
41         case IEEE754_CLASS_QNAN:
42                 /* sqrt(Nan) = Nan */
43                 return x;
44
45         case IEEE754_CLASS_ZERO:
46                 /* sqrt(0) = 0 */
47                 return x;
48
49         case IEEE754_CLASS_INF:
50                 if (xs) {
51                         /* sqrt(-Inf) = Nan */
52                         ieee754_setcx(IEEE754_INVALID_OPERATION);
53                         return ieee754sp_indef();
54                 }
55                 /* sqrt(+Inf) = Inf */
56                 return x;
57
58         case IEEE754_CLASS_DNORM:
59         case IEEE754_CLASS_NORM:
60                 if (xs) {
61                         /* sqrt(-x) = Nan */
62                         ieee754_setcx(IEEE754_INVALID_OPERATION);
63                         return ieee754sp_indef();
64                 }
65                 break;
66         }
67
68         ix = x.bits;
69
70         /* normalize x */
71         m = (ix >> 23);
72         if (m == 0) {           /* subnormal x */
73                 for (i = 0; (ix & 0x00800000) == 0; i++)
74                         ix <<= 1;
75                 m -= i - 1;
76         }
77         m -= 127;               /* unbias exponent */
78         ix = (ix & 0x007fffff) | 0x00800000;
79         if (m & 1)              /* odd m, double x to make it even */
80                 ix += ix;
81         m >>= 1;                /* m = [m/2] */
82
83         /* generate sqrt(x) bit by bit */
84         ix += ix;
85         s = 0;
86         q = 0;                  /* q = sqrt(x) */
87         r = 0x01000000;         /* r = moving bit from right to left */
88
89         while (r != 0) {
90                 t = s + r;
91                 if (t <= ix) {
92                         s = t + r;
93                         ix -= t;
94                         q += r;
95                 }
96                 ix += ix;
97                 r >>= 1;
98         }
99
100         if (ix != 0) {
101                 ieee754_setcx(IEEE754_INEXACT);
102                 switch (ieee754_csr.rm) {
103                 case FPU_CSR_RU:
104                         q += 2;
105                         break;
106                 case FPU_CSR_RN:
107                         q += (q & 1);
108                         break;
109                 }
110         }
111         ix = (q >> 1) + 0x3f000000;
112         ix += (m << 23);
113         x.bits = ix;
114         return x;
115 }