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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [language/] [c/] [libm/] [v2_0/] [src/] [double/] [internal/] [k_rem_pio2.c] - Blame information for rev 228

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

Line No. Rev Author Line
1 27 unneback
//===========================================================================
2
//
3
//      k_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 Red Hat, 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 version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//===========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):   jlarmour
44
// Contributors:  jlarmour
45
// Date:        1998-02-13
46
// Purpose:     
47
// Description: 
48
// Usage:       
49
//
50
//####DESCRIPTIONEND####
51
//
52
//===========================================================================
53
 
54
// CONFIGURATION
55
 
56
#include <pkgconf/libm.h>   // Configuration header
57
 
58
// Include the Math library?
59
#ifdef CYGPKG_LIBM     
60
 
61
// Derived from code with the following copyright
62
 
63
 
64
/* @(#)k_rem_pio2.c 1.3 95/01/18 */
65
/*
66
 * ====================================================
67
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
68
 *
69
 * Developed at SunSoft, a Sun Microsystems, Inc. business.
70
 * Permission to use, copy, modify, and distribute this
71
 * software is freely granted, provided that this notice
72
 * is preserved.
73
 * ====================================================
74
 */
75
 
76
/*
77
 * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
78
 * double x[],y[]; int e0,nx,prec; int ipio2[];
79
 *
80
 * __kernel_rem_pio2 return the last three digits of N with
81
 *              y = x - N*pi/2
82
 * so that |y| < pi/2.
83
 *
84
 * The method is to compute the integer (mod 8) and fraction parts of
85
 * (2/pi)*x without doing the full multiplication. In general we
86
 * skip the part of the product that are known to be a huge integer (
87
 * more accurately, = 0 mod 8 ). Thus the number of operations are
88
 * independent of the exponent of the input.
89
 *
90
 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
91
 *
92
 * Input parameters:
93
 *      x[]     The input value (must be positive) is broken into nx
94
 *              pieces of 24-bit integers in double precision format.
95
 *              x[i] will be the i-th 24 bit of x. The scaled exponent
96
 *              of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
97
 *              match x's up to 24 bits.
98
 *
99
 *              Example of breaking a double positive z into x[0]+x[1]+x[2]:
100
 *                      e0 = ilogb(z)-23
101
 *                      z  = scalbn(z,-e0)
102
 *              for i = 0,1,2
103
 *                      x[i] = floor(z)
104
 *                      z    = (z-x[i])*2**24
105
 *
106
 *
107
 *      y[]     ouput result in an array of double precision numbers.
108
 *              The dimension of y[] is:
109
 *                      24-bit  precision       1
110
 *                      53-bit  precision       2
111
 *                      64-bit  precision       2
112
 *                      113-bit precision       3
113
 *              The actual value is the sum of them. Thus for 113-bit
114
 *              precison, one may have to do something like:
115
 *
116
 *              long double t,w,r_head, r_tail;
117
 *              t = (long double)y[2] + (long double)y[1];
118
 *              w = (long double)y[0];
119
 *              r_head = t+w;
120
 *              r_tail = w - (r_head - t);
121
 *
122
 *      e0      The exponent of x[0]
123
 *
124
 *      nx      dimension of x[]
125
 *
126
 *      prec    an integer indicating the precision:
127
 *                      0       24  bits (single)
128
 *                      1       53  bits (double)
129
 *                      2       64  bits (extended)
130
 *                      3       113 bits (quad)
131
 *
132
 *      ipio2[]
133
 *              integer array, contains the (24*i)-th to (24*i+23)-th
134
 *              bit of 2/pi after binary point. The corresponding
135
 *              floating value is
136
 *
137
 *                      ipio2[i] * 2^(-24(i+1)).
138
 *
139
 * External function:
140
 *      double scalbn(), floor();
141
 *
142
 *
143
 * Here is the description of some local variables:
144
 *
145
 *      jk      jk+1 is the initial number of terms of ipio2[] needed
146
 *              in the computation. The recommended value is 2,3,4,
147
 *              6 for single, double, extended,and quad.
148
 *
149
 *      jz      local integer variable indicating the number of
150
 *              terms of ipio2[] used.
151
 *
152
 *      jx      nx - 1
153
 *
154
 *      jv      index for pointing to the suitable ipio2[] for the
155
 *              computation. In general, we want
156
 *                      ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
157
 *              is an integer. Thus
158
 *                      e0-3-24*jv >= 0 or (e0-3)/24 >= jv
159
 *              Hence jv = max(0,(e0-3)/24).
160
 *
161
 *      jp      jp+1 is the number of terms in PIo2[] needed, jp = jk.
162
 *
163
 *      q[]     double array with integral value, representing the
164
 *              24-bits chunk of the product of x and 2/pi.
165
 *
166
 *      q0      the corresponding exponent of q[0]. Note that the
167
 *              exponent for q[i] would be q0-24*i.
168
 *
169
 *      PIo2[]  double precision array, obtained by cutting pi/2
170
 *              into 24 bits chunks.
171
 *
172
 *      f[]     ipio2[] in floating point
173
 *
174
 *      iq[]    integer array by breaking up q[] in 24-bits chunk.
175
 *
176
 *      fq[]    final product of x*(2/pi) in fq[0],..,fq[jk]
177
 *
178
 *      ih      integer. If >0 it indicates q[] is >= 0.5, hence
179
 *              it also indicates the *sign* of the result.
180
 *
181
 */
