1*7c3d14c8STreehugger Robot//===----- lib/fp_add_impl.inc - floaing point addition -----------*- 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 addition with the IEEE-754 default rounding 11*7c3d14c8STreehugger Robot// (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 __addXf3__(fp_t a, fp_t b) { 18*7c3d14c8STreehugger Robot rep_t aRep = toRep(a); 19*7c3d14c8STreehugger Robot rep_t bRep = toRep(b); 20*7c3d14c8STreehugger Robot const rep_t aAbs = aRep & absMask; 21*7c3d14c8STreehugger Robot const rep_t bAbs = bRep & absMask; 22*7c3d14c8STreehugger Robot 23*7c3d14c8STreehugger Robot // Detect if a or b is zero, infinity, or NaN. 24*7c3d14c8STreehugger Robot if (aAbs - REP_C(1) >= infRep - REP_C(1) || 25*7c3d14c8STreehugger Robot bAbs - REP_C(1) >= infRep - REP_C(1)) { 26*7c3d14c8STreehugger Robot // NaN + anything = qNaN 27*7c3d14c8STreehugger Robot if (aAbs > infRep) return fromRep(toRep(a) | quietBit); 28*7c3d14c8STreehugger Robot // anything + NaN = qNaN 29*7c3d14c8STreehugger Robot if (bAbs > infRep) return fromRep(toRep(b) | quietBit); 30*7c3d14c8STreehugger Robot 31*7c3d14c8STreehugger Robot if (aAbs == infRep) { 32*7c3d14c8STreehugger Robot // +/-infinity + -/+infinity = qNaN 33*7c3d14c8STreehugger Robot if ((toRep(a) ^ toRep(b)) == signBit) return fromRep(qnanRep); 34*7c3d14c8STreehugger Robot // +/-infinity + anything remaining = +/- infinity 35*7c3d14c8STreehugger Robot else return a; 36*7c3d14c8STreehugger Robot } 37*7c3d14c8STreehugger Robot 38*7c3d14c8STreehugger Robot // anything remaining + +/-infinity = +/-infinity 39*7c3d14c8STreehugger Robot if (bAbs == infRep) return b; 40*7c3d14c8STreehugger Robot 41*7c3d14c8STreehugger Robot // zero + anything = anything 42*7c3d14c8STreehugger Robot if (!aAbs) { 43*7c3d14c8STreehugger Robot // but we need to get the sign right for zero + zero 44*7c3d14c8STreehugger Robot if (!bAbs) return fromRep(toRep(a) & toRep(b)); 45*7c3d14c8STreehugger Robot else return b; 46*7c3d14c8STreehugger Robot } 47*7c3d14c8STreehugger Robot 48*7c3d14c8STreehugger Robot // anything + zero = anything 49*7c3d14c8STreehugger Robot if (!bAbs) return a; 50*7c3d14c8STreehugger Robot } 51*7c3d14c8STreehugger Robot 52*7c3d14c8STreehugger Robot // Swap a and b if necessary so that a has the larger absolute value. 53*7c3d14c8STreehugger Robot if (bAbs > aAbs) { 54*7c3d14c8STreehugger Robot const rep_t temp = aRep; 55*7c3d14c8STreehugger Robot aRep = bRep; 56*7c3d14c8STreehugger Robot bRep = temp; 57*7c3d14c8STreehugger Robot } 58*7c3d14c8STreehugger Robot 59*7c3d14c8STreehugger Robot // Extract the exponent and significand from the (possibly swapped) a and b. 60*7c3d14c8STreehugger Robot int aExponent = aRep >> significandBits & maxExponent; 61*7c3d14c8STreehugger Robot int bExponent = bRep >> significandBits & maxExponent; 62*7c3d14c8STreehugger Robot rep_t aSignificand = aRep & significandMask; 63*7c3d14c8STreehugger Robot rep_t bSignificand = bRep & significandMask; 64*7c3d14c8STreehugger Robot 65*7c3d14c8STreehugger Robot // Normalize any denormals, and adjust the exponent accordingly. 66*7c3d14c8STreehugger Robot if (aExponent == 0) aExponent = normalize(&aSignificand); 67*7c3d14c8STreehugger Robot if (bExponent == 0) bExponent = normalize(&bSignificand); 68*7c3d14c8STreehugger Robot 69*7c3d14c8STreehugger Robot // The sign of the result is the sign of the larger operand, a. If they 70*7c3d14c8STreehugger Robot // have opposite signs, we are performing a subtraction; otherwise addition. 71*7c3d14c8STreehugger Robot const rep_t resultSign = aRep & signBit; 72*7c3d14c8STreehugger Robot const bool subtraction = (aRep ^ bRep) & signBit; 73*7c3d14c8STreehugger Robot 74*7c3d14c8STreehugger Robot // Shift the significands to give us round, guard and sticky, and or in the 75*7c3d14c8STreehugger Robot // implicit significand bit. (If we fell through from the denormal path it 76*7c3d14c8STreehugger Robot // was already set by normalize( ), but setting it twice won't hurt 77*7c3d14c8STreehugger Robot // anything.) 78*7c3d14c8STreehugger Robot aSignificand = (aSignificand | implicitBit) << 3; 79*7c3d14c8STreehugger Robot bSignificand = (bSignificand | implicitBit) << 3; 80*7c3d14c8STreehugger Robot 81*7c3d14c8STreehugger Robot // Shift the significand of b by the difference in exponents, with a sticky 82*7c3d14c8STreehugger Robot // bottom bit to get rounding correct. 83*7c3d14c8STreehugger Robot const unsigned int align = aExponent - bExponent; 84*7c3d14c8STreehugger Robot if (align) { 85*7c3d14c8STreehugger Robot if (align < typeWidth) { 86*7c3d14c8STreehugger Robot const bool sticky = bSignificand << (typeWidth - align); 87*7c3d14c8STreehugger Robot bSignificand = bSignificand >> align | sticky; 88*7c3d14c8STreehugger Robot } else { 89*7c3d14c8STreehugger Robot bSignificand = 1; // sticky; b is known to be non-zero. 90*7c3d14c8STreehugger Robot } 91*7c3d14c8STreehugger Robot } 92*7c3d14c8STreehugger Robot if (subtraction) { 93*7c3d14c8STreehugger Robot aSignificand -= bSignificand; 94*7c3d14c8STreehugger Robot // If a == -b, return +zero. 95*7c3d14c8STreehugger Robot if (aSignificand == 0) return fromRep(0); 96*7c3d14c8STreehugger Robot 97*7c3d14c8STreehugger Robot // If partial cancellation occured, we need to left-shift the result 98*7c3d14c8STreehugger Robot // and adjust the exponent: 99*7c3d14c8STreehugger Robot if (aSignificand < implicitBit << 3) { 100*7c3d14c8STreehugger Robot const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3); 101*7c3d14c8STreehugger Robot aSignificand <<= shift; 102*7c3d14c8STreehugger Robot aExponent -= shift; 103*7c3d14c8STreehugger Robot } 104*7c3d14c8STreehugger Robot } 105*7c3d14c8STreehugger Robot else /* addition */ { 106*7c3d14c8STreehugger Robot aSignificand += bSignificand; 107*7c3d14c8STreehugger Robot 108*7c3d14c8STreehugger Robot // If the addition carried up, we need to right-shift the result and 109*7c3d14c8STreehugger Robot // adjust the exponent: 110*7c3d14c8STreehugger Robot if (aSignificand & implicitBit << 4) { 111*7c3d14c8STreehugger Robot const bool sticky = aSignificand & 1; 112*7c3d14c8STreehugger Robot aSignificand = aSignificand >> 1 | sticky; 113*7c3d14c8STreehugger Robot aExponent += 1; 114*7c3d14c8STreehugger Robot } 115*7c3d14c8STreehugger Robot } 116*7c3d14c8STreehugger Robot 117*7c3d14c8STreehugger Robot // If we have overflowed the type, return +/- infinity: 118*7c3d14c8STreehugger Robot if (aExponent >= maxExponent) return fromRep(infRep | resultSign); 119*7c3d14c8STreehugger Robot 120*7c3d14c8STreehugger Robot if (aExponent <= 0) { 121*7c3d14c8STreehugger Robot // Result is denormal before rounding; the exponent is zero and we 122*7c3d14c8STreehugger Robot // need to shift the significand. 123*7c3d14c8STreehugger Robot const int shift = 1 - aExponent; 124*7c3d14c8STreehugger Robot const bool sticky = aSignificand << (typeWidth - shift); 125*7c3d14c8STreehugger Robot aSignificand = aSignificand >> shift | sticky; 126*7c3d14c8STreehugger Robot aExponent = 0; 127*7c3d14c8STreehugger Robot } 128*7c3d14c8STreehugger Robot 129*7c3d14c8STreehugger Robot // Low three bits are round, guard, and sticky. 130*7c3d14c8STreehugger Robot const int roundGuardSticky = aSignificand & 0x7; 131*7c3d14c8STreehugger Robot 132*7c3d14c8STreehugger Robot // Shift the significand into place, and mask off the implicit bit. 133*7c3d14c8STreehugger Robot rep_t result = aSignificand >> 3 & significandMask; 134*7c3d14c8STreehugger Robot 135*7c3d14c8STreehugger Robot // Insert the exponent and sign. 136*7c3d14c8STreehugger Robot result |= (rep_t)aExponent << significandBits; 137*7c3d14c8STreehugger Robot result |= resultSign; 138*7c3d14c8STreehugger Robot 139*7c3d14c8STreehugger Robot // Final rounding. The result may overflow to infinity, but that is the 140*7c3d14c8STreehugger Robot // correct result in that case. 141*7c3d14c8STreehugger Robot if (roundGuardSticky > 0x4) result++; 142*7c3d14c8STreehugger Robot if (roundGuardSticky == 0x4) result += result & 1; 143*7c3d14c8STreehugger Robot return fromRep(result); 144*7c3d14c8STreehugger Robot} 145