1 //===---- lib/fp_mul_impl.inc - floating point multiplication -----*- C -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements soft-float multiplication with the IEEE-754 default
10 // rounding (to nearest, ties to even).
12 //===----------------------------------------------------------------------===//
16 static __inline fp_t __mulXf3__(fp_t a, fp_t b) {
17 const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;
18 const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;
19 const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit;
21 rep_t aSignificand = toRep(a) & significandMask;
22 rep_t bSignificand = toRep(b) & significandMask;
25 // Detect if a or b is zero, denormal, infinity, or NaN.
26 if (aExponent - 1U >= maxExponent - 1U ||
27 bExponent - 1U >= maxExponent - 1U) {
29 const rep_t aAbs = toRep(a) & absMask;
30 const rep_t bAbs = toRep(b) & absMask;
32 // NaN * anything = qNaN
34 return fromRep(toRep(a) | quietBit);
35 // anything * NaN = qNaN
37 return fromRep(toRep(b) | quietBit);
40 // infinity * non-zero = +/- infinity
42 return fromRep(aAbs | productSign);
43 // infinity * zero = NaN
45 return fromRep(qnanRep);
49 // non-zero * infinity = +/- infinity
51 return fromRep(bAbs | productSign);
52 // zero * infinity = NaN
54 return fromRep(qnanRep);
57 // zero * anything = +/- zero
59 return fromRep(productSign);
60 // anything * zero = +/- zero
62 return fromRep(productSign);
64 // One or both of a or b is denormal. The other (if applicable) is a
65 // normal number. Renormalize one or both of a and b, and set scale to
66 // include the necessary exponent adjustment.
67 if (aAbs < implicitBit)
68 scale += normalize(&aSignificand);
69 if (bAbs < implicitBit)
70 scale += normalize(&bSignificand);
73 // Set the implicit significand bit. If we fell through from the
74 // denormal path it was already set by normalize( ), but setting it twice
75 // won't hurt anything.
76 aSignificand |= implicitBit;
77 bSignificand |= implicitBit;
79 // Perform a basic multiplication on the significands. One of them must be
80 // shifted beforehand to be aligned with the exponent.
81 rep_t productHi, productLo;
82 wideMultiply(aSignificand, bSignificand << exponentBits, &productHi,
85 int productExponent = aExponent + bExponent - exponentBias + scale;
87 // Normalize the significand and adjust the exponent if needed.
88 if (productHi & implicitBit)
91 wideLeftShift(&productHi, &productLo, 1);
93 // If we have overflowed the type, return +/- infinity.
94 if (productExponent >= maxExponent)
95 return fromRep(infRep | productSign);
97 if (productExponent <= 0) {
98 // The result is denormal before rounding.
100 // If the result is so small that it just underflows to zero, return
101 // zero with the appropriate sign. Mathematically, there is no need to
102 // handle this case separately, but we make it a special case to
103 // simplify the shift logic.
104 const unsigned int shift = REP_C(1) - (unsigned int)productExponent;
105 if (shift >= typeWidth)
106 return fromRep(productSign);
108 // Otherwise, shift the significand of the result so that the round
109 // bit is the high bit of productLo.
110 wideRightShiftWithSticky(&productHi, &productLo, shift);
112 // The result is normal before rounding. Insert the exponent.
113 productHi &= significandMask;
114 productHi |= (rep_t)productExponent << significandBits;
117 // Insert the sign of the result.
118 productHi |= productSign;
120 // Perform the final rounding. The final result may overflow to infinity,
121 // or underflow to zero, but those are the correct results in those cases.
122 // We use the default IEEE-754 round-to-nearest, ties-to-even rounding mode.
123 if (productLo > signBit)
125 if (productLo == signBit)
126 productHi += productHi & 1;
127 return fromRep(productHi);