182
 
183
 
184
/*
185
 * Constants:
186
 * The hexadecimal values are the intended ones for the following
187
 * constants. The decimal values may be used, provided that the
188
 * compiler will convert from decimal to binary accurately enough
189
 * to produce the hexadecimal values shown.
190
 */
191
 
192
#include "mathincl/fdlibm.h"
193
 
194
static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
195
 
196
static const double PIo2[] = {
197
  1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
198
  7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
199
  5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
200
  3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
201
  1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
202
  1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
203
  2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
204
  2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
205
};
206
 
207
static const double
208
zero   = 0.0,
209
one    = 1.0,
210
two24   =  1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
211
twon24  =  5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
212
 
213
        int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
214
{
215
        int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
216
        double z,fw,f[20],fq[20],q[20];
217
 
218
    /* initialize jk*/
219
        jk = init_jk[prec];
220
        jp = jk;
221
 
222
    /* determine jx,jv,q0, note that 3>q0 */
223
        jx =  nx-1;
224
        jv = (e0-3)/24; if(jv<0) jv=0;
225
        q0 =  e0-24*(jv+1);
226
 
227
    /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
228
        j = jv-jx; m = jx+jk;
229
        for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
230
 
231
    /* compute q[0],q[1],...q[jk] */
232
        for (i=0;i<=jk;i++) {
233
            for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
234
        }
235
 
236
        jz = jk;
237
recompute:
238
    /* distill q[] into iq[] reversingly */
239
        for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
240
            fw    =  (double)((int)(twon24* z));
241
            iq[i] =  (int)(z-two24*fw);
242
            z     =  q[j-1]+fw;
243
        }
244
 
245
    /* compute n */
246
        z  = scalbn(z,q0);              /* actual value of z */
247
        z -= 8.0*floor(z*0.125);                /* trim off integer >= 8 */
248
        n  = (int) z;
249
        z -= (double)n;
250
        ih = 0;
251
        if(q0>0) {      /* need iq[jz-1] to determine n */
252
            i  = (iq[jz-1]>>(24-q0)); n += i;
253
            iq[jz-1] -= i<<(24-q0);
254
            ih = iq[jz-1]>>(23-q0);
255
        }
256
        else if(q0==0) ih = iq[jz-1]>>23;
257
        else if(z>=0.5) ih=2;
258
 
