Subversion Repositories HelenOS-historic

Rev

Rev 563 | Rev 652 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
535 cejka 1
 
2
/*
3
 * Copyright (C) 2005 Josef Cejka
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * - Redistributions of source code must retain the above copyright
11
 *   notice, this list of conditions and the following disclaimer.
12
 * - Redistributions in binary form must reproduce the above copyright
13
 *   notice, this list of conditions and the following disclaimer in the
14
 *   documentation and/or other materials provided with the distribution.
15
 * - The name of the author may not be used to endorse or promote products
16
 *   derived from this software without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 */
29
 
30
#include<softfloat.h>
31
 
563 cejka 32
float32 addFloat32(float32 a, float32 b);
33
float32 subFloat32(float32 a, float32 b);
34
inline int isFloat32NaN(float32 f);
35
inline int isFloat32SigNaN(float32 f);
542 cejka 36
 
37
float __addsf3(float a, float b)
38
{
39
    float32 fa, fb;
563 cejka 40
    fa.f=a;
41
    fb.f=b;
42
    if (fa.parts.sign!=fb.parts.sign) return subFloat32(fa,fb).f;
43
    return addFloat32(fa,fb).f;
542 cejka 44
};
45
 
46
float __subsf3(float a, float b)
47
{
48
    float32 fa, fb;
563 cejka 49
    fa.f=a;
50
    fb.f=b;
51
    if (fa.parts.sign!=fb.parts.sign) return addFloat32(fa,fb).f;
52
    return subFloat32(fa,fb).f;
542 cejka 53
};
54
 
55
float __negsf2(float a)
56
{
57
    float32 fa;
58
    fa.f=a;
59
    fa.parts.sign=!fa.parts.sign;
60
    return fa.f;
61
};
62
 
63
double __negdf2(double a)
64
{
65
    float64 fa;
563 cejka 66
    fa.d=a;
542 cejka 67
    fa.parts.sign=!fa.parts.sign;
563 cejka 68
    return fa.d;
542 cejka 69
};
70
 
563 cejka 71
/** Add two Float32 numbers with same signs
72
 */
542 cejka 73
float32 addFloat32(float32 a, float32 b)
74
{
563 cejka 75
    int expdiff;
542 cejka 76
    __u32 exp1,exp2,mant1,mant2;
77
 
78
    expdiff=a.parts.exp - b.parts.exp;
79
    if (expdiff<0) {
563 cejka 80
        if (isFloat32NaN(b)) {
81
            //TODO: fix SigNaN
82
            if (isFloat32SigNaN(b)) {
83
            };
84
            return b;
542 cejka 85
        };
563 cejka 86
 
87
        if (b.parts.exp==0xFF) {
88
            return b;
89
        }
90
 
542 cejka 91
        mant1=b.parts.mantisa;
92
        exp1=b.parts.exp;
93
        mant2=a.parts.mantisa;
94
        exp2=a.parts.exp;
95
        expdiff*=-1;
96
    } else {
563 cejka 97
        if (isFloat32NaN(a)) {
98
            //TODO: fix SigNaN
99
            if ((isFloat32SigNaN(a))||(isFloat32SigNaN(b))) {
100
            };
101
            return a;
542 cejka 102
        };
563 cejka 103
 
104
        if (a.parts.exp==0xFF) {
105
            return a;
106
        }
107
 
542 cejka 108
        mant1=a.parts.mantisa;
109
        exp1=a.parts.exp;
110
        mant2=b.parts.mantisa;
111
        exp2=b.parts.exp;
112
    };
563 cejka 113
 
114
    if (exp1==0) {
115
        //both are denormalized
116
        mant1+=mant2;
117
        if (mant1&0xF00000) {
118
            a.parts.exp=1;
119
        };
120
        a.parts.mantisa=mant1;
121
        return a;
122
    };
123
 
542 cejka 124
    // create some space for rounding
125
    mant1<<=6;
126
    mant2<<=6;
127
 
563 cejka 128
    mant1|=0x20000000; //add hidden bit
542 cejka 129
 
563 cejka 130
 
542 cejka 131
    if (exp2==0) {
132
        --expdiff; 
133
    } else {
134
        mant2|=0x20000000; //hidden bit
135
    };
136
 
572 cejka 137
    if (expdiff>24) {
138
         goto done;
139
         };
140
 
542 cejka 141
    mant2>>=expdiff;
142
    mant1+=mant2;
143
done:
563 cejka 144
    if (mant1&0x40000000) {
145
        ++exp1;
146
        mant1>>=1;
147
    };
148
 
149
    //rounding - if first bit after mantisa is set then round up
150
    mant1+=0x20;
151
 
542 cejka 152
    a.parts.exp=exp1;
153
    a.parts.mantisa=mant1>>6;
154
    return a;
155
};
156
 
563 cejka 157
/** Substract two float32 numbers with same signs
158
 */
542 cejka 159
float32 subFloat32(float32 a, float32 b)
160
{
161
 
162
 
163
};
164
 
165
inline int isFloat32NaN(float32 f)
166
{   /* NaN : exp = 0xff and nonzero mantisa */
563 cejka 167
    return ((f.parts.exp==0xFF)&&(f.parts.mantisa));
542 cejka 168
};
169
 
170
inline int isFloat32SigNaN(float32 f)
171
{   /* SigNaN : exp = 0xff mantisa = 1xxxxx..x (binary), where at least one x is nonzero */
563 cejka 172
    return ((f.parts.exp==0xFF)&&(f.parts.mantisa>0x400000));
542 cejka 173
};
174