fp_mul_impl.inc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. //===---- lib/fp_mul_impl.inc - floating point multiplication -----*- 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 multiplication with the IEEE-754 default
  10. // rounding (to nearest, ties to even).
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "fp_lib.h"
  14. static __inline fp_t __mulXf3__(fp_t a, fp_t b) {
  15. const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;
  16. const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;
  17. const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit;
  18. rep_t aSignificand = toRep(a) & significandMask;
  19. rep_t bSignificand = toRep(b) & significandMask;
  20. int scale = 0;
  21. // Detect if a or b is zero, denormal, infinity, or NaN.
  22. if (aExponent - 1U >= maxExponent - 1U ||
  23. bExponent - 1U >= maxExponent - 1U) {
  24. const rep_t aAbs = toRep(a) & absMask;
  25. const rep_t bAbs = toRep(b) & absMask;
  26. // NaN * anything = qNaN
  27. if (aAbs > infRep)
  28. return fromRep(toRep(a) | quietBit);
  29. // anything * NaN = qNaN
  30. if (bAbs > infRep)
  31. return fromRep(toRep(b) | quietBit);
  32. if (aAbs == infRep) {
  33. // infinity * non-zero = +/- infinity
  34. if (bAbs)
  35. return fromRep(aAbs | productSign);
  36. // infinity * zero = NaN
  37. else
  38. return fromRep(qnanRep);
  39. }
  40. if (bAbs == infRep) {
  41. // non-zero * infinity = +/- infinity
  42. if (aAbs)
  43. return fromRep(bAbs | productSign);
  44. // zero * infinity = NaN
  45. else
  46. return fromRep(qnanRep);
  47. }
  48. // zero * anything = +/- zero
  49. if (!aAbs)
  50. return fromRep(productSign);
  51. // anything * zero = +/- zero
  52. if (!bAbs)
  53. return fromRep(productSign);
  54. // One or both of a or b is denormal. The other (if applicable) is a
  55. // normal number. Renormalize one or both of a and b, and set scale to
  56. // include the necessary exponent adjustment.
  57. if (aAbs < implicitBit)
  58. scale += normalize(&aSignificand);
  59. if (bAbs < implicitBit)
  60. scale += normalize(&bSignificand);
  61. }
  62. // Set the implicit significand bit. If we fell through from the
  63. // denormal path it was already set by normalize( ), but setting it twice
  64. // won't hurt anything.
  65. aSignificand |= implicitBit;
  66. bSignificand |= implicitBit;
  67. // Perform a basic multiplication on the significands. One of them must be
  68. // shifted beforehand to be aligned with the exponent.
  69. rep_t productHi, productLo;
  70. wideMultiply(aSignificand, bSignificand << exponentBits, &productHi,
  71. &productLo);
  72. int productExponent = aExponent + bExponent - exponentBias + scale;
  73. // Normalize the significand and adjust the exponent if needed.
  74. if (productHi & implicitBit)
  75. productExponent++;
  76. else
  77. wideLeftShift(&productHi, &productLo, 1);
  78. // If we have overflowed the type, return +/- infinity.
  79. if (productExponent >= maxExponent)
  80. return fromRep(infRep | productSign);
  81. if (productExponent <= 0) {
  82. // The result is denormal before rounding.
  83. //
  84. // If the result is so small that it just underflows to zero, return
  85. // zero with the appropriate sign. Mathematically, there is no need to
  86. // handle this case separately, but we make it a special case to
  87. // simplify the shift logic.
  88. const unsigned int shift = REP_C(1) - (unsigned int)productExponent;
  89. if (shift >= typeWidth)
  90. return fromRep(productSign);
  91. // Otherwise, shift the significand of the result so that the round
  92. // bit is the high bit of productLo.
  93. wideRightShiftWithSticky(&productHi, &productLo, shift);
  94. } else {
  95. // The result is normal before rounding. Insert the exponent.
  96. productHi &= significandMask;
  97. productHi |= (rep_t)productExponent << significandBits;
  98. }
  99. // Insert the sign of the result.
  100. productHi |= productSign;
  101. // Perform the final rounding. The final result may overflow to infinity,
  102. // or underflow to zero, but those are the correct results in those cases.
  103. // We use the default IEEE-754 round-to-nearest, ties-to-even rounding mode.
  104. if (productLo > signBit)
  105. productHi++;
  106. if (productLo == signBit)
  107. productHi += productHi & 1;
  108. return fromRep(productHi);
  109. }