~vojtech-horky/helenos/numa

« back to all changes in this revision

Viewing changes to uspace/lib/softfloat/generic/add.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2005 Josef Cejka
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *
 
9
 * - Redistributions of source code must retain the above copyright
 
10
 *   notice, this list of conditions and the following disclaimer.
 
11
 * - Redistributions in binary form must reproduce the above copyright
 
12
 *   notice, this list of conditions and the following disclaimer in the
 
13
 *   documentation and/or other materials provided with the distribution.
 
14
 * - The name of the author may not be used to endorse or promote products
 
15
 *   derived from this software without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
/** @addtogroup softfloat       
 
30
 * @{
 
31
 */
 
32
/** @file
 
33
 */
 
34
 
 
35
#include<sftypes.h>
 
36
#include<add.h>
 
37
#include<comparison.h>
 
38
 
 
39
/** Add two Float32 numbers with same signs
 
40
 */
 
41
float32 addFloat32(float32 a, float32 b)
 
42
{
 
43
        int expdiff;
 
44
        uint32_t exp1, exp2,frac1, frac2;
 
45
        
 
46
        expdiff = a.parts.exp - b.parts.exp;
 
47
        if (expdiff < 0) {
 
48
                if (isFloat32NaN(b)) {
 
49
                        /* TODO: fix SigNaN */
 
50
                        if (isFloat32SigNaN(b)) {
 
51
                        };
 
52
 
 
53
                        return b;
 
54
                };
 
55
                
 
56
                if (b.parts.exp == FLOAT32_MAX_EXPONENT) { 
 
57
                        return b;
 
58
                }
 
59
                
 
60
                frac1 = b.parts.fraction;
 
61
                exp1 = b.parts.exp;
 
62
                frac2 = a.parts.fraction;
 
63
                exp2 = a.parts.exp;
 
64
                expdiff *= -1;
 
65
        } else {
 
66
                if ((isFloat32NaN(a)) || (isFloat32NaN(b))) {
 
67
                        /* TODO: fix SigNaN */
 
68
                        if (isFloat32SigNaN(a) || isFloat32SigNaN(b)) {
 
69
                        };
 
70
                        return (isFloat32NaN(a)?a:b);
 
71
                };
 
72
                
 
73
                if (a.parts.exp == FLOAT32_MAX_EXPONENT) { 
 
74
                        return a;
 
75
                }
 
76
                
 
77
                frac1 = a.parts.fraction;
 
78
                exp1 = a.parts.exp;
 
79
                frac2 = b.parts.fraction;
 
80
                exp2 = b.parts.exp;
 
81
        };
 
82
        
 
83
        if (exp1 == 0) {
 
84
                /* both are denormalized */
 
85
                frac1 += frac2;
 
86
                if (frac1 & FLOAT32_HIDDEN_BIT_MASK ) {
 
87
                        /* result is not denormalized */
 
88
                        a.parts.exp = 1;
 
89
                };
 
90
                a.parts.fraction = frac1;
 
91
                return a;
 
92
        };
 
93
        
 
94
        frac1 |= FLOAT32_HIDDEN_BIT_MASK; /* add hidden bit */
 
95
 
 
96
        if (exp2 == 0) {
 
97
                /* second operand is denormalized */
 
98
                --expdiff;
 
99
        } else {
 
100
                /* add hidden bit to second operand */
 
101
                frac2 |= FLOAT32_HIDDEN_BIT_MASK; 
 
102
        };
 
103
        
 
104
        /* create some space for rounding */
 
105
        frac1 <<= 6;
 
106
        frac2 <<= 6;
 
107
        
 
108
        if (expdiff < (FLOAT32_FRACTION_SIZE + 2) ) {
 
109
                frac2 >>= expdiff;
 
110
                frac1 += frac2;
 
111
        } else {
 
112
                a.parts.exp = exp1;
 
113
                a.parts.fraction = (frac1 >> 6) & (~(FLOAT32_HIDDEN_BIT_MASK));
 
114
                return a;
 
115
        }
 
116
        
 
117
        if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7) ) {
 
118
                ++exp1;
 
119
                frac1 >>= 1;
 
120
        };
 
121
        
 
122
        /* rounding - if first bit after fraction is set then round up */
 
123
        frac1 += (0x1 << 5);
 
124
        
 
125
        if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) { 
 
126
                /* rounding overflow */
 
127
                ++exp1;
 
128
                frac1 >>= 1;
 
129
        };
 
130
        
 
131
        
 
132
        if ((exp1 == FLOAT32_MAX_EXPONENT ) || (exp2 > exp1)) {
 
133
                        /* overflow - set infinity as result */
 
134
                        a.parts.exp = FLOAT32_MAX_EXPONENT;
 
135
                        a.parts.fraction = 0;
 
136
                        return a;
 
137
                        }
 
