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