This source file includes following definitions.
- shift_right
- sqr64
- fsqrt
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/math_emu.h>
14 #include <linux/sched.h>
15
16 static void shift_right(int * c)
17 {
18 __asm__("shrl $1,12(%0) ; rcrl $1,8(%0) ; rcrl $1,4(%0) ; rcrl $1,(%0)"
19 ::"r" ((long) c));
20 }
21
22 static int sqr64(unsigned long * a, unsigned long * b)
23 {
24 unsigned long tmp[4];
25
26 __asm__("movl (%0),%%eax ; mull %%eax\n\t"
27 "movl %%eax,(%1) ; movl %%edx,4(%1)\n\t"
28 "movl 4(%0),%%eax ; mull %%eax\n\t"
29 "movl %%eax,8(%1) ; movl %%edx,12(%1)\n\t"
30 "movl (%0),%%eax ; mull 4(%0)\n\t"
31 "addl %%eax,%%eax ; adcl %%edx,%%edx\n\t"
32 "adcl $0,12(%1) ; addl %%eax,4(%1)\n\t"
33 "adcl %%edx,8(%1) ; adcl $0,12(%1)"
34 ::"b" ((long) a),"c" ((long) tmp)
35 :"ax","bx","cx","dx");
36 if (tmp[3] > b[3] ||
37 (tmp[3] == b[3] && (tmp[2] > b[2] ||
38 (tmp[2] == b[2] && (tmp[1] > b[1] ||
39 (tmp[1] == b[1] && tmp[0] > b[0]))))))
40 return 0;
41 return 1;
42 }
43
44 void fsqrt(const temp_real * s, temp_real * d)
45 {
46 unsigned long src[4];
47 unsigned long res[2];
48 int exponent;
49 unsigned long mask, *c;
50 int i;
51
52 exponent = s->exponent;
53 src[0] = src[1] = 0;
54 src[2] = s->a;
55 src[3] = s->b;
56 d->exponent = 0;
57 d->a = d->b = 0;
58 if (!exponent)
59 return;
60 if (!src[2] && !src[3])
61 return;
62 if (exponent & 0x8000) {
63 send_sig(SIGFPE,current,0);
64 return;
65 }
66 if (exponent & 1) {
67 shift_right(src);
68 exponent++;
69 }
70 exponent >>= 1;
71 exponent += 0x1fff;
72 c = res + 2;
73 mask = 0;
74 for (i = 64 ; i > 0 ; i--) {
75 if (!(mask >>= 1)) {
76 c--;
77 mask = 0x80000000;
78 }
79 res[0] = d->a; res[1] = d->b;
80 *c |= mask;
81 if (sqr64(res,src)) {
82 d->a = res[0];
83 d->b = res[1];
84 }
85 }
86 if (!d->a && !d->b)
87 return;
88 while (!(d->b & 0x80000000)) {
89 __asm__("addl %%eax,%%eax ; adcl %%edx,%%edx"
90 :"=a" (d->a),"=d" (d->b)
91 :"0" (d->a),"1" (d->b));
92 exponent--;
93 }
94 d->exponent = exponent;
95 }