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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [native/] [fdlibm/] [e_rem_pio2.c] - Blame information for rev 817

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 774 jeremybenn
 
2
/* @(#)e_rem_pio2.c 1.4 95/01/18 */
3
/*
4
 * ====================================================
5
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6
 *
7
 * Developed at SunSoft, a Sun Microsystems, Inc. business.
8
 * Permission to use, copy, modify, and distribute this
9
 * software is freely granted, provided that this notice
10
 * is preserved.
11
 * ====================================================
12
 *
13
 */
14
 
15
/* __ieee754_rem_pio2(x,y)
16
 *
17
 * return the remainder of x rem pi/2 in y[0]+y[1]
18
 * use __kernel_rem_pio2()
19
 */
20
 
21
#include "fdlibm.h"
22
 
23
#ifndef _DOUBLE_IS_32BITS  
24
 
25
/*
26
 * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
27
 */
28
#ifdef __STDC__
29
static const int32_t two_over_pi[] = {
30
#else
31
static int32_t two_over_pi[] = {
32
#endif
33
0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
34
0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
35
0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
36
0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
37
0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
38
0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
39
0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
40
0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
41
0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
42
0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
43
0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
44
};
45
 
46
#ifdef __STDC__
47
static const int32_t npio2_hw[] = {
48
#else
49
static int32_t npio2_hw[] = {
50
#endif
51
0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
52
0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
53
0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
54
0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
55
0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
56
0x404858EB, 0x404921FB,
57
};
58
 
59
/*
60
 * invpio2:  53 bits of 2/pi
61
 * pio2_1:   first  33 bit of pi/2
62
 * pio2_1t:  pi/2 - pio2_1
63
 * pio2_2:   second 33 bit of pi/2
64
 * pio2_2t:  pi/2 - (pio2_1+pio2_2)
65
 * pio2_3:   third  33 bit of pi/2
66
 * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
67
 */
68
 
69
#ifdef __STDC__
70
static const double
71
#else
72
static double
73
#endif
74
zero =  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
75
half =  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
76
two24 =  1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
77
invpio2 =  6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
78
pio2_1  =  1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
79
pio2_1t =  6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
80
pio2_2  =  6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
81
pio2_2t =  2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
82
pio2_3  =  2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
83
pio2_3t =  8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
84
 
85
#ifdef __STDC__
86
        int32_t __ieee754_rem_pio2(double x, double *y)
87
#else
88
        int32_t __ieee754_rem_pio2(x,y)
89
        double x,y[];
90
#endif
91
{
92
        double z = 0.,w,t,r,fn;
93
        double tx[3];
94
        int32_t i,j,n,ix,hx;
95
        int e0,nx;
96
        uint32_t low;
97
 
98
        GET_HIGH_WORD(hx,x);            /* high word of x */
99
        ix = hx&0x7fffffff;
100
        if(ix<=0x3fe921fb)   /* |x| ~<= pi/4 , no need for reduction */
101
            {y[0] = x; y[1] = 0; return 0;}
102
        if(ix<0x4002d97c) {  /* |x| < 3pi/4, special case with n=+-1 */
103
            if(hx>0) {
104
                z = x - pio2_1;
105
                if(ix!=0x3ff921fb) {    /* 33+53 bit pi is good enough */
106
                    y[0] = z - pio2_1t;
107
                    y[1] = (z-y[0])-pio2_1t;
108
                } else {                /* near pi/2, use 33+33+53 bit pi */
109
                    z -= pio2_2;
110
                    y[0] = z - pio2_2t;
111
                    y[1] = (z-y[0])-pio2_2t;
112
                }
113
                return 1;
114
            } else {    /* negative x */
115
                z = x + pio2_1;
116
                if(ix!=0x3ff921fb) {    /* 33+53 bit pi is good enough */
117
                    y[0] = z + pio2_1t;
118
                    y[1] = (z-y[0])+pio2_1t;
119
                } else {                /* near pi/2, use 33+33+53 bit pi */
120
                    z += pio2_2;
121
                    y[0] = z + pio2_2t;
122
                    y[1] = (z-y[0])+pio2_2t;
123
                }
124
                return -1;
125
            }
126
        }
127
        if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
128
            t  = fabs(x);
129
            n  = (int32_t) (t*invpio2+half);
130
            fn = (double)n;
131
            r  = t-fn*pio2_1;
132
            w  = fn*pio2_1t;    /* 1st round good to 85 bit */
133
            if(n<32&&ix!=npio2_hw[n-1]) {
134
                y[0] = r-w;      /* quick check no cancellation */
135
            } else {
136
                uint32_t high;
137
 
138
                j  = ix>>20;
139
                y[0] = r-w;
140
                GET_HIGH_WORD(high, y[0]);
141
                i = j-((high>>20)&0x7ff);
142
                if(i>16) {  /* 2nd iteration needed, good to 118 */
143
                    t  = r;
144
                    w  = fn*pio2_2;
145
                    r  = t-w;
146
                    w  = fn*pio2_2t-((t-r)-w);
147
                    y[0] = r-w;
148
                    GET_HIGH_WORD(high,y[0]);
149
                    i = j-((high>>20)&0x7ff);
150
                    if(i>49)  { /* 3rd iteration need, 151 bits acc */
151
                        t  = r; /* will cover all possible cases */
152
                        w  = fn*pio2_3;
153
                        r  = t-w;
154
                        w  = fn*pio2_3t-((t-r)-w);
155
                        y[0] = r-w;
156
                    }
157
                }
158
            }
159
            y[1] = (r-y[0])-w;
160
            if(hx<0)     {y[0] = -y[0]; y[1] = -y[1]; return -n;}
161
            else         return n;
162
        }
163
    /*
164
     * all other (large) arguments
165
     */
166
        if(ix>=0x7ff00000) {            /* x is inf or NaN */
167
            y[0]=y[1]=x-x; return 0;
168
        }
169
    /* set z = scalbn(|x|,ilogb(x)-23) */
170
        GET_LOW_WORD(low,x);
171
        SET_LOW_WORD(z,low);
172
        e0      = (int32_t)(ix>>20)-1046;       /* e0 = ilogb(z)-23; */
173
        SET_HIGH_WORD(z,ix - (e0<<20));
174
        for(i=0;i<2;i++) {
175
                tx[i] = (double)((int32_t)(z));
176
                z     = (z-tx[i])*two24;
177
        }
178
        tx[2] = z;
179
        nx = 3;
180
        while(tx[nx-1]==zero) nx--;     /* skip zero term */
181
        n  =  __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
182
        if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
183
        return n;
184
}
185
#endif /* defined(_DOUBLE_IS_32BITS) */

powered by: WebSVN 2.1.0

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