Changes in uspace/lib/softfloat/generic/sub.c [88d5c1e:9d58539] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/softfloat/generic/sub.c
r88d5c1e r9d58539 39 39 #include <common.h> 40 40 41 /** Subtract two single-precision floats with the same sign. 41 /** 42 * Subtract two single-precision floats with the same signs. 42 43 * 43 44 * @param a First input operand. 44 45 * @param b Second input operand. 45 *46 46 * @return Result of substraction. 47 * 48 */ 49 float32 sub_float32(float32 a, float32 b) 47 */ 48 float32 subFloat32(float32 a, float32 b) 50 49 { 51 50 int expdiff; 52 51 uint32_t exp1, exp2, frac1, frac2; 53 52 float32 result; 54 55 result. bin= 0;53 54 result.f = 0; 56 55 57 56 expdiff = a.parts.exp - b.parts.exp; 58 if ((expdiff < 0 ) || ((expdiff == 0) && 59 (a.parts.fraction < b.parts.fraction))) { 60 if (is_float32_nan(b)) { 61 if (is_float32_signan(b)) { 62 // TODO: fix SigNaN 63 } 64 65 return b; 66 } 67 68 if (b.parts.exp == FLOAT32_MAX_EXPONENT) { 69 /* num -(+-inf) = -+inf */ 70 b.parts.sign = !b.parts.sign; 71 return b; 72 } 73 74 result.parts.sign = !a.parts.sign; 57 if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.fraction < b.parts.fraction))) { 58 if (isFloat32NaN(b)) { 59 /* TODO: fix SigNaN */ 60 if (isFloat32SigNaN(b)) { 61 } 62 return b; 63 } 64 65 if (b.parts.exp == FLOAT32_MAX_EXPONENT) { 66 b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */ 67 return b; 68 } 69 70 result.parts.sign = !a.parts.sign; 75 71 76 72 frac1 = b.parts.fraction; … … 80 76 expdiff *= -1; 81 77 } else { 82 if (is_float32_nan(a)) { 83 if ((is_float32_signan(a)) || (is_float32_signan(b))) { 84 // TODO: fix SigNaN 85 } 86 87 return a; 88 } 89 90 if (a.parts.exp == FLOAT32_MAX_EXPONENT) { 78 if (isFloat32NaN(a)) { 79 /* TODO: fix SigNaN */ 80 if (isFloat32SigNaN(a) || isFloat32SigNaN(b)) { 81 } 82 return a; 83 } 84 85 if (a.parts.exp == FLOAT32_MAX_EXPONENT) { 91 86 if (b.parts.exp == FLOAT32_MAX_EXPONENT) { 92 87 /* inf - inf => nan */ 93 / / TODO: fix exception94 result.bin = FLOAT32_NAN;88 /* TODO: fix exception */ 89 result.binary = FLOAT32_NAN; 95 90 return result; 96 91 } 97 98 92 return a; 99 93 } … … 104 98 exp1 = a.parts.exp; 105 99 frac2 = b.parts.fraction; 106 exp2 = b.parts.exp; 100 exp2 = b.parts.exp; 107 101 } 108 102 … … 111 105 result.parts.fraction = frac1 - frac2; 112 106 if (result.parts.fraction > frac1) { 113 / / TODO: underflow exception107 /* TODO: underflow exception */ 114 108 return result; 115 109 } 116 117 110 result.parts.exp = 0; 118 111 return result; 119 112 } 120 113 121 114 /* add hidden bit */ 122 frac1 |= FLOAT32_HIDDEN_BIT_MASK; 115 frac1 |= FLOAT32_HIDDEN_BIT_MASK; 123 116 124 117 if (exp2 == 0) { 125 118 /* denormalized */ 126 --expdiff; 119 --expdiff; 127 120 } else { 128 121 /* normalized */ … … 134 127 frac2 <<= 6; 135 128 136 if (expdiff > FLOAT32_FRACTION_SIZE + 1) 129 if (expdiff > FLOAT32_FRACTION_SIZE + 1) { 137 130 goto done; 131 } 138 132 139 133 frac1 = frac1 - (frac2 >> expdiff); 140 134 141 135 done: 142 136 /* TODO: find first nonzero digit and shift result and detect possibly underflow */ … … 149 143 /* rounding - if first bit after fraction is set then round up */ 150 144 frac1 += 0x20; 151 145 152 146 if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) { 153 147 ++exp1; … … 156 150 157 151 /* Clear hidden bit and shift */ 158 result.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)); 152 result.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)); 159 153 result.parts.exp = exp1; 160 154 … … 162 156 } 163 157 164 /** Subtract two double-precision floats with the same sign. 158 /** 159 * Subtract two double-precision floats with the same signs. 165 160 * 166 161 * @param a First input operand. 167 162 * @param b Second input operand. 168 *169 163 * @return Result of substraction. 170 * 171 */ 172 float64 sub_float64(float64 a, float64 b) 164 */ 165 float64 subFloat64(float64 a, float64 b) 173 166 { 174 167 int expdiff; … … 176 169 uint64_t frac1, frac2; 177 170 float64 result; 178 179 result. bin= 0;171 172 result.d = 0; 180 173 181 174 expdiff = a.parts.exp - b.parts.exp; 182 if ((expdiff < 0 ) || 183 ((expdiff == 0) && (a.parts.fraction < b.parts.fraction))) { 184 if (is_float64_nan(b)) { 185 if (is_float64_signan(b)) { 186 // TODO: fix SigNaN 187 } 188 189 return b; 190 } 191 192 if (b.parts.exp == FLOAT64_MAX_EXPONENT) { 193 /* num -(+-inf) = -+inf */ 194 b.parts.sign = !b.parts.sign; 195 return b; 196 } 197 198 result.parts.sign = !a.parts.sign; 175 if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.fraction < b.parts.fraction))) { 176 if (isFloat64NaN(b)) { 177 /* TODO: fix SigNaN */ 178 if (isFloat64SigNaN(b)) { 179 } 180 return b; 181 } 182 183 if (b.parts.exp == FLOAT64_MAX_EXPONENT) { 184 b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */ 185 return b; 186 } 187 188 result.parts.sign = !a.parts.sign; 199 189 200 190 frac1 = b.parts.fraction; … … 204 194 expdiff *= -1; 205 195 } else { 206 if (is_float64_nan(a)) { 207 if (is_float64_signan(a) || is_float64_signan(b)) { 208 // TODO: fix SigNaN 209 } 210 211 return a; 212 } 213 214 if (a.parts.exp == FLOAT64_MAX_EXPONENT) { 196 if (isFloat64NaN(a)) { 197 /* TODO: fix SigNaN */ 198 if (isFloat64SigNaN(a) || isFloat64SigNaN(b)) { 199 } 200 return a; 201 } 202 203 if (a.parts.exp == FLOAT64_MAX_EXPONENT) { 215 204 if (b.parts.exp == FLOAT64_MAX_EXPONENT) { 216 205 /* inf - inf => nan */ 217 / / TODO: fix exception218 result.bin = FLOAT64_NAN;206 /* TODO: fix exception */ 207 result.binary = FLOAT64_NAN; 219 208 return result; 220 209 } 221 222 210 return a; 223 211 } … … 228 216 exp1 = a.parts.exp; 229 217 frac2 = b.parts.fraction; 230 exp2 = b.parts.exp; 218 exp2 = b.parts.exp; 231 219 } 232 220 … … 235 223 result.parts.fraction = frac1 - frac2; 236 224 if (result.parts.fraction > frac1) { 237 / / TODO: underflow exception225 /* TODO: underflow exception */ 238 226 return result; 239 227 } 240 241 228 result.parts.exp = 0; 242 229 return result; 243 230 } 244 231 245 232 /* add hidden bit */ 246 frac1 |= FLOAT64_HIDDEN_BIT_MASK; 233 frac1 |= FLOAT64_HIDDEN_BIT_MASK; 247 234 248 235 if (exp2 == 0) { 249 236 /* denormalized */ 250 --expdiff; 237 --expdiff; 251 238 } else { 252 239 /* normalized */ … … 258 245 frac2 <<= 6; 259 246 260 if (expdiff > FLOAT64_FRACTION_SIZE + 1) 247 if (expdiff > FLOAT64_FRACTION_SIZE + 1) { 261 248 goto done; 249 } 262 250 263 251 frac1 = frac1 - (frac2 >> expdiff); 264 252 265 253 done: 266 254 /* TODO: find first nonzero digit and shift result and detect possibly underflow */ … … 273 261 /* rounding - if first bit after fraction is set then round up */ 274 262 frac1 += 0x20; 275 263 276 264 if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) { 277 265 ++exp1; … … 280 268 281 269 /* Clear hidden bit and shift */ 282 result.parts.fraction = ((frac1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK)); 270 result.parts.fraction = ((frac1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK)); 283 271 result.parts.exp = exp1; 284 272 … … 286 274 } 287 275 288 /** Subtract two quadruple-precision floats with the same sign. 276 /** 277 * Subtract two quadruple-precision floats with the same signs. 289 278 * 290 279 * @param a First input operand. 291 280 * @param b Second input operand. 292 *293 281 * @return Result of substraction. 294 * 295 */ 296 float128 sub_float128(float128 a, float128 b) 282 */ 283 float128 subFloat128(float128 a, float128 b) 297 284 { 298 285 int expdiff; … … 300 287 uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo; 301 288 float128 result; 302 303 result.bin .hi = 0;304 result.bin .lo = 0;305 289 290 result.binary.hi = 0; 291 result.binary.lo = 0; 292 306 293 expdiff = a.parts.exp - b.parts.exp; 307 294 if ((expdiff < 0 ) || ((expdiff == 0) && 308 295 lt128(a.parts.frac_hi, a.parts.frac_lo, b.parts.frac_hi, b.parts.frac_lo))) { 309 if (is_float128_nan(b)) { 310 if (is_float128_signan(b)) { 311 // TODO: fix SigNaN 312 } 313 314 return b; 315 } 316 296 if (isFloat128NaN(b)) { 297 /* TODO: fix SigNaN */ 298 if (isFloat128SigNaN(b)) { 299 } 300 return b; 301 } 302 317 303 if (b.parts.exp == FLOAT128_MAX_EXPONENT) { 318 /* num -(+-inf) = -+inf */ 319 b.parts.sign = !b.parts.sign; 320 return b; 321 } 322 304 b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */ 305 return b; 306 } 307 323 308 result.parts.sign = !a.parts.sign; 324 309 325 310 frac1_hi = b.parts.frac_hi; 326 311 frac1_lo = b.parts.frac_lo; … … 331 316 expdiff *= -1; 332 317 } else { 333 if (is_float128_nan(a)) { 334 if (is_float128_signan(a) || is_float128_signan(b)) { 335 // TODO: fix SigNaN 336 } 337 338 return a; 339 } 340 318 if (isFloat128NaN(a)) { 319 /* TODO: fix SigNaN */ 320 if (isFloat128SigNaN(a) || isFloat128SigNaN(b)) { 321 } 322 return a; 323 } 324 341 325 if (a.parts.exp == FLOAT128_MAX_EXPONENT) { 342 326 if (b.parts.exp == FLOAT128_MAX_EXPONENT) { 343 327 /* inf - inf => nan */ 344 / / TODO: fix exception345 result.bin .hi = FLOAT128_NAN_HI;346 result.bin .lo = FLOAT128_NAN_LO;328 /* TODO: fix exception */ 329 result.binary.hi = FLOAT128_NAN_HI; 330 result.binary.lo = FLOAT128_NAN_LO; 347 331 return result; 348 332 } 349 333 return a; 350 334 } 351 335 352 336 result.parts.sign = a.parts.sign; 353 337 354 338 frac1_hi = a.parts.frac_hi; 355 339 frac1_lo = a.parts.frac_lo; … … 359 343 exp2 = b.parts.exp; 360 344 } 361 345 362 346 if (exp1 == 0) { 363 347 /* both are denormalized */ … … 366 350 result.parts.frac_lo = tmp_lo; 367 351 if (lt128(frac1_hi, frac1_lo, result.parts.frac_hi, result.parts.frac_lo)) { 368 / / TODO: underflow exception352 /* TODO: underflow exception */ 369 353 return result; 370 354 } 371 372 355 result.parts.exp = 0; 373 356 return result; 374 357 } 375 358 376 359 /* add hidden bit */ 377 360 or128(frac1_hi, frac1_lo, 378 361 FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 379 362 &frac1_hi, &frac1_lo); 380 363 381 364 if (exp2 == 0) { 382 365 /* denormalized */ … … 388 371 &frac2_hi, &frac2_lo); 389 372 } 390 373 391 374 /* create some space for rounding */ 392 375 lshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo); 393 376 lshift128(frac2_hi, frac2_lo, 6, &frac2_hi, &frac2_lo); 394 395 if (expdiff > FLOAT128_FRACTION_SIZE + 1) 377 378 if (expdiff > FLOAT128_FRACTION_SIZE + 1) { 396 379 goto done; 397 380 } 381 398 382 rshift128(frac2_hi, frac2_lo, expdiff, &tmp_hi, &tmp_lo); 399 383 sub128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &frac1_hi, &frac1_lo); 400 384 401 385 done: 402 386 /* TODO: find first nonzero digit and shift result and detect possibly underflow */ … … 408 392 lshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo); 409 393 /* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */ 410 394 411 395 lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 6, 412 396 &tmp_hi, &tmp_lo); 413 397 and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo); 414 398 } 415 399 416 400 /* rounding - if first bit after fraction is set then round up */ 417 401 add128(frac1_hi, frac1_lo, 0x0ll, 0x20ll, &frac1_hi, &frac1_lo); 418 402 419 403 lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7, 420 404 &tmp_hi, &tmp_lo); … … 424 408 rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo); 425 409 } 426 410 427 411 /* Clear hidden bit and shift */ 428 412 rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo); … … 432 416 result.parts.frac_hi = tmp_hi; 433 417 result.parts.frac_lo = tmp_lo; 434 418 435 419 result.parts.exp = exp1; 436 420 437 421 return result; 438 422 }
Note:
See TracChangeset
for help on using the changeset viewer.