Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / arch / m68k / math-emu / fp_log.c
blob71a8fc25575af8101f3eedc1e275a87b0f1d7ed8
1 /*
3 fp_log.c: floating-point math routines for the Linux-m68k
4 floating point emulator.
6 Copyright (c) 1998-1999 David Huggins-Daines / Roman Zippel.
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.
13 THIS SOFTWARE IS PROVIDED "AS IS", WITH ABSOLUTELY NO WARRANTY, REAL
14 OR IMPLIED.
18 #include "fp_arith.h"
19 #include "fp_emu.h"
20 #include "fp_log.h"
22 static const struct fp_ext fp_one = {
23 .exp = 0x3fff,
26 struct fp_ext *fp_fsqrt(struct fp_ext *dest, struct fp_ext *src)
28 struct fp_ext tmp, src2;
29 int i, exp;
31 dprint(PINSTR, "fsqrt\n");
33 fp_monadic_check(dest, src);
35 if (IS_ZERO(dest))
36 return dest;
38 if (dest->sign) {
39 fp_set_nan(dest);
40 return dest;
42 if (IS_INF(dest))
43 return dest;
46 * sqrt(m) * 2^(p) , if e = 2*p
47 * sqrt(m*2^e) =
48 * sqrt(2*m) * 2^(p) , if e = 2*p + 1
50 * So we use the last bit of the exponent to decide whether to
51 * use the m or 2*m.
53 * Since only the fractional part of the mantissa is stored and
54 * the integer part is assumed to be one, we place a 1 or 2 into
55 * the fixed point representation.
57 exp = dest->exp;
58 dest->exp = 0x3FFF;
59 if (!(exp & 1)) /* lowest bit of exponent is set */
60 dest->exp++;
61 fp_copy_ext(&src2, dest);
64 * The taylor row around a for sqrt(x) is:
65 * sqrt(x) = sqrt(a) + 1/(2*sqrt(a))*(x-a) + R
66 * With a=1 this gives:
67 * sqrt(x) = 1 + 1/2*(x-1)
68 * = 1/2*(1+x)
70 /* It is safe to cast away the constness, as fp_one is normalized */
71 fp_fadd(dest, (struct fp_ext *)&fp_one);
72 dest->exp--; /* * 1/2 */
75 * We now apply the newton rule to the function
76 * f(x) := x^2 - r
77 * which has a null point on x = sqrt(r).
79 * It gives:
80 * x' := x - f(x)/f'(x)
81 * = x - (x^2 -r)/(2*x)
82 * = x - (x - r/x)/2
83 * = (2*x - x + r/x)/2
84 * = (x + r/x)/2
86 for (i = 0; i < 9; i++) {
87 fp_copy_ext(&tmp, &src2);
89 fp_fdiv(&tmp, dest);
90 fp_fadd(dest, &tmp);
91 dest->exp--;
94 dest->exp += (exp - 0x3FFF) / 2;
96 return dest;
99 struct fp_ext *fp_fetoxm1(struct fp_ext *dest, struct fp_ext *src)
101 uprint("fetoxm1\n");
103 fp_monadic_check(dest, src);
105 return dest;
108 struct fp_ext *fp_fetox(struct fp_ext *dest, struct fp_ext *src)
110 uprint("fetox\n");
112 fp_monadic_check(dest, src);
114 return dest;
117 struct fp_ext *fp_ftwotox(struct fp_ext *dest, struct fp_ext *src)
119 uprint("ftwotox\n");
121 fp_monadic_check(dest, src);
123 return dest;
126 struct fp_ext *fp_ftentox(struct fp_ext *dest, struct fp_ext *src)
128 uprint("ftentox\n");
130 fp_monadic_check(dest, src);
132 return dest;
135 struct fp_ext *fp_flogn(struct fp_ext *dest, struct fp_ext *src)
137 uprint("flogn\n");
139 fp_monadic_check(dest, src);
141 return dest;
144 struct fp_ext *fp_flognp1(struct fp_ext *dest, struct fp_ext *src)
146 uprint("flognp1\n");
148 fp_monadic_check(dest, src);
150 return dest;
153 struct fp_ext *fp_flog10(struct fp_ext *dest, struct fp_ext *src)
155 uprint("flog10\n");
157 fp_monadic_check(dest, src);
159 return dest;
162 struct fp_ext *fp_flog2(struct fp_ext *dest, struct fp_ext *src)
164 uprint("flog2\n");
166 fp_monadic_check(dest, src);
168 return dest;
171 struct fp_ext *fp_fgetexp(struct fp_ext *dest, struct fp_ext *src)
173 dprint(PINSTR, "fgetexp\n");
175 fp_monadic_check(dest, src);
177 if (IS_INF(dest)) {
178 fp_set_nan(dest);
179 return dest;
181 if (IS_ZERO(dest))
182 return dest;
184 fp_conv_long2ext(dest, (int)dest->exp - 0x3FFF);
186 fp_normalize_ext(dest);
188 return dest;
191 struct fp_ext *fp_fgetman(struct fp_ext *dest, struct fp_ext *src)
193 dprint(PINSTR, "fgetman\n");
195 fp_monadic_check(dest, src);
197 if (IS_ZERO(dest))
198 return dest;
200 if (IS_INF(dest))
201 return dest;
203 dest->exp = 0x3FFF;
205 return dest;