blob: 2ea197ff94f957561a3b3025529e1cc256715c3f [file] [log] [blame]
Stephen Canon5c6d2ec2010-07-01 17:58:24 +00001//===-- lib/muldf3.c - Double-precision multiplication ------------*- C -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements double-precision soft-float multiplication
11// with the IEEE-754 default rounding (to nearest, ties to even).
12//
13//===----------------------------------------------------------------------===//
Stephen Canone5086322010-07-01 15:52:42 +000014
15#define DOUBLE_PRECISION
16#include "fp_lib.h"
17
Stephen Canone5086322010-07-01 15:52:42 +000018#define loWord(a) (a & 0xffffffffU)
19#define hiWord(a) (a >> 32)
20
21// 64x64 -> 128 wide multiply for platforms that don't have such an operation;
Stephen Canon5c6d2ec2010-07-01 17:58:24 +000022// many 64-bit platforms have this operation, but they tend to have hardware
Stephen Canone5086322010-07-01 15:52:42 +000023// floating-point, so we don't bother with a special case for them here.
24static inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
25 // Each of the component 32x32 -> 64 products
26 const uint64_t plolo = loWord(a) * loWord(b);
27 const uint64_t plohi = loWord(a) * hiWord(b);
28 const uint64_t philo = hiWord(a) * loWord(b);
29 const uint64_t phihi = hiWord(a) * hiWord(b);
Stephen Canon5c6d2ec2010-07-01 17:58:24 +000030 // Sum terms that contribute to lo in a way that allows us to get the carry
Stephen Canone5086322010-07-01 15:52:42 +000031 const uint64_t r0 = loWord(plolo);
32 const uint64_t r1 = hiWord(plolo) + loWord(plohi) + loWord(philo);
33 *lo = r0 + (r1 << 32);
34 // Sum terms contributing to hi with the carry from lo
35 *hi = hiWord(plohi) + hiWord(philo) + hiWord(r1) + phihi;
36}
37
38fp_t __muldf3(fp_t a, fp_t b) {
39
40 const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;
41 const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;
42 const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit;
43
44 rep_t aSignificand = toRep(a) & significandMask;
45 rep_t bSignificand = toRep(b) & significandMask;
46 int scale = 0;
47
48 // Detect if a or b is zero, denormal, infinity, or NaN.
49 if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) {
50
51 const rep_t aAbs = toRep(a) & absMask;
52 const rep_t bAbs = toRep(b) & absMask;
53
54 // NaN * anything = qNaN
55 if (aAbs > infRep) return fromRep(toRep(a) | quietBit);
56 // anything * NaN = qNaN
57 if (bAbs > infRep) return fromRep(toRep(b) | quietBit);
58
59 if (aAbs == infRep) {
60 // infinity * non-zero = +/- infinity
61 if (bAbs) return fromRep(aAbs | productSign);
62 // infinity * zero = NaN
63 else return fromRep(qnanRep);
64 }
65
66 if (bAbs == infRep) {
67 // non-zero * infinity = +/- infinity
68 if (aAbs) return fromRep(bAbs | productSign);
69 // zero * infinity = NaN
70 else return fromRep(qnanRep);
71 }
72
73 // zero * anything = +/- zero
74 if (!aAbs) return fromRep(productSign);
75 // anything * zero = +/- zero
76 if (!bAbs) return fromRep(productSign);
77
78 // one or both of a or b is denormal, the other (if applicable) is a
79 // normal number. Renormalize one or both of a and b, and set scale to
80 // include the necessary exponent adjustment.
81 if (aAbs < implicitBit) scale += normalize(&aSignificand);
82 if (bAbs < implicitBit) scale += normalize(&bSignificand);
83 }
84
85 // Or in the implicit significand bit. (If we fell through from the
86 // denormal path it was already set by normalize( ), but setting it twice
87 // won't hurt anything.)
88 aSignificand |= implicitBit;
89 bSignificand |= implicitBit;
90
91 // Get the significand of a*b. Before multiplying the significands, shift
92 // one of them left to left-align it in the field. Thus, the product will
93 // have (exponentBits + 2) integral digits, all but two of which must be
94 // zero. Normalizing this result is just a conditional left-shift by one
95 // and bumping the exponent accordingly.
96 rep_t productHi, productLo;
97 wideMultiply(aSignificand, bSignificand << exponentBits,
98 &productHi, &productLo);
99
100 int productExponent = aExponent + bExponent - exponentBias + scale;
101
102 // Normalize the significand, adjust exponent if needed.
103 if (productHi & implicitBit) productExponent++;
104 else wideLeftShift(&productHi, &productLo, 1);
105
106 // If we have overflowed the type, return +/- infinity.
107 if (productExponent >= maxExponent) return fromRep(infRep | productSign);
108
109 if (productExponent <= 0) {
110 // Result is denormal before rounding
111 //
112 // If the result is so small that it just underflows to zero, return
113 // a zero of the appropriate sign. Mathematically there is no need to
114 // handle this case separately, but we make it a special case to
115 // simplify the shift logic.
116 const int shift = 1 - productExponent;
117 if (shift >= typeWidth) return fromRep(productSign);
118
119 // Otherwise, shift the significand of the result so that the round
120 // bit is the high bit of productLo.
121 wideRightShiftWithSticky(&productHi, &productLo, shift);
122 }
123
124 else {
125 // Result is normal before rounding; insert the exponent.
126 productHi &= significandMask;
127 productHi |= (rep_t)productExponent << significandBits;
128 }
129
130 // Insert the sign of the result:
131 productHi |= productSign;
132
133 // Final rounding. The final result may overflow to infinity, or underflow
134 // to zero, but those are the correct results in those cases. We use the
135 // default IEEE-754 round-to-nearest, ties-to-even rounding mode.
136 if (productLo > signBit) productHi++;
137 if (productLo == signBit) productHi += productHi & 1;
138 return fromRep(productHi);
139}