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_fmod.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//===========================================================================
2
//
3
//      e_fmod.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_fmod.c 1.3 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_fmod(x,y)
77
 * Return x mod y in exact arithmetic
78
 * Method: shift and subtract
79
 */
80
 
81
#include "mathincl/fdlibm.h"
82
 
83
static const double one = 1.0, Zero[] = {0.0, -0.0,};
84
 
85
        double __ieee754_fmod(double x, double y)
86
{
87
        int n,hx,hy,hz,ix,iy,sx,i;
88
        unsigned lx,ly,lz;
89
 
90
        hx = CYG_LIBM_HI(x);            /* high word of x */
91
        lx = CYG_LIBM_LO(x);            /* low  word of x */
92
        hy = CYG_LIBM_HI(y);            /* high word of y */
93
        ly = CYG_LIBM_LO(y);            /* low  word of y */
94
        sx = hx&0x80000000;             /* sign of x */
95
        hx ^=sx;                /* |x| */
96
        hy &= 0x7fffffff;       /* |y| */
97
 
98
    /* purge off exception values */
99
        if((hy|ly)==0||(hx>=0x7ff00000)||       /* y=0,or x not finite */
100
          ((hy|((ly|-ly)>>31))>0x7ff00000))     /* or y is NaN */
101
            return (x*y)/(x*y);
102
        if(hx<=hy) {
103
            if((hx<hy)||(lx<ly)) return x;      /* |x|<|y| return x */
104
            if(lx==ly)
105
                return Zero[(unsigned)sx>>31];  /* |x|=|y| return x*0*/
106
        }
107
 
108
    /* determine ix = ilogb(x) */
109
        if(hx<0x00100000) {     /* subnormal x */
110
            if(hx==0) {
111
                for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
112
            } else {
113
                for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
114
            }
115
        } else ix = (hx>>20)-1023;
116
 
117
    /* determine iy = ilogb(y) */
118
        if(hy<0x00100000) {     /* subnormal y */
119
            if(hy==0) {
120
                for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
121
            } else {
122
                for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
123
            }
124
        } else iy = (hy>>20)-1023;
125
 
126
    /* set up {hx,lx}, {hy,ly} and align y to x */
127
        if(ix >= -1022)
128
            hx = 0x00100000|(0x000fffff&hx);
129
        else {          /* subnormal x, shift x to normal */
130
            n = -1022-ix;
131
            if(n<=31) {
132
                hx = (hx<<n)|(lx>>(32-n));
133
                lx <<= n;
134
            } else {
135
                hx = lx<<(n-32);
136
                lx = 0;
137
            }
138
        }
139
        if(iy >= -1022)
140
            hy = 0x00100000|(0x000fffff&hy);
141
        else {          /* subnormal y, shift y to normal */
142
            n = -1022-iy;
143
            if(n<=31) {
144
                hy = (hy<<n)|(ly>>(32-n));
145
                ly <<= n;
146
            } else {
147
                hy = ly<<(n-32);
148
                ly = 0;
149
            }
150
        }
151
 
152
    /* fix point fmod */
153
        n = ix - iy;
154
        while(n--) {
155
            hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
156
            if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
157
            else {
158
                if((hz|lz)==0)          /* return sign(x)*0 */
159
                    return Zero[(unsigned)sx>>31];
160
                hx = hz+hz+(lz>>31); lx = lz+lz;
161
            }
162
        }
163
        hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
164
        if(hz>=0) {hx=hz;lx=lz;}
165
 
166
    /* convert back to floating value and restore the sign */
167
        if((hx|lx)==0)                  /* return sign(x)*0 */
168
            return Zero[(unsigned)sx>>31];
169
        while(hx<0x00100000) {          /* normalize x */
170
            hx = hx+hx+(lx>>31); lx = lx+lx;
171
            iy -= 1;
172
        }
173
        if(iy>= -1022) {        /* normalize output */
174
            hx = ((hx-0x00100000)|((iy+1023)<<20));
175
            CYG_LIBM_HI(x) = hx|sx;
176
            CYG_LIBM_LO(x) = lx;
177
        } else {                /* subnormal output */
178
            n = -1022 - iy;
179
            if(n<=20) {
180
                lx = (lx>>n)|((unsigned)hx<<(32-n));
181
                hx >>= n;
182
            } else if (n<=31) {
183
                lx = (hx<<(32-n))|(lx>>n); hx = sx;
184
            } else {
185
                lx = hx>>(n-32); hx = sx;
186
            }
187
            CYG_LIBM_HI(x) = hx|sx;
188
            CYG_LIBM_LO(x) = lx;
189
            x *= one;           /* create necessary signal */
190
        }
191
        return x;               /* exact output */
192
}
193
 
194
#endif // ifdef CYGPKG_LIBM     
195
 
196
// EOF e_fmod.c

powered by: WebSVN 2.1.0

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