• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/m68k/math-emu/
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
20static const struct fp_ext fp_one =
21{
22	.exp = 0x3fff,
23};
24
25extern struct fp_ext *fp_fadd(struct fp_ext *dest, const struct fp_ext *src);
26extern struct fp_ext *fp_fdiv(struct fp_ext *dest, const struct fp_ext *src);
27
28struct fp_ext *
29fp_fsqrt(struct fp_ext *dest, struct fp_ext *src)
30{
31	struct fp_ext tmp, src2;
32	int i, exp;
33
34	dprint(PINSTR, "fsqrt\n");
35
36	fp_monadic_check(dest, src);
37
38	if (IS_ZERO(dest))
39		return dest;
40
41	if (dest->sign) {
42		fp_set_nan(dest);
43		return dest;
44	}
45	if (IS_INF(dest))
46		return dest;
47
48	/*
49	 *		 sqrt(m) * 2^(p)	, if e = 2*p
50	 * sqrt(m*2^e) =
51	 *		 sqrt(2*m) * 2^(p)	, if e = 2*p + 1
52	 *
53	 * So we use the last bit of the exponent to decide wether to
54	 * use the m or 2*m.
55	 *
56	 * Since only the fractional part of the mantissa is stored and
57	 * the integer part is assumed to be one, we place a 1 or 2 into
58	 * the fixed point representation.
59	 */
60	exp = dest->exp;
61	dest->exp = 0x3FFF;
62	if (!(exp & 1))		/* lowest bit of exponent is set */
63		dest->exp++;
64	fp_copy_ext(&src2, dest);
65
66	/*
67	 * The taylor row around a for sqrt(x) is:
68	 *	sqrt(x) = sqrt(a) + 1/(2*sqrt(a))*(x-a) + R
69	 * With a=1 this gives:
70	 *	sqrt(x) = 1 + 1/2*(x-1)
71	 *		= 1/2*(1+x)
72	 */
73	fp_fadd(dest, &fp_one);
74	dest->exp--;		/* * 1/2 */
75
76	/*
77	 * We now apply the newton rule to the function
78	 *	f(x) := x^2 - r
79	 * which has a null point on x = sqrt(r).
80	 *
81	 * It gives:
82	 *	x' := x - f(x)/f'(x)
83	 *	    = x - (x^2 -r)/(2*x)
84	 *	    = x - (x - r/x)/2
85	 *          = (2*x - x + r/x)/2
86	 *	    = (x + r/x)/2
87	 */
88	for (i = 0; i < 9; i++) {
89		fp_copy_ext(&tmp, &src2);
90
91		fp_fdiv(&tmp, dest);
92		fp_fadd(dest, &tmp);
93		dest->exp--;
94	}
95
96	dest->exp += (exp - 0x3FFF) / 2;
97
98	return dest;
99}
100
101struct fp_ext *
102fp_fetoxm1(struct fp_ext *dest, struct fp_ext *src)
103{
104	uprint("fetoxm1\n");
105
106	fp_monadic_check(dest, src);
107
108	if (IS_ZERO(dest))
109		return dest;
110
111	return dest;
112}
113
114struct fp_ext *
115fp_fetox(struct fp_ext *dest, struct fp_ext *src)
116{
117	uprint("fetox\n");
118
119	fp_monadic_check(dest, src);
120
121	return dest;
122}
123
124struct fp_ext *
125fp_ftwotox(struct fp_ext *dest, struct fp_ext *src)
126{
127	uprint("ftwotox\n");
128
129	fp_monadic_check(dest, src);
130
131	return dest;
132}
133
134struct fp_ext *
135fp_ftentox(struct fp_ext *dest, struct fp_ext *src)
136{
137	uprint("ftentox\n");
138
139	fp_monadic_check(dest, src);
140
141	return dest;
142}
143
144struct fp_ext *
145fp_flogn(struct fp_ext *dest, struct fp_ext *src)
146{
147	uprint("flogn\n");
148
149	fp_monadic_check(dest, src);
150
151	return dest;
152}
153
154struct fp_ext *
155fp_flognp1(struct fp_ext *dest, struct fp_ext *src)
156{
157	uprint("flognp1\n");
158
159	fp_monadic_check(dest, src);
160
161	return dest;
162}
163
164struct fp_ext *
165fp_flog10(struct fp_ext *dest, struct fp_ext *src)
166{
167	uprint("flog10\n");
168
169	fp_monadic_check(dest, src);
170
171	return dest;
172}
173
174struct fp_ext *
175fp_flog2(struct fp_ext *dest, struct fp_ext *src)
176{
177	uprint("flog2\n");
178
179	fp_monadic_check(dest, src);
180
181	return dest;
182}
183
184struct fp_ext *
185fp_fgetexp(struct fp_ext *dest, struct fp_ext *src)
186{
187	dprint(PINSTR, "fgetexp\n");
188
189	fp_monadic_check(dest, src);
190
191	if (IS_INF(dest)) {
192		fp_set_nan(dest);
193		return dest;
194	}
195	if (IS_ZERO(dest))
196		return dest;
197
198	fp_conv_long2ext(dest, (int)dest->exp - 0x3FFF);
199
200	fp_normalize_ext(dest);
201
202	return dest;
203}
204
205struct fp_ext *
206fp_fgetman(struct fp_ext *dest, struct fp_ext *src)
207{
208	dprint(PINSTR, "fgetman\n");
209
210	fp_monadic_check(dest, src);
211
212	if (IS_ZERO(dest))
213		return dest;
214
215	if (IS_INF(dest))
216		return dest;
217
218	dest->exp = 0x3FFF;
219
220	return dest;
221}
222