fp_add_impl.inc (5980B)
1 //===----- lib/fp_add_impl.inc - floaing point addition -----------*- C -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements soft-float addition with the IEEE-754 default rounding 10 // (to nearest, ties to even). 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "fp_lib.h" 15 #include "fp_mode.h" 16 17 #define __addXf3__ _FP_NAME(__addXf3__) 18 19 #if defined SINGLE_PRECISION && !defined FP_ADD_SF_EMITTED 20 #define FP_ADD_SF_EMITTED 21 #define _FP_ADD_EMIT 1 22 #elif defined DOUBLE_PRECISION && !defined FP_ADD_DF_EMITTED 23 #define FP_ADD_DF_EMITTED 24 #define _FP_ADD_EMIT 1 25 #elif defined QUAD_PRECISION && !defined FP_ADD_TF_EMITTED 26 #define FP_ADD_TF_EMITTED 27 #define _FP_ADD_EMIT 1 28 #endif 29 30 #ifdef _FP_ADD_EMIT 31 #undef _FP_ADD_EMIT 32 33 static inline fp_t __addXf3__(fp_t a, fp_t b) { 34 rep_t aRep = toRep(a); 35 rep_t bRep = toRep(b); 36 const rep_t aAbs = aRep & absMask; 37 const rep_t bAbs = bRep & absMask; 38 39 // Detect if a or b is zero, infinity, or NaN. 40 if (aAbs - REP_C(1) >= infRep - REP_C(1) || 41 bAbs - REP_C(1) >= infRep - REP_C(1)) { 42 // NaN + anything = qNaN 43 if (aAbs > infRep) 44 return fromRep(toRep(a) | quietBit); 45 // anything + NaN = qNaN 46 if (bAbs > infRep) 47 return fromRep(toRep(b) | quietBit); 48 49 if (aAbs == infRep) { 50 // +/-infinity + -/+infinity = qNaN 51 if ((toRep(a) ^ toRep(b)) == signBit) 52 return fromRep(qnanRep); 53 // +/-infinity + anything remaining = +/- infinity 54 else 55 return a; 56 } 57 58 // anything remaining + +/-infinity = +/-infinity 59 if (bAbs == infRep) 60 return b; 61 62 // zero + anything = anything 63 if (!aAbs) { 64 // We need to get the sign right for zero + zero. 65 if (!bAbs) 66 return fromRep(toRep(a) & toRep(b)); 67 else 68 return b; 69 } 70 71 // anything + zero = anything 72 if (!bAbs) 73 return a; 74 } 75 76 // Swap a and b if necessary so that a has the larger absolute value. 77 if (bAbs > aAbs) { 78 const rep_t temp = aRep; 79 aRep = bRep; 80 bRep = temp; 81 } 82 83 // Extract the exponent and significand from the (possibly swapped) a and b. 84 int aExponent = aRep >> significandBits & maxExponent; 85 int bExponent = bRep >> significandBits & maxExponent; 86 rep_t aSignificand = aRep & significandMask; 87 rep_t bSignificand = bRep & significandMask; 88 89 // Normalize any denormals, and adjust the exponent accordingly. 90 if (aExponent == 0) 91 aExponent = normalize(&aSignificand); 92 if (bExponent == 0) 93 bExponent = normalize(&bSignificand); 94 95 // The sign of the result is the sign of the larger operand, a. If they 96 // have opposite signs, we are performing a subtraction. Otherwise, we 97 // perform addition. 98 const rep_t resultSign = aRep & signBit; 99 const bool subtraction = (aRep ^ bRep) & signBit; 100 101 // Shift the significands to give us round, guard and sticky, and set the 102 // implicit significand bit. If we fell through from the denormal path it 103 // was already set by normalize( ), but setting it twice won't hurt 104 // anything. 105 aSignificand = (aSignificand | implicitBit) << 3; 106 bSignificand = (bSignificand | implicitBit) << 3; 107 108 // Shift the significand of b by the difference in exponents, with a sticky 109 // bottom bit to get rounding correct. 110 const unsigned int align = aExponent - bExponent; 111 if (align) { 112 if (align < typeWidth) { 113 const bool sticky = (bSignificand << (typeWidth - align)) != 0; 114 bSignificand = bSignificand >> align | sticky; 115 } else { 116 bSignificand = 1; // Set the sticky bit. b is known to be non-zero. 117 } 118 } 119 if (subtraction) { 120 aSignificand -= bSignificand; 121 // If a == -b, return +zero. 122 if (aSignificand == 0) 123 return fromRep(0); 124 125 // If partial cancellation occured, we need to left-shift the result 126 // and adjust the exponent. 127 if (aSignificand < implicitBit << 3) { 128 const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3); 129 aSignificand <<= shift; 130 aExponent -= shift; 131 } 132 } else /* addition */ { 133 aSignificand += bSignificand; 134 135 // If the addition carried up, we need to right-shift the result and 136 // adjust the exponent. 137 if (aSignificand & implicitBit << 4) { 138 const bool sticky = aSignificand & 1; 139 aSignificand = aSignificand >> 1 | sticky; 140 aExponent += 1; 141 } 142 } 143 144 // If we have overflowed the type, return +/- infinity. 145 if (aExponent >= maxExponent) 146 return fromRep(infRep | resultSign); 147 148 if (aExponent <= 0) { 149 // The result is denormal before rounding. The exponent is zero and we 150 // need to shift the significand. 151 const int shift = 1 - aExponent; 152 const bool sticky = (aSignificand << (typeWidth - shift)) != 0; 153 aSignificand = aSignificand >> shift | sticky; 154 aExponent = 0; 155 } 156 157 // Low three bits are round, guard, and sticky. 158 const int roundGuardSticky = aSignificand & 0x7; 159 160 // Shift the significand into place, and mask off the implicit bit. 161 rep_t result = aSignificand >> 3 & significandMask; 162 163 // Insert the exponent and sign. 164 result |= (rep_t)aExponent << significandBits; 165 result |= resultSign; 166 167 // Perform the final rounding. The result may overflow to infinity, but 168 // that is the correct result in that case. 169 switch (__fe_getround()) { 170 case CRT_FE_TONEAREST: 171 if (roundGuardSticky > 0x4) 172 result++; 173 if (roundGuardSticky == 0x4) 174 result += result & 1; 175 break; 176 case CRT_FE_DOWNWARD: 177 if (resultSign && roundGuardSticky) result++; 178 break; 179 case CRT_FE_UPWARD: 180 if (!resultSign && roundGuardSticky) result++; 181 break; 182 case CRT_FE_TOWARDZERO: 183 break; 184 } 185 if (roundGuardSticky) 186 __fe_raise_inexact(); 187 return fromRep(result); 188 } 189 190 #endif // _FP_ADD_EMIT