1*7c3d14c8STreehugger Robot//===---- lib/fp_mul_impl.inc - floating point multiplication -----*- C -*-===// 2*7c3d14c8STreehugger Robot// 3*7c3d14c8STreehugger Robot// The LLVM Compiler Infrastructure 4*7c3d14c8STreehugger Robot// 5*7c3d14c8STreehugger Robot// This file is dual licensed under the MIT and the University of Illinois Open 6*7c3d14c8STreehugger Robot// Source Licenses. See LICENSE.TXT for details. 7*7c3d14c8STreehugger Robot// 8*7c3d14c8STreehugger Robot//===----------------------------------------------------------------------===// 9*7c3d14c8STreehugger Robot// 10*7c3d14c8STreehugger Robot// This file implements soft-float multiplication with the IEEE-754 default 11*7c3d14c8STreehugger Robot// rounding (to nearest, ties to even). 12*7c3d14c8STreehugger Robot// 13*7c3d14c8STreehugger Robot//===----------------------------------------------------------------------===// 14*7c3d14c8STreehugger Robot 15*7c3d14c8STreehugger Robot#include "fp_lib.h" 16*7c3d14c8STreehugger Robot 17*7c3d14c8STreehugger Robotstatic __inline fp_t __mulXf3__(fp_t a, fp_t b) { 18*7c3d14c8STreehugger Robot const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; 19*7c3d14c8STreehugger Robot const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; 20*7c3d14c8STreehugger Robot const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit; 21*7c3d14c8STreehugger Robot 22*7c3d14c8STreehugger Robot rep_t aSignificand = toRep(a) & significandMask; 23*7c3d14c8STreehugger Robot rep_t bSignificand = toRep(b) & significandMask; 24*7c3d14c8STreehugger Robot int scale = 0; 25*7c3d14c8STreehugger Robot 26*7c3d14c8STreehugger Robot // Detect if a or b is zero, denormal, infinity, or NaN. 27*7c3d14c8STreehugger Robot if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) { 28*7c3d14c8STreehugger Robot 29*7c3d14c8STreehugger Robot const rep_t aAbs = toRep(a) & absMask; 30*7c3d14c8STreehugger Robot const rep_t bAbs = toRep(b) & absMask; 31*7c3d14c8STreehugger Robot 32*7c3d14c8STreehugger Robot // NaN * anything = qNaN 33*7c3d14c8STreehugger Robot if (aAbs > infRep) return fromRep(toRep(a) | quietBit); 34*7c3d14c8STreehugger Robot // anything * NaN = qNaN 35*7c3d14c8STreehugger Robot if (bAbs > infRep) return fromRep(toRep(b) | quietBit); 36*7c3d14c8STreehugger Robot 37*7c3d14c8STreehugger Robot if (aAbs == infRep) { 38*7c3d14c8STreehugger Robot // infinity * non-zero = +/- infinity 39*7c3d14c8STreehugger Robot if (bAbs) return fromRep(aAbs | productSign); 40*7c3d14c8STreehugger Robot // infinity * zero = NaN 41*7c3d14c8STreehugger Robot else return fromRep(qnanRep); 42*7c3d14c8STreehugger Robot } 43*7c3d14c8STreehugger Robot 44*7c3d14c8STreehugger Robot if (bAbs == infRep) { 45*7c3d14c8STreehugger Robot //? non-zero * infinity = +/- infinity 46*7c3d14c8STreehugger Robot if (aAbs) return fromRep(bAbs | productSign); 47*7c3d14c8STreehugger Robot // zero * infinity = NaN 48*7c3d14c8STreehugger Robot else return fromRep(qnanRep); 49*7c3d14c8STreehugger Robot } 50*7c3d14c8STreehugger Robot 51*7c3d14c8STreehugger Robot // zero * anything = +/- zero 52*7c3d14c8STreehugger Robot if (!aAbs) return fromRep(productSign); 53*7c3d14c8STreehugger Robot // anything * zero = +/- zero 54*7c3d14c8STreehugger Robot if (!bAbs) return fromRep(productSign); 55*7c3d14c8STreehugger Robot 56*7c3d14c8STreehugger Robot // one or both of a or b is denormal, the other (if applicable) is a 57*7c3d14c8STreehugger Robot // normal number. Renormalize one or both of a and b, and set scale to 58*7c3d14c8STreehugger Robot // include the necessary exponent adjustment. 59*7c3d14c8STreehugger Robot if (aAbs < implicitBit) scale += normalize(&aSignificand); 60*7c3d14c8STreehugger Robot if (bAbs < implicitBit) scale += normalize(&bSignificand); 61*7c3d14c8STreehugger Robot } 62*7c3d14c8STreehugger Robot 63*7c3d14c8STreehugger Robot // Or in the implicit significand bit. (If we fell through from the 64*7c3d14c8STreehugger Robot // denormal path it was already set by normalize( ), but setting it twice 65*7c3d14c8STreehugger Robot // won't hurt anything.) 66*7c3d14c8STreehugger Robot aSignificand |= implicitBit; 67*7c3d14c8STreehugger Robot bSignificand |= implicitBit; 68*7c3d14c8STreehugger Robot 69*7c3d14c8STreehugger Robot // Get the significand of a*b. Before multiplying the significands, shift 70*7c3d14c8STreehugger Robot // one of them left to left-align it in the field. Thus, the product will 71*7c3d14c8STreehugger Robot // have (exponentBits + 2) integral digits, all but two of which must be 72*7c3d14c8STreehugger Robot // zero. Normalizing this result is just a conditional left-shift by one 73*7c3d14c8STreehugger Robot // and bumping the exponent accordingly. 74*7c3d14c8STreehugger Robot rep_t productHi, productLo; 75*7c3d14c8STreehugger Robot wideMultiply(aSignificand, bSignificand << exponentBits, 76*7c3d14c8STreehugger Robot &productHi, &productLo); 77*7c3d14c8STreehugger Robot 78*7c3d14c8STreehugger Robot int productExponent = aExponent + bExponent - exponentBias + scale; 79*7c3d14c8STreehugger Robot 80*7c3d14c8STreehugger Robot // Normalize the significand, adjust exponent if needed. 81*7c3d14c8STreehugger Robot if (productHi & implicitBit) productExponent++; 82*7c3d14c8STreehugger Robot else wideLeftShift(&productHi, &productLo, 1); 83*7c3d14c8STreehugger Robot 84*7c3d14c8STreehugger Robot // If we have overflowed the type, return +/- infinity. 85*7c3d14c8STreehugger Robot if (productExponent >= maxExponent) return fromRep(infRep | productSign); 86*7c3d14c8STreehugger Robot 87*7c3d14c8STreehugger Robot if (productExponent <= 0) { 88*7c3d14c8STreehugger Robot // Result is denormal before rounding 89*7c3d14c8STreehugger Robot // 90*7c3d14c8STreehugger Robot // If the result is so small that it just underflows to zero, return 91*7c3d14c8STreehugger Robot // a zero of the appropriate sign. Mathematically there is no need to 92*7c3d14c8STreehugger Robot // handle this case separately, but we make it a special case to 93*7c3d14c8STreehugger Robot // simplify the shift logic. 94*7c3d14c8STreehugger Robot const unsigned int shift = REP_C(1) - (unsigned int)productExponent; 95*7c3d14c8STreehugger Robot if (shift >= typeWidth) return fromRep(productSign); 96*7c3d14c8STreehugger Robot 97*7c3d14c8STreehugger Robot // Otherwise, shift the significand of the result so that the round 98*7c3d14c8STreehugger Robot // bit is the high bit of productLo. 99*7c3d14c8STreehugger Robot wideRightShiftWithSticky(&productHi, &productLo, shift); 100*7c3d14c8STreehugger Robot } 101*7c3d14c8STreehugger Robot else { 102*7c3d14c8STreehugger Robot // Result is normal before rounding; insert the exponent. 103*7c3d14c8STreehugger Robot productHi &= significandMask; 104*7c3d14c8STreehugger Robot productHi |= (rep_t)productExponent << significandBits; 105*7c3d14c8STreehugger Robot } 106*7c3d14c8STreehugger Robot 107*7c3d14c8STreehugger Robot // Insert the sign of the result: 108*7c3d14c8STreehugger Robot productHi |= productSign; 109*7c3d14c8STreehugger Robot 110*7c3d14c8STreehugger Robot // Final rounding. The final result may overflow to infinity, or underflow 111*7c3d14c8STreehugger Robot // to zero, but those are the correct results in those cases. We use the 112*7c3d14c8STreehugger Robot // default IEEE-754 round-to-nearest, ties-to-even rounding mode. 113*7c3d14c8STreehugger Robot if (productLo > signBit) productHi++; 114*7c3d14c8STreehugger Robot if (productLo == signBit) productHi += productHi & 1; 115*7c3d14c8STreehugger Robot return fromRep(productHi); 116*7c3d14c8STreehugger Robot} 117