1 /*******************************************************************
2 Components for embedded applications builded for
3 laboratory and medical instruments firmware
5 math_sqrtll.c - fast routine for 64-bit unsigned square root
7 Copyright (C) 2001-2014 by Pavel Pisa - originator
9 (C) 2001-2014 by PiKRON Ltd. - originator
12 This file can be used and copied according to next
14 - GPL - GNU Public License
15 - other license provided by project originators
17 *******************************************************************/
25 y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
27 y := (y+x/y)/2 ... almost 17 sig. bits
28 y := (y+x/y)/2 ... almost 35 sig. bits
32 uint32_t __attribute__((unused))
37 2147418619,2146907255,2145906284,2144436844,
38 2142518597,2140169865,2137407758,2134248281,
39 2130706432,2126796288,2122531084,2117923281,
40 2112984627,2107726213,2102158525,2096291488,
41 2090134507,2083696503,2076985953,2070010911,
42 2062779045,2055297659,2047573718,2039613867,
43 2031424454,2023011548,2014380954,2005538230,
44 1996488704,1987237480,1977789459,1968149347,
45 1970116061,1983291585,1995774699,2007595298,
46 2018781187,2029358280,2039350771,2048781297,
47 2057671066,2066039988,2073906780,2081289063,
48 2088203452,2094665633,2100690434,2106291892,
49 2111483306,2116277295,2120685844,2124720346,
50 2128391644,2131710068,2134685466,2137327238,
51 2139644360,2141645415,2143338612,2144731814,
52 2145832551,2146648046,2147185228,2147450751
57 unsigned long sqrtll(unsigned long long x)
60 uint32_t x0 = x, x1 = x >> 32;
64 if (x1) { /* x[32:63] != 0 */
65 if (x1 & 0xffff0000){ /* x[48:63] != 0 */
67 if (x1 >= 0xfffffffe) /* exception bypass */
70 } else { /* x[48:63] == 0 */
71 t1 = x0 >> 16 | x1 << 16;
74 } else { /* x[32:64] == 0 */
76 if (x0 & 0xffff0000){ /* x[16:31] != 0 */
79 } else { /* x[16:31] == 0 */
85 while (!(t1 & 0x80000000)) {
90 if (x1) { /* x[32:63] != 0 */
91 if (x1 >= 0xfffffffe) /* exception bypass */
93 t2 = __builtin_clz(x1);
94 t1 = (x1 << t2) | ((x0 >> (32 - t2)));
99 t2 = __builtin_clz(x0);
118 y = (y >> 1) + (y & 1);
122 y= (y + x0 / y + 1) / 2;
123 y= (y + x0 / y + 1) / 2;
124 } else if (x1 < 0x00010000) {
125 uint32_t y0, y1, y2, xt, r;
127 xt = (x1 << 16) | (x0 >> 16);
133 xt = (r << 8) + (x0 & 0xffff);
134 y0 = (xt / y) + (y1 << 8) + (y2 << 16);
135 y = (y + y0 + 1) / 2;
137 xt = (x1 << 16) | (x0 >> 16);
143 xt = (r << 8) + (x0 & 0xffff);
144 y0 = (xt / y) + (y1 << 8) + (y2 << 16);
145 y = (y + y0 + 1) / 2;
150 y = (y + x / y + 1) / 2;
151 y = (y + x / y + 1) / 2;
158 unsigned long sqrtll_approx(unsigned long long x)
161 uint32_t x1 = x >> 32;
165 r = __builtin_clz(x1);
167 x1 = sqrtll(x >> (r * 2));
176 unsigned long sqrtll(unsigned long long x)
178 unsigned long y,t1,t2,t3;
179 unsigned long x0=x, x1=x>>32;
186 " movel %2,%3\n" /* x[48:64] != 0 */
188 " cmpl #0xfffffffe,%3\n"
190 " movl #0xffffffff,%0\n"
193 "1: movel %1,%4\n" /* x[48:64] == 0 */
199 "2: movel %1,%3\n" /* x[32:64] == 0 */
201 " clrl %0\n" /* x==0 */
207 " movel %1,%3\n" /* x[16:31] != 0 */
209 "4: lsll #1,%3\n" /* %3 .. normalized */
210 " dbcs %4,4b\n" /* %4 .. exponent bit order */
212 " roxrl #1,%3\n" /* exp%2 -> %4.31, exp/=2 */
214 " roll #6,%3\n" /* 6 MSB bits of %4 index to table */
217 " addl @(sqrtll_T1,%3:w:4),%0\n" /* lin. approximated table */
220 " lsrl %3,%0\n" /* denormalize result */
226 " divul %0,%4,%3\n" /* y := (y+x/y)/2 */
228 " subl %0,%4\n" /* divission overflow */
232 "5: addl %3,%0\n" /* regular path without ov */
237 " divul %0,%4,%3\n" /* y := (y+x/y)/2 */
243 :"=d"(y),"=d"(x0),"=d"(x1),"=d"(t1),"=d"(t2),"=d"(t3)