Changeset c67aff2 in mainline for uspace/lib/softfloat/generic/sub.c
- Timestamp:
- 2011-08-06T07:04:50Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d3e241a, e0e922d
- Parents:
- 9a6034a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/softfloat/generic/sub.c
r9a6034a rc67aff2 1 1 /* 2 2 * Copyright (c) 2005 Josef Cejka 3 * Copyright (c) 2011 Petr Koupy 3 4 * All rights reserved. 4 5 * … … 30 31 * @{ 31 32 */ 32 /** @file 33 /** @file Substraction functions. 33 34 */ 34 35 … … 36 37 #include <sub.h> 37 38 #include <comparison.h> 38 39 /** Subtract two float32 numbers with same signs 39 #include <common.h> 40 41 /** 42 * Subtract two single-precision floats with the same signs. 43 * 44 * @param a First input operand. 45 * @param b Second input operand. 46 * @return Result of substraction. 40 47 */ 41 48 float32 subFloat32(float32 a, float32 b) … … 52 59 /* TODO: fix SigNaN */ 53 60 if (isFloat32SigNaN(b)) { 54 } ;55 return b; 56 } ;61 } 62 return b; 63 } 57 64 58 65 if (b.parts.exp == FLOAT32_MAX_EXPONENT) { … … 72 79 /* TODO: fix SigNaN */ 73 80 if (isFloat32SigNaN(a) || isFloat32SigNaN(b)) { 74 } ;75 return a; 76 } ;81 } 82 return a; 83 } 77 84 78 85 if (a.parts.exp == FLOAT32_MAX_EXPONENT) { … … 82 89 result.binary = FLOAT32_NAN; 83 90 return result; 84 } ;91 } 85 92 return a; 86 93 } … … 92 99 frac2 = b.parts.fraction; 93 100 exp2 = b.parts.exp; 94 } ;101 } 95 102 96 103 if (exp1 == 0) { 97 104 /* both are denormalized */ 98 result.parts.fraction = frac1 -frac2;105 result.parts.fraction = frac1 - frac2; 99 106 if (result.parts.fraction > frac1) { 100 107 /* TODO: underflow exception */ 101 108 return result; 102 } ;109 } 103 110 result.parts.exp = 0; 104 111 return result; 105 } ;112 } 106 113 107 114 /* add hidden bit */ … … 114 121 /* normalized */ 115 122 frac2 |= FLOAT32_HIDDEN_BIT_MASK; 116 } ;123 } 117 124 118 125 /* create some space for rounding */ … … 121 128 122 129 if (expdiff > FLOAT32_FRACTION_SIZE + 1) { 123 goto done;124 };130 goto done; 131 } 125 132 126 133 frac1 = frac1 - (frac2 >> expdiff); 134 127 135 done: 128 136 /* TODO: find first nonzero digit and shift result and detect possibly underflow */ … … 130 138 --exp1; 131 139 frac1 <<= 1; 132 133 } ;140 /* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */ 141 } 134 142 135 143 /* rounding - if first bit after fraction is set then round up */ … … 139 147 ++exp1; 140 148 frac1 >>= 1; 141 } ;142 143 /* Clear hidden bit and shift */149 } 150 151 /* Clear hidden bit and shift */ 144 152 result.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)); 145 153 result.parts.exp = exp1; … … 148 156 } 149 157 150 /** Subtract two float64 numbers with same signs 158 /** 159 * Subtract two double-precision floats with the same signs. 160 * 161 * @param a First input operand. 162 * @param b Second input operand. 163 * @return Result of substraction. 151 164 */ 152 165 float64 subFloat64(float64 a, float64 b) … … 164 177 /* TODO: fix SigNaN */ 165 178 if (isFloat64SigNaN(b)) { 166 } ;167 return b; 168 } ;179 } 180 return b; 181 } 169 182 170 183 if (b.parts.exp == FLOAT64_MAX_EXPONENT) { … … 184 197 /* TODO: fix SigNaN */ 185 198 if (isFloat64SigNaN(a) || isFloat64SigNaN(b)) { 186 } ;187 return a; 188 } ;199 } 200 return a; 201 } 189 202 190 203 if (a.parts.exp == FLOAT64_MAX_EXPONENT) { … … 194 207 result.binary = FLOAT64_NAN; 195 208 return result; 196 } ;209 } 197 210 return a; 198 211 } … … 204 217 frac2 = b.parts.fraction; 205 218 exp2 = b.parts.exp; 206 } ;219 } 207 220 208 221 if (exp1 == 0) { … … 212 225 /* TODO: underflow exception */ 213 226 return result; 214 } ;227 } 215 228 result.parts.exp = 0; 216 229 return result; 217 } ;230 } 218 231 219 232 /* add hidden bit */ … … 226 239 /* normalized */ 227 240 frac2 |= FLOAT64_HIDDEN_BIT_MASK; 228 } ;241 } 229 242 230 243 /* create some space for rounding */ … … 233 246 234 247 if (expdiff > FLOAT64_FRACTION_SIZE + 1) { 235 goto done;236 };248 goto done; 249 } 237 250 238 251 frac1 = frac1 - (frac2 >> expdiff); 252 239 253 done: 240 254 /* TODO: find first nonzero digit and shift result and detect possibly underflow */ … … 242 256 --exp1; 243 257 frac1 <<= 1; 244 245 } ;258 /* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */ 259 } 246 260 247 261 /* rounding - if first bit after fraction is set then round up */ … … 251 265 ++exp1; 252 266 frac1 >>= 1; 253 } ;254 255 /* Clear hidden bit and shift */267 } 268 269 /* Clear hidden bit and shift */ 256 270 result.parts.fraction = ((frac1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK)); 257 271 result.parts.exp = exp1; … … 260 274 } 261 275 276 /** 277 * Subtract two quadruple-precision floats with the same signs. 278 * 279 * @param a First input operand. 280 * @param b Second input operand. 281 * @return Result of substraction. 282 */ 283 float128 subFloat128(float128 a, float128 b) 284 { 285 int expdiff; 286 uint32_t exp1, exp2; 287 uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo; 288 float128 result; 289 290 result.binary.hi = 0; 291 result.binary.lo = 0; 292 293 expdiff = a.parts.exp - b.parts.exp; 294 if ((expdiff < 0 ) || ((expdiff == 0) && 295 lt128(a.parts.frac_hi, a.parts.frac_lo, b.parts.frac_hi, b.parts.frac_lo))) { 296 if (isFloat128NaN(b)) { 297 /* TODO: fix SigNaN */ 298 if (isFloat128SigNaN(b)) { 299 } 300 return b; 301 } 302 303 if (b.parts.exp == FLOAT128_MAX_EXPONENT) { 304 b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */ 305 return b; 306 } 307 308 result.parts.sign = !a.parts.sign; 309 310 frac1_hi = b.parts.frac_hi; 311 frac1_lo = b.parts.frac_lo; 312 exp1 = b.parts.exp; 313 frac2_hi = a.parts.frac_hi; 314 frac2_lo = a.parts.frac_lo; 315 exp2 = a.parts.exp; 316 expdiff *= -1; 317 } else { 318 if (isFloat128NaN(a)) { 319 /* TODO: fix SigNaN */ 320 if (isFloat128SigNaN(a) || isFloat128SigNaN(b)) { 321 } 322 return a; 323 } 324 325 if (a.parts.exp == FLOAT128_MAX_EXPONENT) { 326 if (b.parts.exp == FLOAT128_MAX_EXPONENT) { 327 /* inf - inf => nan */ 328 /* TODO: fix exception */ 329 result.binary.hi = FLOAT128_NAN_HI; 330 result.binary.lo = FLOAT128_NAN_LO; 331 return result; 332 } 333 return a; 334 } 335 336 result.parts.sign = a.parts.sign; 337 338 frac1_hi = a.parts.frac_hi; 339 frac1_lo = a.parts.frac_lo; 340 exp1 = a.parts.exp; 341 frac2_hi = b.parts.frac_hi; 342 frac2_lo = b.parts.frac_lo; 343 exp2 = b.parts.exp; 344 } 345 346 if (exp1 == 0) { 347 /* both are denormalized */ 348 sub128(frac1_hi, frac1_lo, frac2_hi, frac2_lo, &tmp_hi, &tmp_lo); 349 result.parts.frac_hi = tmp_hi; 350 result.parts.frac_lo = tmp_lo; 351 if (lt128(frac1_hi, frac1_lo, result.parts.frac_hi, result.parts.frac_lo)) { 352 /* TODO: underflow exception */ 353 return result; 354 } 355 result.parts.exp = 0; 356 return result; 357 } 358 359 /* add hidden bit */ 360 or128(frac1_hi, frac1_lo, 361 FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 362 &frac1_hi, &frac1_lo); 363 364 if (exp2 == 0) { 365 /* denormalized */ 366 --expdiff; 367 } else { 368 /* normalized */ 369 or128(frac2_hi, frac2_lo, 370 FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 371 &frac2_hi, &frac2_lo); 372 } 373 374 /* create some space for rounding */ 375 lshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo); 376 lshift128(frac2_hi, frac2_lo, 6, &frac2_hi, &frac2_lo); 377 378 if (expdiff > FLOAT128_FRACTION_SIZE + 1) { 379 goto done; 380 } 381 382 rshift128(frac2_hi, frac2_lo, expdiff, &tmp_hi, &tmp_lo); 383 sub128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &frac1_hi, &frac1_lo); 384 385 done: 386 /* TODO: find first nonzero digit and shift result and detect possibly underflow */ 387 lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 6, 388 &tmp_hi, &tmp_lo); 389 and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo); 390 while ((exp1 > 0) && (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo))) { 391 --exp1; 392 lshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo); 393 /* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */ 394 395 lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 6, 396 &tmp_hi, &tmp_lo); 397 and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo); 398 } 399 400 /* rounding - if first bit after fraction is set then round up */ 401 add128(frac1_hi, frac1_lo, 0x0ll, 0x20ll, &frac1_hi, &frac1_lo); 402 403 lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7, 404 &tmp_hi, &tmp_lo); 405 and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo); 406 if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) { 407 ++exp1; 408 rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo); 409 } 410 411 /* Clear hidden bit and shift */ 412 rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo); 413 not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 414 &tmp_hi, &tmp_lo); 415 and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo); 416 result.parts.frac_hi = tmp_hi; 417 result.parts.frac_lo = tmp_lo; 418 419 result.parts.exp = exp1; 420 421 return result; 422 } 423 262 424 /** @} 263 425 */
Note:
See TracChangeset
for help on using the changeset viewer.