Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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         q = s = 0;              /* q = sqrt(x) */
86         r = 0x01000000;         /* r = moving bit from right to left */
87
88         while (r != 0) {
89                 t = s + r;
90                 if (t <= ix) {
91                         s = t + r;
92                         ix -= t;
93                         q += r;
94                 }
95                 ix += ix;
96                 r >>= 1;
97         }
98
99         if (ix != 0) {
100                 ieee754_setcx(IEEE754_INEXACT);
101                 switch (ieee754_csr.rm) {
102                 case FPU_CSR_RU:
103                         q += 2;
104                         break;
105                 case FPU_CSR_RN:
106                         q += (q & 1);
107                         break;
108                 }
109         }
110         ix = (q >> 1) + 0x3f000000;
111         ix += (m << 23);
112         x.bits = ix;
113         return x;
114 }