259
        if(ih>0) {      /* q > 0.5 */
260
            n += 1; carry = 0;
261
            for(i=0;i<jz ;i++) {        /* compute 1-q */
262
                j = iq[i];
263
                if(carry==0) {
264
                    if(j!=0) {
265
                        carry = 1; iq[i] = 0x1000000- j;
266
                    }
267
                } else  iq[i] = 0xffffff - j;
268
            }
269
            if(q0>0) {          /* rare case: chance is 1 in 12 */
270
                switch(q0) {
271
                case 1:
272
                   iq[jz-1] &= 0x7fffff; break;
273
                case 2:
274
                   iq[jz-1] &= 0x3fffff; break;
275
                }
276
            }
277
            if(ih==2) {
278
                z = one - z;
279
                if(carry!=0) z -= scalbn(one,q0);
280
            }
281
        }
282
 
283
    /* check if recomputation is needed */
284
        if(z==zero) {
285
            j = 0;
286
            for (i=jz-1;i>=jk;i--) j |= iq[i];
287
            if(j==0) { /* need recomputation */
288
                for(k=1;iq[jk-k]==0;k++);   /* k = no. of terms needed */
289
 
290
                for(i=jz+1;i<=jz+k;i++) {   /* add q[jz+1] to q[jz+k] */
291
                    f[jx+i] = (double) ipio2[jv+i];
292
                    for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
293
                    q[i] = fw;
294
                }
295
                jz += k;
296
                goto recompute;
297
            }
298
        }
299
 
300
    /* chop off zero terms */
301
        if(z==0.0) {
302
            jz -= 1; q0 -= 24;
303
            while(iq[jz]==0) { jz--; q0-=24;}
304
        } else { /* break z into 24-bit if necessary */
305
            z = scalbn(z,-q0);
306
            if(z>=two24) {
307
                fw = (double)((int)(twon24*z));
308
                iq[jz] = (int)(z-two24*fw);
309
                jz += 1; q0 += 24;
310
                iq[jz] = (int) fw;
311
            } else iq[jz] = (int) z ;
312
        }
313
 
314
    /* convert integer "bit" chunk to floating-point value */
315
        fw = scalbn(one,q0);
316
        for(i=jz;i>=0;i--) {
317
            q[i] = fw*(double)iq[i]; fw*=twon24;
318
        }
319
 
320
    /* compute PIo2[0,...,jp]*q[jz,...,0] */
321
        for(i=jz;i>=0;i--) {
322
            for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
323
            fq[jz-i] = fw;
324
        }
325
 
326
    /* compress fq[] into y[] */
327
        switch(prec) {
328
            case 0:
329
                fw = 0.0;
330
                for (i=jz;i>=0;i--) fw += fq[i];
331
                y[0] = (ih==0)? fw: -fw;
332
                break;
333
            case 1:
334
            case 2:
335
                fw = 0.0;
336
                for (i=jz;i>=0;i--) fw += fq[i];
337
                y[0] = (ih==0)? fw: -fw;
338
                fw = fq[0]-fw;
339
                for (i=1;i<=jz;i++) fw += fq[i];
340
                y[1] = (ih==0)? fw: -fw;
341
                break;
342
            case 3:     /* painful */
343
                for (i=jz;i>0;i--) {
344
                    fw      = fq[i-1]+fq[i];
345
                    fq[i]  += fq[i-1]-fw;
346
                    fq[i-1] = fw;
347
                }
348
                for (i=jz;i>1;i--) {
349
                    fw      = fq[i-1]+fq[i];
350
                    fq[i]  += fq[i-1]-fw;
351
                    fq[i-1] = fw;
352
                }
353
                for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
354
                if(ih==0) {
355
                    y[0] =  fq[0]; y[1] =  fq[1]; y[2] =  fw;
356
                } else {
357
                    y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
358
                }
359
        }
360
        return n&7;
361
}
362
 
363
#endif // ifdef CYGPKG_LIBM     
364
 
365
// EOF k_rem_pio2.c

powered by: WebSVN 2.1.0

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