source: mainline/uspace/lib/softfloat/generic/add.c@ 9a6034a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9a6034a was 750636a, checked in by Martin Decky <martin@…>, 14 years ago

softfloat: slightly improve coding style (no change in functionality)

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