1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "ieee754sp.h"
23
24union ieee754sp ieee754sp_sqrt(union ieee754sp x)
25{
26 int ix, s, q, m, t, i;
27 unsigned int r;
28 COMPXSP;
29
30
31
32 EXPLODEXSP;
33 ieee754_clearcx();
34 FLUSHXSP;
35
36
37 switch (xc) {
38 case IEEE754_CLASS_SNAN:
39 return ieee754sp_nanxcpt(x);
40
41 case IEEE754_CLASS_QNAN:
42
43 return x;
44
45 case IEEE754_CLASS_ZERO:
46
47 return x;
48
49 case IEEE754_CLASS_INF:
50 if (xs) {
51
52 ieee754_setcx(IEEE754_INVALID_OPERATION);
53 return ieee754sp_indef();
54 }
55
56 return x;
57
58 case IEEE754_CLASS_DNORM:
59 case IEEE754_CLASS_NORM:
60 if (xs) {
61
62 ieee754_setcx(IEEE754_INVALID_OPERATION);
63 return ieee754sp_indef();
64 }
65 break;
66 }
67
68 ix = x.bits;
69
70
71 m = (ix >> 23);
72 if (m == 0) {
73 for (i = 0; (ix & 0x00800000) == 0; i++)
74 ix <<= 1;
75 m -= i - 1;
76 }
77 m -= 127;
78 ix = (ix & 0x007fffff) | 0x00800000;
79 if (m & 1)
80 ix += ix;
81 m >>= 1;
82
83
84 ix += ix;
85 s = 0;
86 q = 0;
87 r = 0x01000000;
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}
116