source: mainline/uspace/softfloat/generic/add.c@ df4ed85

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since df4ed85 was df4ed85, checked in by Jakub Jermar <jakub@…>, 18 years ago

© versus ©

  • Property mode set to 100644
File size: 5.8 KB
Line 
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 */
41float32 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 */
149float64 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 */
Note: See TracBrowser for help on using the repository browser.