138
        
 
139
        a.parts.exp = exp1;
 
140
        
 
141
        /*Clear hidden bit and shift */
 
142
        a.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)) ; 
 
143
        return a;
 
144
}
 
145
 
 
146
 
 
147
/** Add two Float64 numbers with same signs
 
148
 */
 
149
float64 addFloat64(float64 a, float64 b)
 
150
{
 
151
        int expdiff;
 
152
        uint32_t exp1, exp2;
 
153
        uint64_t frac1, frac2;
 
154
        
 
155
        expdiff = ((int )a.parts.exp) - b.parts.exp;
 
156
        if (expdiff < 0) {
 
157
                if (isFloat64NaN(b)) {
 
158
                        /* TODO: fix SigNaN */
 
159
                        if (isFloat64SigNaN(b)) {
 
160
                        };
 
161
 
 
162
                        return b;
 
163
                };
 
164
                
 
165
                /* b is infinity and a not */   
 
166
                if (b.parts.exp == FLOAT64_MAX_EXPONENT ) { 
 
167
                        return b;
 
168
                }
 
169
                
 
170
                frac1 = b.parts.fraction;
 
171
                exp1 = b.parts.exp;
 
172
                frac2 = a.parts.fraction;
 
173
                exp2 = a.parts.exp;
 
174
                expdiff *= -1;
 
175
        } else {
 
176
                if (isFloat64NaN(a)) {
 
177
                        /* TODO: fix SigNaN */
 
178
                        if (isFloat64SigNaN(a) || isFloat64SigNaN(b)) {
 
179
                        };
 
180
                        return a;
 
181
                };
 
182
                
 
183
                /* a is infinity and b not */
 
184
                if (a.parts.exp == FLOAT64_MAX_EXPONENT ) { 
 
185
                        return a;
 
186
                }
 
187
                
 
188
                frac1 = a.parts.fraction;
 
189
                exp1 = a.parts.exp;
 
190
                frac2 = b.parts.fraction;
 
191
                exp2 = b.parts.exp;
 
192
        };
 
193
        
 
194
        if (exp1 == 0) {
 
195
                /* both are denormalized */
 
196
                frac1 += frac2;
 
197
                if (frac1 & FLOAT64_HIDDEN_BIT_MASK) { 
 
198
                        /* result is not denormalized */
 
199
                        a.parts.exp = 1;
 
200
                };
 
201
                a.parts.fraction = frac1;
 
202
                return a;
 
203
        };
 
204
        
 
205
        /* add hidden bit - frac1 is sure not denormalized */
 
206
        frac1 |= FLOAT64_HIDDEN_BIT_MASK;
 
207
 
 
208
        /* second operand ... */
 
209
        if (exp2 == 0) {
 
210
                /* ... is denormalized */
 
211
                --expdiff;      
 
212
        } else {
 
213
                /* is not denormalized */
 
214
                frac2 |= FLOAT64_HIDDEN_BIT_MASK;
 
215
        };
 
216
        
 
217
        /* create some space for rounding */
 
218
        frac1 <<= 6;
 
219
        frac2 <<= 6;
 
220
        
 
221
        if (expdiff < (FLOAT64_FRACTION_SIZE + 2) ) {
 
222
                frac2 >>= expdiff;
 
223
                frac1 += frac2;
 
224
        } else {
 
225
                a.parts.exp = exp1;
 
226
                a.parts.fraction = (frac1 >> 6) & (~(FLOAT64_HIDDEN_BIT_MASK));
 
227
                return a;
 
228
        }
 
229
        
 
230
        if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7) ) {
 
231
                ++exp1;
 
232
                frac1 >>= 1;
 
233
        };
 
234
        
 
235
        /* rounding - if first bit after fraction is set then round up */
 
236
        frac1 += (0x1 << 5); 
 
237
        
 
238
        if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) { 
 
239
                /* rounding overflow */
 
240
                ++exp1;
 
241
                frac1 >>= 1;
 
242
        };
 
243
        
 
244
        if ((exp1 == FLOAT64_MAX_EXPONENT ) || (exp2 > exp1)) {
 
245
                        /* overflow - set infinity as result */
 
246
                        a.parts.exp = FLOAT64_MAX_EXPONENT;
 
247
                        a.parts.fraction = 0;
 
248
                        return a;
 
249
                        }
 
250
        
 
251
        a.parts.exp = exp1;
 
252
        /*Clear hidden bit and shift */
 
253
        a.parts.fraction = ( (frac1 >> 6 ) & (~FLOAT64_HIDDEN_BIT_MASK));
 
254
        
 
255
        return a;
 
256
}
 
257
 
 
258
/** @}
 
259
 */