OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [language/] [c/] [libm/] [current/] [src/] [double/] [ieee754-core/] [e_rem_pio2.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//===========================================================================
2
//
3
//      e_rem_pio2.c
4
//
5
//      Part of the standard mathematical function library
6
//
7
//===========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//===========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):   jlarmour
43
// Contributors:  jlarmour
44
// Date:        1998-02-13
45
// Purpose:     
46
// Description: 
47
// Usage:       
48
//
49
//####DESCRIPTIONEND####
50
//
51
//===========================================================================
52
 
53
// CONFIGURATION
54
 
55
#include <pkgconf/libm.h>   // Configuration header
56
 
57
// Include the Math library?
58
#ifdef CYGPKG_LIBM     
59
 
60
// Derived from code with the following copyright
61
 
62
 
63
/* @(#)e_rem_pio2.c 1.4 95/01/18 */
64
/*
65
 * ====================================================
66
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
67
 *
68
 * Developed at SunSoft, a Sun Microsystems, Inc. business.
69
 * Permission to use, copy, modify, and distribute this
70
 * software is freely granted, provided that this notice
71
 * is preserved.
72
 * ====================================================
73
 *
74
 */
75
 
76
/* __ieee754_rem_pio2(x,y)
77
 *
78
 * return the remainder of x rem pi/2 in y[0]+y[1]
79
 * use __kernel_rem_pio2()
80
 */
81
 
82
#include "mathincl/fdlibm.h"
83
 
84
/*
85
 * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
86
 */
87
static const int two_over_pi[] = {
88
0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
89
0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
90
0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
91
0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
92
0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
93
0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
94
0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
95
0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
96
0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
97
0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
98
0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
99
};
100
 
101
static const int npio2_hw[] = {
102
0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
103
0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
104
0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
105
0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
106
0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
107
0x404858EB, 0x404921FB,
108
};
109
 
110
/*
111
 * invpio2:  53 bits of 2/pi
112
 * pio2_1:   first  33 bit of pi/2
113
 * pio2_1t:  pi/2 - pio2_1
114
 * pio2_2:   second 33 bit of pi/2
115
 * pio2_2t:  pi/2 - (pio2_1+pio2_2)
116
 * pio2_3:   third  33 bit of pi/2
117
 * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
118
 */
119
 
120
static const double
121
zero =  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
122
half =  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
123
two24 =  1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
124
invpio2 =  6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
125
pio2_1  =  1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
126
pio2_1t =  6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
127
pio2_2  =  6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
128
pio2_2t =  2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
129
pio2_3  =  2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
130
pio2_3t =  8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
131
 
132
        int __ieee754_rem_pio2(double x, double *y)
133
{
134
        double z,w,t,r,fn;
135
        double tx[3];
136
        int e0,i,j,nx,n,ix,hx;
137
 
138
        hx = CYG_LIBM_HI(x);            /* high word of x */
139
        ix = hx&0x7fffffff;
140
        if(ix<=0x3fe921fb)   /* |x| ~<= pi/4 , no need for reduction */
141
            {y[0] = x; y[1] = 0; return 0;}
142
        if(ix<0x4002d97c) {  /* |x| < 3pi/4, special case with n=+-1 */
143
            if(hx>0) {
144
                z = x - pio2_1;
145
                if(ix!=0x3ff921fb) {    /* 33+53 bit pi is good enough */
146
                    y[0] = z - pio2_1t;
147
                    y[1] = (z-y[0])-pio2_1t;
148
                } else {                /* near pi/2, use 33+33+53 bit pi */
149
                    z -= pio2_2;
150
                    y[0] = z - pio2_2t;
151
                    y[1] = (z-y[0])-pio2_2t;
152
                }
153
                return 1;
154
            } else {    /* negative x */
155
                z = x + pio2_1;
156
                if(ix!=0x3ff921fb) {    /* 33+53 bit pi is good enough */
157
                    y[0] = z + pio2_1t;
158
                    y[1] = (z-y[0])+pio2_1t;
159
                } else {                /* near pi/2, use 33+33+53 bit pi */
160
                    z += pio2_2;
161
                    y[0] = z + pio2_2t;
162
                    y[1] = (z-y[0])+pio2_2t;
163
                }
164
                return -1;
165
            }
166
        }
167
        if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
168
            t  = fabs(x);
169
            n  = (int) (t*invpio2+half);
170
            fn = (double)n;
171
            r  = t-fn*pio2_1;
172
            w  = fn*pio2_1t;    /* 1st round good to 85 bit */
173
            if(n<32&&ix!=npio2_hw[n-1]) {
174
                y[0] = r-w;     /* quick check no cancellation */
175
            } else {
176
                j  = ix>>20;
177
                y[0] = r-w;
178
                i = j-(((CYG_LIBM_HI(y[0]))>>20)&0x7ff);
179
                if(i>16) {  /* 2nd iteration needed, good to 118 */
180
                    t  = r;
181
                    w  = fn*pio2_2;
182
                    r  = t-w;
183
                    w  = fn*pio2_2t-((t-r)-w);
184
                    y[0] = r-w;
185
                    i = j-(((CYG_LIBM_HI(y[0]))>>20)&0x7ff);
186
                    if(i>49)  { /* 3rd iteration need, 151 bits acc */
187
                        t  = r; /* will cover all possible cases */
188
                        w  = fn*pio2_3;
189
                        r  = t-w;
190
                        w  = fn*pio2_3t-((t-r)-w);
191
                        y[0] = r-w;
192
                    }
193
                }
194
            }
195
            y[1] = (r-y[0])-w;
196
            if(hx<0)    {y[0] = -y[0]; y[1] = -y[1]; return -n;}
197
            else         return n;
198
        }
199
    /*
200
     * all other (large) arguments
201
     */
202
        if(ix>=0x7ff00000) {            /* x is inf or NaN */
203
            y[0]=y[1]=x-x; return 0;
204
        }
205
    /* set z = scalbn(|x|,ilogb(x)-23) */
206
        CYG_LIBM_LO(z) = CYG_LIBM_LO(x);
207
        e0      = (ix>>20)-1046;        /* e0 = ilogb(z)-23; */
208
        CYG_LIBM_HI(z) = ix - (e0<<20);
209
        for(i=0;i<2;i++) {
210
                tx[i] = (double)((int)(z));
211
                z     = (z-tx[i])*two24;
212
        }
213
        tx[2] = z;
214
        nx = 3;
215
        while(tx[nx-1]==zero) nx--;     /* skip zero term */
216
        n  =  __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
217
        if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
218
        return n;
219
}
220
 
221
#endif // ifdef CYGPKG_LIBM     
222
 
223
// EOF e_rem_pio2.c

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.