addsf3.c revision 222656
1222656Sed//===-- lib/addsf3.c - Single-precision addition ------------------*- C -*-===// 2214152Sed// 3214152Sed// The LLVM Compiler Infrastructure 4214152Sed// 5222656Sed// This file is dual licensed under the MIT and the University of Illinois Open 6222656Sed// Source Licenses. See LICENSE.TXT for details. 7214152Sed// 8214152Sed//===----------------------------------------------------------------------===// 9214152Sed// 10222656Sed// This file implements single-precision soft-float addition with the IEEE-754 11222656Sed// default rounding (to nearest, ties to even). 12214152Sed// 13214152Sed//===----------------------------------------------------------------------===// 14214152Sed 15222656Sed#include "abi.h" 16222656Sed 17214152Sed#define SINGLE_PRECISION 18214152Sed#include "fp_lib.h" 19214152Sed 20222656SedARM_EABI_FNALIAS(fadd, addsf3); 21222656Sed 22214152Sedfp_t __addsf3(fp_t a, fp_t b) { 23214152Sed 24214152Sed rep_t aRep = toRep(a); 25214152Sed rep_t bRep = toRep(b); 26214152Sed const rep_t aAbs = aRep & absMask; 27214152Sed const rep_t bAbs = bRep & absMask; 28214152Sed 29214152Sed // Detect if a or b is zero, infinity, or NaN. 30214152Sed if (aAbs - 1U >= infRep - 1U || bAbs - 1U >= infRep - 1U) { 31214152Sed 32214152Sed // NaN + anything = qNaN 33214152Sed if (aAbs > infRep) return fromRep(toRep(a) | quietBit); 34214152Sed // anything + NaN = qNaN 35214152Sed if (bAbs > infRep) return fromRep(toRep(b) | quietBit); 36214152Sed 37214152Sed if (aAbs == infRep) { 38214152Sed // +/-infinity + -/+infinity = qNaN 39214152Sed if ((toRep(a) ^ toRep(b)) == signBit) return fromRep(qnanRep); 40214152Sed // +/-infinity + anything remaining = +/- infinity 41214152Sed else return a; 42214152Sed } 43214152Sed 44214152Sed // anything remaining + +/-infinity = +/-infinity 45214152Sed if (bAbs == infRep) return b; 46214152Sed 47214152Sed // zero + anything = anything 48214152Sed if (!aAbs) { 49214152Sed // but we need to get the sign right for zero + zero 50214152Sed if (!bAbs) return fromRep(toRep(a) & toRep(b)); 51214152Sed else return b; 52214152Sed } 53214152Sed 54214152Sed // anything + zero = anything 55214152Sed if (!bAbs) return a; 56214152Sed } 57214152Sed 58214152Sed // Swap a and b if necessary so that a has the larger absolute value. 59214152Sed if (bAbs > aAbs) { 60214152Sed const rep_t temp = aRep; 61214152Sed aRep = bRep; 62214152Sed bRep = temp; 63214152Sed } 64214152Sed 65214152Sed // Extract the exponent and significand from the (possibly swapped) a and b. 66214152Sed int aExponent = aRep >> significandBits & maxExponent; 67214152Sed int bExponent = bRep >> significandBits & maxExponent; 68214152Sed rep_t aSignificand = aRep & significandMask; 69214152Sed rep_t bSignificand = bRep & significandMask; 70214152Sed 71214152Sed // Normalize any denormals, and adjust the exponent accordingly. 72214152Sed if (aExponent == 0) aExponent = normalize(&aSignificand); 73214152Sed if (bExponent == 0) bExponent = normalize(&bSignificand); 74214152Sed 75214152Sed // The sign of the result is the sign of the larger operand, a. If they 76214152Sed // have opposite signs, we are performing a subtraction; otherwise addition. 77214152Sed const rep_t resultSign = aRep & signBit; 78214152Sed const bool subtraction = (aRep ^ bRep) & signBit; 79214152Sed 80214152Sed // Shift the significands to give us round, guard and sticky, and or in the 81214152Sed // implicit significand bit. (If we fell through from the denormal path it 82214152Sed // was already set by normalize( ), but setting it twice won't hurt 83214152Sed // anything.) 84214152Sed aSignificand = (aSignificand | implicitBit) << 3; 85214152Sed bSignificand = (bSignificand | implicitBit) << 3; 86214152Sed 87214152Sed // Shift the significand of b by the difference in exponents, with a sticky 88214152Sed // bottom bit to get rounding correct. 89214152Sed const int align = aExponent - bExponent; 90214152Sed if (align) { 91214152Sed if (align < typeWidth) { 92214152Sed const bool sticky = bSignificand << (typeWidth - align); 93214152Sed bSignificand = bSignificand >> align | sticky; 94214152Sed } else { 95214152Sed bSignificand = 1; // sticky; b is known to be non-zero. 96214152Sed } 97214152Sed } 98214152Sed 99214152Sed if (subtraction) { 100214152Sed aSignificand -= bSignificand; 101214152Sed 102214152Sed // If a == -b, return +zero. 103214152Sed if (aSignificand == 0) return fromRep(0); 104214152Sed 105214152Sed // If partial cancellation occured, we need to left-shift the result 106214152Sed // and adjust the exponent: 107214152Sed if (aSignificand < implicitBit << 3) { 108214152Sed const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3); 109214152Sed aSignificand <<= shift; 110214152Sed aExponent -= shift; 111214152Sed } 112214152Sed } 113214152Sed 114214152Sed else /* addition */ { 115214152Sed aSignificand += bSignificand; 116214152Sed 117214152Sed // If the addition carried up, we need to right-shift the result and 118214152Sed // adjust the exponent: 119214152Sed if (aSignificand & implicitBit << 4) { 120214152Sed const bool sticky = aSignificand & 1; 121214152Sed aSignificand = aSignificand >> 1 | sticky; 122214152Sed aExponent += 1; 123214152Sed } 124214152Sed } 125214152Sed 126214152Sed // If we have overflowed the type, return +/- infinity: 127214152Sed if (aExponent >= maxExponent) return fromRep(infRep | resultSign); 128214152Sed 129214152Sed if (aExponent <= 0) { 130214152Sed // Result is denormal before rounding; the exponent is zero and we 131214152Sed // need to shift the significand. 132214152Sed const int shift = 1 - aExponent; 133214152Sed const bool sticky = aSignificand << (typeWidth - shift); 134214152Sed aSignificand = aSignificand >> shift | sticky; 135214152Sed aExponent = 0; 136214152Sed } 137214152Sed 138214152Sed // Low three bits are round, guard, and sticky. 139214152Sed const int roundGuardSticky = aSignificand & 0x7; 140214152Sed 141214152Sed // Shift the significand into place, and mask off the implicit bit. 142214152Sed rep_t result = aSignificand >> 3 & significandMask; 143214152Sed 144214152Sed // Insert the exponent and sign. 145214152Sed result |= (rep_t)aExponent << significandBits; 146214152Sed result |= resultSign; 147214152Sed 148214152Sed // Final rounding. The result may overflow to infinity, but that is the 149214152Sed // correct result in that case. 150214152Sed if (roundGuardSticky > 0x4) result++; 151214152Sed if (roundGuardSticky == 0x4) result += result & 1; 152214152Sed return fromRep(result); 153214152Sed} 154