diff options
Diffstat (limited to 'arch/m68k/math-emu/fp_log.c')
-rw-r--r-- | arch/m68k/math-emu/fp_log.c | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/arch/m68k/math-emu/fp_log.c b/arch/m68k/math-emu/fp_log.c new file mode 100644 index 000000000000..87b4f0158560 --- /dev/null +++ b/arch/m68k/math-emu/fp_log.c | |||
@@ -0,0 +1,223 @@ | |||
1 | /* | ||
2 | |||
3 | fp_trig.c: floating-point math routines for the Linux-m68k | ||
4 | floating point emulator. | ||
5 | |||
6 | Copyright (c) 1998-1999 David Huggins-Daines / Roman Zippel. | ||
7 | |||
8 | I hereby give permission, free of charge, to copy, modify, and | ||
9 | redistribute this software, in source or binary form, provided that | ||
10 | the above copyright notice and the following disclaimer are included | ||
11 | in all such copies. | ||
12 | |||
13 | THIS SOFTWARE IS PROVIDED "AS IS", WITH ABSOLUTELY NO WARRANTY, REAL | ||
14 | OR IMPLIED. | ||
15 | |||
16 | */ | ||
17 | |||
18 | #include "fp_emu.h" | ||
19 | |||
20 | static const struct fp_ext fp_one = | ||
21 | { | ||
22 | .exp = 0x3fff, | ||
23 | }; | ||
24 | |||
25 | extern struct fp_ext *fp_fadd(struct fp_ext *dest, const struct fp_ext *src); | ||
26 | extern struct fp_ext *fp_fdiv(struct fp_ext *dest, const struct fp_ext *src); | ||
27 | extern struct fp_ext *fp_fmul(struct fp_ext *dest, const struct fp_ext *src); | ||
28 | |||
29 | struct fp_ext * | ||
30 | fp_fsqrt(struct fp_ext *dest, struct fp_ext *src) | ||
31 | { | ||
32 | struct fp_ext tmp, src2; | ||
33 | int i, exp; | ||
34 | |||
35 | dprint(PINSTR, "fsqrt\n"); | ||
36 | |||
37 | fp_monadic_check(dest, src); | ||
38 | |||
39 | if (IS_ZERO(dest)) | ||
40 | return dest; | ||
41 | |||
42 | if (dest->sign) { | ||
43 | fp_set_nan(dest); | ||
44 | return dest; | ||
45 | } | ||
46 | if (IS_INF(dest)) | ||
47 | return dest; | ||
48 | |||
49 | /* | ||
50 | * sqrt(m) * 2^(p) , if e = 2*p | ||
51 | * sqrt(m*2^e) = | ||
52 | * sqrt(2*m) * 2^(p) , if e = 2*p + 1 | ||
53 | * | ||
54 | * So we use the last bit of the exponent to decide wether to | ||
55 | * use the m or 2*m. | ||
56 | * | ||
57 | * Since only the fractional part of the mantissa is stored and | ||
58 | * the integer part is assumed to be one, we place a 1 or 2 into | ||
59 | * the fixed point representation. | ||
60 | */ | ||
61 | exp = dest->exp; | ||
62 | dest->exp = 0x3FFF; | ||
63 | if (!(exp & 1)) /* lowest bit of exponent is set */ | ||
64 | dest->exp++; | ||
65 | fp_copy_ext(&src2, dest); | ||
66 | |||
67 | /* | ||
68 | * The taylor row arround a for sqrt(x) is: | ||
69 | * sqrt(x) = sqrt(a) + 1/(2*sqrt(a))*(x-a) + R | ||
70 | * With a=1 this gives: | ||
71 | * sqrt(x) = 1 + 1/2*(x-1) | ||
72 | * = 1/2*(1+x) | ||
73 | */ | ||
74 | fp_fadd(dest, &fp_one); | ||
75 | dest->exp--; /* * 1/2 */ | ||
76 | |||
77 | /* | ||
78 | * We now apply the newton rule to the function | ||
79 | * f(x) := x^2 - r | ||
80 | * which has a null point on x = sqrt(r). | ||
81 | * | ||
82 | * It gives: | ||
83 | * x' := x - f(x)/f'(x) | ||
84 | * = x - (x^2 -r)/(2*x) | ||
85 | * = x - (x - r/x)/2 | ||
86 | * = (2*x - x + r/x)/2 | ||
87 | * = (x + r/x)/2 | ||
88 | */ | ||
89 | for (i = 0; i < 9; i++) { | ||
90 | fp_copy_ext(&tmp, &src2); | ||
91 | |||
92 | fp_fdiv(&tmp, dest); | ||
93 | fp_fadd(dest, &tmp); | ||
94 | dest->exp--; | ||
95 | } | ||
96 | |||
97 | dest->exp += (exp - 0x3FFF) / 2; | ||
98 | |||
99 | return dest; | ||
100 | } | ||
101 | |||
102 | struct fp_ext * | ||
103 | fp_fetoxm1(struct fp_ext *dest, struct fp_ext *src) | ||
104 | { | ||
105 | uprint("fetoxm1\n"); | ||
106 | |||
107 | fp_monadic_check(dest, src); | ||
108 | |||
109 | if (IS_ZERO(dest)) | ||
110 | return dest; | ||
111 | |||
112 | return dest; | ||
113 | } | ||
114 | |||
115 | struct fp_ext * | ||
116 | fp_fetox(struct fp_ext *dest, struct fp_ext *src) | ||
117 | { | ||
118 | uprint("fetox\n"); | ||
119 | |||
120 | fp_monadic_check(dest, src); | ||
121 | |||
122 | return dest; | ||
123 | } | ||
124 | |||
125 | struct fp_ext * | ||
126 | fp_ftwotox(struct fp_ext *dest, struct fp_ext *src) | ||
127 | { | ||
128 | uprint("ftwotox\n"); | ||
129 | |||
130 | fp_monadic_check(dest, src); | ||
131 | |||
132 | return dest; | ||
133 | } | ||
134 | |||
135 | struct fp_ext * | ||
136 | fp_ftentox(struct fp_ext *dest, struct fp_ext *src) | ||
137 | { | ||
138 | uprint("ftentox\n"); | ||
139 | |||
140 | fp_monadic_check(dest, src); | ||
141 | |||
142 | return dest; | ||
143 | } | ||
144 | |||
145 | struct fp_ext * | ||
146 | fp_flogn(struct fp_ext *dest, struct fp_ext *src) | ||
147 | { | ||
148 | uprint("flogn\n"); | ||
149 | |||
150 | fp_monadic_check(dest, src); | ||
151 | |||
152 | return dest; | ||
153 | } | ||
154 | |||
155 | struct fp_ext * | ||
156 | fp_flognp1(struct fp_ext *dest, struct fp_ext *src) | ||
157 | { | ||
158 | uprint("flognp1\n"); | ||
159 | |||
160 | fp_monadic_check(dest, src); | ||
161 | |||
162 | return dest; | ||
163 | } | ||
164 | |||
165 | struct fp_ext * | ||
166 | fp_flog10(struct fp_ext *dest, struct fp_ext *src) | ||
167 | { | ||
168 | uprint("flog10\n"); | ||
169 | |||
170 | fp_monadic_check(dest, src); | ||
171 | |||
172 | return dest; | ||
173 | } | ||
174 | |||
175 | struct fp_ext * | ||
176 | fp_flog2(struct fp_ext *dest, struct fp_ext *src) | ||
177 | { | ||
178 | uprint("flog2\n"); | ||
179 | |||
180 | fp_monadic_check(dest, src); | ||
181 | |||
182 | return dest; | ||
183 | } | ||
184 | |||
185 | struct fp_ext * | ||
186 | fp_fgetexp(struct fp_ext *dest, struct fp_ext *src) | ||
187 | { | ||
188 | dprint(PINSTR, "fgetexp\n"); | ||
189 | |||
190 | fp_monadic_check(dest, src); | ||
191 | |||
192 | if (IS_INF(dest)) { | ||
193 | fp_set_nan(dest); | ||
194 | return dest; | ||
195 | } | ||
196 | if (IS_ZERO(dest)) | ||
197 | return dest; | ||
198 | |||
199 | fp_conv_long2ext(dest, (int)dest->exp - 0x3FFF); | ||
200 | |||
201 | fp_normalize_ext(dest); | ||
202 | |||
203 | return dest; | ||
204 | } | ||
205 | |||
206 | struct fp_ext * | ||
207 | fp_fgetman(struct fp_ext *dest, struct fp_ext *src) | ||
208 | { | ||
209 | dprint(PINSTR, "fgetman\n"); | ||
210 | |||
211 | fp_monadic_check(dest, src); | ||
212 | |||
213 | if (IS_ZERO(dest)) | ||
214 | return dest; | ||
215 | |||
216 | if (IS_INF(dest)) | ||
217 | return dest; | ||
218 | |||
219 | dest->exp = 0x3FFF; | ||
220 | |||
221 | return dest; | ||
222 | } | ||
223 | |||