1*9050bf24Sisaki /* $NetBSD: fpu_log.c,v 1.18 2014/01/04 13:23:22 isaki Exp $ */
2fc8793fbSbriggs
3fc8793fbSbriggs /*
4fc8793fbSbriggs * Copyright (c) 1995 Ken Nakata
5fc8793fbSbriggs * All rights reserved.
6fc8793fbSbriggs *
7fc8793fbSbriggs * Redistribution and use in source and binary forms, with or without
8fc8793fbSbriggs * modification, are permitted provided that the following conditions
9fc8793fbSbriggs * are met:
10fc8793fbSbriggs * 1. Redistributions of source code must retain the above copyright
11fc8793fbSbriggs * notice, this list of conditions and the following disclaimer.
12fc8793fbSbriggs * 2. Redistributions in binary form must reproduce the above copyright
13fc8793fbSbriggs * notice, this list of conditions and the following disclaimer in the
14fc8793fbSbriggs * documentation and/or other materials provided with the distribution.
15fc8793fbSbriggs * 3. Neither the name of the author nor the names of its contributors
16fc8793fbSbriggs * may be used to endorse or promote products derived from this software
17fc8793fbSbriggs * without specific prior written permission.
18fc8793fbSbriggs *
19fc8793fbSbriggs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20fc8793fbSbriggs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21fc8793fbSbriggs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22fc8793fbSbriggs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23fc8793fbSbriggs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24fc8793fbSbriggs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25fc8793fbSbriggs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26fc8793fbSbriggs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27fc8793fbSbriggs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28fc8793fbSbriggs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29fc8793fbSbriggs * SUCH DAMAGE.
30fc8793fbSbriggs *
31fc8793fbSbriggs * @(#)fpu_log.c 10/8/95
32fc8793fbSbriggs */
33fc8793fbSbriggs
344b2744bfSlukem #include <sys/cdefs.h>
35*9050bf24Sisaki __KERNEL_RCSID(0, "$NetBSD: fpu_log.c,v 1.18 2014/01/04 13:23:22 isaki Exp $");
364b2744bfSlukem
37fc8793fbSbriggs #include <sys/types.h>
3841f393e6Sbriggs #include <sys/systm.h>
39fc8793fbSbriggs
40fc8793fbSbriggs #include "fpu_emulate.h"
41fc8793fbSbriggs
42f53c2e8dSisaki static uint32_t logA6[] = { 0x3FC2499A, 0xB5E4040B };
43f53c2e8dSisaki static uint32_t logA5[] = { 0xBFC555B5, 0x848CB7DB };
44f53c2e8dSisaki static uint32_t logA4[] = { 0x3FC99999, 0x987D8730 };
45f53c2e8dSisaki static uint32_t logA3[] = { 0xBFCFFFFF, 0xFF6F7E97 };
46f53c2e8dSisaki static uint32_t logA2[] = { 0x3FD55555, 0x555555A4 };
47f53c2e8dSisaki static uint32_t logA1[] = { 0xBFE00000, 0x00000008 };
48fc8793fbSbriggs
49f53c2e8dSisaki static uint32_t logB5[] = { 0x3F175496, 0xADD7DAD6 };
50f53c2e8dSisaki static uint32_t logB4[] = { 0x3F3C71C2, 0xFE80C7E0 };
51f53c2e8dSisaki static uint32_t logB3[] = { 0x3F624924, 0x928BCCFF };
52f53c2e8dSisaki static uint32_t logB2[] = { 0x3F899999, 0x999995EC };
53f53c2e8dSisaki static uint32_t logB1[] = { 0x3FB55555, 0x55555555 };
54fc8793fbSbriggs
55fc8793fbSbriggs /* sfpn = shortened fp number; can represent only positive numbers */
56fc8793fbSbriggs static struct sfpn {
57fc8793fbSbriggs int sp_exp;
58f53c2e8dSisaki uint32_t sp_m0, sp_m1;
59fc8793fbSbriggs } logtbl[] = {
60fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xFE03F80FU, 0xE03F80FEU },
61fc8793fbSbriggs { 0x3FF7 - 0x3fff, 0xFF015358U, 0x833C47E2U },
62fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xFA232CF2U, 0x52138AC0U },
63fc8793fbSbriggs { 0x3FF9 - 0x3fff, 0xBDC8D83EU, 0xAD88D549U },
64fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xF6603D98U, 0x0F6603DAU },
65fc8793fbSbriggs { 0x3FFA - 0x3fff, 0x9CF43DCFU, 0xF5EAFD48U },
66fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xF2B9D648U, 0x0F2B9D65U },
67fc8793fbSbriggs { 0x3FFA - 0x3fff, 0xDA16EB88U, 0xCB8DF614U },
68fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xEF2EB71FU, 0xC4345238U },
69fc8793fbSbriggs { 0x3FFB - 0x3fff, 0x8B29B775U, 0x1BD70743U },
70fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xEBBDB2A5U, 0xC1619C8CU },
71fc8793fbSbriggs { 0x3FFB - 0x3fff, 0xA8D839F8U, 0x30C1FB49U },
72fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xE865AC7BU, 0x7603A197U },
73fc8793fbSbriggs { 0x3FFB - 0x3fff, 0xC61A2EB1U, 0x8CD907ADU },
74fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xE525982AU, 0xF70C880EU },
75fc8793fbSbriggs { 0x3FFB - 0x3fff, 0xE2F2A47AU, 0xDE3A18AFU },
76fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xE1FC780EU, 0x1FC780E2U },
77fc8793fbSbriggs { 0x3FFB - 0x3fff, 0xFF64898EU, 0xDF55D551U },
78fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xDEE95C4CU, 0xA037BA57U },
79fc8793fbSbriggs { 0x3FFC - 0x3fff, 0x8DB956A9U, 0x7B3D0148U },
80fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xDBEB61EEU, 0xD19C5958U },
81fc8793fbSbriggs { 0x3FFC - 0x3fff, 0x9B8FE100U, 0xF47BA1DEU },
82fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xD901B203U, 0x6406C80EU },
83fc8793fbSbriggs { 0x3FFC - 0x3fff, 0xA9372F1DU, 0x0DA1BD17U },
84fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xD62B80D6U, 0x2B80D62CU },
85fc8793fbSbriggs { 0x3FFC - 0x3fff, 0xB6B07F38U, 0xCE90E46BU },
86fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xD3680D36U, 0x80D3680DU },
87fc8793fbSbriggs { 0x3FFC - 0x3fff, 0xC3FD0329U, 0x06488481U },
88fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xD0B69FCBU, 0xD2580D0BU },
89fc8793fbSbriggs { 0x3FFC - 0x3fff, 0xD11DE0FFU, 0x15AB18CAU },
90fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xCE168A77U, 0x25080CE1U },
91fc8793fbSbriggs { 0x3FFC - 0x3fff, 0xDE1433A1U, 0x6C66B150U },
92fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xCB8727C0U, 0x65C393E0U },
93fc8793fbSbriggs { 0x3FFC - 0x3fff, 0xEAE10B5AU, 0x7DDC8ADDU },
94fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xC907DA4EU, 0x871146ADU },
95fc8793fbSbriggs { 0x3FFC - 0x3fff, 0xF7856E5EU, 0xE2C9B291U },
96fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xC6980C69U, 0x80C6980CU },
97fc8793fbSbriggs { 0x3FFD - 0x3fff, 0x82012CA5U, 0xA68206D7U },
98fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xC4372F85U, 0x5D824CA6U },
99fc8793fbSbriggs { 0x3FFD - 0x3fff, 0x882C5FCDU, 0x7256A8C5U },
100fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xC1E4BBD5U, 0x95F6E947U },
101fc8793fbSbriggs { 0x3FFD - 0x3fff, 0x8E44C60BU, 0x4CCFD7DEU },
102fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xBFA02FE8U, 0x0BFA02FFU },
103fc8793fbSbriggs { 0x3FFD - 0x3fff, 0x944AD09EU, 0xF4351AF6U },
104fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xBD691047U, 0x07661AA3U },
105fc8793fbSbriggs { 0x3FFD - 0x3fff, 0x9A3EECD4U, 0xC3EAA6B2U },
106fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xBB3EE721U, 0xA54D880CU },
107fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xA0218434U, 0x353F1DE8U },
108fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xB92143FAU, 0x36F5E02EU },
109fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xA5F2FCABU, 0xBBC506DAU },
110fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xB70FBB5AU, 0x19BE3659U },
111fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xABB3B8BAU, 0x2AD362A5U },
112fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xB509E68AU, 0x9B94821FU },
113fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xB1641795U, 0xCE3CA97BU },
114fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xB30F6352U, 0x8917C80BU },
115fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xB7047551U, 0x5D0F1C61U },
116fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xB11FD3B8U, 0x0B11FD3CU },
117fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xBC952AFEU, 0xEA3D13E1U },
118fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xAF3ADDC6U, 0x80AF3ADEU },
119fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xC2168ED0U, 0xF458BA4AU },
120fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xAD602B58U, 0x0AD602B6U },
121fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xC788F439U, 0xB3163BF1U },
122fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xAB8F69E2U, 0x8359CD11U },
123fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xCCECAC08U, 0xBF04565DU },
124fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xA9C84A47U, 0xA07F5638U },
125fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xD2420487U, 0x2DD85160U },
126fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xA80A80A8U, 0x0A80A80BU },
127fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xD7894992U, 0x3BC3588AU },
128fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xA655C439U, 0x2D7B73A8U },
129fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xDCC2C4B4U, 0x9887DACCU },
130fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xA4A9CF1DU, 0x96833751U },
131fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xE1EEBD3EU, 0x6D6A6B9EU },
132fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xA3065E3FU, 0xAE7CD0E0U },
133fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xE70D785CU, 0x2F9F5BDCU },
134fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xA16B312EU, 0xA8FC377DU },
135fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xEC1F392CU, 0x5179F283U },
136fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x9FD809FDU, 0x809FD80AU },
137fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xF12440D3U, 0xE36130E6U },
138fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x9E4CAD23U, 0xDD5F3A20U },
139fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xF61CCE92U, 0x346600BBU },
140fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x9CC8E160U, 0xC3FB19B9U },
141fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xFB091FD3U, 0x8145630AU },
142fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x9B4C6F9EU, 0xF03A3CAAU },
143fc8793fbSbriggs { 0x3FFD - 0x3fff, 0xFFE97042U, 0xBFA4C2ADU },
144fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x99D722DAU, 0xBDE58F06U },
145fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x825EFCEDU, 0x49369330U },
146fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x9868C809U, 0x868C8098U },
147fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x84C37A7AU, 0xB9A905C9U },
148fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x97012E02U, 0x5C04B809U },
149fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x87224C2EU, 0x8E645FB7U },
150fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x95A02568U, 0x095A0257U },
151fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x897B8CACU, 0x9F7DE298U },
152fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x94458094U, 0x45809446U },
153fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x8BCF55DEU, 0xC4CD05FEU },
154fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x92F11384U, 0x0497889CU },
155fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x8E1DC0FBU, 0x89E125E5U },
156fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x91A2B3C4U, 0xD5E6F809U },
157fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x9066E68CU, 0x955B6C9BU },
158fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x905A3863U, 0x3E06C43BU },
159fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x92AADE74U, 0xC7BE59E0U },
160fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x8F1779D9U, 0xFDC3A219U },
161fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x94E9BFF6U, 0x15845643U },
162fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x8DDA5202U, 0x37694809U },
163fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x9723A1B7U, 0x20134203U },
164fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x8CA29C04U, 0x6514E023U },
165fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x995899C8U, 0x90EB8990U },
166fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x8B70344AU, 0x139BC75AU },
167fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x9B88BDAAU, 0x3A3DAE2FU },
168fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x8A42F870U, 0x5669DB46U },
169fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x9DB4224FU, 0xFFE1157CU },
170fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x891AC73AU, 0xE9819B50U },
171fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x9FDADC26U, 0x8B7A12DAU },
172fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x87F78087U, 0xF78087F8U },
173fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xA1FCFF17U, 0xCE733BD4U },
174fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x86D90544U, 0x7A34ACC6U },
175fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xA41A9E8FU, 0x5446FB9FU },
176fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x85BF3761U, 0x2CEE3C9BU },
177fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xA633CD7EU, 0x6771CD8BU },
178fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x84A9F9C8U, 0x084A9F9DU },
179fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xA8489E60U, 0x0B435A5EU },
180fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x83993052U, 0x3FBE3368U },
181fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xAA59233CU, 0xCCA4BD49U },
182fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x828CBFBEU, 0xB9A020A3U },
183fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xAC656DAEU, 0x6BCC4985U },
184fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x81848DA8U, 0xFAF0D277U },
185fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xAE6D8EE3U, 0x60BB2468U },
186fc8793fbSbriggs { 0x3FFE - 0x3fff, 0x80808080U, 0x80808081U },
187fc8793fbSbriggs { 0x3FFE - 0x3fff, 0xB07197A2U, 0x3C46C654U },
188fc8793fbSbriggs };
189fc8793fbSbriggs
19002cdf4d2Sdsl static struct fpn *__fpu_logn(struct fpemu *fe);
191fc8793fbSbriggs
192fc8793fbSbriggs /*
193fc8793fbSbriggs * natural log - algorithm taken from Motorola FPSP,
194fc8793fbSbriggs * except this doesn't bother to check for invalid input.
195fc8793fbSbriggs */
196fc8793fbSbriggs static struct fpn *
__fpu_logn(struct fpemu * fe)19782357f6dSdsl __fpu_logn(struct fpemu *fe)
198fc8793fbSbriggs {
199fc8793fbSbriggs static struct fpn X, F, U, V, W, KLOG2;
200fc8793fbSbriggs struct fpn *d;
201fc8793fbSbriggs int i, k;
202fc8793fbSbriggs
203fc8793fbSbriggs CPYFPN(&X, &fe->fe_f2);
204fc8793fbSbriggs
205fc8793fbSbriggs /* see if |X-1| < 1/16 approx. */
206fc8793fbSbriggs if ((-1 == X.fp_exp && (0xf07d0000U >> (31 - FP_LG)) <= X.fp_mant[0]) ||
207fc8793fbSbriggs (0 == X.fp_exp && X.fp_mant[0] <= (0x88410000U >> (31 - FP_LG)))) {
208fc8793fbSbriggs /* log near 1 */
20959422960Sbriggs #if FPE_DEBUG
2109dc680b6Schristos printf("__fpu_logn: log near 1\n");
21159422960Sbriggs #endif
212fc8793fbSbriggs
213a85a92a0Sisaki fpu_const(&fe->fe_f1, FPU_CONST_1);
214fc8793fbSbriggs /* X+1 */
215fc8793fbSbriggs d = fpu_add(fe);
216fc8793fbSbriggs CPYFPN(&V, d);
217fc8793fbSbriggs
218fc8793fbSbriggs CPYFPN(&fe->fe_f1, &X);
219a85a92a0Sisaki fpu_const(&fe->fe_f2, FPU_CONST_1);
220fc8793fbSbriggs fe->fe_f2.fp_sign = 1; /* -1.0 */
221fc8793fbSbriggs /* X-1 */
222fc8793fbSbriggs d = fpu_add(fe);
223fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
224fc8793fbSbriggs /* 2(X-1) */
225fc8793fbSbriggs fe->fe_f1.fp_exp++; /* *= 2 */
226fc8793fbSbriggs CPYFPN(&fe->fe_f2, &V);
227fc8793fbSbriggs /* U=2(X-1)/(X+1) */
228fc8793fbSbriggs d = fpu_div(fe);
229fc8793fbSbriggs CPYFPN(&U, d);
230fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
231fc8793fbSbriggs CPYFPN(&fe->fe_f2, d);
232fc8793fbSbriggs /* V=U*U */
233fc8793fbSbriggs d = fpu_mul(fe);
234fc8793fbSbriggs CPYFPN(&V, d);
235fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
236fc8793fbSbriggs CPYFPN(&fe->fe_f2, d);
237fc8793fbSbriggs /* W=V*V */
238fc8793fbSbriggs d = fpu_mul(fe);
239fc8793fbSbriggs CPYFPN(&W, d);
240fc8793fbSbriggs
241fc8793fbSbriggs /* calculate U+U*V*([B1+W*(B3+W*B5)]+[V*(B2+W*B4)]) */
242fc8793fbSbriggs
243fc8793fbSbriggs /* B1+W*(B3+W*B5) part */
244fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
245fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logB5);
246fc8793fbSbriggs /* W*B5 */
247fc8793fbSbriggs d = fpu_mul(fe);
248fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
249fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logB3);
250fc8793fbSbriggs /* B3+W*B5 */
251fc8793fbSbriggs d = fpu_add(fe);
252fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
253fc8793fbSbriggs CPYFPN(&fe->fe_f2, &W);
254fc8793fbSbriggs /* W*(B3+W*B5) */
255fc8793fbSbriggs d = fpu_mul(fe);
256fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
257fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logB1);
258fc8793fbSbriggs /* B1+W*(B3+W*B5) */
259fc8793fbSbriggs d = fpu_add(fe);
260fc8793fbSbriggs CPYFPN(&X, d);
261fc8793fbSbriggs
262fc8793fbSbriggs /* [V*(B2+W*B4)] part */
263fc8793fbSbriggs CPYFPN(&fe->fe_f1, &W);
264fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logB4);
265fc8793fbSbriggs /* W*B4 */
266fc8793fbSbriggs d = fpu_mul(fe);
267fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
268fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logB2);
269fc8793fbSbriggs /* B2+W*B4 */
270fc8793fbSbriggs d = fpu_add(fe);
271fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
272fc8793fbSbriggs CPYFPN(&fe->fe_f2, &V);
273fc8793fbSbriggs /* V*(B2+W*B4) */
274fc8793fbSbriggs d = fpu_mul(fe);
275fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
276fc8793fbSbriggs CPYFPN(&fe->fe_f2, &X);
277fc8793fbSbriggs /* B1+W*(B3+W*B5)+V*(B2+W*B4) */
278fc8793fbSbriggs d = fpu_add(fe);
279fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
280fc8793fbSbriggs CPYFPN(&fe->fe_f2, &V);
281fc8793fbSbriggs /* V*(B1+W*(B3+W*B5)+V*(B2+W*B4)) */
282fc8793fbSbriggs d = fpu_mul(fe);
283fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
284fc8793fbSbriggs CPYFPN(&fe->fe_f2, &U);
285fc8793fbSbriggs /* U*V*(B1+W*(B3+W*B5)+V*(B2+W*B4)) */
286fc8793fbSbriggs d = fpu_mul(fe);
287fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
288fc8793fbSbriggs CPYFPN(&fe->fe_f2, &U);
289fc8793fbSbriggs /* U+U*V*(B1+W*(B3+W*B5)+V*(B2+W*B4)) */
290fc8793fbSbriggs d = fpu_add(fe);
291fc8793fbSbriggs } else /* the usual case */ {
29259422960Sbriggs #if FPE_DEBUG
2939dc680b6Schristos printf("__fpu_logn: the usual case. X=(%d,%08x,%08x...)\n",
294fc8793fbSbriggs X.fp_exp, X.fp_mant[0], X.fp_mant[1]);
29559422960Sbriggs #endif
296fc8793fbSbriggs
297fc8793fbSbriggs k = X.fp_exp;
298fc8793fbSbriggs /* X <- Y */
299fc8793fbSbriggs X.fp_exp = fe->fe_f2.fp_exp = 0;
300fc8793fbSbriggs
301fc8793fbSbriggs /* get the most significant 7 bits of X */
302fc8793fbSbriggs F.fp_class = FPC_NUM;
303fc8793fbSbriggs F.fp_sign = 0;
304fc8793fbSbriggs F.fp_exp = X.fp_exp;
305fc8793fbSbriggs F.fp_mant[0] = X.fp_mant[0] & (0xfe000000U >> (31 - FP_LG));
306fc8793fbSbriggs F.fp_mant[0] |= (0x01000000U >> (31 - FP_LG));
30759422960Sbriggs F.fp_mant[1] = F.fp_mant[2] = 0;
308fc8793fbSbriggs F.fp_sticky = 0;
309fc8793fbSbriggs
31059422960Sbriggs #if FPE_DEBUG
3119dc680b6Schristos printf("__fpu_logn: X=Y*2^k=(%d,%08x,%08x...)*2^%d\n",
312fc8793fbSbriggs fe->fe_f2.fp_exp, fe->fe_f2.fp_mant[0],
313fc8793fbSbriggs fe->fe_f2.fp_mant[1], k);
3149dc680b6Schristos printf("__fpu_logn: F=(%d,%08x,%08x...)\n",
315fc8793fbSbriggs F.fp_exp, F.fp_mant[0], F.fp_mant[1]);
31659422960Sbriggs #endif
317fc8793fbSbriggs
318fc8793fbSbriggs /* index to the table */
3194e2cf368Sis i = (F.fp_mant[0] >> (FP_LG - 7)) & 0x7e;
320fc8793fbSbriggs
32159422960Sbriggs #if FPE_DEBUG
3229dc680b6Schristos printf("__fpu_logn: index to logtbl i=%d(%x)\n", i, i);
32359422960Sbriggs #endif
324fc8793fbSbriggs
325fc8793fbSbriggs CPYFPN(&fe->fe_f1, &F);
326fc8793fbSbriggs /* -F */
327fc8793fbSbriggs fe->fe_f1.fp_sign = 1;
328fc8793fbSbriggs /* Y-F */
329fc8793fbSbriggs d = fpu_add(fe);
330fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
331fc8793fbSbriggs
332fc8793fbSbriggs /* fe_f2 = 1/F */
333fc8793fbSbriggs fe->fe_f2.fp_class = FPC_NUM;
3341e5cdc09Sisaki fe->fe_f2.fp_sign = fe->fe_f2.fp_sticky = fe->fe_f2.fp_mant[2]
3351e5cdc09Sisaki = 0;
336fc8793fbSbriggs fe->fe_f2.fp_exp = logtbl[i].sp_exp;
337fc8793fbSbriggs fe->fe_f2.fp_mant[0] = (logtbl[i].sp_m0 >> (31 - FP_LG));
338fc8793fbSbriggs fe->fe_f2.fp_mant[1] = (logtbl[i].sp_m0 << (FP_LG + 1)) |
339fc8793fbSbriggs (logtbl[i].sp_m1 >> (31 - FP_LG));
340f53c2e8dSisaki fe->fe_f2.fp_mant[2] =
341f53c2e8dSisaki (uint32_t)(logtbl[i].sp_m1 << (FP_LG + 1));
342fc8793fbSbriggs
34359422960Sbriggs #if FPE_DEBUG
3449dc680b6Schristos printf("__fpu_logn: 1/F=(%d,%08x,%08x...)\n", fe->fe_f2.fp_exp,
345fc8793fbSbriggs fe->fe_f2.fp_mant[0], fe->fe_f2.fp_mant[1]);
34659422960Sbriggs #endif
347fc8793fbSbriggs
348fc8793fbSbriggs /* U = (Y-F) * (1/F) */
349fc8793fbSbriggs d = fpu_mul(fe);
350fc8793fbSbriggs CPYFPN(&U, d);
351fc8793fbSbriggs
352fc8793fbSbriggs /* KLOG2 = K * ln(2) */
353fc8793fbSbriggs /* fe_f1 == (fpn)k */
354fc8793fbSbriggs fpu_explode(fe, &fe->fe_f1, FTYPE_LNG, &k);
355a85a92a0Sisaki (void)fpu_const(&fe->fe_f2, FPU_CONST_LN_2);
35659422960Sbriggs #if FPE_DEBUG
3571e5cdc09Sisaki printf("__fpu_logn: fp(k)=(%d,%08x,%08x...)\n",
3581e5cdc09Sisaki fe->fe_f1.fp_exp,
359fc8793fbSbriggs fe->fe_f1.fp_mant[0], fe->fe_f1.fp_mant[1]);
3601e5cdc09Sisaki printf("__fpu_logn: ln(2)=(%d,%08x,%08x...)\n",
3611e5cdc09Sisaki fe->fe_f2.fp_exp,
362fc8793fbSbriggs fe->fe_f2.fp_mant[0], fe->fe_f2.fp_mant[1]);
36359422960Sbriggs #endif
364fc8793fbSbriggs /* K * LOGOF2 */
365fc8793fbSbriggs d = fpu_mul(fe);
366fc8793fbSbriggs CPYFPN(&KLOG2, d);
367fc8793fbSbriggs
368fc8793fbSbriggs /* V=U*U */
369fc8793fbSbriggs CPYFPN(&fe->fe_f1, &U);
370fc8793fbSbriggs CPYFPN(&fe->fe_f2, &U);
371fc8793fbSbriggs d = fpu_mul(fe);
372fc8793fbSbriggs CPYFPN(&V, d);
373fc8793fbSbriggs
374fc8793fbSbriggs /*
375fc8793fbSbriggs * approximation of LOG(1+U) by
376fc8793fbSbriggs * (U+V*(A1+V*(A3+V*A5)))+(U*V*(A2+V*(A4+V*A6)))
377fc8793fbSbriggs */
378fc8793fbSbriggs
379fc8793fbSbriggs /* (U+V*(A1+V*(A3+V*A5))) part */
380fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
381fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA5);
382fc8793fbSbriggs /* V*A5 */
383fc8793fbSbriggs d = fpu_mul(fe);
384fc8793fbSbriggs
385fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
386fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA3);
387fc8793fbSbriggs /* A3+V*A5 */
388fc8793fbSbriggs d = fpu_add(fe);
389fc8793fbSbriggs
390fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
391fc8793fbSbriggs CPYFPN(&fe->fe_f2, &V);
392fc8793fbSbriggs /* V*(A3+V*A5) */
393fc8793fbSbriggs d = fpu_mul(fe);
394fc8793fbSbriggs
395fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
396fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA1);
397fc8793fbSbriggs /* A1+V*(A3+V*A5) */
398fc8793fbSbriggs d = fpu_add(fe);
399fc8793fbSbriggs
400fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
401fc8793fbSbriggs CPYFPN(&fe->fe_f2, &V);
402fc8793fbSbriggs /* V*(A1+V*(A3+V*A5)) */
403fc8793fbSbriggs d = fpu_mul(fe);
404fc8793fbSbriggs
405fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
406fc8793fbSbriggs CPYFPN(&fe->fe_f2, &U);
407fc8793fbSbriggs /* U+V*(A1+V*(A3+V*A5)) */
408fc8793fbSbriggs d = fpu_add(fe);
409fc8793fbSbriggs
410fc8793fbSbriggs CPYFPN(&X, d);
411fc8793fbSbriggs
412fc8793fbSbriggs /* (U*V*(A2+V*(A4+V*A6))) part */
413fc8793fbSbriggs CPYFPN(&fe->fe_f1, &V);
414fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA6);
415fc8793fbSbriggs /* V*A6 */
416fc8793fbSbriggs d = fpu_mul(fe);
417fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
418fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA4);
419fc8793fbSbriggs /* A4+V*A6 */
420fc8793fbSbriggs d = fpu_add(fe);
421fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
422fc8793fbSbriggs CPYFPN(&fe->fe_f2, &V);
423fc8793fbSbriggs /* V*(A4+V*A6) */
424fc8793fbSbriggs d = fpu_mul(fe);
425fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
426fc8793fbSbriggs fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA2);
427fc8793fbSbriggs /* A2+V*(A4+V*A6) */
428fc8793fbSbriggs d = fpu_add(fe);
429fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
430fc8793fbSbriggs CPYFPN(&fe->fe_f2, &V);
431fc8793fbSbriggs /* V*(A2+V*(A4+V*A6)) */
432fc8793fbSbriggs d = fpu_mul(fe);
433fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
434fc8793fbSbriggs CPYFPN(&fe->fe_f2, &U);
435fc8793fbSbriggs /* U*V*(A2+V*(A4+V*A6)) */
436fc8793fbSbriggs d = fpu_mul(fe);
437fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
438fc8793fbSbriggs i++;
439fc8793fbSbriggs /* fe_f2 = logtbl[i+1] (== LOG(F)) */
440fc8793fbSbriggs fe->fe_f2.fp_class = FPC_NUM;
4411e5cdc09Sisaki fe->fe_f2.fp_sign = fe->fe_f2.fp_sticky = fe->fe_f2.fp_mant[2]
4421e5cdc09Sisaki = 0;
443fc8793fbSbriggs fe->fe_f2.fp_exp = logtbl[i].sp_exp;
444fc8793fbSbriggs fe->fe_f2.fp_mant[0] = (logtbl[i].sp_m0 >> (31 - FP_LG));
445fc8793fbSbriggs fe->fe_f2.fp_mant[1] = (logtbl[i].sp_m0 << (FP_LG + 1)) |
446fc8793fbSbriggs (logtbl[i].sp_m1 >> (31 - FP_LG));
447fc8793fbSbriggs fe->fe_f2.fp_mant[2] = (logtbl[i].sp_m1 << (FP_LG + 1));
448fc8793fbSbriggs
44959422960Sbriggs #if FPE_DEBUG
4501e5cdc09Sisaki printf("__fpu_logn: ln(F)=(%d,%08x,%08x,...)\n",
4511e5cdc09Sisaki fe->fe_f2.fp_exp,
452fc8793fbSbriggs fe->fe_f2.fp_mant[0], fe->fe_f2.fp_mant[1]);
45359422960Sbriggs #endif
454fc8793fbSbriggs
455fc8793fbSbriggs /* LOG(F)+U*V*(A2+V*(A4+V*A6)) */
456fc8793fbSbriggs d = fpu_add(fe);
457fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
458fc8793fbSbriggs CPYFPN(&fe->fe_f2, &X);
459fc8793fbSbriggs /* LOG(F)+U+V*(A1+V*(A3+V*A5))+U*V*(A2+V*(A4+V*A6)) */
460fc8793fbSbriggs d = fpu_add(fe);
461fc8793fbSbriggs
46259422960Sbriggs #if FPE_DEBUG
46359422960Sbriggs printf("__fpu_logn: ln(Y)=(%c,%d,%08x,%08x,%08x)\n",
464fc8793fbSbriggs d->fp_sign ? '-' : '+', d->fp_exp,
46559422960Sbriggs d->fp_mant[0], d->fp_mant[1], d->fp_mant[2]);
46659422960Sbriggs #endif
467fc8793fbSbriggs
468fc8793fbSbriggs CPYFPN(&fe->fe_f1, d);
469fc8793fbSbriggs CPYFPN(&fe->fe_f2, &KLOG2);
470fc8793fbSbriggs /* K*LOGOF2+LOG(F)+U+V*(A1+V*(A3+V*A5))+U*V*(A2+V*(A4+V*A6)) */
471fc8793fbSbriggs d = fpu_add(fe);
472fc8793fbSbriggs }
473fc8793fbSbriggs
474fc8793fbSbriggs return d;
475fc8793fbSbriggs }
476fc8793fbSbriggs
477fc8793fbSbriggs struct fpn *
fpu_log10(struct fpemu * fe)478454af1c0Sdsl fpu_log10(struct fpemu *fe)
479fc8793fbSbriggs {
480fc8793fbSbriggs struct fpn *fp = &fe->fe_f2;
481f53c2e8dSisaki uint32_t fpsr;
482fc8793fbSbriggs
483fc8793fbSbriggs fpsr = fe->fe_fpsr & ~FPSR_EXCP; /* clear all exceptions */
484fc8793fbSbriggs
485fc8793fbSbriggs if (fp->fp_class >= FPC_NUM) {
486fc8793fbSbriggs if (fp->fp_sign) { /* negative number or Inf */
487fc8793fbSbriggs fp = fpu_newnan(fe);
488fc8793fbSbriggs fpsr |= FPSR_OPERR;
489fc8793fbSbriggs } else if (fp->fp_class == FPC_NUM) {
490fc8793fbSbriggs /* the real work here */
491fc8793fbSbriggs fp = __fpu_logn(fe);
492fc8793fbSbriggs if (fp != &fe->fe_f1)
493fc8793fbSbriggs CPYFPN(&fe->fe_f1, fp);
494a85a92a0Sisaki (void)fpu_const(&fe->fe_f2, FPU_CONST_LN_10);
495fc8793fbSbriggs fp = fpu_div(fe);
496fc8793fbSbriggs } /* else if fp == +Inf, return +Inf */
497fc8793fbSbriggs } else if (fp->fp_class == FPC_ZERO) {
498fc8793fbSbriggs /* return -Inf */
499fc8793fbSbriggs fp->fp_class = FPC_INF;
500fc8793fbSbriggs fp->fp_sign = 1;
501fc8793fbSbriggs fpsr |= FPSR_DZ;
502fc8793fbSbriggs } else if (fp->fp_class == FPC_SNAN) {
503fc8793fbSbriggs fpsr |= FPSR_SNAN;
504fc8793fbSbriggs fp = fpu_newnan(fe);
505fc8793fbSbriggs } else {
506fc8793fbSbriggs fp = fpu_newnan(fe);
507fc8793fbSbriggs }
508fc8793fbSbriggs
509fc8793fbSbriggs fe->fe_fpsr = fpsr;
510fc8793fbSbriggs
511fc8793fbSbriggs return fp;
512fc8793fbSbriggs }
513fc8793fbSbriggs
514fc8793fbSbriggs struct fpn *
fpu_log2(struct fpemu * fe)515454af1c0Sdsl fpu_log2(struct fpemu *fe)
516fc8793fbSbriggs {
517fc8793fbSbriggs struct fpn *fp = &fe->fe_f2;
518f53c2e8dSisaki uint32_t fpsr;
519fc8793fbSbriggs
520fc8793fbSbriggs fpsr = fe->fe_fpsr & ~FPSR_EXCP; /* clear all exceptions */
521fc8793fbSbriggs
522fc8793fbSbriggs if (fp->fp_class >= FPC_NUM) {
523fc8793fbSbriggs if (fp->fp_sign) { /* negative number or Inf */
524fc8793fbSbriggs fp = fpu_newnan(fe);
525fc8793fbSbriggs fpsr |= FPSR_OPERR;
526fc8793fbSbriggs } else if (fp->fp_class == FPC_NUM) {
527fc8793fbSbriggs /* the real work here */
528fc8793fbSbriggs if (fp->fp_mant[0] == FP_1 && fp->fp_mant[1] == 0 &&
52959422960Sbriggs fp->fp_mant[2] == 0) {
530fc8793fbSbriggs /* fp == 2.0 ^ exp <--> log2(fp) == exp */
5311e5cdc09Sisaki fpu_explode(fe, &fe->fe_f3, FTYPE_LNG,
5321e5cdc09Sisaki &fp->fp_exp);
533fc8793fbSbriggs fp = &fe->fe_f3;
534fc8793fbSbriggs } else {
535fc8793fbSbriggs fp = __fpu_logn(fe);
536fc8793fbSbriggs if (fp != &fe->fe_f1)
537fc8793fbSbriggs CPYFPN(&fe->fe_f1, fp);
538a85a92a0Sisaki (void)fpu_const(&fe->fe_f2, FPU_CONST_LN_2);
539fc8793fbSbriggs fp = fpu_div(fe);
540fc8793fbSbriggs }
541fc8793fbSbriggs } /* else if fp == +Inf, return +Inf */
542fc8793fbSbriggs } else if (fp->fp_class == FPC_ZERO) {
543fc8793fbSbriggs /* return -Inf */
544fc8793fbSbriggs fp->fp_class = FPC_INF;
545fc8793fbSbriggs fp->fp_sign = 1;
546fc8793fbSbriggs fpsr |= FPSR_DZ;
547fc8793fbSbriggs } else if (fp->fp_class == FPC_SNAN) {
548fc8793fbSbriggs fpsr |= FPSR_SNAN;
549fc8793fbSbriggs fp = fpu_newnan(fe);
550fc8793fbSbriggs } else {
551fc8793fbSbriggs fp = fpu_newnan(fe);
552fc8793fbSbriggs }
553fc8793fbSbriggs
554fc8793fbSbriggs fe->fe_fpsr = fpsr;
555fc8793fbSbriggs return fp;
556fc8793fbSbriggs }
557fc8793fbSbriggs
558fc8793fbSbriggs struct fpn *
fpu_logn(struct fpemu * fe)559454af1c0Sdsl fpu_logn(struct fpemu *fe)
560fc8793fbSbriggs {
561fc8793fbSbriggs struct fpn *fp = &fe->fe_f2;
562f53c2e8dSisaki uint32_t fpsr;
563fc8793fbSbriggs
564fc8793fbSbriggs fpsr = fe->fe_fpsr & ~FPSR_EXCP; /* clear all exceptions */
565fc8793fbSbriggs
566fc8793fbSbriggs if (fp->fp_class >= FPC_NUM) {
567fc8793fbSbriggs if (fp->fp_sign) { /* negative number or Inf */
568fc8793fbSbriggs fp = fpu_newnan(fe);
569fc8793fbSbriggs fpsr |= FPSR_OPERR;
570fc8793fbSbriggs } else if (fp->fp_class == FPC_NUM) {
571fc8793fbSbriggs /* the real work here */
572fc8793fbSbriggs fp = __fpu_logn(fe);
573fc8793fbSbriggs } /* else if fp == +Inf, return +Inf */
574fc8793fbSbriggs } else if (fp->fp_class == FPC_ZERO) {
575fc8793fbSbriggs /* return -Inf */
576fc8793fbSbriggs fp->fp_class = FPC_INF;
577fc8793fbSbriggs fp->fp_sign = 1;
578fc8793fbSbriggs fpsr |= FPSR_DZ;
579fc8793fbSbriggs } else if (fp->fp_class == FPC_SNAN) {
580fc8793fbSbriggs fpsr |= FPSR_SNAN;
581fc8793fbSbriggs fp = fpu_newnan(fe);
582fc8793fbSbriggs } else {
583fc8793fbSbriggs fp = fpu_newnan(fe);
584fc8793fbSbriggs }
585fc8793fbSbriggs
586fc8793fbSbriggs fe->fe_fpsr = fpsr;
587fc8793fbSbriggs
588fc8793fbSbriggs return fp;
589fc8793fbSbriggs }
590fc8793fbSbriggs
591fc8793fbSbriggs struct fpn *
fpu_lognp1(struct fpemu * fe)592454af1c0Sdsl fpu_lognp1(struct fpemu *fe)
593fc8793fbSbriggs {
594fc8793fbSbriggs struct fpn *fp;
595fc8793fbSbriggs
596*9050bf24Sisaki /* if src is +0/-0, return +0/-0 */
597*9050bf24Sisaki if (ISZERO(&fe->fe_f2))
598*9050bf24Sisaki return &fe->fe_f2;
599*9050bf24Sisaki
600fc8793fbSbriggs /* build a 1.0 */
601a85a92a0Sisaki fp = fpu_const(&fe->fe_f1, FPU_CONST_1);
602fc8793fbSbriggs /* fp = 1.0 + f2 */
603fc8793fbSbriggs fp = fpu_add(fe);
604fc8793fbSbriggs
605fc8793fbSbriggs /* copy the result to the src opr */
606fc8793fbSbriggs CPYFPN(&fe->fe_f2, fp);
607fc8793fbSbriggs
608fc8793fbSbriggs return fpu_logn(fe);
609fc8793fbSbriggs }
610