Changes in uspace/lib/softfloat/generic/mul.c [88d5c1e:c67aff2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/softfloat/generic/mul.c
r88d5c1e rc67aff2 39 39 #include <common.h> 40 40 41 /** Multiply two single-precision floats. 41 /** 42 * Multiply two single-precision floats. 42 43 * 43 44 * @param a First input operand. 44 45 * @param b Second input operand. 45 *46 46 * @return Result of multiplication. 47 * 48 */ 49 float32 mul_float32(float32 a, float32 b) 47 */ 48 float32 mulFloat32(float32 a, float32 b) 50 49 { 51 50 float32 result; 52 51 uint64_t frac1, frac2; 53 52 int32_t exp; 54 53 55 54 result.parts.sign = a.parts.sign ^ b.parts.sign; 56 55 57 if (is _float32_nan(a) || is_float32_nan(b)) {56 if (isFloat32NaN(a) || isFloat32NaN(b)) { 58 57 /* TODO: fix SigNaNs */ 59 if (is _float32_signan(a)) {58 if (isFloat32SigNaN(a)) { 60 59 result.parts.fraction = a.parts.fraction; 61 60 result.parts.exp = a.parts.exp; 62 61 return result; 63 62 } 64 if (is _float32_signan(b)) { /* TODO: fix SigNaN */63 if (isFloat32SigNaN(b)) { /* TODO: fix SigNaN */ 65 64 result.parts.fraction = b.parts.fraction; 66 65 result.parts.exp = b.parts.exp; … … 68 67 } 69 68 /* set NaN as result */ 70 result.bin = FLOAT32_NAN;71 return result; 72 } 73 74 if (is _float32_infinity(a)) {75 if (is _float32_zero(b)) {76 /* FIXME: zero * infinity */ 77 result.bin = FLOAT32_NAN;69 result.binary = FLOAT32_NAN; 70 return result; 71 } 72 73 if (isFloat32Infinity(a)) { 74 if (isFloat32Zero(b)) { 75 /* FIXME: zero * infinity */ 76 result.binary = FLOAT32_NAN; 78 77 return result; 79 78 } … … 82 81 return result; 83 82 } 84 85 if (is _float32_infinity(b)) {86 if (is _float32_zero(a)) {87 /* FIXME: zero * infinity */ 88 result.bin = FLOAT32_NAN;83 84 if (isFloat32Infinity(b)) { 85 if (isFloat32Zero(a)) { 86 /* FIXME: zero * infinity */ 87 result.binary = FLOAT32_NAN; 89 88 return result; 90 89 } … … 93 92 return result; 94 93 } 95 94 96 95 /* exp is signed so we can easy detect underflow */ 97 96 exp = a.parts.exp + b.parts.exp; … … 101 100 /* FIXME: overflow */ 102 101 /* set infinity as result */ 103 result.bin = FLOAT32_INF;102 result.binary = FLOAT32_INF; 104 103 result.parts.sign = a.parts.sign ^ b.parts.sign; 105 104 return result; … … 122 121 123 122 frac2 = b.parts.fraction; 124 123 125 124 if (b.parts.exp > 0) { 126 125 frac2 |= FLOAT32_HIDDEN_BIT_MASK; … … 128 127 ++exp; 129 128 } 130 129 131 130 frac1 <<= 1; /* one bit space for rounding */ 132 131 133 132 frac1 = frac1 * frac2; 134 133 135 134 /* round and return */ 136 while ((exp < FLOAT32_MAX_EXPONENT) && 137 (frac1 >= (1 << (FLOAT32_FRACTION_SIZE + 2)))) { 135 while ((exp < FLOAT32_MAX_EXPONENT) && (frac1 >= (1 << (FLOAT32_FRACTION_SIZE + 2)))) { 138 136 /* 23 bits of fraction + one more for hidden bit (all shifted 1 bit left) */ 139 137 ++exp; 140 138 frac1 >>= 1; 141 139 } 142 140 143 141 /* rounding */ 144 142 /* ++frac1; FIXME: not works - without it is ok */ 145 143 frac1 >>= 1; /* shift off rounding space */ 146 144 147 if ((exp < FLOAT32_MAX_EXPONENT) && 148 (frac1 >= (1 << (FLOAT32_FRACTION_SIZE + 1)))) { 145 if ((exp < FLOAT32_MAX_EXPONENT) && (frac1 >= (1 << (FLOAT32_FRACTION_SIZE + 1)))) { 149 146 ++exp; 150 147 frac1 >>= 1; 151 148 } 152 153 if (exp >= FLOAT32_MAX_EXPONENT) { 149 150 if (exp >= FLOAT32_MAX_EXPONENT) { 154 151 /* TODO: fix overflow */ 155 152 /* return infinity*/ … … 160 157 161 158 exp -= FLOAT32_FRACTION_SIZE; 162 163 if (exp <= FLOAT32_FRACTION_SIZE) { 159 160 if (exp <= FLOAT32_FRACTION_SIZE) { 164 161 /* denormalized number */ 165 162 frac1 >>= 1; /* denormalize */ … … 178 175 result.parts.fraction = frac1 & ((1 << FLOAT32_FRACTION_SIZE) - 1); 179 176 180 return result; 177 return result; 181 178 } 182 179 183 /** Multiply two double-precision floats. 180 /** 181 * Multiply two double-precision floats. 184 182 * 185 183 * @param a First input operand. 186 184 * @param b Second input operand. 187 *188 185 * @return Result of multiplication. 189 * 190 */ 191 float64 mul_float64(float64 a, float64 b) 186 */ 187 float64 mulFloat64(float64 a, float64 b) 192 188 { 193 189 float64 result; 194 190 uint64_t frac1, frac2; 195 191 int32_t exp; 196 192 197 193 result.parts.sign = a.parts.sign ^ b.parts.sign; 198 194 199 if (is _float64_nan(a) || is_float64_nan(b)) {195 if (isFloat64NaN(a) || isFloat64NaN(b)) { 200 196 /* TODO: fix SigNaNs */ 201 if (is _float64_signan(a)) {197 if (isFloat64SigNaN(a)) { 202 198 result.parts.fraction = a.parts.fraction; 203 199 result.parts.exp = a.parts.exp; 204 200 return result; 205 201 } 206 if (is _float64_signan(b)) { /* TODO: fix SigNaN */202 if (isFloat64SigNaN(b)) { /* TODO: fix SigNaN */ 207 203 result.parts.fraction = b.parts.fraction; 208 204 result.parts.exp = b.parts.exp; … … 210 206 } 211 207 /* set NaN as result */ 212 result.bin = FLOAT64_NAN;213 return result; 214 } 215 216 if (is _float64_infinity(a)) {217 if (is _float64_zero(b)) {218 /* FIXME: zero * infinity */ 219 result.bin = FLOAT64_NAN;208 result.binary = FLOAT64_NAN; 209 return result; 210 } 211 212 if (isFloat64Infinity(a)) { 213 if (isFloat64Zero(b)) { 214 /* FIXME: zero * infinity */ 215 result.binary = FLOAT64_NAN; 220 216 return result; 221 217 } … … 224 220 return result; 225 221 } 226 227 if (is _float64_infinity(b)) {228 if (is _float64_zero(a)) {229 /* FIXME: zero * infinity */ 230 result.bin = FLOAT64_NAN;222 223 if (isFloat64Infinity(b)) { 224 if (isFloat64Zero(a)) { 225 /* FIXME: zero * infinity */ 226 result.binary = FLOAT64_NAN; 231 227 return result; 232 228 } … … 235 231 return result; 236 232 } 237 233 238 234 /* exp is signed so we can easy detect underflow */ 239 235 exp = a.parts.exp + b.parts.exp - FLOAT64_BIAS; 240 236 241 237 frac1 = a.parts.fraction; 242 238 243 239 if (a.parts.exp > 0) { 244 240 frac1 |= FLOAT64_HIDDEN_BIT_MASK; … … 248 244 249 245 frac2 = b.parts.fraction; 250 246 251 247 if (b.parts.exp > 0) { 252 248 frac2 |= FLOAT64_HIDDEN_BIT_MASK; … … 254 250 ++exp; 255 251 } 256 252 257 253 frac1 <<= (64 - FLOAT64_FRACTION_SIZE - 1); 258 254 frac2 <<= (64 - FLOAT64_FRACTION_SIZE - 2); 259 255 260 256 mul64(frac1, frac2, &frac1, &frac2); 261 257 262 258 frac1 |= (frac2 != 0); 263 259 if (frac1 & (0x1ll << 62)) { … … 265 261 exp--; 266 262 } 267 268 result = finish _float64(exp, frac1, result.parts.sign);263 264 result = finishFloat64(exp, frac1, result.parts.sign); 269 265 return result; 270 266 } 271 267 272 /** Multiply two quadruple-precision floats. 268 /** 269 * Multiply two quadruple-precision floats. 273 270 * 274 271 * @param a First input operand. 275 272 * @param b Second input operand. 276 *277 273 * @return Result of multiplication. 278 * 279 */ 280 float128 mul_float128(float128 a, float128 b) 274 */ 275 float128 mulFloat128(float128 a, float128 b) 281 276 { 282 277 float128 result; 283 278 uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo; 284 279 int32_t exp; 285 280 286 281 result.parts.sign = a.parts.sign ^ b.parts.sign; 287 288 if (is _float128_nan(a) || is_float128_nan(b)) {282 283 if (isFloat128NaN(a) || isFloat128NaN(b)) { 289 284 /* TODO: fix SigNaNs */ 290 if (is _float128_signan(a)) {285 if (isFloat128SigNaN(a)) { 291 286 result.parts.frac_hi = a.parts.frac_hi; 292 287 result.parts.frac_lo = a.parts.frac_lo; … … 294 289 return result; 295 290 } 296 if (is _float128_signan(b)) { /* TODO: fix SigNaN */291 if (isFloat128SigNaN(b)) { /* TODO: fix SigNaN */ 297 292 result.parts.frac_hi = b.parts.frac_hi; 298 293 result.parts.frac_lo = b.parts.frac_lo; … … 301 296 } 302 297 /* set NaN as result */ 303 result.bin .hi = FLOAT128_NAN_HI;304 result.bin .lo = FLOAT128_NAN_LO;305 return result; 306 } 307 308 if (is _float128_infinity(a)) {309 if (is _float128_zero(b)) {310 /* FIXME: zero * infinity */ 311 result.bin .hi = FLOAT128_NAN_HI;312 result.bin .lo = FLOAT128_NAN_LO;298 result.binary.hi = FLOAT128_NAN_HI; 299 result.binary.lo = FLOAT128_NAN_LO; 300 return result; 301 } 302 303 if (isFloat128Infinity(a)) { 304 if (isFloat128Zero(b)) { 305 /* FIXME: zero * infinity */ 306 result.binary.hi = FLOAT128_NAN_HI; 307 result.binary.lo = FLOAT128_NAN_LO; 313 308 return result; 314 309 } … … 318 313 return result; 319 314 } 320 321 if (is _float128_infinity(b)) {322 if (is _float128_zero(a)) {323 /* FIXME: zero * infinity */ 324 result.bin .hi = FLOAT128_NAN_HI;325 result.bin .lo = FLOAT128_NAN_LO;315 316 if (isFloat128Infinity(b)) { 317 if (isFloat128Zero(a)) { 318 /* FIXME: zero * infinity */ 319 result.binary.hi = FLOAT128_NAN_HI; 320 result.binary.lo = FLOAT128_NAN_LO; 326 321 return result; 327 322 } … … 331 326 return result; 332 327 } 333 328 334 329 /* exp is signed so we can easy detect underflow */ 335 330 exp = a.parts.exp + b.parts.exp - FLOAT128_BIAS - 1; 336 331 337 332 frac1_hi = a.parts.frac_hi; 338 333 frac1_lo = a.parts.frac_lo; 339 334 340 335 if (a.parts.exp > 0) { 341 336 or128(frac1_hi, frac1_lo, 342 343 344 } else { 345 ++exp; 346 } 347 337 FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 338 &frac1_hi, &frac1_lo); 339 } else { 340 ++exp; 341 } 342 348 343 frac2_hi = b.parts.frac_hi; 349 344 frac2_lo = b.parts.frac_lo; 350 345 351 346 if (b.parts.exp > 0) { 352 347 or128(frac2_hi, frac2_lo, … … 356 351 ++exp; 357 352 } 358 353 359 354 lshift128(frac2_hi, frac2_lo, 360 355 128 - FLOAT128_FRACTION_SIZE, &frac2_hi, &frac2_lo); 361 356 362 357 tmp_hi = frac1_hi; 363 358 tmp_lo = frac1_lo; … … 366 361 add128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &frac1_hi, &frac1_lo); 367 362 frac2_hi |= (frac2_lo != 0x0ll); 368 363 369 364 if ((FLOAT128_HIDDEN_BIT_MASK_HI << 1) <= frac1_hi) { 370 365 frac2_hi >>= 1; … … 375 370 ++exp; 376 371 } 377 378 result = finish _float128(exp, frac1_hi, frac1_lo, result.parts.sign, frac2_hi);372 373 result = finishFloat128(exp, frac1_hi, frac1_lo, result.parts.sign, frac2_hi); 379 374 return result; 380 375 }
Note:
See TracChangeset
for help on using the changeset viewer.