source: mainline/softfloat/generic/add.c@ ce5bcb4

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ce5bcb4 was aa59fa0, checked in by Josef Cejka <malyzelenyhnus@…>, 19 years ago

SoftFloat integrated into HelenOS uspace.

  • Property mode set to 100644
File size: 5.8 KB
RevLine 
[12c6f2d]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#include<sftypes.h>
30#include<add.h>
31#include<comparison.h>
32
33/** Add two Float32 numbers with same signs
34 */
35float32 addFloat32(float32 a, float32 b)
36{
37 int expdiff;
[aa59fa0]38 uint32_t exp1, exp2,frac1, frac2;
[12c6f2d]39
[4a5abddd]40 expdiff = a.parts.exp - b.parts.exp;
41 if (expdiff < 0) {
[12c6f2d]42 if (isFloat32NaN(b)) {
[1266543]43 /* TODO: fix SigNaN */
[12c6f2d]44 if (isFloat32SigNaN(b)) {
45 };
46
47 return b;
48 };
49
[4a5abddd]50 if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
[12c6f2d]51 return b;
52 }
53
[1266543]54 frac1 = b.parts.fraction;
[4a5abddd]55 exp1 = b.parts.exp;
[1266543]56 frac2 = a.parts.fraction;
[4a5abddd]57 exp2 = a.parts.exp;
58 expdiff *= -1;
[12c6f2d]59 } else {
[1266543]60 if ((isFloat32NaN(a)) || (isFloat32NaN(b))) {
61 /* TODO: fix SigNaN */
[4a5abddd]62 if (isFloat32SigNaN(a) || isFloat32SigNaN(b)) {
[12c6f2d]63 };
[1266543]64 return (isFloat32NaN(a)?a:b);
[12c6f2d]65 };
66
[4a5abddd]67 if (a.parts.exp == FLOAT32_MAX_EXPONENT) {
[12c6f2d]68 return a;
69 }
70
[1266543]71 frac1 = a.parts.fraction;
[4a5abddd]72 exp1 = a.parts.exp;
[1266543]73 frac2 = b.parts.fraction;
[4a5abddd]74 exp2 = b.parts.exp;
[12c6f2d]75 };
76
77 if (exp1 == 0) {
78 /* both are denormalized */
[1266543]79 frac1 += frac2;
80 if (frac1 & FLOAT32_HIDDEN_BIT_MASK ) {
[12c6f2d]81 /* result is not denormalized */
82 a.parts.exp = 1;
83 };
[1266543]84 a.parts.fraction = frac1;
[12c6f2d]85 return a;
86 };
87
[1266543]88 frac1 |= FLOAT32_HIDDEN_BIT_MASK; /* add hidden bit */
[12c6f2d]89
90 if (exp2 == 0) {
91 /* second operand is denormalized */
[e6a40ac]92 --expdiff;
[12c6f2d]93 } else {
94 /* add hidden bit to second operand */
[1266543]95 frac2 |= FLOAT32_HIDDEN_BIT_MASK;
[12c6f2d]96 };
97
98 /* create some space for rounding */
[1266543]99 frac1 <<= 6;
100 frac2 <<= 6;
[12c6f2d]101
[1266543]102 if (expdiff < (FLOAT32_FRACTION_SIZE + 2) ) {
103 frac2 >>= expdiff;
104 frac1 += frac2;
[d3ca210]105 } else {
106 a.parts.exp = exp1;
107 a.parts.fraction = (frac1 >> 6) & (~(FLOAT32_HIDDEN_BIT_MASK));
108 return a;
109 }
[12c6f2d]110
[1266543]111 if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7) ) {
[12c6f2d]112 ++exp1;
[1266543]113 frac1 >>= 1;
[12c6f2d]114 };
115
[1266543]116 /* rounding - if first bit after fraction is set then round up */
117 frac1 += (0x1 << 5);
[12c6f2d]118
[1266543]119 if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
120 /* rounding overflow */
[12c6f2d]121 ++exp1;
[1266543]122 frac1 >>= 1;
[12c6f2d]123 };
124
[e6a40ac]125
126 if ((exp1 == FLOAT32_MAX_EXPONENT ) || (exp2 > exp1)) {
[1266543]127 /* overflow - set infinity as result */
128 a.parts.exp = FLOAT32_MAX_EXPONENT;
129 a.parts.fraction = 0;
130 return a;
131 }
132
[12c6f2d]133 a.parts.exp = exp1;
134
135 /*Clear hidden bit and shift */
[1266543]136 a.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)) ;
[12c6f2d]137 return a;
138}
139
140
141/** Add two Float64 numbers with same signs
142 */
143float64 addFloat64(float64 a, float64 b)
144{
145 int expdiff;
[aa59fa0]146 uint32_t exp1, exp2;
147 uint64_t frac1, frac2;
[12c6f2d]148
[d3ca210]149 expdiff = ((int )a.parts.exp) - b.parts.exp;
[4a5abddd]150 if (expdiff < 0) {
[12c6f2d]151 if (isFloat64NaN(b)) {
[1266543]152 /* TODO: fix SigNaN */
[12c6f2d]153 if (isFloat64SigNaN(b)) {
154 };
155
156 return b;
157 };
158
159 /* b is infinity and a not */
[4a5abddd]160 if (b.parts.exp == FLOAT64_MAX_EXPONENT ) {
[12c6f2d]161 return b;
162 }
163
[1266543]164 frac1 = b.parts.fraction;
[4a5abddd]165 exp1 = b.parts.exp;
[1266543]166 frac2 = a.parts.fraction;
[4a5abddd]167 exp2 = a.parts.exp;
168 expdiff *= -1;
[12c6f2d]169 } else {
170 if (isFloat64NaN(a)) {
[1266543]171 /* TODO: fix SigNaN */
[4a5abddd]172 if (isFloat64SigNaN(a) || isFloat64SigNaN(b)) {
[12c6f2d]173 };
174 return a;
175 };
176
177 /* a is infinity and b not */
[4a5abddd]178 if (a.parts.exp == FLOAT64_MAX_EXPONENT ) {
[12c6f2d]179 return a;
180 }
181
[1266543]182 frac1 = a.parts.fraction;
[12c6f2d]183 exp1 = a.parts.exp;
[1266543]184 frac2 = b.parts.fraction;
[12c6f2d]185 exp2 = b.parts.exp;
186 };
187
188 if (exp1 == 0) {
189 /* both are denormalized */
[1266543]190 frac1 += frac2;
191 if (frac1 & FLOAT64_HIDDEN_BIT_MASK) {
[12c6f2d]192 /* result is not denormalized */
193 a.parts.exp = 1;
194 };
[1266543]195 a.parts.fraction = frac1;
[12c6f2d]196 return a;
197 };
198
[1266543]199 /* add hidden bit - frac1 is sure not denormalized */
200 frac1 |= FLOAT64_HIDDEN_BIT_MASK;
[12c6f2d]201
202 /* second operand ... */
203 if (exp2 == 0) {
204 /* ... is denormalized */
205 --expdiff;
206 } else {
207 /* is not denormalized */
[1266543]208 frac2 |= FLOAT64_HIDDEN_BIT_MASK;
[12c6f2d]209 };
210
211 /* create some space for rounding */
[1266543]212 frac1 <<= 6;
213 frac2 <<= 6;
[12c6f2d]214
[1266543]215 if (expdiff < (FLOAT64_FRACTION_SIZE + 2) ) {
216 frac2 >>= expdiff;
217 frac1 += frac2;
[d3ca210]218 } else {
219 a.parts.exp = exp1;
220 a.parts.fraction = (frac1 >> 6) & (~(FLOAT64_HIDDEN_BIT_MASK));
221 return a;
222 }
[12c6f2d]223
[1266543]224 if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7) ) {
[12c6f2d]225 ++exp1;
[1266543]226 frac1 >>= 1;
[12c6f2d]227 };
228
[1266543]229 /* rounding - if first bit after fraction is set then round up */
230 frac1 += (0x1 << 5);
[12c6f2d]231
[1266543]232 if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
233 /* rounding overflow */
[12c6f2d]234 ++exp1;
[1266543]235 frac1 >>= 1;
[12c6f2d]236 };
237
[d3ca210]238 if ((exp1 == FLOAT64_MAX_EXPONENT ) || (exp2 > exp1)) {
[1266543]239 /* overflow - set infinity as result */
240 a.parts.exp = FLOAT64_MAX_EXPONENT;
241 a.parts.fraction = 0;
242 return a;
243 }
244
[12c6f2d]245 a.parts.exp = exp1;
246 /*Clear hidden bit and shift */
[1266543]247 a.parts.fraction = ( (frac1 >> 6 ) & (~FLOAT64_HIDDEN_BIT_MASK));
[d3ca210]248
[12c6f2d]249 return a;
250}
251
252
Note: See TracBrowser for help on using the repository browser.