1f22ef01cSRoman Divacky //===-- APFloat.cpp - Implement APFloat class -----------------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file implements a class to represent arbitrary precision floating
11f22ef01cSRoman Divacky // point values and provide a variety of arithmetic operations on them.
12f22ef01cSRoman Divacky //
13f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
14f22ef01cSRoman Divacky 
15f22ef01cSRoman Divacky #include "llvm/ADT/APFloat.h"
1617a519f9SDimitry Andric #include "llvm/ADT/APSInt.h"
173ca95b02SDimitry Andric #include "llvm/ADT/ArrayRef.h"
18f22ef01cSRoman Divacky #include "llvm/ADT/FoldingSet.h"
19dff0c46cSDimitry Andric #include "llvm/ADT/Hashing.h"
20139f7f9bSDimitry Andric #include "llvm/ADT/StringExtras.h"
21dff0c46cSDimitry Andric #include "llvm/ADT/StringRef.h"
22*4ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
23d88c1a5aSDimitry Andric #include "llvm/Support/Debug.h"
24f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
25f22ef01cSRoman Divacky #include "llvm/Support/MathExtras.h"
26d88c1a5aSDimitry Andric #include "llvm/Support/raw_ostream.h"
27f22ef01cSRoman Divacky #include <cstring>
28139f7f9bSDimitry Andric #include <limits.h>
29f22ef01cSRoman Divacky 
307a7e6055SDimitry Andric #define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL)                             \
317a7e6055SDimitry Andric   do {                                                                         \
327a7e6055SDimitry Andric     if (usesLayout<IEEEFloat>(getSemantics()))                                 \
337a7e6055SDimitry Andric       return U.IEEE.METHOD_CALL;                                               \
347a7e6055SDimitry Andric     if (usesLayout<DoubleAPFloat>(getSemantics()))                             \
357a7e6055SDimitry Andric       return U.Double.METHOD_CALL;                                             \
367a7e6055SDimitry Andric     llvm_unreachable("Unexpected semantics");                                  \
377a7e6055SDimitry Andric   } while (false)
387a7e6055SDimitry Andric 
39f22ef01cSRoman Divacky using namespace llvm;
40f22ef01cSRoman Divacky 
41f785676fSDimitry Andric /// A macro used to combine two fcCategory enums into one key which can be used
42f785676fSDimitry Andric /// in a switch statement to classify how the interaction of two APFloat's
43f785676fSDimitry Andric /// categories affects an operation.
44f785676fSDimitry Andric ///
45f785676fSDimitry Andric /// TODO: If clang source code is ever allowed to use constexpr in its own
46f785676fSDimitry Andric /// codebase, change this into a static inline function.
47f785676fSDimitry Andric #define PackCategoriesIntoKey(_lhs, _rhs) ((_lhs) * 4 + (_rhs))
48f22ef01cSRoman Divacky 
49f22ef01cSRoman Divacky /* Assumed in hexadecimal significand parsing, and conversion to
50f22ef01cSRoman Divacky    hexadecimal strings.  */
51edd7eaddSDimitry Andric static_assert(APFloatBase::integerPartWidth % 4 == 0, "Part width must be divisible by 4!");
52f22ef01cSRoman Divacky 
53f22ef01cSRoman Divacky namespace llvm {
54f22ef01cSRoman Divacky   /* Represents floating point arithmetic semantics.  */
55f22ef01cSRoman Divacky   struct fltSemantics {
56f22ef01cSRoman Divacky     /* The largest E such that 2^E is representable; this matches the
57f22ef01cSRoman Divacky        definition of IEEE 754.  */
58d88c1a5aSDimitry Andric     APFloatBase::ExponentType maxExponent;
59f22ef01cSRoman Divacky 
60f22ef01cSRoman Divacky     /* The smallest E such that 2^E is a normalized number; this
61f22ef01cSRoman Divacky        matches the definition of IEEE 754.  */
62d88c1a5aSDimitry Andric     APFloatBase::ExponentType minExponent;
63f22ef01cSRoman Divacky 
64f22ef01cSRoman Divacky     /* Number of bits in the significand.  This includes the integer
65f22ef01cSRoman Divacky        bit.  */
66f22ef01cSRoman Divacky     unsigned int precision;
67875ed548SDimitry Andric 
68875ed548SDimitry Andric     /* Number of bits actually used in the semantics. */
69875ed548SDimitry Andric     unsigned int sizeInBits;
70f22ef01cSRoman Divacky   };
71f22ef01cSRoman Divacky 
72d88c1a5aSDimitry Andric   static const fltSemantics semIEEEhalf = {15, -14, 11, 16};
73d88c1a5aSDimitry Andric   static const fltSemantics semIEEEsingle = {127, -126, 24, 32};
74d88c1a5aSDimitry Andric   static const fltSemantics semIEEEdouble = {1023, -1022, 53, 64};
75d88c1a5aSDimitry Andric   static const fltSemantics semIEEEquad = {16383, -16382, 113, 128};
76d88c1a5aSDimitry Andric   static const fltSemantics semX87DoubleExtended = {16383, -16382, 64, 80};
77d88c1a5aSDimitry Andric   static const fltSemantics semBogus = {0, 0, 0, 0};
78f22ef01cSRoman Divacky 
797a7e6055SDimitry Andric   /* The IBM double-double semantics. Such a number consists of a pair of IEEE
807a7e6055SDimitry Andric      64-bit doubles (Hi, Lo), where |Hi| > |Lo|, and if normal,
817a7e6055SDimitry Andric      (double)(Hi + Lo) == Hi. The numeric value it's modeling is Hi + Lo.
827a7e6055SDimitry Andric      Therefore it has two 53-bit mantissa parts that aren't necessarily adjacent
837a7e6055SDimitry Andric      to each other, and two 11-bit exponents.
848e0f8b8cSDimitry Andric 
858e0f8b8cSDimitry Andric      Note: we need to make the value different from semBogus as otherwise
868e0f8b8cSDimitry Andric      an unsafe optimization may collapse both values to a single address,
878e0f8b8cSDimitry Andric      and we heavily rely on them having distinct addresses.             */
888e0f8b8cSDimitry Andric   static const fltSemantics semPPCDoubleDouble = {-1, 0, 0, 0};
89d88c1a5aSDimitry Andric 
907a7e6055SDimitry Andric   /* These are legacy semantics for the fallback, inaccrurate implementation of
917a7e6055SDimitry Andric      IBM double-double, if the accurate semPPCDoubleDouble doesn't handle the
927a7e6055SDimitry Andric      operation. It's equivalent to having an IEEE number with consecutive 106
937a7e6055SDimitry Andric      bits of mantissa and 11 bits of exponent.
94d88c1a5aSDimitry Andric 
957a7e6055SDimitry Andric      It's not equivalent to IBM double-double. For example, a legit IBM
967a7e6055SDimitry Andric      double-double, 1 + epsilon:
977a7e6055SDimitry Andric 
987a7e6055SDimitry Andric        1 + epsilon = 1 + (1 >> 1076)
997a7e6055SDimitry Andric 
1007a7e6055SDimitry Andric      is not representable by a consecutive 106 bits of mantissa.
1017a7e6055SDimitry Andric 
1027a7e6055SDimitry Andric      Currently, these semantics are used in the following way:
1037a7e6055SDimitry Andric 
1047a7e6055SDimitry Andric        semPPCDoubleDouble -> (IEEEdouble, IEEEdouble) ->
1057a7e6055SDimitry Andric        (64-bit APInt, 64-bit APInt) -> (128-bit APInt) ->
1067a7e6055SDimitry Andric        semPPCDoubleDoubleLegacy -> IEEE operations
1077a7e6055SDimitry Andric 
1087a7e6055SDimitry Andric      We use bitcastToAPInt() to get the bit representation (in APInt) of the
1097a7e6055SDimitry Andric      underlying IEEEdouble, then use the APInt constructor to construct the
1107a7e6055SDimitry Andric      legacy IEEE float.
1117a7e6055SDimitry Andric 
1127a7e6055SDimitry Andric      TODO: Implement all operations in semPPCDoubleDouble, and delete these
1137a7e6055SDimitry Andric      semantics.  */
1147a7e6055SDimitry Andric   static const fltSemantics semPPCDoubleDoubleLegacy = {1023, -1022 + 53,
1157a7e6055SDimitry Andric                                                         53 + 53, 128};
116d88c1a5aSDimitry Andric 
IEEEhalf()117d88c1a5aSDimitry Andric   const fltSemantics &APFloatBase::IEEEhalf() {
118d88c1a5aSDimitry Andric     return semIEEEhalf;
119d88c1a5aSDimitry Andric   }
IEEEsingle()120d88c1a5aSDimitry Andric   const fltSemantics &APFloatBase::IEEEsingle() {
121d88c1a5aSDimitry Andric     return semIEEEsingle;
122d88c1a5aSDimitry Andric   }
IEEEdouble()123d88c1a5aSDimitry Andric   const fltSemantics &APFloatBase::IEEEdouble() {
124d88c1a5aSDimitry Andric     return semIEEEdouble;
125d88c1a5aSDimitry Andric   }
IEEEquad()126d88c1a5aSDimitry Andric   const fltSemantics &APFloatBase::IEEEquad() {
127d88c1a5aSDimitry Andric     return semIEEEquad;
128d88c1a5aSDimitry Andric   }
x87DoubleExtended()129d88c1a5aSDimitry Andric   const fltSemantics &APFloatBase::x87DoubleExtended() {
130d88c1a5aSDimitry Andric     return semX87DoubleExtended;
131d88c1a5aSDimitry Andric   }
Bogus()132d88c1a5aSDimitry Andric   const fltSemantics &APFloatBase::Bogus() {
133d88c1a5aSDimitry Andric     return semBogus;
134d88c1a5aSDimitry Andric   }
PPCDoubleDouble()135d88c1a5aSDimitry Andric   const fltSemantics &APFloatBase::PPCDoubleDouble() {
136d88c1a5aSDimitry Andric     return semPPCDoubleDouble;
137d88c1a5aSDimitry Andric   }
138f22ef01cSRoman Divacky 
139f22ef01cSRoman Divacky   /* A tight upper bound on number of parts required to hold the value
140f22ef01cSRoman Divacky      pow(5, power) is
141f22ef01cSRoman Divacky 
142f22ef01cSRoman Divacky        power * 815 / (351 * integerPartWidth) + 1
143f22ef01cSRoman Divacky 
144f22ef01cSRoman Divacky      However, whilst the result may require only this many parts,
145f22ef01cSRoman Divacky      because we are multiplying two values to get it, the
146f22ef01cSRoman Divacky      multiplication may require an extra part with the excess part
147f22ef01cSRoman Divacky      being zero (consider the trivial case of 1 * 1, tcFullMultiply
148f22ef01cSRoman Divacky      requires two parts to hold the single-part result).  So we add an
149f22ef01cSRoman Divacky      extra one to guarantee enough space whilst multiplying.  */
150f22ef01cSRoman Divacky   const unsigned int maxExponent = 16383;
151f22ef01cSRoman Divacky   const unsigned int maxPrecision = 113;
152f22ef01cSRoman Divacky   const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1;
153edd7eaddSDimitry Andric   const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 815) / (351 * APFloatBase::integerPartWidth));
154d88c1a5aSDimitry Andric 
semanticsPrecision(const fltSemantics & semantics)155d88c1a5aSDimitry Andric   unsigned int APFloatBase::semanticsPrecision(const fltSemantics &semantics) {
156d88c1a5aSDimitry Andric     return semantics.precision;
157d88c1a5aSDimitry Andric   }
158d88c1a5aSDimitry Andric   APFloatBase::ExponentType
semanticsMaxExponent(const fltSemantics & semantics)159d88c1a5aSDimitry Andric   APFloatBase::semanticsMaxExponent(const fltSemantics &semantics) {
160d88c1a5aSDimitry Andric     return semantics.maxExponent;
161d88c1a5aSDimitry Andric   }
162d88c1a5aSDimitry Andric   APFloatBase::ExponentType
semanticsMinExponent(const fltSemantics & semantics)163d88c1a5aSDimitry Andric   APFloatBase::semanticsMinExponent(const fltSemantics &semantics) {
164d88c1a5aSDimitry Andric     return semantics.minExponent;
165d88c1a5aSDimitry Andric   }
semanticsSizeInBits(const fltSemantics & semantics)166d88c1a5aSDimitry Andric   unsigned int APFloatBase::semanticsSizeInBits(const fltSemantics &semantics) {
167d88c1a5aSDimitry Andric     return semantics.sizeInBits;
168d88c1a5aSDimitry Andric   }
169d88c1a5aSDimitry Andric 
getSizeInBits(const fltSemantics & Sem)170d88c1a5aSDimitry Andric   unsigned APFloatBase::getSizeInBits(const fltSemantics &Sem) {
171d88c1a5aSDimitry Andric     return Sem.sizeInBits;
1723dac3a9bSDimitry Andric }
173f22ef01cSRoman Divacky 
174f22ef01cSRoman Divacky /* A bunch of private, handy routines.  */
175f22ef01cSRoman Divacky 
176f22ef01cSRoman Divacky static inline unsigned int
partCountForBits(unsigned int bits)177f22ef01cSRoman Divacky partCountForBits(unsigned int bits)
178f22ef01cSRoman Divacky {
179edd7eaddSDimitry Andric   return ((bits) + APFloatBase::integerPartWidth - 1) / APFloatBase::integerPartWidth;
180f22ef01cSRoman Divacky }
181f22ef01cSRoman Divacky 
182f22ef01cSRoman Divacky /* Returns 0U-9U.  Return values >= 10U are not digits.  */
183f22ef01cSRoman Divacky static inline unsigned int
decDigitValue(unsigned int c)184f22ef01cSRoman Divacky decDigitValue(unsigned int c)
185f22ef01cSRoman Divacky {
186f22ef01cSRoman Divacky   return c - '0';
187f22ef01cSRoman Divacky }
188f22ef01cSRoman Divacky 
189f22ef01cSRoman Divacky /* Return the value of a decimal exponent of the form
190f22ef01cSRoman Divacky    [+-]ddddddd.
191f22ef01cSRoman Divacky 
192f22ef01cSRoman Divacky    If the exponent overflows, returns a large exponent with the
193f22ef01cSRoman Divacky    appropriate sign.  */
194f22ef01cSRoman Divacky static int
readExponent(StringRef::iterator begin,StringRef::iterator end)195f22ef01cSRoman Divacky readExponent(StringRef::iterator begin, StringRef::iterator end)
196f22ef01cSRoman Divacky {
197f22ef01cSRoman Divacky   bool isNegative;
198f22ef01cSRoman Divacky   unsigned int absExponent;
199f22ef01cSRoman Divacky   const unsigned int overlargeExponent = 24000;  /* FIXME.  */
200f22ef01cSRoman Divacky   StringRef::iterator p = begin;
201f22ef01cSRoman Divacky 
202f22ef01cSRoman Divacky   assert(p != end && "Exponent has no digits");
203f22ef01cSRoman Divacky 
204f22ef01cSRoman Divacky   isNegative = (*p == '-');
205f22ef01cSRoman Divacky   if (*p == '-' || *p == '+') {
206f22ef01cSRoman Divacky     p++;
207f22ef01cSRoman Divacky     assert(p != end && "Exponent has no digits");
208f22ef01cSRoman Divacky   }
209f22ef01cSRoman Divacky 
210f22ef01cSRoman Divacky   absExponent = decDigitValue(*p++);
211f22ef01cSRoman Divacky   assert(absExponent < 10U && "Invalid character in exponent");
212f22ef01cSRoman Divacky 
213f22ef01cSRoman Divacky   for (; p != end; ++p) {
214f22ef01cSRoman Divacky     unsigned int value;
215f22ef01cSRoman Divacky 
216f22ef01cSRoman Divacky     value = decDigitValue(*p);
217f22ef01cSRoman Divacky     assert(value < 10U && "Invalid character in exponent");
218f22ef01cSRoman Divacky 
219f22ef01cSRoman Divacky     value += absExponent * 10;
220f22ef01cSRoman Divacky     if (absExponent >= overlargeExponent) {
221f22ef01cSRoman Divacky       absExponent = overlargeExponent;
222e580952dSDimitry Andric       p = end;  /* outwit assert below */
223f22ef01cSRoman Divacky       break;
224f22ef01cSRoman Divacky     }
225f22ef01cSRoman Divacky     absExponent = value;
226f22ef01cSRoman Divacky   }
227f22ef01cSRoman Divacky 
228f22ef01cSRoman Divacky   assert(p == end && "Invalid exponent in exponent");
229f22ef01cSRoman Divacky 
230f22ef01cSRoman Divacky   if (isNegative)
231f22ef01cSRoman Divacky     return -(int) absExponent;
232f22ef01cSRoman Divacky   else
233f22ef01cSRoman Divacky     return (int) absExponent;
234f22ef01cSRoman Divacky }
235f22ef01cSRoman Divacky 
236f22ef01cSRoman Divacky /* This is ugly and needs cleaning up, but I don't immediately see
237f22ef01cSRoman Divacky    how whilst remaining safe.  */
238f22ef01cSRoman Divacky static int
totalExponent(StringRef::iterator p,StringRef::iterator end,int exponentAdjustment)239f22ef01cSRoman Divacky totalExponent(StringRef::iterator p, StringRef::iterator end,
240f22ef01cSRoman Divacky               int exponentAdjustment)
241f22ef01cSRoman Divacky {
242f22ef01cSRoman Divacky   int unsignedExponent;
243f22ef01cSRoman Divacky   bool negative, overflow;
2442754fe60SDimitry Andric   int exponent = 0;
245f22ef01cSRoman Divacky 
246f22ef01cSRoman Divacky   assert(p != end && "Exponent has no digits");
247f22ef01cSRoman Divacky 
248f22ef01cSRoman Divacky   negative = *p == '-';
249f22ef01cSRoman Divacky   if (*p == '-' || *p == '+') {
250f22ef01cSRoman Divacky     p++;
251f22ef01cSRoman Divacky     assert(p != end && "Exponent has no digits");
252f22ef01cSRoman Divacky   }
253f22ef01cSRoman Divacky 
254f22ef01cSRoman Divacky   unsignedExponent = 0;
255f22ef01cSRoman Divacky   overflow = false;
256f22ef01cSRoman Divacky   for (; p != end; ++p) {
257f22ef01cSRoman Divacky     unsigned int value;
258f22ef01cSRoman Divacky 
259f22ef01cSRoman Divacky     value = decDigitValue(*p);
260f22ef01cSRoman Divacky     assert(value < 10U && "Invalid character in exponent");
261f22ef01cSRoman Divacky 
262f22ef01cSRoman Divacky     unsignedExponent = unsignedExponent * 10 + value;
2633861d79fSDimitry Andric     if (unsignedExponent > 32767) {
264f22ef01cSRoman Divacky       overflow = true;
2653861d79fSDimitry Andric       break;
2663861d79fSDimitry Andric     }
267f22ef01cSRoman Divacky   }
268f22ef01cSRoman Divacky 
2692754fe60SDimitry Andric   if (exponentAdjustment > 32767 || exponentAdjustment < -32768)
270f22ef01cSRoman Divacky     overflow = true;
271f22ef01cSRoman Divacky 
272f22ef01cSRoman Divacky   if (!overflow) {
273f22ef01cSRoman Divacky     exponent = unsignedExponent;
274f22ef01cSRoman Divacky     if (negative)
275f22ef01cSRoman Divacky       exponent = -exponent;
276f22ef01cSRoman Divacky     exponent += exponentAdjustment;
2772754fe60SDimitry Andric     if (exponent > 32767 || exponent < -32768)
278f22ef01cSRoman Divacky       overflow = true;
279f22ef01cSRoman Divacky   }
280f22ef01cSRoman Divacky 
281f22ef01cSRoman Divacky   if (overflow)
2822754fe60SDimitry Andric     exponent = negative ? -32768: 32767;
283f22ef01cSRoman Divacky 
284f22ef01cSRoman Divacky   return exponent;
285f22ef01cSRoman Divacky }
286f22ef01cSRoman Divacky 
287f22ef01cSRoman Divacky static StringRef::iterator
skipLeadingZeroesAndAnyDot(StringRef::iterator begin,StringRef::iterator end,StringRef::iterator * dot)288f22ef01cSRoman Divacky skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end,
289f22ef01cSRoman Divacky                            StringRef::iterator *dot)
290f22ef01cSRoman Divacky {
291f22ef01cSRoman Divacky   StringRef::iterator p = begin;
292f22ef01cSRoman Divacky   *dot = end;
29339d628a0SDimitry Andric   while (p != end && *p == '0')
294f22ef01cSRoman Divacky     p++;
295f22ef01cSRoman Divacky 
29639d628a0SDimitry Andric   if (p != end && *p == '.') {
297f22ef01cSRoman Divacky     *dot = p++;
298f22ef01cSRoman Divacky 
299f22ef01cSRoman Divacky     assert(end - begin != 1 && "Significand has no digits");
300f22ef01cSRoman Divacky 
30139d628a0SDimitry Andric     while (p != end && *p == '0')
302f22ef01cSRoman Divacky       p++;
303f22ef01cSRoman Divacky   }
304f22ef01cSRoman Divacky 
305f22ef01cSRoman Divacky   return p;
306f22ef01cSRoman Divacky }
307f22ef01cSRoman Divacky 
308f22ef01cSRoman Divacky /* Given a normal decimal floating point number of the form
309f22ef01cSRoman Divacky 
310f22ef01cSRoman Divacky      dddd.dddd[eE][+-]ddd
311f22ef01cSRoman Divacky 
312f22ef01cSRoman Divacky    where the decimal point and exponent are optional, fill out the
313f22ef01cSRoman Divacky    structure D.  Exponent is appropriate if the significand is
314f22ef01cSRoman Divacky    treated as an integer, and normalizedExponent if the significand
315f22ef01cSRoman Divacky    is taken to have the decimal point after a single leading
316f22ef01cSRoman Divacky    non-zero digit.
317f22ef01cSRoman Divacky 
318f22ef01cSRoman Divacky    If the value is zero, V->firstSigDigit points to a non-digit, and
319f22ef01cSRoman Divacky    the return exponent is zero.
320f22ef01cSRoman Divacky */
321f22ef01cSRoman Divacky struct decimalInfo {
322f22ef01cSRoman Divacky   const char *firstSigDigit;
323f22ef01cSRoman Divacky   const char *lastSigDigit;
324f22ef01cSRoman Divacky   int exponent;
325f22ef01cSRoman Divacky   int normalizedExponent;
326f22ef01cSRoman Divacky };
327f22ef01cSRoman Divacky 
328f22ef01cSRoman Divacky static void
interpretDecimal(StringRef::iterator begin,StringRef::iterator end,decimalInfo * D)329f22ef01cSRoman Divacky interpretDecimal(StringRef::iterator begin, StringRef::iterator end,
330f22ef01cSRoman Divacky                  decimalInfo *D)
331f22ef01cSRoman Divacky {
332f22ef01cSRoman Divacky   StringRef::iterator dot = end;
333f22ef01cSRoman Divacky   StringRef::iterator p = skipLeadingZeroesAndAnyDot (begin, end, &dot);
334f22ef01cSRoman Divacky 
335f22ef01cSRoman Divacky   D->firstSigDigit = p;
336f22ef01cSRoman Divacky   D->exponent = 0;
337f22ef01cSRoman Divacky   D->normalizedExponent = 0;
338f22ef01cSRoman Divacky 
339f22ef01cSRoman Divacky   for (; p != end; ++p) {
340f22ef01cSRoman Divacky     if (*p == '.') {
341f22ef01cSRoman Divacky       assert(dot == end && "String contains multiple dots");
342f22ef01cSRoman Divacky       dot = p++;
343f22ef01cSRoman Divacky       if (p == end)
344f22ef01cSRoman Divacky         break;
345f22ef01cSRoman Divacky     }
346f22ef01cSRoman Divacky     if (decDigitValue(*p) >= 10U)
347f22ef01cSRoman Divacky       break;
348f22ef01cSRoman Divacky   }
349f22ef01cSRoman Divacky 
350f22ef01cSRoman Divacky   if (p != end) {
351f22ef01cSRoman Divacky     assert((*p == 'e' || *p == 'E') && "Invalid character in significand");
352f22ef01cSRoman Divacky     assert(p != begin && "Significand has no digits");
353f22ef01cSRoman Divacky     assert((dot == end || p - begin != 1) && "Significand has no digits");
354f22ef01cSRoman Divacky 
355f22ef01cSRoman Divacky     /* p points to the first non-digit in the string */
356f22ef01cSRoman Divacky     D->exponent = readExponent(p + 1, end);
357f22ef01cSRoman Divacky 
358f22ef01cSRoman Divacky     /* Implied decimal point?  */
359f22ef01cSRoman Divacky     if (dot == end)
360f22ef01cSRoman Divacky       dot = p;
361f22ef01cSRoman Divacky   }
362f22ef01cSRoman Divacky 
363f22ef01cSRoman Divacky   /* If number is all zeroes accept any exponent.  */
364f22ef01cSRoman Divacky   if (p != D->firstSigDigit) {
365f22ef01cSRoman Divacky     /* Drop insignificant trailing zeroes.  */
366f22ef01cSRoman Divacky     if (p != begin) {
367f22ef01cSRoman Divacky       do
368f22ef01cSRoman Divacky         do
369f22ef01cSRoman Divacky           p--;
370f22ef01cSRoman Divacky         while (p != begin && *p == '0');
371f22ef01cSRoman Divacky       while (p != begin && *p == '.');
372f22ef01cSRoman Divacky     }
373f22ef01cSRoman Divacky 
374f22ef01cSRoman Divacky     /* Adjust the exponents for any decimal point.  */
375f785676fSDimitry Andric     D->exponent += static_cast<APFloat::ExponentType>((dot - p) - (dot > p));
376f22ef01cSRoman Divacky     D->normalizedExponent = (D->exponent +
377f785676fSDimitry Andric               static_cast<APFloat::ExponentType>((p - D->firstSigDigit)
378f22ef01cSRoman Divacky                                       - (dot > D->firstSigDigit && dot < p)));
379f22ef01cSRoman Divacky   }
380f22ef01cSRoman Divacky 
381f22ef01cSRoman Divacky   D->lastSigDigit = p;
382f22ef01cSRoman Divacky }
383f22ef01cSRoman Divacky 
384f22ef01cSRoman Divacky /* Return the trailing fraction of a hexadecimal number.
385f22ef01cSRoman Divacky    DIGITVALUE is the first hex digit of the fraction, P points to
386f22ef01cSRoman Divacky    the next digit.  */
387f22ef01cSRoman Divacky static lostFraction
trailingHexadecimalFraction(StringRef::iterator p,StringRef::iterator end,unsigned int digitValue)388f22ef01cSRoman Divacky trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end,
389f22ef01cSRoman Divacky                             unsigned int digitValue)
390f22ef01cSRoman Divacky {
391f22ef01cSRoman Divacky   unsigned int hexDigit;
392f22ef01cSRoman Divacky 
393f22ef01cSRoman Divacky   /* If the first trailing digit isn't 0 or 8 we can work out the
394f22ef01cSRoman Divacky      fraction immediately.  */
395f22ef01cSRoman Divacky   if (digitValue > 8)
396f22ef01cSRoman Divacky     return lfMoreThanHalf;
397f22ef01cSRoman Divacky   else if (digitValue < 8 && digitValue > 0)
398f22ef01cSRoman Divacky     return lfLessThanHalf;
399f22ef01cSRoman Divacky 
400f785676fSDimitry Andric   // Otherwise we need to find the first non-zero digit.
401f785676fSDimitry Andric   while (p != end && (*p == '0' || *p == '.'))
402f22ef01cSRoman Divacky     p++;
403f22ef01cSRoman Divacky 
404f22ef01cSRoman Divacky   assert(p != end && "Invalid trailing hexadecimal fraction!");
405f22ef01cSRoman Divacky 
406f22ef01cSRoman Divacky   hexDigit = hexDigitValue(*p);
407f22ef01cSRoman Divacky 
408f22ef01cSRoman Divacky   /* If we ran off the end it is exactly zero or one-half, otherwise
409f22ef01cSRoman Divacky      a little more.  */
410f22ef01cSRoman Divacky   if (hexDigit == -1U)
411f22ef01cSRoman Divacky     return digitValue == 0 ? lfExactlyZero: lfExactlyHalf;
412f22ef01cSRoman Divacky   else
413f22ef01cSRoman Divacky     return digitValue == 0 ? lfLessThanHalf: lfMoreThanHalf;
414f22ef01cSRoman Divacky }
415f22ef01cSRoman Divacky 
416f22ef01cSRoman Divacky /* Return the fraction lost were a bignum truncated losing the least
417f22ef01cSRoman Divacky    significant BITS bits.  */
418f22ef01cSRoman Divacky static lostFraction
lostFractionThroughTruncation(const APFloatBase::integerPart * parts,unsigned int partCount,unsigned int bits)419edd7eaddSDimitry Andric lostFractionThroughTruncation(const APFloatBase::integerPart *parts,
420f22ef01cSRoman Divacky                               unsigned int partCount,
421f22ef01cSRoman Divacky                               unsigned int bits)
422f22ef01cSRoman Divacky {
423f22ef01cSRoman Divacky   unsigned int lsb;
424f22ef01cSRoman Divacky 
425f22ef01cSRoman Divacky   lsb = APInt::tcLSB(parts, partCount);
426f22ef01cSRoman Divacky 
427f22ef01cSRoman Divacky   /* Note this is guaranteed true if bits == 0, or LSB == -1U.  */
428f22ef01cSRoman Divacky   if (bits <= lsb)
429f22ef01cSRoman Divacky     return lfExactlyZero;
430f22ef01cSRoman Divacky   if (bits == lsb + 1)
431f22ef01cSRoman Divacky     return lfExactlyHalf;
432edd7eaddSDimitry Andric   if (bits <= partCount * APFloatBase::integerPartWidth &&
433f22ef01cSRoman Divacky       APInt::tcExtractBit(parts, bits - 1))
434f22ef01cSRoman Divacky     return lfMoreThanHalf;
435f22ef01cSRoman Divacky 
436f22ef01cSRoman Divacky   return lfLessThanHalf;
437f22ef01cSRoman Divacky }
438f22ef01cSRoman Divacky 
439f22ef01cSRoman Divacky /* Shift DST right BITS bits noting lost fraction.  */
440f22ef01cSRoman Divacky static lostFraction
shiftRight(APFloatBase::integerPart * dst,unsigned int parts,unsigned int bits)441edd7eaddSDimitry Andric shiftRight(APFloatBase::integerPart *dst, unsigned int parts, unsigned int bits)
442f22ef01cSRoman Divacky {
443f22ef01cSRoman Divacky   lostFraction lost_fraction;
444f22ef01cSRoman Divacky 
445f22ef01cSRoman Divacky   lost_fraction = lostFractionThroughTruncation(dst, parts, bits);
446f22ef01cSRoman Divacky 
447f22ef01cSRoman Divacky   APInt::tcShiftRight(dst, parts, bits);
448f22ef01cSRoman Divacky 
449f22ef01cSRoman Divacky   return lost_fraction;
450f22ef01cSRoman Divacky }
451f22ef01cSRoman Divacky 
452f22ef01cSRoman Divacky /* Combine the effect of two lost fractions.  */
453f22ef01cSRoman Divacky static lostFraction
combineLostFractions(lostFraction moreSignificant,lostFraction lessSignificant)454f22ef01cSRoman Divacky combineLostFractions(lostFraction moreSignificant,
455f22ef01cSRoman Divacky                      lostFraction lessSignificant)
456f22ef01cSRoman Divacky {
457f22ef01cSRoman Divacky   if (lessSignificant != lfExactlyZero) {
458f22ef01cSRoman Divacky     if (moreSignificant == lfExactlyZero)
459f22ef01cSRoman Divacky       moreSignificant = lfLessThanHalf;
460f22ef01cSRoman Divacky     else if (moreSignificant == lfExactlyHalf)
461f22ef01cSRoman Divacky       moreSignificant = lfMoreThanHalf;
462f22ef01cSRoman Divacky   }
463f22ef01cSRoman Divacky 
464f22ef01cSRoman Divacky   return moreSignificant;
465f22ef01cSRoman Divacky }
466f22ef01cSRoman Divacky 
467f22ef01cSRoman Divacky /* The error from the true value, in half-ulps, on multiplying two
468f22ef01cSRoman Divacky    floating point numbers, which differ from the value they
469f22ef01cSRoman Divacky    approximate by at most HUE1 and HUE2 half-ulps, is strictly less
470f22ef01cSRoman Divacky    than the returned value.
471f22ef01cSRoman Divacky 
472f22ef01cSRoman Divacky    See "How to Read Floating Point Numbers Accurately" by William D
473f22ef01cSRoman Divacky    Clinger.  */
474f22ef01cSRoman Divacky static unsigned int
HUerrBound(bool inexactMultiply,unsigned int HUerr1,unsigned int HUerr2)475f22ef01cSRoman Divacky HUerrBound(bool inexactMultiply, unsigned int HUerr1, unsigned int HUerr2)
476f22ef01cSRoman Divacky {
477f22ef01cSRoman Divacky   assert(HUerr1 < 2 || HUerr2 < 2 || (HUerr1 + HUerr2 < 8));
478f22ef01cSRoman Divacky 
479f22ef01cSRoman Divacky   if (HUerr1 + HUerr2 == 0)
480f22ef01cSRoman Divacky     return inexactMultiply * 2;  /* <= inexactMultiply half-ulps.  */
481f22ef01cSRoman Divacky   else
482f22ef01cSRoman Divacky     return inexactMultiply + 2 * (HUerr1 + HUerr2);
483f22ef01cSRoman Divacky }
484f22ef01cSRoman Divacky 
485f22ef01cSRoman Divacky /* The number of ulps from the boundary (zero, or half if ISNEAREST)
486f22ef01cSRoman Divacky    when the least significant BITS are truncated.  BITS cannot be
487f22ef01cSRoman Divacky    zero.  */
488edd7eaddSDimitry Andric static APFloatBase::integerPart
ulpsFromBoundary(const APFloatBase::integerPart * parts,unsigned int bits,bool isNearest)489edd7eaddSDimitry Andric ulpsFromBoundary(const APFloatBase::integerPart *parts, unsigned int bits,
490edd7eaddSDimitry Andric                  bool isNearest) {
491f22ef01cSRoman Divacky   unsigned int count, partBits;
492edd7eaddSDimitry Andric   APFloatBase::integerPart part, boundary;
493f22ef01cSRoman Divacky 
494f22ef01cSRoman Divacky   assert(bits != 0);
495f22ef01cSRoman Divacky 
496f22ef01cSRoman Divacky   bits--;
497edd7eaddSDimitry Andric   count = bits / APFloatBase::integerPartWidth;
498edd7eaddSDimitry Andric   partBits = bits % APFloatBase::integerPartWidth + 1;
499f22ef01cSRoman Divacky 
500edd7eaddSDimitry Andric   part = parts[count] & (~(APFloatBase::integerPart) 0 >> (APFloatBase::integerPartWidth - partBits));
501f22ef01cSRoman Divacky 
502f22ef01cSRoman Divacky   if (isNearest)
503edd7eaddSDimitry Andric     boundary = (APFloatBase::integerPart) 1 << (partBits - 1);
504f22ef01cSRoman Divacky   else
505f22ef01cSRoman Divacky     boundary = 0;
506f22ef01cSRoman Divacky 
507f22ef01cSRoman Divacky   if (count == 0) {
508f22ef01cSRoman Divacky     if (part - boundary <= boundary - part)
509f22ef01cSRoman Divacky       return part - boundary;
510f22ef01cSRoman Divacky     else
511f22ef01cSRoman Divacky       return boundary - part;
512f22ef01cSRoman Divacky   }
513f22ef01cSRoman Divacky 
514f22ef01cSRoman Divacky   if (part == boundary) {
515f22ef01cSRoman Divacky     while (--count)
516f22ef01cSRoman Divacky       if (parts[count])
517edd7eaddSDimitry Andric         return ~(APFloatBase::integerPart) 0; /* A lot.  */
518f22ef01cSRoman Divacky 
519f22ef01cSRoman Divacky     return parts[0];
520f22ef01cSRoman Divacky   } else if (part == boundary - 1) {
521f22ef01cSRoman Divacky     while (--count)
522f22ef01cSRoman Divacky       if (~parts[count])
523edd7eaddSDimitry Andric         return ~(APFloatBase::integerPart) 0; /* A lot.  */
524f22ef01cSRoman Divacky 
525f22ef01cSRoman Divacky     return -parts[0];
526f22ef01cSRoman Divacky   }
527f22ef01cSRoman Divacky 
528edd7eaddSDimitry Andric   return ~(APFloatBase::integerPart) 0; /* A lot.  */
529f22ef01cSRoman Divacky }
530f22ef01cSRoman Divacky 
531f22ef01cSRoman Divacky /* Place pow(5, power) in DST, and return the number of parts used.
532f22ef01cSRoman Divacky    DST must be at least one part larger than size of the answer.  */
533f22ef01cSRoman Divacky static unsigned int
powerOf5(APFloatBase::integerPart * dst,unsigned int power)534edd7eaddSDimitry Andric powerOf5(APFloatBase::integerPart *dst, unsigned int power) {
535edd7eaddSDimitry Andric   static const APFloatBase::integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, 15625, 78125 };
536edd7eaddSDimitry Andric   APFloatBase::integerPart pow5s[maxPowerOfFiveParts * 2 + 5];
537f22ef01cSRoman Divacky   pow5s[0] = 78125 * 5;
538f22ef01cSRoman Divacky 
539f22ef01cSRoman Divacky   unsigned int partsCount[16] = { 1 };
540edd7eaddSDimitry Andric   APFloatBase::integerPart scratch[maxPowerOfFiveParts], *p1, *p2, *pow5;
541f22ef01cSRoman Divacky   unsigned int result;
542f22ef01cSRoman Divacky   assert(power <= maxExponent);
543f22ef01cSRoman Divacky 
544f22ef01cSRoman Divacky   p1 = dst;
545f22ef01cSRoman Divacky   p2 = scratch;
546f22ef01cSRoman Divacky 
547f22ef01cSRoman Divacky   *p1 = firstEightPowers[power & 7];
548f22ef01cSRoman Divacky   power >>= 3;
549f22ef01cSRoman Divacky 
550f22ef01cSRoman Divacky   result = 1;
551f22ef01cSRoman Divacky   pow5 = pow5s;
552f22ef01cSRoman Divacky 
553f22ef01cSRoman Divacky   for (unsigned int n = 0; power; power >>= 1, n++) {
554f22ef01cSRoman Divacky     unsigned int pc;
555f22ef01cSRoman Divacky 
556f22ef01cSRoman Divacky     pc = partsCount[n];
557f22ef01cSRoman Divacky 
558f22ef01cSRoman Divacky     /* Calculate pow(5,pow(2,n+3)) if we haven't yet.  */
559f22ef01cSRoman Divacky     if (pc == 0) {
560f22ef01cSRoman Divacky       pc = partsCount[n - 1];
561f22ef01cSRoman Divacky       APInt::tcFullMultiply(pow5, pow5 - pc, pow5 - pc, pc, pc);
562f22ef01cSRoman Divacky       pc *= 2;
563f22ef01cSRoman Divacky       if (pow5[pc - 1] == 0)
564f22ef01cSRoman Divacky         pc--;
565f22ef01cSRoman Divacky       partsCount[n] = pc;
566f22ef01cSRoman Divacky     }
567f22ef01cSRoman Divacky 
568f22ef01cSRoman Divacky     if (power & 1) {
569edd7eaddSDimitry Andric       APFloatBase::integerPart *tmp;
570f22ef01cSRoman Divacky 
571f22ef01cSRoman Divacky       APInt::tcFullMultiply(p2, p1, pow5, result, pc);
572f22ef01cSRoman Divacky       result += pc;
573f22ef01cSRoman Divacky       if (p2[result - 1] == 0)
574f22ef01cSRoman Divacky         result--;
575f22ef01cSRoman Divacky 
576f22ef01cSRoman Divacky       /* Now result is in p1 with partsCount parts and p2 is scratch
577f22ef01cSRoman Divacky          space.  */
5783ca95b02SDimitry Andric       tmp = p1;
5793ca95b02SDimitry Andric       p1 = p2;
5803ca95b02SDimitry Andric       p2 = tmp;
581f22ef01cSRoman Divacky     }
582f22ef01cSRoman Divacky 
583f22ef01cSRoman Divacky     pow5 += pc;
584f22ef01cSRoman Divacky   }
585f22ef01cSRoman Divacky 
586f22ef01cSRoman Divacky   if (p1 != dst)
587f22ef01cSRoman Divacky     APInt::tcAssign(dst, p1, result);
588f22ef01cSRoman Divacky 
589f22ef01cSRoman Divacky   return result;
590f22ef01cSRoman Divacky }
591f22ef01cSRoman Divacky 
592f22ef01cSRoman Divacky /* Zero at the end to avoid modular arithmetic when adding one; used
593f22ef01cSRoman Divacky    when rounding up during hexadecimal output.  */
594f22ef01cSRoman Divacky static const char hexDigitsLower[] = "0123456789abcdef0";
595f22ef01cSRoman Divacky static const char hexDigitsUpper[] = "0123456789ABCDEF0";
596f22ef01cSRoman Divacky static const char infinityL[] = "infinity";
597f22ef01cSRoman Divacky static const char infinityU[] = "INFINITY";
598f22ef01cSRoman Divacky static const char NaNL[] = "nan";
599f22ef01cSRoman Divacky static const char NaNU[] = "NAN";
600f22ef01cSRoman Divacky 
601f22ef01cSRoman Divacky /* Write out an integerPart in hexadecimal, starting with the most
602f22ef01cSRoman Divacky    significant nibble.  Write out exactly COUNT hexdigits, return
603f22ef01cSRoman Divacky    COUNT.  */
604f22ef01cSRoman Divacky static unsigned int
partAsHex(char * dst,APFloatBase::integerPart part,unsigned int count,const char * hexDigitChars)605edd7eaddSDimitry Andric partAsHex (char *dst, APFloatBase::integerPart part, unsigned int count,
606f22ef01cSRoman Divacky            const char *hexDigitChars)
607f22ef01cSRoman Divacky {
608f22ef01cSRoman Divacky   unsigned int result = count;
609f22ef01cSRoman Divacky 
610edd7eaddSDimitry Andric   assert(count != 0 && count <= APFloatBase::integerPartWidth / 4);
611f22ef01cSRoman Divacky 
612edd7eaddSDimitry Andric   part >>= (APFloatBase::integerPartWidth - 4 * count);
613f22ef01cSRoman Divacky   while (count--) {
614f22ef01cSRoman Divacky     dst[count] = hexDigitChars[part & 0xf];
615f22ef01cSRoman Divacky     part >>= 4;
616f22ef01cSRoman Divacky   }
617f22ef01cSRoman Divacky 
618f22ef01cSRoman Divacky   return result;
619f22ef01cSRoman Divacky }
620f22ef01cSRoman Divacky 
621f22ef01cSRoman Divacky /* Write out an unsigned decimal integer.  */
622f22ef01cSRoman Divacky static char *
writeUnsignedDecimal(char * dst,unsigned int n)623f22ef01cSRoman Divacky writeUnsignedDecimal (char *dst, unsigned int n)
624f22ef01cSRoman Divacky {
625f22ef01cSRoman Divacky   char buff[40], *p;
626f22ef01cSRoman Divacky 
627f22ef01cSRoman Divacky   p = buff;
628f22ef01cSRoman Divacky   do
629f22ef01cSRoman Divacky     *p++ = '0' + n % 10;
630f22ef01cSRoman Divacky   while (n /= 10);
631f22ef01cSRoman Divacky 
632f22ef01cSRoman Divacky   do
633f22ef01cSRoman Divacky     *dst++ = *--p;
634f22ef01cSRoman Divacky   while (p != buff);
635f22ef01cSRoman Divacky 
636f22ef01cSRoman Divacky   return dst;
637f22ef01cSRoman Divacky }
638f22ef01cSRoman Divacky 
639f22ef01cSRoman Divacky /* Write out a signed decimal integer.  */
640f22ef01cSRoman Divacky static char *
writeSignedDecimal(char * dst,int value)641f22ef01cSRoman Divacky writeSignedDecimal (char *dst, int value)
642f22ef01cSRoman Divacky {
643f22ef01cSRoman Divacky   if (value < 0) {
644f22ef01cSRoman Divacky     *dst++ = '-';
645f22ef01cSRoman Divacky     dst = writeUnsignedDecimal(dst, -(unsigned) value);
646f22ef01cSRoman Divacky   } else
647f22ef01cSRoman Divacky     dst = writeUnsignedDecimal(dst, value);
648f22ef01cSRoman Divacky 
649f22ef01cSRoman Divacky   return dst;
650f22ef01cSRoman Divacky }
651f22ef01cSRoman Divacky 
652d88c1a5aSDimitry Andric namespace detail {
653f22ef01cSRoman Divacky /* Constructors.  */
initialize(const fltSemantics * ourSemantics)654d88c1a5aSDimitry Andric void IEEEFloat::initialize(const fltSemantics *ourSemantics) {
655f22ef01cSRoman Divacky   unsigned int count;
656f22ef01cSRoman Divacky 
657f22ef01cSRoman Divacky   semantics = ourSemantics;
658f22ef01cSRoman Divacky   count = partCount();
659f22ef01cSRoman Divacky   if (count > 1)
660f22ef01cSRoman Divacky     significand.parts = new integerPart[count];
661f22ef01cSRoman Divacky }
662f22ef01cSRoman Divacky 
freeSignificand()663d88c1a5aSDimitry Andric void IEEEFloat::freeSignificand() {
664f785676fSDimitry Andric   if (needsCleanup())
665f22ef01cSRoman Divacky     delete [] significand.parts;
666f22ef01cSRoman Divacky }
667f22ef01cSRoman Divacky 
assign(const IEEEFloat & rhs)668d88c1a5aSDimitry Andric void IEEEFloat::assign(const IEEEFloat &rhs) {
669f22ef01cSRoman Divacky   assert(semantics == rhs.semantics);
670f22ef01cSRoman Divacky 
671f22ef01cSRoman Divacky   sign = rhs.sign;
672f22ef01cSRoman Divacky   category = rhs.category;
673f22ef01cSRoman Divacky   exponent = rhs.exponent;
674f785676fSDimitry Andric   if (isFiniteNonZero() || category == fcNaN)
675f22ef01cSRoman Divacky     copySignificand(rhs);
676f22ef01cSRoman Divacky }
677f22ef01cSRoman Divacky 
copySignificand(const IEEEFloat & rhs)678d88c1a5aSDimitry Andric void IEEEFloat::copySignificand(const IEEEFloat &rhs) {
679f785676fSDimitry Andric   assert(isFiniteNonZero() || category == fcNaN);
680f22ef01cSRoman Divacky   assert(rhs.partCount() >= partCount());
681f22ef01cSRoman Divacky 
682f22ef01cSRoman Divacky   APInt::tcAssign(significandParts(), rhs.significandParts(),
683f22ef01cSRoman Divacky                   partCount());
684f22ef01cSRoman Divacky }
685f22ef01cSRoman Divacky 
686f22ef01cSRoman Divacky /* Make this number a NaN, with an arbitrary but deterministic value
687f22ef01cSRoman Divacky    for the significand.  If double or longer, this is a signalling NaN,
688f22ef01cSRoman Divacky    which may not be ideal.  If float, this is QNaN(0).  */
makeNaN(bool SNaN,bool Negative,const APInt * fill)689d88c1a5aSDimitry Andric void IEEEFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) {
690f22ef01cSRoman Divacky   category = fcNaN;
691f22ef01cSRoman Divacky   sign = Negative;
692f22ef01cSRoman Divacky 
693f22ef01cSRoman Divacky   integerPart *significand = significandParts();
694f22ef01cSRoman Divacky   unsigned numParts = partCount();
695f22ef01cSRoman Divacky 
696f22ef01cSRoman Divacky   // Set the significand bits to the fill.
697f22ef01cSRoman Divacky   if (!fill || fill->getNumWords() < numParts)
698f22ef01cSRoman Divacky     APInt::tcSet(significand, 0, numParts);
699f22ef01cSRoman Divacky   if (fill) {
700f22ef01cSRoman Divacky     APInt::tcAssign(significand, fill->getRawData(),
701f22ef01cSRoman Divacky                     std::min(fill->getNumWords(), numParts));
702f22ef01cSRoman Divacky 
703f22ef01cSRoman Divacky     // Zero out the excess bits of the significand.
704f22ef01cSRoman Divacky     unsigned bitsToPreserve = semantics->precision - 1;
705f22ef01cSRoman Divacky     unsigned part = bitsToPreserve / 64;
706f22ef01cSRoman Divacky     bitsToPreserve %= 64;
707f22ef01cSRoman Divacky     significand[part] &= ((1ULL << bitsToPreserve) - 1);
708f22ef01cSRoman Divacky     for (part++; part != numParts; ++part)
709f22ef01cSRoman Divacky       significand[part] = 0;
710f22ef01cSRoman Divacky   }
711f22ef01cSRoman Divacky 
712f22ef01cSRoman Divacky   unsigned QNaNBit = semantics->precision - 2;
713f22ef01cSRoman Divacky 
714f22ef01cSRoman Divacky   if (SNaN) {
715f22ef01cSRoman Divacky     // We always have to clear the QNaN bit to make it an SNaN.
716f22ef01cSRoman Divacky     APInt::tcClearBit(significand, QNaNBit);
717f22ef01cSRoman Divacky 
718f22ef01cSRoman Divacky     // If there are no bits set in the payload, we have to set
719f22ef01cSRoman Divacky     // *something* to make it a NaN instead of an infinity;
720f22ef01cSRoman Divacky     // conventionally, this is the next bit down from the QNaN bit.
721f22ef01cSRoman Divacky     if (APInt::tcIsZero(significand, numParts))
722f22ef01cSRoman Divacky       APInt::tcSetBit(significand, QNaNBit - 1);
723f22ef01cSRoman Divacky   } else {
724f22ef01cSRoman Divacky     // We always have to set the QNaN bit to make it a QNaN.
725f22ef01cSRoman Divacky     APInt::tcSetBit(significand, QNaNBit);
726f22ef01cSRoman Divacky   }
727f22ef01cSRoman Divacky 
728f22ef01cSRoman Divacky   // For x87 extended precision, we want to make a NaN, not a
729f22ef01cSRoman Divacky   // pseudo-NaN.  Maybe we should expose the ability to make
730f22ef01cSRoman Divacky   // pseudo-NaNs?
731d88c1a5aSDimitry Andric   if (semantics == &semX87DoubleExtended)
732f22ef01cSRoman Divacky     APInt::tcSetBit(significand, QNaNBit + 1);
733f22ef01cSRoman Divacky }
734f22ef01cSRoman Divacky 
operator =(const IEEEFloat & rhs)735d88c1a5aSDimitry Andric IEEEFloat &IEEEFloat::operator=(const IEEEFloat &rhs) {
736f22ef01cSRoman Divacky   if (this != &rhs) {
737f22ef01cSRoman Divacky     if (semantics != rhs.semantics) {
738f22ef01cSRoman Divacky       freeSignificand();
739f22ef01cSRoman Divacky       initialize(rhs.semantics);
740f22ef01cSRoman Divacky     }
741f22ef01cSRoman Divacky     assign(rhs);
742f22ef01cSRoman Divacky   }
743f22ef01cSRoman Divacky 
744f22ef01cSRoman Divacky   return *this;
745f22ef01cSRoman Divacky }
746f22ef01cSRoman Divacky 
operator =(IEEEFloat && rhs)747d88c1a5aSDimitry Andric IEEEFloat &IEEEFloat::operator=(IEEEFloat &&rhs) {
74891bc56edSDimitry Andric   freeSignificand();
74991bc56edSDimitry Andric 
75091bc56edSDimitry Andric   semantics = rhs.semantics;
75191bc56edSDimitry Andric   significand = rhs.significand;
75291bc56edSDimitry Andric   exponent = rhs.exponent;
75391bc56edSDimitry Andric   category = rhs.category;
75491bc56edSDimitry Andric   sign = rhs.sign;
75591bc56edSDimitry Andric 
756d88c1a5aSDimitry Andric   rhs.semantics = &semBogus;
75791bc56edSDimitry Andric   return *this;
75891bc56edSDimitry Andric }
75991bc56edSDimitry Andric 
isDenormal() const760d88c1a5aSDimitry Andric bool IEEEFloat::isDenormal() const {
761f785676fSDimitry Andric   return isFiniteNonZero() && (exponent == semantics->minExponent) &&
762139f7f9bSDimitry Andric          (APInt::tcExtractBit(significandParts(),
763139f7f9bSDimitry Andric                               semantics->precision - 1) == 0);
764139f7f9bSDimitry Andric }
765139f7f9bSDimitry Andric 
isSmallest() const766d88c1a5aSDimitry Andric bool IEEEFloat::isSmallest() const {
767f785676fSDimitry Andric   // The smallest number by magnitude in our format will be the smallest
768f785676fSDimitry Andric   // denormal, i.e. the floating point number with exponent being minimum
769f785676fSDimitry Andric   // exponent and significand bitwise equal to 1 (i.e. with MSB equal to 0).
770f785676fSDimitry Andric   return isFiniteNonZero() && exponent == semantics->minExponent &&
771f785676fSDimitry Andric     significandMSB() == 0;
772f785676fSDimitry Andric }
773f785676fSDimitry Andric 
isSignificandAllOnes() const774d88c1a5aSDimitry Andric bool IEEEFloat::isSignificandAllOnes() const {
775f785676fSDimitry Andric   // Test if the significand excluding the integral bit is all ones. This allows
776f785676fSDimitry Andric   // us to test for binade boundaries.
777f785676fSDimitry Andric   const integerPart *Parts = significandParts();
778f785676fSDimitry Andric   const unsigned PartCount = partCount();
779f785676fSDimitry Andric   for (unsigned i = 0; i < PartCount - 1; i++)
780f785676fSDimitry Andric     if (~Parts[i])
781f785676fSDimitry Andric       return false;
782f785676fSDimitry Andric 
783f785676fSDimitry Andric   // Set the unused high bits to all ones when we compare.
784f785676fSDimitry Andric   const unsigned NumHighBits =
785f785676fSDimitry Andric     PartCount*integerPartWidth - semantics->precision + 1;
786f785676fSDimitry Andric   assert(NumHighBits <= integerPartWidth && "Can not have more high bits to "
787f785676fSDimitry Andric          "fill than integerPartWidth");
788f785676fSDimitry Andric   const integerPart HighBitFill =
789f785676fSDimitry Andric     ~integerPart(0) << (integerPartWidth - NumHighBits);
790f785676fSDimitry Andric   if (~(Parts[PartCount - 1] | HighBitFill))
791f785676fSDimitry Andric     return false;
792f785676fSDimitry Andric 
793f785676fSDimitry Andric   return true;
794f785676fSDimitry Andric }
795f785676fSDimitry Andric 
isSignificandAllZeros() const796d88c1a5aSDimitry Andric bool IEEEFloat::isSignificandAllZeros() const {
797f785676fSDimitry Andric   // Test if the significand excluding the integral bit is all zeros. This
798f785676fSDimitry Andric   // allows us to test for binade boundaries.
799f785676fSDimitry Andric   const integerPart *Parts = significandParts();
800f785676fSDimitry Andric   const unsigned PartCount = partCount();
801f785676fSDimitry Andric 
802f785676fSDimitry Andric   for (unsigned i = 0; i < PartCount - 1; i++)
803f785676fSDimitry Andric     if (Parts[i])
804f785676fSDimitry Andric       return false;
805f785676fSDimitry Andric 
806f785676fSDimitry Andric   const unsigned NumHighBits =
807f785676fSDimitry Andric     PartCount*integerPartWidth - semantics->precision + 1;
808f785676fSDimitry Andric   assert(NumHighBits <= integerPartWidth && "Can not have more high bits to "
809f785676fSDimitry Andric          "clear than integerPartWidth");
810f785676fSDimitry Andric   const integerPart HighBitMask = ~integerPart(0) >> NumHighBits;
811f785676fSDimitry Andric 
812f785676fSDimitry Andric   if (Parts[PartCount - 1] & HighBitMask)
813f785676fSDimitry Andric     return false;
814f785676fSDimitry Andric 
815f785676fSDimitry Andric   return true;
816f785676fSDimitry Andric }
817f785676fSDimitry Andric 
isLargest() const818d88c1a5aSDimitry Andric bool IEEEFloat::isLargest() const {
819f785676fSDimitry Andric   // The largest number by magnitude in our format will be the floating point
820f785676fSDimitry Andric   // number with maximum exponent and with significand that is all ones.
821f785676fSDimitry Andric   return isFiniteNonZero() && exponent == semantics->maxExponent
822f785676fSDimitry Andric     && isSignificandAllOnes();
823f785676fSDimitry Andric }
824f785676fSDimitry Andric 
isInteger() const825d88c1a5aSDimitry Andric bool IEEEFloat::isInteger() const {
8267d523365SDimitry Andric   // This could be made more efficient; I'm going for obviously correct.
8277d523365SDimitry Andric   if (!isFinite()) return false;
828d88c1a5aSDimitry Andric   IEEEFloat truncated = *this;
8297d523365SDimitry Andric   truncated.roundToIntegral(rmTowardZero);
8307d523365SDimitry Andric   return compare(truncated) == cmpEqual;
8317d523365SDimitry Andric }
8327d523365SDimitry Andric 
bitwiseIsEqual(const IEEEFloat & rhs) const833d88c1a5aSDimitry Andric bool IEEEFloat::bitwiseIsEqual(const IEEEFloat &rhs) const {
834f22ef01cSRoman Divacky   if (this == &rhs)
835f22ef01cSRoman Divacky     return true;
836f22ef01cSRoman Divacky   if (semantics != rhs.semantics ||
837f22ef01cSRoman Divacky       category != rhs.category ||
838f22ef01cSRoman Divacky       sign != rhs.sign)
839f22ef01cSRoman Divacky     return false;
840f22ef01cSRoman Divacky   if (category==fcZero || category==fcInfinity)
841f22ef01cSRoman Divacky     return true;
8427d523365SDimitry Andric 
8437d523365SDimitry Andric   if (isFiniteNonZero() && exponent != rhs.exponent)
844f22ef01cSRoman Divacky     return false;
8457d523365SDimitry Andric 
8467d523365SDimitry Andric   return std::equal(significandParts(), significandParts() + partCount(),
8477d523365SDimitry Andric                     rhs.significandParts());
848f22ef01cSRoman Divacky }
849f22ef01cSRoman Divacky 
IEEEFloat(const fltSemantics & ourSemantics,integerPart value)850d88c1a5aSDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, integerPart value) {
851f22ef01cSRoman Divacky   initialize(&ourSemantics);
852f22ef01cSRoman Divacky   sign = 0;
853f785676fSDimitry Andric   category = fcNormal;
854f22ef01cSRoman Divacky   zeroSignificand();
855f22ef01cSRoman Divacky   exponent = ourSemantics.precision - 1;
856f22ef01cSRoman Divacky   significandParts()[0] = value;
857f22ef01cSRoman Divacky   normalize(rmNearestTiesToEven, lfExactlyZero);
858f22ef01cSRoman Divacky }
859f22ef01cSRoman Divacky 
IEEEFloat(const fltSemantics & ourSemantics)860d88c1a5aSDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics) {
861f22ef01cSRoman Divacky   initialize(&ourSemantics);
862f22ef01cSRoman Divacky   category = fcZero;
863f22ef01cSRoman Divacky   sign = false;
864f22ef01cSRoman Divacky }
865f22ef01cSRoman Divacky 
866d88c1a5aSDimitry Andric // Delegate to the previous constructor, because later copy constructor may
867d88c1a5aSDimitry Andric // actually inspects category, which can't be garbage.
IEEEFloat(const fltSemantics & ourSemantics,uninitializedTag tag)868d88c1a5aSDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, uninitializedTag tag)
869d88c1a5aSDimitry Andric     : IEEEFloat(ourSemantics) {}
870f22ef01cSRoman Divacky 
IEEEFloat(const IEEEFloat & rhs)871d88c1a5aSDimitry Andric IEEEFloat::IEEEFloat(const IEEEFloat &rhs) {
872f22ef01cSRoman Divacky   initialize(rhs.semantics);
873f22ef01cSRoman Divacky   assign(rhs);
874f22ef01cSRoman Divacky }
875f22ef01cSRoman Divacky 
IEEEFloat(IEEEFloat && rhs)876d88c1a5aSDimitry Andric IEEEFloat::IEEEFloat(IEEEFloat &&rhs) : semantics(&semBogus) {
87791bc56edSDimitry Andric   *this = std::move(rhs);
87891bc56edSDimitry Andric }
87991bc56edSDimitry Andric 
~IEEEFloat()880d88c1a5aSDimitry Andric IEEEFloat::~IEEEFloat() { freeSignificand(); }
881f22ef01cSRoman Divacky 
partCount() const882d88c1a5aSDimitry Andric unsigned int IEEEFloat::partCount() const {
883f22ef01cSRoman Divacky   return partCountForBits(semantics->precision + 1);
884f22ef01cSRoman Divacky }
885f22ef01cSRoman Divacky 
significandParts() const886edd7eaddSDimitry Andric const IEEEFloat::integerPart *IEEEFloat::significandParts() const {
887d88c1a5aSDimitry Andric   return const_cast<IEEEFloat *>(this)->significandParts();
8887d523365SDimitry Andric }
889f22ef01cSRoman Divacky 
significandParts()890edd7eaddSDimitry Andric IEEEFloat::integerPart *IEEEFloat::significandParts() {
891f22ef01cSRoman Divacky   if (partCount() > 1)
892f22ef01cSRoman Divacky     return significand.parts;
893f22ef01cSRoman Divacky   else
894f22ef01cSRoman Divacky     return &significand.part;
895f22ef01cSRoman Divacky }
896f22ef01cSRoman Divacky 
zeroSignificand()897d88c1a5aSDimitry Andric void IEEEFloat::zeroSignificand() {
898f22ef01cSRoman Divacky   APInt::tcSet(significandParts(), 0, partCount());
899f22ef01cSRoman Divacky }
900f22ef01cSRoman Divacky 
901f22ef01cSRoman Divacky /* Increment an fcNormal floating point number's significand.  */
incrementSignificand()902d88c1a5aSDimitry Andric void IEEEFloat::incrementSignificand() {
903f22ef01cSRoman Divacky   integerPart carry;
904f22ef01cSRoman Divacky 
905f22ef01cSRoman Divacky   carry = APInt::tcIncrement(significandParts(), partCount());
906f22ef01cSRoman Divacky 
907f22ef01cSRoman Divacky   /* Our callers should never cause us to overflow.  */
908f22ef01cSRoman Divacky   assert(carry == 0);
9096122f3e6SDimitry Andric   (void)carry;
910f22ef01cSRoman Divacky }
911f22ef01cSRoman Divacky 
912f22ef01cSRoman Divacky /* Add the significand of the RHS.  Returns the carry flag.  */
addSignificand(const IEEEFloat & rhs)913edd7eaddSDimitry Andric IEEEFloat::integerPart IEEEFloat::addSignificand(const IEEEFloat &rhs) {
914f22ef01cSRoman Divacky   integerPart *parts;
915f22ef01cSRoman Divacky 
916f22ef01cSRoman Divacky   parts = significandParts();
917f22ef01cSRoman Divacky 
918f22ef01cSRoman Divacky   assert(semantics == rhs.semantics);
919f22ef01cSRoman Divacky   assert(exponent == rhs.exponent);
920f22ef01cSRoman Divacky 
921f22ef01cSRoman Divacky   return APInt::tcAdd(parts, rhs.significandParts(), 0, partCount());
922f22ef01cSRoman Divacky }
923f22ef01cSRoman Divacky 
924f22ef01cSRoman Divacky /* Subtract the significand of the RHS with a borrow flag.  Returns
925f22ef01cSRoman Divacky    the borrow flag.  */
subtractSignificand(const IEEEFloat & rhs,integerPart borrow)926edd7eaddSDimitry Andric IEEEFloat::integerPart IEEEFloat::subtractSignificand(const IEEEFloat &rhs,
927d88c1a5aSDimitry Andric                                                       integerPart borrow) {
928f22ef01cSRoman Divacky   integerPart *parts;
929f22ef01cSRoman Divacky 
930f22ef01cSRoman Divacky   parts = significandParts();
931f22ef01cSRoman Divacky 
932f22ef01cSRoman Divacky   assert(semantics == rhs.semantics);
933f22ef01cSRoman Divacky   assert(exponent == rhs.exponent);
934f22ef01cSRoman Divacky 
935f22ef01cSRoman Divacky   return APInt::tcSubtract(parts, rhs.significandParts(), borrow,
936f22ef01cSRoman Divacky                            partCount());
937f22ef01cSRoman Divacky }
938f22ef01cSRoman Divacky 
939f22ef01cSRoman Divacky /* Multiply the significand of the RHS.  If ADDEND is non-NULL, add it
940f22ef01cSRoman Divacky    on to the full-precision result of the multiplication.  Returns the
941f22ef01cSRoman Divacky    lost fraction.  */
multiplySignificand(const IEEEFloat & rhs,const IEEEFloat * addend)942d88c1a5aSDimitry Andric lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs,
943d88c1a5aSDimitry Andric                                             const IEEEFloat *addend) {
944f22ef01cSRoman Divacky   unsigned int omsb;        // One, not zero, based MSB.
945f22ef01cSRoman Divacky   unsigned int partsCount, newPartsCount, precision;
946f22ef01cSRoman Divacky   integerPart *lhsSignificand;
947f22ef01cSRoman Divacky   integerPart scratch[4];
948f22ef01cSRoman Divacky   integerPart *fullSignificand;
949f22ef01cSRoman Divacky   lostFraction lost_fraction;
950f22ef01cSRoman Divacky   bool ignored;
951f22ef01cSRoman Divacky 
952f22ef01cSRoman Divacky   assert(semantics == rhs.semantics);
953f22ef01cSRoman Divacky 
954f22ef01cSRoman Divacky   precision = semantics->precision;
95539d628a0SDimitry Andric 
95639d628a0SDimitry Andric   // Allocate space for twice as many bits as the original significand, plus one
95739d628a0SDimitry Andric   // extra bit for the addition to overflow into.
95839d628a0SDimitry Andric   newPartsCount = partCountForBits(precision * 2 + 1);
959f22ef01cSRoman Divacky 
960f22ef01cSRoman Divacky   if (newPartsCount > 4)
961f22ef01cSRoman Divacky     fullSignificand = new integerPart[newPartsCount];
962f22ef01cSRoman Divacky   else
963f22ef01cSRoman Divacky     fullSignificand = scratch;
964f22ef01cSRoman Divacky 
965f22ef01cSRoman Divacky   lhsSignificand = significandParts();
966f22ef01cSRoman Divacky   partsCount = partCount();
967f22ef01cSRoman Divacky 
968f22ef01cSRoman Divacky   APInt::tcFullMultiply(fullSignificand, lhsSignificand,
969f22ef01cSRoman Divacky                         rhs.significandParts(), partsCount, partsCount);
970f22ef01cSRoman Divacky 
971f22ef01cSRoman Divacky   lost_fraction = lfExactlyZero;
972f22ef01cSRoman Divacky   omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
973f22ef01cSRoman Divacky   exponent += rhs.exponent;
974f22ef01cSRoman Divacky 
975f785676fSDimitry Andric   // Assume the operands involved in the multiplication are single-precision
976f785676fSDimitry Andric   // FP, and the two multiplicants are:
977f785676fSDimitry Andric   //   *this = a23 . a22 ... a0 * 2^e1
978f785676fSDimitry Andric   //     rhs = b23 . b22 ... b0 * 2^e2
979f785676fSDimitry Andric   // the result of multiplication is:
98039d628a0SDimitry Andric   //   *this = c48 c47 c46 . c45 ... c0 * 2^(e1+e2)
98139d628a0SDimitry Andric   // Note that there are three significant bits at the left-hand side of the
98239d628a0SDimitry Andric   // radix point: two for the multiplication, and an overflow bit for the
98339d628a0SDimitry Andric   // addition (that will always be zero at this point). Move the radix point
98439d628a0SDimitry Andric   // toward left by two bits, and adjust exponent accordingly.
98539d628a0SDimitry Andric   exponent += 2;
986f785676fSDimitry Andric 
98739d628a0SDimitry Andric   if (addend && addend->isNonZero()) {
988f785676fSDimitry Andric     // The intermediate result of the multiplication has "2 * precision"
989f785676fSDimitry Andric     // signicant bit; adjust the addend to be consistent with mul result.
990f785676fSDimitry Andric     //
991f22ef01cSRoman Divacky     Significand savedSignificand = significand;
992f22ef01cSRoman Divacky     const fltSemantics *savedSemantics = semantics;
993f22ef01cSRoman Divacky     fltSemantics extendedSemantics;
994f22ef01cSRoman Divacky     opStatus status;
995f22ef01cSRoman Divacky     unsigned int extendedPrecision;
996f22ef01cSRoman Divacky 
99739d628a0SDimitry Andric     // Normalize our MSB to one below the top bit to allow for overflow.
99839d628a0SDimitry Andric     extendedPrecision = 2 * precision + 1;
99939d628a0SDimitry Andric     if (omsb != extendedPrecision - 1) {
1000f785676fSDimitry Andric       assert(extendedPrecision > omsb);
1001f22ef01cSRoman Divacky       APInt::tcShiftLeft(fullSignificand, newPartsCount,
100239d628a0SDimitry Andric                          (extendedPrecision - 1) - omsb);
100339d628a0SDimitry Andric       exponent -= (extendedPrecision - 1) - omsb;
1004f22ef01cSRoman Divacky     }
1005f22ef01cSRoman Divacky 
1006f22ef01cSRoman Divacky     /* Create new semantics.  */
1007f22ef01cSRoman Divacky     extendedSemantics = *semantics;
1008f22ef01cSRoman Divacky     extendedSemantics.precision = extendedPrecision;
1009f22ef01cSRoman Divacky 
1010f22ef01cSRoman Divacky     if (newPartsCount == 1)
1011f22ef01cSRoman Divacky       significand.part = fullSignificand[0];
1012f22ef01cSRoman Divacky     else
1013f22ef01cSRoman Divacky       significand.parts = fullSignificand;
1014f22ef01cSRoman Divacky     semantics = &extendedSemantics;
1015f22ef01cSRoman Divacky 
1016d88c1a5aSDimitry Andric     IEEEFloat extendedAddend(*addend);
1017f22ef01cSRoman Divacky     status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored);
1018f22ef01cSRoman Divacky     assert(status == opOK);
10196122f3e6SDimitry Andric     (void)status;
102039d628a0SDimitry Andric 
102139d628a0SDimitry Andric     // Shift the significand of the addend right by one bit. This guarantees
102239d628a0SDimitry Andric     // that the high bit of the significand is zero (same as fullSignificand),
102339d628a0SDimitry Andric     // so the addition will overflow (if it does overflow at all) into the top bit.
102439d628a0SDimitry Andric     lost_fraction = extendedAddend.shiftSignificandRight(1);
102539d628a0SDimitry Andric     assert(lost_fraction == lfExactlyZero &&
102639d628a0SDimitry Andric            "Lost precision while shifting addend for fused-multiply-add.");
102739d628a0SDimitry Andric 
1028f22ef01cSRoman Divacky     lost_fraction = addOrSubtractSignificand(extendedAddend, false);
1029f22ef01cSRoman Divacky 
1030f22ef01cSRoman Divacky     /* Restore our state.  */
1031f22ef01cSRoman Divacky     if (newPartsCount == 1)
1032f22ef01cSRoman Divacky       fullSignificand[0] = significand.part;
1033f22ef01cSRoman Divacky     significand = savedSignificand;
1034f22ef01cSRoman Divacky     semantics = savedSemantics;
1035f22ef01cSRoman Divacky 
1036f22ef01cSRoman Divacky     omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
1037f22ef01cSRoman Divacky   }
1038f22ef01cSRoman Divacky 
1039f785676fSDimitry Andric   // Convert the result having "2 * precision" significant-bits back to the one
1040f785676fSDimitry Andric   // having "precision" significant-bits. First, move the radix point from
1041f785676fSDimitry Andric   // poision "2*precision - 1" to "precision - 1". The exponent need to be
1042f785676fSDimitry Andric   // adjusted by "2*precision - 1" - "precision - 1" = "precision".
104339d628a0SDimitry Andric   exponent -= precision + 1;
1044f22ef01cSRoman Divacky 
1045f785676fSDimitry Andric   // In case MSB resides at the left-hand side of radix point, shift the
1046f785676fSDimitry Andric   // mantissa right by some amount to make sure the MSB reside right before
1047f785676fSDimitry Andric   // the radix point (i.e. "MSB . rest-significant-bits").
1048f785676fSDimitry Andric   //
1049f785676fSDimitry Andric   // Note that the result is not normalized when "omsb < precision". So, the
1050d88c1a5aSDimitry Andric   // caller needs to call IEEEFloat::normalize() if normalized value is
1051d88c1a5aSDimitry Andric   // expected.
1052f22ef01cSRoman Divacky   if (omsb > precision) {
1053f22ef01cSRoman Divacky     unsigned int bits, significantParts;
1054f22ef01cSRoman Divacky     lostFraction lf;
1055f22ef01cSRoman Divacky 
1056f22ef01cSRoman Divacky     bits = omsb - precision;
1057f22ef01cSRoman Divacky     significantParts = partCountForBits(omsb);
1058f22ef01cSRoman Divacky     lf = shiftRight(fullSignificand, significantParts, bits);
1059f22ef01cSRoman Divacky     lost_fraction = combineLostFractions(lf, lost_fraction);
1060f22ef01cSRoman Divacky     exponent += bits;
1061f22ef01cSRoman Divacky   }
1062f22ef01cSRoman Divacky 
1063f22ef01cSRoman Divacky   APInt::tcAssign(lhsSignificand, fullSignificand, partsCount);
1064f22ef01cSRoman Divacky 
1065f22ef01cSRoman Divacky   if (newPartsCount > 4)
1066f22ef01cSRoman Divacky     delete [] fullSignificand;
1067f22ef01cSRoman Divacky 
1068f22ef01cSRoman Divacky   return lost_fraction;
1069f22ef01cSRoman Divacky }
1070f22ef01cSRoman Divacky 
1071f22ef01cSRoman Divacky /* Multiply the significands of LHS and RHS to DST.  */
divideSignificand(const IEEEFloat & rhs)1072d88c1a5aSDimitry Andric lostFraction IEEEFloat::divideSignificand(const IEEEFloat &rhs) {
1073f22ef01cSRoman Divacky   unsigned int bit, i, partsCount;
1074f22ef01cSRoman Divacky   const integerPart *rhsSignificand;
1075f22ef01cSRoman Divacky   integerPart *lhsSignificand, *dividend, *divisor;
1076f22ef01cSRoman Divacky   integerPart scratch[4];
1077f22ef01cSRoman Divacky   lostFraction lost_fraction;
1078f22ef01cSRoman Divacky 
1079f22ef01cSRoman Divacky   assert(semantics == rhs.semantics);
1080f22ef01cSRoman Divacky 
1081f22ef01cSRoman Divacky   lhsSignificand = significandParts();
1082f22ef01cSRoman Divacky   rhsSignificand = rhs.significandParts();
1083f22ef01cSRoman Divacky   partsCount = partCount();
1084f22ef01cSRoman Divacky 
1085f22ef01cSRoman Divacky   if (partsCount > 2)
1086f22ef01cSRoman Divacky     dividend = new integerPart[partsCount * 2];
1087f22ef01cSRoman Divacky   else
1088f22ef01cSRoman Divacky     dividend = scratch;
1089f22ef01cSRoman Divacky 
1090f22ef01cSRoman Divacky   divisor = dividend + partsCount;
1091f22ef01cSRoman Divacky 
1092f22ef01cSRoman Divacky   /* Copy the dividend and divisor as they will be modified in-place.  */
1093f22ef01cSRoman Divacky   for (i = 0; i < partsCount; i++) {
1094f22ef01cSRoman Divacky     dividend[i] = lhsSignificand[i];
1095f22ef01cSRoman Divacky     divisor[i] = rhsSignificand[i];
1096f22ef01cSRoman Divacky     lhsSignificand[i] = 0;
1097f22ef01cSRoman Divacky   }
1098f22ef01cSRoman Divacky 
1099f22ef01cSRoman Divacky   exponent -= rhs.exponent;
1100f22ef01cSRoman Divacky 
1101f22ef01cSRoman Divacky   unsigned int precision = semantics->precision;
1102f22ef01cSRoman Divacky 
1103f22ef01cSRoman Divacky   /* Normalize the divisor.  */
1104f22ef01cSRoman Divacky   bit = precision - APInt::tcMSB(divisor, partsCount) - 1;
1105f22ef01cSRoman Divacky   if (bit) {
1106f22ef01cSRoman Divacky     exponent += bit;
1107f22ef01cSRoman Divacky     APInt::tcShiftLeft(divisor, partsCount, bit);
1108f22ef01cSRoman Divacky   }
1109f22ef01cSRoman Divacky 
1110f22ef01cSRoman Divacky   /* Normalize the dividend.  */
1111f22ef01cSRoman Divacky   bit = precision - APInt::tcMSB(dividend, partsCount) - 1;
1112f22ef01cSRoman Divacky   if (bit) {
1113f22ef01cSRoman Divacky     exponent -= bit;
1114f22ef01cSRoman Divacky     APInt::tcShiftLeft(dividend, partsCount, bit);
1115f22ef01cSRoman Divacky   }
1116f22ef01cSRoman Divacky 
1117f22ef01cSRoman Divacky   /* Ensure the dividend >= divisor initially for the loop below.
1118f22ef01cSRoman Divacky      Incidentally, this means that the division loop below is
1119f22ef01cSRoman Divacky      guaranteed to set the integer bit to one.  */
1120f22ef01cSRoman Divacky   if (APInt::tcCompare(dividend, divisor, partsCount) < 0) {
1121f22ef01cSRoman Divacky     exponent--;
1122f22ef01cSRoman Divacky     APInt::tcShiftLeft(dividend, partsCount, 1);
1123f22ef01cSRoman Divacky     assert(APInt::tcCompare(dividend, divisor, partsCount) >= 0);
1124f22ef01cSRoman Divacky   }
1125f22ef01cSRoman Divacky 
1126f22ef01cSRoman Divacky   /* Long division.  */
1127f22ef01cSRoman Divacky   for (bit = precision; bit; bit -= 1) {
1128f22ef01cSRoman Divacky     if (APInt::tcCompare(dividend, divisor, partsCount) >= 0) {
1129f22ef01cSRoman Divacky       APInt::tcSubtract(dividend, divisor, 0, partsCount);
1130f22ef01cSRoman Divacky       APInt::tcSetBit(lhsSignificand, bit - 1);
1131f22ef01cSRoman Divacky     }
1132f22ef01cSRoman Divacky 
1133f22ef01cSRoman Divacky     APInt::tcShiftLeft(dividend, partsCount, 1);
1134f22ef01cSRoman Divacky   }
1135f22ef01cSRoman Divacky 
1136f22ef01cSRoman Divacky   /* Figure out the lost fraction.  */
1137f22ef01cSRoman Divacky   int cmp = APInt::tcCompare(dividend, divisor, partsCount);
1138f22ef01cSRoman Divacky 
1139f22ef01cSRoman Divacky   if (cmp > 0)
1140f22ef01cSRoman Divacky     lost_fraction = lfMoreThanHalf;
1141f22ef01cSRoman Divacky   else if (cmp == 0)
1142f22ef01cSRoman Divacky     lost_fraction = lfExactlyHalf;
1143f22ef01cSRoman Divacky   else if (APInt::tcIsZero(dividend, partsCount))
1144f22ef01cSRoman Divacky     lost_fraction = lfExactlyZero;
1145f22ef01cSRoman Divacky   else
1146f22ef01cSRoman Divacky     lost_fraction = lfLessThanHalf;
1147f22ef01cSRoman Divacky 
1148f22ef01cSRoman Divacky   if (partsCount > 2)
1149f22ef01cSRoman Divacky     delete [] dividend;
1150f22ef01cSRoman Divacky 
1151f22ef01cSRoman Divacky   return lost_fraction;
1152f22ef01cSRoman Divacky }
1153f22ef01cSRoman Divacky 
significandMSB() const1154d88c1a5aSDimitry Andric unsigned int IEEEFloat::significandMSB() const {
1155f22ef01cSRoman Divacky   return APInt::tcMSB(significandParts(), partCount());
1156f22ef01cSRoman Divacky }
1157f22ef01cSRoman Divacky 
significandLSB() const1158d88c1a5aSDimitry Andric unsigned int IEEEFloat::significandLSB() const {
1159f22ef01cSRoman Divacky   return APInt::tcLSB(significandParts(), partCount());
1160f22ef01cSRoman Divacky }
1161f22ef01cSRoman Divacky 
1162f22ef01cSRoman Divacky /* Note that a zero result is NOT normalized to fcZero.  */
shiftSignificandRight(unsigned int bits)1163d88c1a5aSDimitry Andric lostFraction IEEEFloat::shiftSignificandRight(unsigned int bits) {
1164f22ef01cSRoman Divacky   /* Our exponent should not overflow.  */
1165f785676fSDimitry Andric   assert((ExponentType) (exponent + bits) >= exponent);
1166f22ef01cSRoman Divacky 
1167f22ef01cSRoman Divacky   exponent += bits;
1168f22ef01cSRoman Divacky 
1169f22ef01cSRoman Divacky   return shiftRight(significandParts(), partCount(), bits);
1170f22ef01cSRoman Divacky }
1171f22ef01cSRoman Divacky 
1172f22ef01cSRoman Divacky /* Shift the significand left BITS bits, subtract BITS from its exponent.  */
shiftSignificandLeft(unsigned int bits)1173d88c1a5aSDimitry Andric void IEEEFloat::shiftSignificandLeft(unsigned int bits) {
1174f22ef01cSRoman Divacky   assert(bits < semantics->precision);
1175f22ef01cSRoman Divacky 
1176f22ef01cSRoman Divacky   if (bits) {
1177f22ef01cSRoman Divacky     unsigned int partsCount = partCount();
1178f22ef01cSRoman Divacky 
1179f22ef01cSRoman Divacky     APInt::tcShiftLeft(significandParts(), partsCount, bits);
1180f22ef01cSRoman Divacky     exponent -= bits;
1181f22ef01cSRoman Divacky 
1182f22ef01cSRoman Divacky     assert(!APInt::tcIsZero(significandParts(), partsCount));
1183f22ef01cSRoman Divacky   }
1184f22ef01cSRoman Divacky }
1185f22ef01cSRoman Divacky 
1186d88c1a5aSDimitry Andric IEEEFloat::cmpResult
compareAbsoluteValue(const IEEEFloat & rhs) const1187d88c1a5aSDimitry Andric IEEEFloat::compareAbsoluteValue(const IEEEFloat &rhs) const {
1188f22ef01cSRoman Divacky   int compare;
1189f22ef01cSRoman Divacky 
1190f22ef01cSRoman Divacky   assert(semantics == rhs.semantics);
1191f785676fSDimitry Andric   assert(isFiniteNonZero());
1192f785676fSDimitry Andric   assert(rhs.isFiniteNonZero());
1193f22ef01cSRoman Divacky 
1194f22ef01cSRoman Divacky   compare = exponent - rhs.exponent;
1195f22ef01cSRoman Divacky 
1196f22ef01cSRoman Divacky   /* If exponents are equal, do an unsigned bignum comparison of the
1197f22ef01cSRoman Divacky      significands.  */
1198f22ef01cSRoman Divacky   if (compare == 0)
1199f22ef01cSRoman Divacky     compare = APInt::tcCompare(significandParts(), rhs.significandParts(),
1200f22ef01cSRoman Divacky                                partCount());
1201f22ef01cSRoman Divacky 
1202f22ef01cSRoman Divacky   if (compare > 0)
1203f22ef01cSRoman Divacky     return cmpGreaterThan;
1204f22ef01cSRoman Divacky   else if (compare < 0)
1205f22ef01cSRoman Divacky     return cmpLessThan;
1206f22ef01cSRoman Divacky   else
1207f22ef01cSRoman Divacky     return cmpEqual;
1208f22ef01cSRoman Divacky }
1209f22ef01cSRoman Divacky 
1210f22ef01cSRoman Divacky /* Handle overflow.  Sign is preserved.  We either become infinity or
1211f22ef01cSRoman Divacky    the largest finite number.  */
handleOverflow(roundingMode rounding_mode)1212d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::handleOverflow(roundingMode rounding_mode) {
1213f22ef01cSRoman Divacky   /* Infinity?  */
1214f22ef01cSRoman Divacky   if (rounding_mode == rmNearestTiesToEven ||
1215f22ef01cSRoman Divacky       rounding_mode == rmNearestTiesToAway ||
1216f22ef01cSRoman Divacky       (rounding_mode == rmTowardPositive && !sign) ||
1217f22ef01cSRoman Divacky       (rounding_mode == rmTowardNegative && sign)) {
1218f22ef01cSRoman Divacky     category = fcInfinity;
1219f22ef01cSRoman Divacky     return (opStatus) (opOverflow | opInexact);
1220f22ef01cSRoman Divacky   }
1221f22ef01cSRoman Divacky 
1222f22ef01cSRoman Divacky   /* Otherwise we become the largest finite number.  */
1223f22ef01cSRoman Divacky   category = fcNormal;
1224f22ef01cSRoman Divacky   exponent = semantics->maxExponent;
1225f22ef01cSRoman Divacky   APInt::tcSetLeastSignificantBits(significandParts(), partCount(),
1226f22ef01cSRoman Divacky                                    semantics->precision);
1227f22ef01cSRoman Divacky 
1228f22ef01cSRoman Divacky   return opInexact;
1229f22ef01cSRoman Divacky }
1230f22ef01cSRoman Divacky 
1231f22ef01cSRoman Divacky /* Returns TRUE if, when truncating the current number, with BIT the
1232f22ef01cSRoman Divacky    new LSB, with the given lost fraction and rounding mode, the result
1233f22ef01cSRoman Divacky    would need to be rounded away from zero (i.e., by increasing the
1234f22ef01cSRoman Divacky    signficand).  This routine must work for fcZero of both signs, and
1235f22ef01cSRoman Divacky    fcNormal numbers.  */
roundAwayFromZero(roundingMode rounding_mode,lostFraction lost_fraction,unsigned int bit) const1236d88c1a5aSDimitry Andric bool IEEEFloat::roundAwayFromZero(roundingMode rounding_mode,
1237f22ef01cSRoman Divacky                                   lostFraction lost_fraction,
1238d88c1a5aSDimitry Andric                                   unsigned int bit) const {
1239f22ef01cSRoman Divacky   /* NaNs and infinities should not have lost fractions.  */
1240f785676fSDimitry Andric   assert(isFiniteNonZero() || category == fcZero);
1241f22ef01cSRoman Divacky 
1242f22ef01cSRoman Divacky   /* Current callers never pass this so we don't handle it.  */
1243f22ef01cSRoman Divacky   assert(lost_fraction != lfExactlyZero);
1244f22ef01cSRoman Divacky 
1245f22ef01cSRoman Divacky   switch (rounding_mode) {
1246f22ef01cSRoman Divacky   case rmNearestTiesToAway:
1247f22ef01cSRoman Divacky     return lost_fraction == lfExactlyHalf || lost_fraction == lfMoreThanHalf;
1248f22ef01cSRoman Divacky 
1249f22ef01cSRoman Divacky   case rmNearestTiesToEven:
1250f22ef01cSRoman Divacky     if (lost_fraction == lfMoreThanHalf)
1251f22ef01cSRoman Divacky       return true;
1252f22ef01cSRoman Divacky 
1253f22ef01cSRoman Divacky     /* Our zeroes don't have a significand to test.  */
1254f22ef01cSRoman Divacky     if (lost_fraction == lfExactlyHalf && category != fcZero)
1255f22ef01cSRoman Divacky       return APInt::tcExtractBit(significandParts(), bit);
1256f22ef01cSRoman Divacky 
1257f22ef01cSRoman Divacky     return false;
1258f22ef01cSRoman Divacky 
1259f22ef01cSRoman Divacky   case rmTowardZero:
1260f22ef01cSRoman Divacky     return false;
1261f22ef01cSRoman Divacky 
1262f22ef01cSRoman Divacky   case rmTowardPositive:
1263ff0cc061SDimitry Andric     return !sign;
1264f22ef01cSRoman Divacky 
1265f22ef01cSRoman Divacky   case rmTowardNegative:
1266ff0cc061SDimitry Andric     return sign;
1267f22ef01cSRoman Divacky   }
1268dff0c46cSDimitry Andric   llvm_unreachable("Invalid rounding mode found");
1269f22ef01cSRoman Divacky }
1270f22ef01cSRoman Divacky 
normalize(roundingMode rounding_mode,lostFraction lost_fraction)1271d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::normalize(roundingMode rounding_mode,
1272d88c1a5aSDimitry Andric                                          lostFraction lost_fraction) {
1273f22ef01cSRoman Divacky   unsigned int omsb;                /* One, not zero, based MSB.  */
1274f22ef01cSRoman Divacky   int exponentChange;
1275f22ef01cSRoman Divacky 
1276f785676fSDimitry Andric   if (!isFiniteNonZero())
1277f22ef01cSRoman Divacky     return opOK;
1278f22ef01cSRoman Divacky 
1279f22ef01cSRoman Divacky   /* Before rounding normalize the exponent of fcNormal numbers.  */
1280f22ef01cSRoman Divacky   omsb = significandMSB() + 1;
1281f22ef01cSRoman Divacky 
1282f22ef01cSRoman Divacky   if (omsb) {
1283f22ef01cSRoman Divacky     /* OMSB is numbered from 1.  We want to place it in the integer
12846122f3e6SDimitry Andric        bit numbered PRECISION if possible, with a compensating change in
1285f22ef01cSRoman Divacky        the exponent.  */
1286f22ef01cSRoman Divacky     exponentChange = omsb - semantics->precision;
1287f22ef01cSRoman Divacky 
1288f22ef01cSRoman Divacky     /* If the resulting exponent is too high, overflow according to
1289f22ef01cSRoman Divacky        the rounding mode.  */
1290f22ef01cSRoman Divacky     if (exponent + exponentChange > semantics->maxExponent)
1291f22ef01cSRoman Divacky       return handleOverflow(rounding_mode);
1292f22ef01cSRoman Divacky 
1293f22ef01cSRoman Divacky     /* Subnormal numbers have exponent minExponent, and their MSB
1294f22ef01cSRoman Divacky        is forced based on that.  */
1295f22ef01cSRoman Divacky     if (exponent + exponentChange < semantics->minExponent)
1296f22ef01cSRoman Divacky       exponentChange = semantics->minExponent - exponent;
1297f22ef01cSRoman Divacky 
1298f22ef01cSRoman Divacky     /* Shifting left is easy as we don't lose precision.  */
1299f22ef01cSRoman Divacky     if (exponentChange < 0) {
1300f22ef01cSRoman Divacky       assert(lost_fraction == lfExactlyZero);
1301f22ef01cSRoman Divacky 
1302f22ef01cSRoman Divacky       shiftSignificandLeft(-exponentChange);
1303f22ef01cSRoman Divacky 
1304f22ef01cSRoman Divacky       return opOK;
1305f22ef01cSRoman Divacky     }
1306f22ef01cSRoman Divacky 
1307f22ef01cSRoman Divacky     if (exponentChange > 0) {
1308f22ef01cSRoman Divacky       lostFraction lf;
1309f22ef01cSRoman Divacky 
1310f22ef01cSRoman Divacky       /* Shift right and capture any new lost fraction.  */
1311f22ef01cSRoman Divacky       lf = shiftSignificandRight(exponentChange);
1312f22ef01cSRoman Divacky 
1313f22ef01cSRoman Divacky       lost_fraction = combineLostFractions(lf, lost_fraction);
1314f22ef01cSRoman Divacky 
1315f22ef01cSRoman Divacky       /* Keep OMSB up-to-date.  */
1316f22ef01cSRoman Divacky       if (omsb > (unsigned) exponentChange)
1317f22ef01cSRoman Divacky         omsb -= exponentChange;
1318f22ef01cSRoman Divacky       else
1319f22ef01cSRoman Divacky         omsb = 0;
1320f22ef01cSRoman Divacky     }
1321f22ef01cSRoman Divacky   }
1322f22ef01cSRoman Divacky 
1323f22ef01cSRoman Divacky   /* Now round the number according to rounding_mode given the lost
1324f22ef01cSRoman Divacky      fraction.  */
1325f22ef01cSRoman Divacky 
1326f22ef01cSRoman Divacky   /* As specified in IEEE 754, since we do not trap we do not report
1327f22ef01cSRoman Divacky      underflow for exact results.  */
1328f22ef01cSRoman Divacky   if (lost_fraction == lfExactlyZero) {
1329f22ef01cSRoman Divacky     /* Canonicalize zeroes.  */
1330f22ef01cSRoman Divacky     if (omsb == 0)
1331f22ef01cSRoman Divacky       category = fcZero;
1332f22ef01cSRoman Divacky 
1333f22ef01cSRoman Divacky     return opOK;
1334f22ef01cSRoman Divacky   }
1335f22ef01cSRoman Divacky 
1336f22ef01cSRoman Divacky   /* Increment the significand if we're rounding away from zero.  */
1337f22ef01cSRoman Divacky   if (roundAwayFromZero(rounding_mode, lost_fraction, 0)) {
1338f22ef01cSRoman Divacky     if (omsb == 0)
1339f22ef01cSRoman Divacky       exponent = semantics->minExponent;
1340f22ef01cSRoman Divacky 
1341f22ef01cSRoman Divacky     incrementSignificand();
1342f22ef01cSRoman Divacky     omsb = significandMSB() + 1;
1343f22ef01cSRoman Divacky 
1344f22ef01cSRoman Divacky     /* Did the significand increment overflow?  */
1345f22ef01cSRoman Divacky     if (omsb == (unsigned) semantics->precision + 1) {
1346f22ef01cSRoman Divacky       /* Renormalize by incrementing the exponent and shifting our
1347f22ef01cSRoman Divacky          significand right one.  However if we already have the
1348f22ef01cSRoman Divacky          maximum exponent we overflow to infinity.  */
1349f22ef01cSRoman Divacky       if (exponent == semantics->maxExponent) {
1350f22ef01cSRoman Divacky         category = fcInfinity;
1351f22ef01cSRoman Divacky 
1352f22ef01cSRoman Divacky         return (opStatus) (opOverflow | opInexact);
1353f22ef01cSRoman Divacky       }
1354f22ef01cSRoman Divacky 
1355f22ef01cSRoman Divacky       shiftSignificandRight(1);
1356f22ef01cSRoman Divacky 
1357f22ef01cSRoman Divacky       return opInexact;
1358f22ef01cSRoman Divacky     }
1359f22ef01cSRoman Divacky   }
1360f22ef01cSRoman Divacky 
1361f22ef01cSRoman Divacky   /* The normal case - we were and are not denormal, and any
1362f22ef01cSRoman Divacky      significand increment above didn't overflow.  */
1363f22ef01cSRoman Divacky   if (omsb == semantics->precision)
1364f22ef01cSRoman Divacky     return opInexact;
1365f22ef01cSRoman Divacky 
1366f22ef01cSRoman Divacky   /* We have a non-zero denormal.  */
1367f22ef01cSRoman Divacky   assert(omsb < semantics->precision);
1368f22ef01cSRoman Divacky 
1369f22ef01cSRoman Divacky   /* Canonicalize zeroes.  */
1370f22ef01cSRoman Divacky   if (omsb == 0)
1371f22ef01cSRoman Divacky     category = fcZero;
1372f22ef01cSRoman Divacky 
1373f22ef01cSRoman Divacky   /* The fcZero case is a denormal that underflowed to zero.  */
1374f22ef01cSRoman Divacky   return (opStatus) (opUnderflow | opInexact);
1375f22ef01cSRoman Divacky }
1376f22ef01cSRoman Divacky 
addOrSubtractSpecials(const IEEEFloat & rhs,bool subtract)1377d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::addOrSubtractSpecials(const IEEEFloat &rhs,
1378d88c1a5aSDimitry Andric                                                      bool subtract) {
1379f785676fSDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
1380f22ef01cSRoman Divacky   default:
138191bc56edSDimitry Andric     llvm_unreachable(nullptr);
1382f22ef01cSRoman Divacky 
1383f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
1384f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
1385f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
1386f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
1387f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
1388f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
1389f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
1390f22ef01cSRoman Divacky     return opOK;
1391f22ef01cSRoman Divacky 
1392f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
1393f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
1394f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
139591bc56edSDimitry Andric     // We need to be sure to flip the sign here for subtraction because we
139691bc56edSDimitry Andric     // don't have a separate negate operation so -NaN becomes 0 - NaN here.
139791bc56edSDimitry Andric     sign = rhs.sign ^ subtract;
1398f22ef01cSRoman Divacky     category = fcNaN;
1399f22ef01cSRoman Divacky     copySignificand(rhs);
1400f22ef01cSRoman Divacky     return opOK;
1401f22ef01cSRoman Divacky 
1402f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
1403f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
1404f22ef01cSRoman Divacky     category = fcInfinity;
1405f22ef01cSRoman Divacky     sign = rhs.sign ^ subtract;
1406f22ef01cSRoman Divacky     return opOK;
1407f22ef01cSRoman Divacky 
1408f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
1409f22ef01cSRoman Divacky     assign(rhs);
1410f22ef01cSRoman Divacky     sign = rhs.sign ^ subtract;
1411f22ef01cSRoman Divacky     return opOK;
1412f22ef01cSRoman Divacky 
1413f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
1414f22ef01cSRoman Divacky     /* Sign depends on rounding mode; handled by caller.  */
1415f22ef01cSRoman Divacky     return opOK;
1416f22ef01cSRoman Divacky 
1417f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
1418f22ef01cSRoman Divacky     /* Differently signed infinities can only be validly
1419f22ef01cSRoman Divacky        subtracted.  */
1420f22ef01cSRoman Divacky     if (((sign ^ rhs.sign)!=0) != subtract) {
1421f22ef01cSRoman Divacky       makeNaN();
1422f22ef01cSRoman Divacky       return opInvalidOp;
1423f22ef01cSRoman Divacky     }
1424f22ef01cSRoman Divacky 
1425f22ef01cSRoman Divacky     return opOK;
1426f22ef01cSRoman Divacky 
1427f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
1428f22ef01cSRoman Divacky     return opDivByZero;
1429f22ef01cSRoman Divacky   }
1430f22ef01cSRoman Divacky }
1431f22ef01cSRoman Divacky 
1432f22ef01cSRoman Divacky /* Add or subtract two normal numbers.  */
addOrSubtractSignificand(const IEEEFloat & rhs,bool subtract)1433d88c1a5aSDimitry Andric lostFraction IEEEFloat::addOrSubtractSignificand(const IEEEFloat &rhs,
1434d88c1a5aSDimitry Andric                                                  bool subtract) {
1435f22ef01cSRoman Divacky   integerPart carry;
1436f22ef01cSRoman Divacky   lostFraction lost_fraction;
1437f22ef01cSRoman Divacky   int bits;
1438f22ef01cSRoman Divacky 
1439f22ef01cSRoman Divacky   /* Determine if the operation on the absolute values is effectively
1440f22ef01cSRoman Divacky      an addition or subtraction.  */
1441ff0cc061SDimitry Andric   subtract ^= static_cast<bool>(sign ^ rhs.sign);
1442f22ef01cSRoman Divacky 
1443f22ef01cSRoman Divacky   /* Are we bigger exponent-wise than the RHS?  */
1444f22ef01cSRoman Divacky   bits = exponent - rhs.exponent;
1445f22ef01cSRoman Divacky 
1446f22ef01cSRoman Divacky   /* Subtraction is more subtle than one might naively expect.  */
1447f22ef01cSRoman Divacky   if (subtract) {
1448d88c1a5aSDimitry Andric     IEEEFloat temp_rhs(rhs);
1449f22ef01cSRoman Divacky     bool reverse;
1450f22ef01cSRoman Divacky 
1451f22ef01cSRoman Divacky     if (bits == 0) {
1452f22ef01cSRoman Divacky       reverse = compareAbsoluteValue(temp_rhs) == cmpLessThan;
1453f22ef01cSRoman Divacky       lost_fraction = lfExactlyZero;
1454f22ef01cSRoman Divacky     } else if (bits > 0) {
1455f22ef01cSRoman Divacky       lost_fraction = temp_rhs.shiftSignificandRight(bits - 1);
1456f22ef01cSRoman Divacky       shiftSignificandLeft(1);
1457f22ef01cSRoman Divacky       reverse = false;
1458f22ef01cSRoman Divacky     } else {
1459f22ef01cSRoman Divacky       lost_fraction = shiftSignificandRight(-bits - 1);
1460f22ef01cSRoman Divacky       temp_rhs.shiftSignificandLeft(1);
1461f22ef01cSRoman Divacky       reverse = true;
1462f22ef01cSRoman Divacky     }
1463f22ef01cSRoman Divacky 
1464f22ef01cSRoman Divacky     if (reverse) {
1465f22ef01cSRoman Divacky       carry = temp_rhs.subtractSignificand
1466f22ef01cSRoman Divacky         (*this, lost_fraction != lfExactlyZero);
1467f22ef01cSRoman Divacky       copySignificand(temp_rhs);
1468f22ef01cSRoman Divacky       sign = !sign;
1469f22ef01cSRoman Divacky     } else {
1470f22ef01cSRoman Divacky       carry = subtractSignificand
1471f22ef01cSRoman Divacky         (temp_rhs, lost_fraction != lfExactlyZero);
1472f22ef01cSRoman Divacky     }
1473f22ef01cSRoman Divacky 
1474f22ef01cSRoman Divacky     /* Invert the lost fraction - it was on the RHS and
1475f22ef01cSRoman Divacky        subtracted.  */
1476f22ef01cSRoman Divacky     if (lost_fraction == lfLessThanHalf)
1477f22ef01cSRoman Divacky       lost_fraction = lfMoreThanHalf;
1478f22ef01cSRoman Divacky     else if (lost_fraction == lfMoreThanHalf)
1479f22ef01cSRoman Divacky       lost_fraction = lfLessThanHalf;
1480f22ef01cSRoman Divacky 
1481f22ef01cSRoman Divacky     /* The code above is intended to ensure that no borrow is
1482f22ef01cSRoman Divacky        necessary.  */
1483f22ef01cSRoman Divacky     assert(!carry);
14846122f3e6SDimitry Andric     (void)carry;
1485f22ef01cSRoman Divacky   } else {
1486f22ef01cSRoman Divacky     if (bits > 0) {
1487d88c1a5aSDimitry Andric       IEEEFloat temp_rhs(rhs);
1488f22ef01cSRoman Divacky 
1489f22ef01cSRoman Divacky       lost_fraction = temp_rhs.shiftSignificandRight(bits);
1490f22ef01cSRoman Divacky       carry = addSignificand(temp_rhs);
1491f22ef01cSRoman Divacky     } else {
1492f22ef01cSRoman Divacky       lost_fraction = shiftSignificandRight(-bits);
1493f22ef01cSRoman Divacky       carry = addSignificand(rhs);
1494f22ef01cSRoman Divacky     }
1495f22ef01cSRoman Divacky 
1496f22ef01cSRoman Divacky     /* We have a guard bit; generating a carry cannot happen.  */
1497f22ef01cSRoman Divacky     assert(!carry);
14986122f3e6SDimitry Andric     (void)carry;
1499f22ef01cSRoman Divacky   }
1500f22ef01cSRoman Divacky 
1501f22ef01cSRoman Divacky   return lost_fraction;
1502f22ef01cSRoman Divacky }
1503f22ef01cSRoman Divacky 
multiplySpecials(const IEEEFloat & rhs)1504d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::multiplySpecials(const IEEEFloat &rhs) {
1505f785676fSDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
1506f22ef01cSRoman Divacky   default:
150791bc56edSDimitry Andric     llvm_unreachable(nullptr);
1508f22ef01cSRoman Divacky 
1509f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
1510f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
1511f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
1512f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
1513f785676fSDimitry Andric     sign = false;
1514f22ef01cSRoman Divacky     return opOK;
1515f22ef01cSRoman Divacky 
1516f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
1517f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
1518f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
1519f785676fSDimitry Andric     sign = false;
1520f22ef01cSRoman Divacky     category = fcNaN;
1521f22ef01cSRoman Divacky     copySignificand(rhs);
1522f22ef01cSRoman Divacky     return opOK;
1523f22ef01cSRoman Divacky 
1524f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
1525f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
1526f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
1527f22ef01cSRoman Divacky     category = fcInfinity;
1528f22ef01cSRoman Divacky     return opOK;
1529f22ef01cSRoman Divacky 
1530f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
1531f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
1532f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
1533f22ef01cSRoman Divacky     category = fcZero;
1534f22ef01cSRoman Divacky     return opOK;
1535f22ef01cSRoman Divacky 
1536f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
1537f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
1538f22ef01cSRoman Divacky     makeNaN();
1539f22ef01cSRoman Divacky     return opInvalidOp;
1540f22ef01cSRoman Divacky 
1541f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
1542f22ef01cSRoman Divacky     return opOK;
1543f22ef01cSRoman Divacky   }
1544f22ef01cSRoman Divacky }
1545f22ef01cSRoman Divacky 
divideSpecials(const IEEEFloat & rhs)1546d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::divideSpecials(const IEEEFloat &rhs) {
1547f785676fSDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
1548f22ef01cSRoman Divacky   default:
154991bc56edSDimitry Andric     llvm_unreachable(nullptr);
1550f22ef01cSRoman Divacky 
1551f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
1552f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
1553f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
1554f22ef01cSRoman Divacky     category = fcNaN;
1555f22ef01cSRoman Divacky     copySignificand(rhs);
155689cb50c9SDimitry Andric     LLVM_FALLTHROUGH;
1557f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
1558f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
1559f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
1560f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
1561f785676fSDimitry Andric     sign = false;
156289cb50c9SDimitry Andric     LLVM_FALLTHROUGH;
1563f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
1564f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
1565f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
1566f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
1567f22ef01cSRoman Divacky     return opOK;
1568f22ef01cSRoman Divacky 
1569f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
1570f22ef01cSRoman Divacky     category = fcZero;
1571f22ef01cSRoman Divacky     return opOK;
1572f22ef01cSRoman Divacky 
1573f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
1574f22ef01cSRoman Divacky     category = fcInfinity;
1575f22ef01cSRoman Divacky     return opDivByZero;
1576f22ef01cSRoman Divacky 
1577f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
1578f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
1579f22ef01cSRoman Divacky     makeNaN();
1580f22ef01cSRoman Divacky     return opInvalidOp;
1581f22ef01cSRoman Divacky 
1582f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
1583f22ef01cSRoman Divacky     return opOK;
1584f22ef01cSRoman Divacky   }
1585f22ef01cSRoman Divacky }
1586f22ef01cSRoman Divacky 
modSpecials(const IEEEFloat & rhs)1587d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::modSpecials(const IEEEFloat &rhs) {
1588f785676fSDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
1589f22ef01cSRoman Divacky   default:
159091bc56edSDimitry Andric     llvm_unreachable(nullptr);
1591f22ef01cSRoman Divacky 
1592f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
1593f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
1594f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
1595f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
1596f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
1597f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
1598f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
1599f22ef01cSRoman Divacky     return opOK;
1600f22ef01cSRoman Divacky 
1601f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
1602f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
1603f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
1604f785676fSDimitry Andric     sign = false;
1605f22ef01cSRoman Divacky     category = fcNaN;
1606f22ef01cSRoman Divacky     copySignificand(rhs);
1607f22ef01cSRoman Divacky     return opOK;
1608f22ef01cSRoman Divacky 
1609f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
1610f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
1611f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
1612f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
1613f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
1614f22ef01cSRoman Divacky     makeNaN();
1615f22ef01cSRoman Divacky     return opInvalidOp;
1616f22ef01cSRoman Divacky 
1617f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
1618f22ef01cSRoman Divacky     return opOK;
1619f22ef01cSRoman Divacky   }
1620f22ef01cSRoman Divacky }
1621f22ef01cSRoman Divacky 
1622f22ef01cSRoman Divacky /* Change sign.  */
changeSign()1623d88c1a5aSDimitry Andric void IEEEFloat::changeSign() {
1624f22ef01cSRoman Divacky   /* Look mummy, this one's easy.  */
1625f22ef01cSRoman Divacky   sign = !sign;
1626f22ef01cSRoman Divacky }
1627f22ef01cSRoman Divacky 
1628f22ef01cSRoman Divacky /* Normalized addition or subtraction.  */
addOrSubtract(const IEEEFloat & rhs,roundingMode rounding_mode,bool subtract)1629d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::addOrSubtract(const IEEEFloat &rhs,
1630d88c1a5aSDimitry Andric                                              roundingMode rounding_mode,
1631d88c1a5aSDimitry Andric                                              bool subtract) {
1632f22ef01cSRoman Divacky   opStatus fs;
1633f22ef01cSRoman Divacky 
1634f22ef01cSRoman Divacky   fs = addOrSubtractSpecials(rhs, subtract);
1635f22ef01cSRoman Divacky 
1636f22ef01cSRoman Divacky   /* This return code means it was not a simple case.  */
1637f22ef01cSRoman Divacky   if (fs == opDivByZero) {
1638f22ef01cSRoman Divacky     lostFraction lost_fraction;
1639f22ef01cSRoman Divacky 
1640f22ef01cSRoman Divacky     lost_fraction = addOrSubtractSignificand(rhs, subtract);
1641f22ef01cSRoman Divacky     fs = normalize(rounding_mode, lost_fraction);
1642f22ef01cSRoman Divacky 
1643f22ef01cSRoman Divacky     /* Can only be zero if we lost no fraction.  */
1644f22ef01cSRoman Divacky     assert(category != fcZero || lost_fraction == lfExactlyZero);
1645f22ef01cSRoman Divacky   }
1646f22ef01cSRoman Divacky 
1647f22ef01cSRoman Divacky   /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a
1648f22ef01cSRoman Divacky      positive zero unless rounding to minus infinity, except that
1649f22ef01cSRoman Divacky      adding two like-signed zeroes gives that zero.  */
1650f22ef01cSRoman Divacky   if (category == fcZero) {
1651f22ef01cSRoman Divacky     if (rhs.category != fcZero || (sign == rhs.sign) == subtract)
1652f22ef01cSRoman Divacky       sign = (rounding_mode == rmTowardNegative);
1653f22ef01cSRoman Divacky   }
1654f22ef01cSRoman Divacky 
1655f22ef01cSRoman Divacky   return fs;
1656f22ef01cSRoman Divacky }
1657f22ef01cSRoman Divacky 
1658f22ef01cSRoman Divacky /* Normalized addition.  */
add(const IEEEFloat & rhs,roundingMode rounding_mode)1659d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::add(const IEEEFloat &rhs,
1660d88c1a5aSDimitry Andric                                    roundingMode rounding_mode) {
1661f22ef01cSRoman Divacky   return addOrSubtract(rhs, rounding_mode, false);
1662f22ef01cSRoman Divacky }
1663f22ef01cSRoman Divacky 
1664f22ef01cSRoman Divacky /* Normalized subtraction.  */
subtract(const IEEEFloat & rhs,roundingMode rounding_mode)1665d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::subtract(const IEEEFloat &rhs,
1666d88c1a5aSDimitry Andric                                         roundingMode rounding_mode) {
1667f22ef01cSRoman Divacky   return addOrSubtract(rhs, rounding_mode, true);
1668f22ef01cSRoman Divacky }
1669f22ef01cSRoman Divacky 
1670f22ef01cSRoman Divacky /* Normalized multiply.  */
multiply(const IEEEFloat & rhs,roundingMode rounding_mode)1671d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::multiply(const IEEEFloat &rhs,
1672d88c1a5aSDimitry Andric                                         roundingMode rounding_mode) {
1673f22ef01cSRoman Divacky   opStatus fs;
1674f22ef01cSRoman Divacky 
1675f22ef01cSRoman Divacky   sign ^= rhs.sign;
1676f22ef01cSRoman Divacky   fs = multiplySpecials(rhs);
1677f22ef01cSRoman Divacky 
1678f785676fSDimitry Andric   if (isFiniteNonZero()) {
167991bc56edSDimitry Andric     lostFraction lost_fraction = multiplySignificand(rhs, nullptr);
1680f22ef01cSRoman Divacky     fs = normalize(rounding_mode, lost_fraction);
1681f22ef01cSRoman Divacky     if (lost_fraction != lfExactlyZero)
1682f22ef01cSRoman Divacky       fs = (opStatus) (fs | opInexact);
1683f22ef01cSRoman Divacky   }
1684f22ef01cSRoman Divacky 
1685f22ef01cSRoman Divacky   return fs;
1686f22ef01cSRoman Divacky }
1687f22ef01cSRoman Divacky 
1688f22ef01cSRoman Divacky /* Normalized divide.  */
divide(const IEEEFloat & rhs,roundingMode rounding_mode)1689d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::divide(const IEEEFloat &rhs,
1690d88c1a5aSDimitry Andric                                       roundingMode rounding_mode) {
1691f22ef01cSRoman Divacky   opStatus fs;
1692f22ef01cSRoman Divacky 
1693f22ef01cSRoman Divacky   sign ^= rhs.sign;
1694f22ef01cSRoman Divacky   fs = divideSpecials(rhs);
1695f22ef01cSRoman Divacky 
1696f785676fSDimitry Andric   if (isFiniteNonZero()) {
1697f22ef01cSRoman Divacky     lostFraction lost_fraction = divideSignificand(rhs);
1698f22ef01cSRoman Divacky     fs = normalize(rounding_mode, lost_fraction);
1699f22ef01cSRoman Divacky     if (lost_fraction != lfExactlyZero)
1700f22ef01cSRoman Divacky       fs = (opStatus) (fs | opInexact);
1701f22ef01cSRoman Divacky   }
1702f22ef01cSRoman Divacky 
1703f22ef01cSRoman Divacky   return fs;
1704f22ef01cSRoman Divacky }
1705f22ef01cSRoman Divacky 
1706f22ef01cSRoman Divacky /* Normalized remainder.  This is not currently correct in all cases.  */
remainder(const IEEEFloat & rhs)1707d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::remainder(const IEEEFloat &rhs) {
1708f22ef01cSRoman Divacky   opStatus fs;
1709d88c1a5aSDimitry Andric   IEEEFloat V = *this;
1710f22ef01cSRoman Divacky   unsigned int origSign = sign;
1711f22ef01cSRoman Divacky 
1712f22ef01cSRoman Divacky   fs = V.divide(rhs, rmNearestTiesToEven);
1713f22ef01cSRoman Divacky   if (fs == opDivByZero)
1714f22ef01cSRoman Divacky     return fs;
1715f22ef01cSRoman Divacky 
1716f22ef01cSRoman Divacky   int parts = partCount();
1717f22ef01cSRoman Divacky   integerPart *x = new integerPart[parts];
1718f22ef01cSRoman Divacky   bool ignored;
17197a7e6055SDimitry Andric   fs = V.convertToInteger(makeMutableArrayRef(x, parts),
17207a7e6055SDimitry Andric                           parts * integerPartWidth, true, rmNearestTiesToEven,
17217a7e6055SDimitry Andric                           &ignored);
1722d88c1a5aSDimitry Andric   if (fs == opInvalidOp) {
1723d88c1a5aSDimitry Andric     delete[] x;
1724f22ef01cSRoman Divacky     return fs;
1725d88c1a5aSDimitry Andric   }
1726f22ef01cSRoman Divacky 
1727f22ef01cSRoman Divacky   fs = V.convertFromZeroExtendedInteger(x, parts * integerPartWidth, true,
1728f22ef01cSRoman Divacky                                         rmNearestTiesToEven);
1729f22ef01cSRoman Divacky   assert(fs==opOK);   // should always work
1730f22ef01cSRoman Divacky 
1731f22ef01cSRoman Divacky   fs = V.multiply(rhs, rmNearestTiesToEven);
1732f22ef01cSRoman Divacky   assert(fs==opOK || fs==opInexact);   // should not overflow or underflow
1733f22ef01cSRoman Divacky 
1734f22ef01cSRoman Divacky   fs = subtract(V, rmNearestTiesToEven);
1735f22ef01cSRoman Divacky   assert(fs==opOK || fs==opInexact);   // likewise
1736f22ef01cSRoman Divacky 
1737f22ef01cSRoman Divacky   if (isZero())
1738f22ef01cSRoman Divacky     sign = origSign;    // IEEE754 requires this
1739f22ef01cSRoman Divacky   delete[] x;
1740f22ef01cSRoman Divacky   return fs;
1741f22ef01cSRoman Divacky }
1742f22ef01cSRoman Divacky 
17437a7e6055SDimitry Andric /* Normalized llvm frem (C fmod). */
mod(const IEEEFloat & rhs)1744d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::mod(const IEEEFloat &rhs) {
1745f22ef01cSRoman Divacky   opStatus fs;
1746f22ef01cSRoman Divacky   fs = modSpecials(rhs);
17472cab237bSDimitry Andric   unsigned int origSign = sign;
1748f22ef01cSRoman Divacky 
17497a7e6055SDimitry Andric   while (isFiniteNonZero() && rhs.isFiniteNonZero() &&
17507a7e6055SDimitry Andric          compareAbsoluteValue(rhs) != cmpLessThan) {
17517a7e6055SDimitry Andric     IEEEFloat V = scalbn(rhs, ilogb(*this) - ilogb(rhs), rmNearestTiesToEven);
17527a7e6055SDimitry Andric     if (compareAbsoluteValue(V) == cmpLessThan)
17537a7e6055SDimitry Andric       V = scalbn(V, -1, rmNearestTiesToEven);
17547a7e6055SDimitry Andric     V.sign = sign;
1755f22ef01cSRoman Divacky 
17567d523365SDimitry Andric     fs = subtract(V, rmNearestTiesToEven);
17577a7e6055SDimitry Andric     assert(fs==opOK);
1758f22ef01cSRoman Divacky   }
17592cab237bSDimitry Andric   if (isZero())
17602cab237bSDimitry Andric     sign = origSign; // fmod requires this
1761f22ef01cSRoman Divacky   return fs;
1762f22ef01cSRoman Divacky }
1763f22ef01cSRoman Divacky 
1764f22ef01cSRoman Divacky /* Normalized fused-multiply-add.  */
fusedMultiplyAdd(const IEEEFloat & multiplicand,const IEEEFloat & addend,roundingMode rounding_mode)1765d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::fusedMultiplyAdd(const IEEEFloat &multiplicand,
1766d88c1a5aSDimitry Andric                                                 const IEEEFloat &addend,
1767d88c1a5aSDimitry Andric                                                 roundingMode rounding_mode) {
1768f22ef01cSRoman Divacky   opStatus fs;
1769f22ef01cSRoman Divacky 
1770f22ef01cSRoman Divacky   /* Post-multiplication sign, before addition.  */
1771f22ef01cSRoman Divacky   sign ^= multiplicand.sign;
1772f22ef01cSRoman Divacky 
1773f22ef01cSRoman Divacky   /* If and only if all arguments are normal do we need to do an
1774f22ef01cSRoman Divacky      extended-precision calculation.  */
1775f785676fSDimitry Andric   if (isFiniteNonZero() &&
1776f785676fSDimitry Andric       multiplicand.isFiniteNonZero() &&
177739d628a0SDimitry Andric       addend.isFinite()) {
1778f22ef01cSRoman Divacky     lostFraction lost_fraction;
1779f22ef01cSRoman Divacky 
1780f22ef01cSRoman Divacky     lost_fraction = multiplySignificand(multiplicand, &addend);
1781f22ef01cSRoman Divacky     fs = normalize(rounding_mode, lost_fraction);
1782f22ef01cSRoman Divacky     if (lost_fraction != lfExactlyZero)
1783f22ef01cSRoman Divacky       fs = (opStatus) (fs | opInexact);
1784f22ef01cSRoman Divacky 
1785f22ef01cSRoman Divacky     /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a
1786f22ef01cSRoman Divacky        positive zero unless rounding to minus infinity, except that
1787f22ef01cSRoman Divacky        adding two like-signed zeroes gives that zero.  */
178839d628a0SDimitry Andric     if (category == fcZero && !(fs & opUnderflow) && sign != addend.sign)
1789f22ef01cSRoman Divacky       sign = (rounding_mode == rmTowardNegative);
1790f22ef01cSRoman Divacky   } else {
1791f22ef01cSRoman Divacky     fs = multiplySpecials(multiplicand);
1792f22ef01cSRoman Divacky 
1793f22ef01cSRoman Divacky     /* FS can only be opOK or opInvalidOp.  There is no more work
1794f22ef01cSRoman Divacky        to do in the latter case.  The IEEE-754R standard says it is
1795f22ef01cSRoman Divacky        implementation-defined in this case whether, if ADDEND is a
1796f22ef01cSRoman Divacky        quiet NaN, we raise invalid op; this implementation does so.
1797f22ef01cSRoman Divacky 
1798f22ef01cSRoman Divacky        If we need to do the addition we can do so with normal
1799f22ef01cSRoman Divacky        precision.  */
1800f22ef01cSRoman Divacky     if (fs == opOK)
1801f22ef01cSRoman Divacky       fs = addOrSubtract(addend, rounding_mode, false);
1802f22ef01cSRoman Divacky   }
1803f22ef01cSRoman Divacky 
1804f22ef01cSRoman Divacky   return fs;
1805f22ef01cSRoman Divacky }
1806f22ef01cSRoman Divacky 
18077ae0e2c9SDimitry Andric /* Rounding-mode corrrect round to integral value.  */
roundToIntegral(roundingMode rounding_mode)1808d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::roundToIntegral(roundingMode rounding_mode) {
18097ae0e2c9SDimitry Andric   opStatus fs;
18107ae0e2c9SDimitry Andric 
18117ae0e2c9SDimitry Andric   // If the exponent is large enough, we know that this value is already
18127ae0e2c9SDimitry Andric   // integral, and the arithmetic below would potentially cause it to saturate
18137ae0e2c9SDimitry Andric   // to +/-Inf.  Bail out early instead.
1814f785676fSDimitry Andric   if (isFiniteNonZero() && exponent+1 >= (int)semanticsPrecision(*semantics))
18157ae0e2c9SDimitry Andric     return opOK;
18167ae0e2c9SDimitry Andric 
18177ae0e2c9SDimitry Andric   // The algorithm here is quite simple: we add 2^(p-1), where p is the
18187ae0e2c9SDimitry Andric   // precision of our format, and then subtract it back off again.  The choice
18197ae0e2c9SDimitry Andric   // of rounding modes for the addition/subtraction determines the rounding mode
18207ae0e2c9SDimitry Andric   // for our integral rounding as well.
18217ae0e2c9SDimitry Andric   // NOTE: When the input value is negative, we do subtraction followed by
18227ae0e2c9SDimitry Andric   // addition instead.
18237ae0e2c9SDimitry Andric   APInt IntegerConstant(NextPowerOf2(semanticsPrecision(*semantics)), 1);
18247ae0e2c9SDimitry Andric   IntegerConstant <<= semanticsPrecision(*semantics)-1;
1825d88c1a5aSDimitry Andric   IEEEFloat MagicConstant(*semantics);
18267ae0e2c9SDimitry Andric   fs = MagicConstant.convertFromAPInt(IntegerConstant, false,
18277ae0e2c9SDimitry Andric                                       rmNearestTiesToEven);
18287a7e6055SDimitry Andric   MagicConstant.sign = sign;
18297ae0e2c9SDimitry Andric 
18307ae0e2c9SDimitry Andric   if (fs != opOK)
18317ae0e2c9SDimitry Andric     return fs;
18327ae0e2c9SDimitry Andric 
18337ae0e2c9SDimitry Andric   // Preserve the input sign so that we can handle 0.0/-0.0 cases correctly.
18347ae0e2c9SDimitry Andric   bool inputSign = isNegative();
18357ae0e2c9SDimitry Andric 
18367ae0e2c9SDimitry Andric   fs = add(MagicConstant, rounding_mode);
18377ae0e2c9SDimitry Andric   if (fs != opOK && fs != opInexact)
18387ae0e2c9SDimitry Andric     return fs;
18397ae0e2c9SDimitry Andric 
18407ae0e2c9SDimitry Andric   fs = subtract(MagicConstant, rounding_mode);
18417ae0e2c9SDimitry Andric 
18427ae0e2c9SDimitry Andric   // Restore the input sign.
18437ae0e2c9SDimitry Andric   if (inputSign != isNegative())
18447ae0e2c9SDimitry Andric     changeSign();
18457ae0e2c9SDimitry Andric 
18467ae0e2c9SDimitry Andric   return fs;
18477ae0e2c9SDimitry Andric }
18487ae0e2c9SDimitry Andric 
18497ae0e2c9SDimitry Andric 
1850f22ef01cSRoman Divacky /* Comparison requires normalized numbers.  */
compare(const IEEEFloat & rhs) const1851d88c1a5aSDimitry Andric IEEEFloat::cmpResult IEEEFloat::compare(const IEEEFloat &rhs) const {
1852f22ef01cSRoman Divacky   cmpResult result;
1853f22ef01cSRoman Divacky 
1854f22ef01cSRoman Divacky   assert(semantics == rhs.semantics);
1855f22ef01cSRoman Divacky 
1856f785676fSDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
1857f22ef01cSRoman Divacky   default:
185891bc56edSDimitry Andric     llvm_unreachable(nullptr);
1859f22ef01cSRoman Divacky 
1860f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
1861f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
1862f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
1863f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
1864f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
1865f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
1866f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
1867f22ef01cSRoman Divacky     return cmpUnordered;
1868f22ef01cSRoman Divacky 
1869f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
1870f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
1871f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
1872f22ef01cSRoman Divacky     if (sign)
1873f22ef01cSRoman Divacky       return cmpLessThan;
1874f22ef01cSRoman Divacky     else
1875f22ef01cSRoman Divacky       return cmpGreaterThan;
1876f22ef01cSRoman Divacky 
1877f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
1878f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
1879f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
1880f22ef01cSRoman Divacky     if (rhs.sign)
1881f22ef01cSRoman Divacky       return cmpGreaterThan;
1882f22ef01cSRoman Divacky     else
1883f22ef01cSRoman Divacky       return cmpLessThan;
1884f22ef01cSRoman Divacky 
1885f785676fSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
1886f22ef01cSRoman Divacky     if (sign == rhs.sign)
1887f22ef01cSRoman Divacky       return cmpEqual;
1888f22ef01cSRoman Divacky     else if (sign)
1889f22ef01cSRoman Divacky       return cmpLessThan;
1890f22ef01cSRoman Divacky     else
1891f22ef01cSRoman Divacky       return cmpGreaterThan;
1892f22ef01cSRoman Divacky 
1893f785676fSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
1894f22ef01cSRoman Divacky     return cmpEqual;
1895f22ef01cSRoman Divacky 
1896f785676fSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
1897f22ef01cSRoman Divacky     break;
1898f22ef01cSRoman Divacky   }
1899f22ef01cSRoman Divacky 
1900f22ef01cSRoman Divacky   /* Two normal numbers.  Do they have the same sign?  */
1901f22ef01cSRoman Divacky   if (sign != rhs.sign) {
1902f22ef01cSRoman Divacky     if (sign)
1903f22ef01cSRoman Divacky       result = cmpLessThan;
1904f22ef01cSRoman Divacky     else
1905f22ef01cSRoman Divacky       result = cmpGreaterThan;
1906f22ef01cSRoman Divacky   } else {
1907f22ef01cSRoman Divacky     /* Compare absolute values; invert result if negative.  */
1908f22ef01cSRoman Divacky     result = compareAbsoluteValue(rhs);
1909f22ef01cSRoman Divacky 
1910f22ef01cSRoman Divacky     if (sign) {
1911f22ef01cSRoman Divacky       if (result == cmpLessThan)
1912f22ef01cSRoman Divacky         result = cmpGreaterThan;
1913f22ef01cSRoman Divacky       else if (result == cmpGreaterThan)
1914f22ef01cSRoman Divacky         result = cmpLessThan;
1915f22ef01cSRoman Divacky     }
1916f22ef01cSRoman Divacky   }
1917f22ef01cSRoman Divacky 
1918f22ef01cSRoman Divacky   return result;
1919f22ef01cSRoman Divacky }
1920f22ef01cSRoman Divacky 
1921d88c1a5aSDimitry Andric /// IEEEFloat::convert - convert a value of one floating point type to another.
1922f22ef01cSRoman Divacky /// The return value corresponds to the IEEE754 exceptions.  *losesInfo
1923f22ef01cSRoman Divacky /// records whether the transformation lost information, i.e. whether
1924f22ef01cSRoman Divacky /// converting the result back to the original type will produce the
1925f22ef01cSRoman Divacky /// original value (this is almost the same as return value==fsOK, but there
1926f22ef01cSRoman Divacky /// are edge cases where this is not so).
1927f22ef01cSRoman Divacky 
convert(const fltSemantics & toSemantics,roundingMode rounding_mode,bool * losesInfo)1928d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics,
1929d88c1a5aSDimitry Andric                                        roundingMode rounding_mode,
1930d88c1a5aSDimitry Andric                                        bool *losesInfo) {
1931f22ef01cSRoman Divacky   lostFraction lostFraction;
1932f22ef01cSRoman Divacky   unsigned int newPartCount, oldPartCount;
1933f22ef01cSRoman Divacky   opStatus fs;
1934dff0c46cSDimitry Andric   int shift;
1935dff0c46cSDimitry Andric   const fltSemantics &fromSemantics = *semantics;
1936f22ef01cSRoman Divacky 
1937f22ef01cSRoman Divacky   lostFraction = lfExactlyZero;
1938f22ef01cSRoman Divacky   newPartCount = partCountForBits(toSemantics.precision + 1);
1939f22ef01cSRoman Divacky   oldPartCount = partCount();
1940dff0c46cSDimitry Andric   shift = toSemantics.precision - fromSemantics.precision;
1941f22ef01cSRoman Divacky 
1942dff0c46cSDimitry Andric   bool X86SpecialNan = false;
1943d88c1a5aSDimitry Andric   if (&fromSemantics == &semX87DoubleExtended &&
1944d88c1a5aSDimitry Andric       &toSemantics != &semX87DoubleExtended && category == fcNaN &&
1945dff0c46cSDimitry Andric       (!(*significandParts() & 0x8000000000000000ULL) ||
1946dff0c46cSDimitry Andric        !(*significandParts() & 0x4000000000000000ULL))) {
1947dff0c46cSDimitry Andric     // x86 has some unusual NaNs which cannot be represented in any other
1948dff0c46cSDimitry Andric     // format; note them here.
1949dff0c46cSDimitry Andric     X86SpecialNan = true;
1950dff0c46cSDimitry Andric   }
1951dff0c46cSDimitry Andric 
1952f785676fSDimitry Andric   // If this is a truncation of a denormal number, and the target semantics
1953f785676fSDimitry Andric   // has larger exponent range than the source semantics (this can happen
1954f785676fSDimitry Andric   // when truncating from PowerPC double-double to double format), the
1955f785676fSDimitry Andric   // right shift could lose result mantissa bits.  Adjust exponent instead
1956f785676fSDimitry Andric   // of performing excessive shift.
1957f785676fSDimitry Andric   if (shift < 0 && isFiniteNonZero()) {
1958f785676fSDimitry Andric     int exponentChange = significandMSB() + 1 - fromSemantics.precision;
1959f785676fSDimitry Andric     if (exponent + exponentChange < toSemantics.minExponent)
1960f785676fSDimitry Andric       exponentChange = toSemantics.minExponent - exponent;
1961f785676fSDimitry Andric     if (exponentChange < shift)
1962f785676fSDimitry Andric       exponentChange = shift;
1963f785676fSDimitry Andric     if (exponentChange < 0) {
1964f785676fSDimitry Andric       shift -= exponentChange;
1965f785676fSDimitry Andric       exponent += exponentChange;
1966f785676fSDimitry Andric     }
1967f785676fSDimitry Andric   }
1968f785676fSDimitry Andric 
1969dff0c46cSDimitry Andric   // If this is a truncation, perform the shift before we narrow the storage.
1970f785676fSDimitry Andric   if (shift < 0 && (isFiniteNonZero() || category==fcNaN))
1971dff0c46cSDimitry Andric     lostFraction = shiftRight(significandParts(), oldPartCount, -shift);
1972dff0c46cSDimitry Andric 
1973dff0c46cSDimitry Andric   // Fix the storage so it can hold to new value.
1974f22ef01cSRoman Divacky   if (newPartCount > oldPartCount) {
1975dff0c46cSDimitry Andric     // The new type requires more storage; make it available.
1976f22ef01cSRoman Divacky     integerPart *newParts;
1977f22ef01cSRoman Divacky     newParts = new integerPart[newPartCount];
1978f22ef01cSRoman Divacky     APInt::tcSet(newParts, 0, newPartCount);
1979f785676fSDimitry Andric     if (isFiniteNonZero() || category==fcNaN)
1980f22ef01cSRoman Divacky       APInt::tcAssign(newParts, significandParts(), oldPartCount);
1981f22ef01cSRoman Divacky     freeSignificand();
1982f22ef01cSRoman Divacky     significand.parts = newParts;
1983dff0c46cSDimitry Andric   } else if (newPartCount == 1 && oldPartCount != 1) {
1984dff0c46cSDimitry Andric     // Switch to built-in storage for a single part.
1985f22ef01cSRoman Divacky     integerPart newPart = 0;
1986f785676fSDimitry Andric     if (isFiniteNonZero() || category==fcNaN)
1987f22ef01cSRoman Divacky       newPart = significandParts()[0];
1988f22ef01cSRoman Divacky     freeSignificand();
1989f22ef01cSRoman Divacky     significand.part = newPart;
1990f22ef01cSRoman Divacky   }
1991dff0c46cSDimitry Andric 
1992dff0c46cSDimitry Andric   // Now that we have the right storage, switch the semantics.
1993dff0c46cSDimitry Andric   semantics = &toSemantics;
1994dff0c46cSDimitry Andric 
1995dff0c46cSDimitry Andric   // If this is an extension, perform the shift now that the storage is
1996dff0c46cSDimitry Andric   // available.
1997f785676fSDimitry Andric   if (shift > 0 && (isFiniteNonZero() || category==fcNaN))
1998dff0c46cSDimitry Andric     APInt::tcShiftLeft(significandParts(), newPartCount, shift);
1999f22ef01cSRoman Divacky 
2000f785676fSDimitry Andric   if (isFiniteNonZero()) {
2001f22ef01cSRoman Divacky     fs = normalize(rounding_mode, lostFraction);
2002f22ef01cSRoman Divacky     *losesInfo = (fs != opOK);
2003f22ef01cSRoman Divacky   } else if (category == fcNaN) {
2004dff0c46cSDimitry Andric     *losesInfo = lostFraction != lfExactlyZero || X86SpecialNan;
2005139f7f9bSDimitry Andric 
2006139f7f9bSDimitry Andric     // For x87 extended precision, we want to make a NaN, not a special NaN if
2007139f7f9bSDimitry Andric     // the input wasn't special either.
2008d88c1a5aSDimitry Andric     if (!X86SpecialNan && semantics == &semX87DoubleExtended)
2009139f7f9bSDimitry Andric       APInt::tcSetBit(significandParts(), semantics->precision - 1);
2010139f7f9bSDimitry Andric 
2011f22ef01cSRoman Divacky     // gcc forces the Quiet bit on, which means (float)(double)(float_sNan)
2012f22ef01cSRoman Divacky     // does not give you back the same bits.  This is dubious, and we
2013f22ef01cSRoman Divacky     // don't currently do it.  You're really supposed to get
2014f22ef01cSRoman Divacky     // an invalid operation signal at runtime, but nobody does that.
2015f22ef01cSRoman Divacky     fs = opOK;
2016f22ef01cSRoman Divacky   } else {
2017f22ef01cSRoman Divacky     *losesInfo = false;
2018dff0c46cSDimitry Andric     fs = opOK;
2019f22ef01cSRoman Divacky   }
2020f22ef01cSRoman Divacky 
2021f22ef01cSRoman Divacky   return fs;
2022f22ef01cSRoman Divacky }
2023f22ef01cSRoman Divacky 
2024f22ef01cSRoman Divacky /* Convert a floating point number to an integer according to the
2025f22ef01cSRoman Divacky    rounding mode.  If the rounded integer value is out of range this
2026f22ef01cSRoman Divacky    returns an invalid operation exception and the contents of the
2027f22ef01cSRoman Divacky    destination parts are unspecified.  If the rounded value is in
2028f22ef01cSRoman Divacky    range but the floating point number is not the exact integer, the C
2029f22ef01cSRoman Divacky    standard doesn't require an inexact exception to be raised.  IEEE
2030f22ef01cSRoman Divacky    854 does require it so we do that.
2031f22ef01cSRoman Divacky 
2032f22ef01cSRoman Divacky    Note that for conversions to integer type the C standard requires
2033f22ef01cSRoman Divacky    round-to-zero to always be used.  */
convertToSignExtendedInteger(MutableArrayRef<integerPart> parts,unsigned int width,bool isSigned,roundingMode rounding_mode,bool * isExact) const2034d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
20357a7e6055SDimitry Andric     MutableArrayRef<integerPart> parts, unsigned int width, bool isSigned,
2036d88c1a5aSDimitry Andric     roundingMode rounding_mode, bool *isExact) const {
2037f22ef01cSRoman Divacky   lostFraction lost_fraction;
2038f22ef01cSRoman Divacky   const integerPart *src;
2039f22ef01cSRoman Divacky   unsigned int dstPartsCount, truncatedBits;
2040f22ef01cSRoman Divacky 
2041f22ef01cSRoman Divacky   *isExact = false;
2042f22ef01cSRoman Divacky 
2043f22ef01cSRoman Divacky   /* Handle the three special cases first.  */
2044f22ef01cSRoman Divacky   if (category == fcInfinity || category == fcNaN)
2045f22ef01cSRoman Divacky     return opInvalidOp;
2046f22ef01cSRoman Divacky 
2047f22ef01cSRoman Divacky   dstPartsCount = partCountForBits(width);
20487a7e6055SDimitry Andric   assert(dstPartsCount <= parts.size() && "Integer too big");
2049f22ef01cSRoman Divacky 
2050f22ef01cSRoman Divacky   if (category == fcZero) {
20517a7e6055SDimitry Andric     APInt::tcSet(parts.data(), 0, dstPartsCount);
2052f22ef01cSRoman Divacky     // Negative zero can't be represented as an int.
2053f22ef01cSRoman Divacky     *isExact = !sign;
2054f22ef01cSRoman Divacky     return opOK;
2055f22ef01cSRoman Divacky   }
2056f22ef01cSRoman Divacky 
2057f22ef01cSRoman Divacky   src = significandParts();
2058f22ef01cSRoman Divacky 
2059f22ef01cSRoman Divacky   /* Step 1: place our absolute value, with any fraction truncated, in
2060f22ef01cSRoman Divacky      the destination.  */
2061f22ef01cSRoman Divacky   if (exponent < 0) {
2062f22ef01cSRoman Divacky     /* Our absolute value is less than one; truncate everything.  */
20637a7e6055SDimitry Andric     APInt::tcSet(parts.data(), 0, dstPartsCount);
2064f22ef01cSRoman Divacky     /* For exponent -1 the integer bit represents .5, look at that.
2065f22ef01cSRoman Divacky        For smaller exponents leftmost truncated bit is 0. */
2066f22ef01cSRoman Divacky     truncatedBits = semantics->precision -1U - exponent;
2067f22ef01cSRoman Divacky   } else {
2068f22ef01cSRoman Divacky     /* We want the most significant (exponent + 1) bits; the rest are
2069f22ef01cSRoman Divacky        truncated.  */
2070f22ef01cSRoman Divacky     unsigned int bits = exponent + 1U;
2071f22ef01cSRoman Divacky 
2072f22ef01cSRoman Divacky     /* Hopelessly large in magnitude?  */
2073f22ef01cSRoman Divacky     if (bits > width)
2074f22ef01cSRoman Divacky       return opInvalidOp;
2075f22ef01cSRoman Divacky 
2076f22ef01cSRoman Divacky     if (bits < semantics->precision) {
2077f22ef01cSRoman Divacky       /* We truncate (semantics->precision - bits) bits.  */
2078f22ef01cSRoman Divacky       truncatedBits = semantics->precision - bits;
20797a7e6055SDimitry Andric       APInt::tcExtract(parts.data(), dstPartsCount, src, bits, truncatedBits);
2080f22ef01cSRoman Divacky     } else {
2081f22ef01cSRoman Divacky       /* We want at least as many bits as are available.  */
20827a7e6055SDimitry Andric       APInt::tcExtract(parts.data(), dstPartsCount, src, semantics->precision,
20837a7e6055SDimitry Andric                        0);
20847a7e6055SDimitry Andric       APInt::tcShiftLeft(parts.data(), dstPartsCount,
20857a7e6055SDimitry Andric                          bits - semantics->precision);
2086f22ef01cSRoman Divacky       truncatedBits = 0;
2087f22ef01cSRoman Divacky     }
2088f22ef01cSRoman Divacky   }
2089f22ef01cSRoman Divacky 
2090f22ef01cSRoman Divacky   /* Step 2: work out any lost fraction, and increment the absolute
2091f22ef01cSRoman Divacky      value if we would round away from zero.  */
2092f22ef01cSRoman Divacky   if (truncatedBits) {
2093f22ef01cSRoman Divacky     lost_fraction = lostFractionThroughTruncation(src, partCount(),
2094f22ef01cSRoman Divacky                                                   truncatedBits);
2095f22ef01cSRoman Divacky     if (lost_fraction != lfExactlyZero &&
2096f22ef01cSRoman Divacky         roundAwayFromZero(rounding_mode, lost_fraction, truncatedBits)) {
20977a7e6055SDimitry Andric       if (APInt::tcIncrement(parts.data(), dstPartsCount))
2098f22ef01cSRoman Divacky         return opInvalidOp;     /* Overflow.  */
2099f22ef01cSRoman Divacky     }
2100f22ef01cSRoman Divacky   } else {
2101f22ef01cSRoman Divacky     lost_fraction = lfExactlyZero;
2102f22ef01cSRoman Divacky   }
2103f22ef01cSRoman Divacky 
2104f22ef01cSRoman Divacky   /* Step 3: check if we fit in the destination.  */
21057a7e6055SDimitry Andric   unsigned int omsb = APInt::tcMSB(parts.data(), dstPartsCount) + 1;
2106f22ef01cSRoman Divacky 
2107f22ef01cSRoman Divacky   if (sign) {
2108f22ef01cSRoman Divacky     if (!isSigned) {
2109f22ef01cSRoman Divacky       /* Negative numbers cannot be represented as unsigned.  */
2110f22ef01cSRoman Divacky       if (omsb != 0)
2111f22ef01cSRoman Divacky         return opInvalidOp;
2112f22ef01cSRoman Divacky     } else {
2113f22ef01cSRoman Divacky       /* It takes omsb bits to represent the unsigned integer value.
2114f22ef01cSRoman Divacky          We lose a bit for the sign, but care is needed as the
2115f22ef01cSRoman Divacky          maximally negative integer is a special case.  */
21167a7e6055SDimitry Andric       if (omsb == width &&
21177a7e6055SDimitry Andric           APInt::tcLSB(parts.data(), dstPartsCount) + 1 != omsb)
2118f22ef01cSRoman Divacky         return opInvalidOp;
2119f22ef01cSRoman Divacky 
2120f22ef01cSRoman Divacky       /* This case can happen because of rounding.  */
2121f22ef01cSRoman Divacky       if (omsb > width)
2122f22ef01cSRoman Divacky         return opInvalidOp;
2123f22ef01cSRoman Divacky     }
2124f22ef01cSRoman Divacky 
21257a7e6055SDimitry Andric     APInt::tcNegate (parts.data(), dstPartsCount);
2126f22ef01cSRoman Divacky   } else {
2127f22ef01cSRoman Divacky     if (omsb >= width + !isSigned)
2128f22ef01cSRoman Divacky       return opInvalidOp;
2129f22ef01cSRoman Divacky   }
2130f22ef01cSRoman Divacky 
2131f22ef01cSRoman Divacky   if (lost_fraction == lfExactlyZero) {
2132f22ef01cSRoman Divacky     *isExact = true;
2133f22ef01cSRoman Divacky     return opOK;
2134f22ef01cSRoman Divacky   } else
2135f22ef01cSRoman Divacky     return opInexact;
2136f22ef01cSRoman Divacky }
2137f22ef01cSRoman Divacky 
2138f22ef01cSRoman Divacky /* Same as convertToSignExtendedInteger, except we provide
2139f22ef01cSRoman Divacky    deterministic values in case of an invalid operation exception,
2140f22ef01cSRoman Divacky    namely zero for NaNs and the minimal or maximal value respectively
2141f22ef01cSRoman Divacky    for underflow or overflow.
2142f22ef01cSRoman Divacky    The *isExact output tells whether the result is exact, in the sense
2143f22ef01cSRoman Divacky    that converting it back to the original floating point type produces
2144f22ef01cSRoman Divacky    the original value.  This is almost equivalent to result==opOK,
2145f22ef01cSRoman Divacky    except for negative zeroes.
2146f22ef01cSRoman Divacky */
21477a7e6055SDimitry Andric IEEEFloat::opStatus
convertToInteger(MutableArrayRef<integerPart> parts,unsigned int width,bool isSigned,roundingMode rounding_mode,bool * isExact) const21487a7e6055SDimitry Andric IEEEFloat::convertToInteger(MutableArrayRef<integerPart> parts,
21497a7e6055SDimitry Andric                             unsigned int width, bool isSigned,
21507a7e6055SDimitry Andric                             roundingMode rounding_mode, bool *isExact) const {
2151f22ef01cSRoman Divacky   opStatus fs;
2152f22ef01cSRoman Divacky 
2153f22ef01cSRoman Divacky   fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode,
2154f22ef01cSRoman Divacky                                     isExact);
2155f22ef01cSRoman Divacky 
2156f22ef01cSRoman Divacky   if (fs == opInvalidOp) {
2157f22ef01cSRoman Divacky     unsigned int bits, dstPartsCount;
2158f22ef01cSRoman Divacky 
2159f22ef01cSRoman Divacky     dstPartsCount = partCountForBits(width);
21607a7e6055SDimitry Andric     assert(dstPartsCount <= parts.size() && "Integer too big");
2161f22ef01cSRoman Divacky 
2162f22ef01cSRoman Divacky     if (category == fcNaN)
2163f22ef01cSRoman Divacky       bits = 0;
2164f22ef01cSRoman Divacky     else if (sign)
2165f22ef01cSRoman Divacky       bits = isSigned;
2166f22ef01cSRoman Divacky     else
2167f22ef01cSRoman Divacky       bits = width - isSigned;
2168f22ef01cSRoman Divacky 
21697a7e6055SDimitry Andric     APInt::tcSetLeastSignificantBits(parts.data(), dstPartsCount, bits);
2170f22ef01cSRoman Divacky     if (sign && isSigned)
21717a7e6055SDimitry Andric       APInt::tcShiftLeft(parts.data(), dstPartsCount, width - 1);
2172f22ef01cSRoman Divacky   }
2173f22ef01cSRoman Divacky 
2174f22ef01cSRoman Divacky   return fs;
2175f22ef01cSRoman Divacky }
2176f22ef01cSRoman Divacky 
2177f22ef01cSRoman Divacky /* Convert an unsigned integer SRC to a floating point number,
2178f22ef01cSRoman Divacky    rounding according to ROUNDING_MODE.  The sign of the floating
2179f22ef01cSRoman Divacky    point number is not modified.  */
convertFromUnsignedParts(const integerPart * src,unsigned int srcCount,roundingMode rounding_mode)2180d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::convertFromUnsignedParts(
2181d88c1a5aSDimitry Andric     const integerPart *src, unsigned int srcCount, roundingMode rounding_mode) {
2182f22ef01cSRoman Divacky   unsigned int omsb, precision, dstCount;
2183f22ef01cSRoman Divacky   integerPart *dst;
2184f22ef01cSRoman Divacky   lostFraction lost_fraction;
2185f22ef01cSRoman Divacky 
2186f22ef01cSRoman Divacky   category = fcNormal;
2187f22ef01cSRoman Divacky   omsb = APInt::tcMSB(src, srcCount) + 1;
2188f22ef01cSRoman Divacky   dst = significandParts();
2189f22ef01cSRoman Divacky   dstCount = partCount();
2190f22ef01cSRoman Divacky   precision = semantics->precision;
2191f22ef01cSRoman Divacky 
21926122f3e6SDimitry Andric   /* We want the most significant PRECISION bits of SRC.  There may not
2193f22ef01cSRoman Divacky      be that many; extract what we can.  */
2194f22ef01cSRoman Divacky   if (precision <= omsb) {
2195f22ef01cSRoman Divacky     exponent = omsb - 1;
2196f22ef01cSRoman Divacky     lost_fraction = lostFractionThroughTruncation(src, srcCount,
2197f22ef01cSRoman Divacky                                                   omsb - precision);
2198f22ef01cSRoman Divacky     APInt::tcExtract(dst, dstCount, src, precision, omsb - precision);
2199f22ef01cSRoman Divacky   } else {
2200f22ef01cSRoman Divacky     exponent = precision - 1;
2201f22ef01cSRoman Divacky     lost_fraction = lfExactlyZero;
2202f22ef01cSRoman Divacky     APInt::tcExtract(dst, dstCount, src, omsb, 0);
2203f22ef01cSRoman Divacky   }
2204f22ef01cSRoman Divacky 
2205f22ef01cSRoman Divacky   return normalize(rounding_mode, lost_fraction);
2206f22ef01cSRoman Divacky }
2207f22ef01cSRoman Divacky 
convertFromAPInt(const APInt & Val,bool isSigned,roundingMode rounding_mode)2208d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::convertFromAPInt(const APInt &Val, bool isSigned,
2209d88c1a5aSDimitry Andric                                                 roundingMode rounding_mode) {
2210f22ef01cSRoman Divacky   unsigned int partCount = Val.getNumWords();
2211f22ef01cSRoman Divacky   APInt api = Val;
2212f22ef01cSRoman Divacky 
2213f22ef01cSRoman Divacky   sign = false;
2214f22ef01cSRoman Divacky   if (isSigned && api.isNegative()) {
2215f22ef01cSRoman Divacky     sign = true;
2216f22ef01cSRoman Divacky     api = -api;
2217f22ef01cSRoman Divacky   }
2218f22ef01cSRoman Divacky 
2219f22ef01cSRoman Divacky   return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
2220f22ef01cSRoman Divacky }
2221f22ef01cSRoman Divacky 
2222f22ef01cSRoman Divacky /* Convert a two's complement integer SRC to a floating point number,
2223f22ef01cSRoman Divacky    rounding according to ROUNDING_MODE.  ISSIGNED is true if the
2224f22ef01cSRoman Divacky    integer is signed, in which case it must be sign-extended.  */
2225d88c1a5aSDimitry Andric IEEEFloat::opStatus
convertFromSignExtendedInteger(const integerPart * src,unsigned int srcCount,bool isSigned,roundingMode rounding_mode)2226d88c1a5aSDimitry Andric IEEEFloat::convertFromSignExtendedInteger(const integerPart *src,
2227d88c1a5aSDimitry Andric                                           unsigned int srcCount, bool isSigned,
2228d88c1a5aSDimitry Andric                                           roundingMode rounding_mode) {
2229f22ef01cSRoman Divacky   opStatus status;
2230f22ef01cSRoman Divacky 
2231f22ef01cSRoman Divacky   if (isSigned &&
2232f22ef01cSRoman Divacky       APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) {
2233f22ef01cSRoman Divacky     integerPart *copy;
2234f22ef01cSRoman Divacky 
2235f22ef01cSRoman Divacky     /* If we're signed and negative negate a copy.  */
2236f22ef01cSRoman Divacky     sign = true;
2237f22ef01cSRoman Divacky     copy = new integerPart[srcCount];
2238f22ef01cSRoman Divacky     APInt::tcAssign(copy, src, srcCount);
2239f22ef01cSRoman Divacky     APInt::tcNegate(copy, srcCount);
2240f22ef01cSRoman Divacky     status = convertFromUnsignedParts(copy, srcCount, rounding_mode);
2241f22ef01cSRoman Divacky     delete [] copy;
2242f22ef01cSRoman Divacky   } else {
2243f22ef01cSRoman Divacky     sign = false;
2244f22ef01cSRoman Divacky     status = convertFromUnsignedParts(src, srcCount, rounding_mode);
2245f22ef01cSRoman Divacky   }
2246f22ef01cSRoman Divacky 
2247f22ef01cSRoman Divacky   return status;
2248f22ef01cSRoman Divacky }
2249f22ef01cSRoman Divacky 
2250f22ef01cSRoman Divacky /* FIXME: should this just take a const APInt reference?  */
2251d88c1a5aSDimitry Andric IEEEFloat::opStatus
convertFromZeroExtendedInteger(const integerPart * parts,unsigned int width,bool isSigned,roundingMode rounding_mode)2252d88c1a5aSDimitry Andric IEEEFloat::convertFromZeroExtendedInteger(const integerPart *parts,
2253f22ef01cSRoman Divacky                                           unsigned int width, bool isSigned,
2254d88c1a5aSDimitry Andric                                           roundingMode rounding_mode) {
2255f22ef01cSRoman Divacky   unsigned int partCount = partCountForBits(width);
22566122f3e6SDimitry Andric   APInt api = APInt(width, makeArrayRef(parts, partCount));
2257f22ef01cSRoman Divacky 
2258f22ef01cSRoman Divacky   sign = false;
2259f22ef01cSRoman Divacky   if (isSigned && APInt::tcExtractBit(parts, width - 1)) {
2260f22ef01cSRoman Divacky     sign = true;
2261f22ef01cSRoman Divacky     api = -api;
2262f22ef01cSRoman Divacky   }
2263f22ef01cSRoman Divacky 
2264f22ef01cSRoman Divacky   return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
2265f22ef01cSRoman Divacky }
2266f22ef01cSRoman Divacky 
2267d88c1a5aSDimitry Andric IEEEFloat::opStatus
convertFromHexadecimalString(StringRef s,roundingMode rounding_mode)2268d88c1a5aSDimitry Andric IEEEFloat::convertFromHexadecimalString(StringRef s,
2269d88c1a5aSDimitry Andric                                         roundingMode rounding_mode) {
2270f22ef01cSRoman Divacky   lostFraction lost_fraction = lfExactlyZero;
2271f22ef01cSRoman Divacky 
2272f785676fSDimitry Andric   category = fcNormal;
2273f22ef01cSRoman Divacky   zeroSignificand();
2274f22ef01cSRoman Divacky   exponent = 0;
2275f22ef01cSRoman Divacky 
2276f785676fSDimitry Andric   integerPart *significand = significandParts();
2277f785676fSDimitry Andric   unsigned partsCount = partCount();
2278f785676fSDimitry Andric   unsigned bitPos = partsCount * integerPartWidth;
2279f785676fSDimitry Andric   bool computedTrailingFraction = false;
2280f22ef01cSRoman Divacky 
2281f785676fSDimitry Andric   // Skip leading zeroes and any (hexa)decimal point.
2282f22ef01cSRoman Divacky   StringRef::iterator begin = s.begin();
2283f22ef01cSRoman Divacky   StringRef::iterator end = s.end();
2284f785676fSDimitry Andric   StringRef::iterator dot;
2285f22ef01cSRoman Divacky   StringRef::iterator p = skipLeadingZeroesAndAnyDot(begin, end, &dot);
2286f785676fSDimitry Andric   StringRef::iterator firstSignificantDigit = p;
2287f22ef01cSRoman Divacky 
2288f785676fSDimitry Andric   while (p != end) {
2289f22ef01cSRoman Divacky     integerPart hex_value;
2290f22ef01cSRoman Divacky 
2291f22ef01cSRoman Divacky     if (*p == '.') {
2292f22ef01cSRoman Divacky       assert(dot == end && "String contains multiple dots");
2293f22ef01cSRoman Divacky       dot = p++;
2294f785676fSDimitry Andric       continue;
2295f22ef01cSRoman Divacky     }
2296f22ef01cSRoman Divacky 
2297f22ef01cSRoman Divacky     hex_value = hexDigitValue(*p);
2298f785676fSDimitry Andric     if (hex_value == -1U)
2299f22ef01cSRoman Divacky       break;
2300f22ef01cSRoman Divacky 
2301f22ef01cSRoman Divacky     p++;
2302f22ef01cSRoman Divacky 
2303f785676fSDimitry Andric     // Store the number while we have space.
2304f22ef01cSRoman Divacky     if (bitPos) {
2305f22ef01cSRoman Divacky       bitPos -= 4;
2306f22ef01cSRoman Divacky       hex_value <<= bitPos % integerPartWidth;
2307f22ef01cSRoman Divacky       significand[bitPos / integerPartWidth] |= hex_value;
2308f785676fSDimitry Andric     } else if (!computedTrailingFraction) {
2309f22ef01cSRoman Divacky       lost_fraction = trailingHexadecimalFraction(p, end, hex_value);
2310f785676fSDimitry Andric       computedTrailingFraction = true;
2311f22ef01cSRoman Divacky     }
2312f22ef01cSRoman Divacky   }
2313f22ef01cSRoman Divacky 
2314f22ef01cSRoman Divacky   /* Hex floats require an exponent but not a hexadecimal point.  */
2315f22ef01cSRoman Divacky   assert(p != end && "Hex strings require an exponent");
2316f22ef01cSRoman Divacky   assert((*p == 'p' || *p == 'P') && "Invalid character in significand");
2317f22ef01cSRoman Divacky   assert(p != begin && "Significand has no digits");
2318f22ef01cSRoman Divacky   assert((dot == end || p - begin != 1) && "Significand has no digits");
2319f22ef01cSRoman Divacky 
2320f22ef01cSRoman Divacky   /* Ignore the exponent if we are zero.  */
2321f22ef01cSRoman Divacky   if (p != firstSignificantDigit) {
2322f22ef01cSRoman Divacky     int expAdjustment;
2323f22ef01cSRoman Divacky 
2324f22ef01cSRoman Divacky     /* Implicit hexadecimal point?  */
2325f22ef01cSRoman Divacky     if (dot == end)
2326f22ef01cSRoman Divacky       dot = p;
2327f22ef01cSRoman Divacky 
2328f22ef01cSRoman Divacky     /* Calculate the exponent adjustment implicit in the number of
2329f22ef01cSRoman Divacky        significant digits.  */
2330f22ef01cSRoman Divacky     expAdjustment = static_cast<int>(dot - firstSignificantDigit);
2331f22ef01cSRoman Divacky     if (expAdjustment < 0)
2332f22ef01cSRoman Divacky       expAdjustment++;
2333f22ef01cSRoman Divacky     expAdjustment = expAdjustment * 4 - 1;
2334f22ef01cSRoman Divacky 
2335f22ef01cSRoman Divacky     /* Adjust for writing the significand starting at the most
2336f22ef01cSRoman Divacky        significant nibble.  */
2337f22ef01cSRoman Divacky     expAdjustment += semantics->precision;
2338f22ef01cSRoman Divacky     expAdjustment -= partsCount * integerPartWidth;
2339f22ef01cSRoman Divacky 
2340f22ef01cSRoman Divacky     /* Adjust for the given exponent.  */
2341f22ef01cSRoman Divacky     exponent = totalExponent(p + 1, end, expAdjustment);
2342f22ef01cSRoman Divacky   }
2343f22ef01cSRoman Divacky 
2344f22ef01cSRoman Divacky   return normalize(rounding_mode, lost_fraction);
2345f22ef01cSRoman Divacky }
2346f22ef01cSRoman Divacky 
2347d88c1a5aSDimitry Andric IEEEFloat::opStatus
roundSignificandWithExponent(const integerPart * decSigParts,unsigned sigPartCount,int exp,roundingMode rounding_mode)2348d88c1a5aSDimitry Andric IEEEFloat::roundSignificandWithExponent(const integerPart *decSigParts,
2349f22ef01cSRoman Divacky                                         unsigned sigPartCount, int exp,
2350d88c1a5aSDimitry Andric                                         roundingMode rounding_mode) {
2351f22ef01cSRoman Divacky   unsigned int parts, pow5PartCount;
2352875ed548SDimitry Andric   fltSemantics calcSemantics = { 32767, -32767, 0, 0 };
2353f22ef01cSRoman Divacky   integerPart pow5Parts[maxPowerOfFiveParts];
2354f22ef01cSRoman Divacky   bool isNearest;
2355f22ef01cSRoman Divacky 
2356f22ef01cSRoman Divacky   isNearest = (rounding_mode == rmNearestTiesToEven ||
2357f22ef01cSRoman Divacky                rounding_mode == rmNearestTiesToAway);
2358f22ef01cSRoman Divacky 
2359f22ef01cSRoman Divacky   parts = partCountForBits(semantics->precision + 11);
2360f22ef01cSRoman Divacky 
2361f22ef01cSRoman Divacky   /* Calculate pow(5, abs(exp)).  */
2362f22ef01cSRoman Divacky   pow5PartCount = powerOf5(pow5Parts, exp >= 0 ? exp: -exp);
2363f22ef01cSRoman Divacky 
2364f22ef01cSRoman Divacky   for (;; parts *= 2) {
2365f22ef01cSRoman Divacky     opStatus sigStatus, powStatus;
2366f22ef01cSRoman Divacky     unsigned int excessPrecision, truncatedBits;
2367f22ef01cSRoman Divacky 
2368f22ef01cSRoman Divacky     calcSemantics.precision = parts * integerPartWidth - 1;
2369f22ef01cSRoman Divacky     excessPrecision = calcSemantics.precision - semantics->precision;
2370f22ef01cSRoman Divacky     truncatedBits = excessPrecision;
2371f22ef01cSRoman Divacky 
2372d88c1a5aSDimitry Andric     IEEEFloat decSig(calcSemantics, uninitialized);
2373d88c1a5aSDimitry Andric     decSig.makeZero(sign);
2374d88c1a5aSDimitry Andric     IEEEFloat pow5(calcSemantics);
2375f22ef01cSRoman Divacky 
2376f22ef01cSRoman Divacky     sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount,
2377f22ef01cSRoman Divacky                                                 rmNearestTiesToEven);
2378f22ef01cSRoman Divacky     powStatus = pow5.convertFromUnsignedParts(pow5Parts, pow5PartCount,
2379f22ef01cSRoman Divacky                                               rmNearestTiesToEven);
2380f22ef01cSRoman Divacky     /* Add exp, as 10^n = 5^n * 2^n.  */
2381f22ef01cSRoman Divacky     decSig.exponent += exp;
2382f22ef01cSRoman Divacky 
2383f22ef01cSRoman Divacky     lostFraction calcLostFraction;
2384f22ef01cSRoman Divacky     integerPart HUerr, HUdistance;
2385f22ef01cSRoman Divacky     unsigned int powHUerr;
2386f22ef01cSRoman Divacky 
2387f22ef01cSRoman Divacky     if (exp >= 0) {
2388f22ef01cSRoman Divacky       /* multiplySignificand leaves the precision-th bit set to 1.  */
238991bc56edSDimitry Andric       calcLostFraction = decSig.multiplySignificand(pow5, nullptr);
2390f22ef01cSRoman Divacky       powHUerr = powStatus != opOK;
2391f22ef01cSRoman Divacky     } else {
2392f22ef01cSRoman Divacky       calcLostFraction = decSig.divideSignificand(pow5);
2393f22ef01cSRoman Divacky       /* Denormal numbers have less precision.  */
2394f22ef01cSRoman Divacky       if (decSig.exponent < semantics->minExponent) {
2395f22ef01cSRoman Divacky         excessPrecision += (semantics->minExponent - decSig.exponent);
2396f22ef01cSRoman Divacky         truncatedBits = excessPrecision;
2397f22ef01cSRoman Divacky         if (excessPrecision > calcSemantics.precision)
2398f22ef01cSRoman Divacky           excessPrecision = calcSemantics.precision;
2399f22ef01cSRoman Divacky       }
2400f22ef01cSRoman Divacky       /* Extra half-ulp lost in reciprocal of exponent.  */
2401f22ef01cSRoman Divacky       powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0:2;
2402f22ef01cSRoman Divacky     }
2403f22ef01cSRoman Divacky 
2404f22ef01cSRoman Divacky     /* Both multiplySignificand and divideSignificand return the
2405f22ef01cSRoman Divacky        result with the integer bit set.  */
2406f22ef01cSRoman Divacky     assert(APInt::tcExtractBit
2407f22ef01cSRoman Divacky            (decSig.significandParts(), calcSemantics.precision - 1) == 1);
2408f22ef01cSRoman Divacky 
2409f22ef01cSRoman Divacky     HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus != opOK,
2410f22ef01cSRoman Divacky                        powHUerr);
2411f22ef01cSRoman Divacky     HUdistance = 2 * ulpsFromBoundary(decSig.significandParts(),
2412f22ef01cSRoman Divacky                                       excessPrecision, isNearest);
2413f22ef01cSRoman Divacky 
2414f22ef01cSRoman Divacky     /* Are we guaranteed to round correctly if we truncate?  */
2415f22ef01cSRoman Divacky     if (HUdistance >= HUerr) {
2416f22ef01cSRoman Divacky       APInt::tcExtract(significandParts(), partCount(), decSig.significandParts(),
2417f22ef01cSRoman Divacky                        calcSemantics.precision - excessPrecision,
2418f22ef01cSRoman Divacky                        excessPrecision);
2419f22ef01cSRoman Divacky       /* Take the exponent of decSig.  If we tcExtract-ed less bits
2420f22ef01cSRoman Divacky          above we must adjust our exponent to compensate for the
2421f22ef01cSRoman Divacky          implicit right shift.  */
2422f22ef01cSRoman Divacky       exponent = (decSig.exponent + semantics->precision
2423f22ef01cSRoman Divacky                   - (calcSemantics.precision - excessPrecision));
2424f22ef01cSRoman Divacky       calcLostFraction = lostFractionThroughTruncation(decSig.significandParts(),
2425f22ef01cSRoman Divacky                                                        decSig.partCount(),
2426f22ef01cSRoman Divacky                                                        truncatedBits);
2427f22ef01cSRoman Divacky       return normalize(rounding_mode, calcLostFraction);
2428f22ef01cSRoman Divacky     }
2429f22ef01cSRoman Divacky   }
2430f22ef01cSRoman Divacky }
2431f22ef01cSRoman Divacky 
2432d88c1a5aSDimitry Andric IEEEFloat::opStatus
convertFromDecimalString(StringRef str,roundingMode rounding_mode)2433d88c1a5aSDimitry Andric IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) {
2434f22ef01cSRoman Divacky   decimalInfo D;
2435f22ef01cSRoman Divacky   opStatus fs;
2436f22ef01cSRoman Divacky 
2437f22ef01cSRoman Divacky   /* Scan the text.  */
2438f22ef01cSRoman Divacky   StringRef::iterator p = str.begin();
2439f22ef01cSRoman Divacky   interpretDecimal(p, str.end(), &D);
2440f22ef01cSRoman Divacky 
2441f22ef01cSRoman Divacky   /* Handle the quick cases.  First the case of no significant digits,
2442f22ef01cSRoman Divacky      i.e. zero, and then exponents that are obviously too large or too
2443f22ef01cSRoman Divacky      small.  Writing L for log 10 / log 2, a number d.ddddd*10^exp
2444f22ef01cSRoman Divacky      definitely overflows if
2445f22ef01cSRoman Divacky 
2446f22ef01cSRoman Divacky            (exp - 1) * L >= maxExponent
2447f22ef01cSRoman Divacky 
2448f22ef01cSRoman Divacky      and definitely underflows to zero where
2449f22ef01cSRoman Divacky 
2450f22ef01cSRoman Divacky            (exp + 1) * L <= minExponent - precision
2451f22ef01cSRoman Divacky 
2452f22ef01cSRoman Divacky      With integer arithmetic the tightest bounds for L are
2453f22ef01cSRoman Divacky 
2454f22ef01cSRoman Divacky            93/28 < L < 196/59            [ numerator <= 256 ]
2455f22ef01cSRoman Divacky            42039/12655 < L < 28738/8651  [ numerator <= 65536 ]
2456f22ef01cSRoman Divacky   */
2457f22ef01cSRoman Divacky 
2458f785676fSDimitry Andric   // Test if we have a zero number allowing for strings with no null terminators
2459f785676fSDimitry Andric   // and zero decimals with non-zero exponents.
2460f785676fSDimitry Andric   //
2461f785676fSDimitry Andric   // We computed firstSigDigit by ignoring all zeros and dots. Thus if
2462f785676fSDimitry Andric   // D->firstSigDigit equals str.end(), every digit must be a zero and there can
2463f785676fSDimitry Andric   // be at most one dot. On the other hand, if we have a zero with a non-zero
2464f785676fSDimitry Andric   // exponent, then we know that D.firstSigDigit will be non-numeric.
2465f785676fSDimitry Andric   if (D.firstSigDigit == str.end() || decDigitValue(*D.firstSigDigit) >= 10U) {
2466f22ef01cSRoman Divacky     category = fcZero;
2467f22ef01cSRoman Divacky     fs = opOK;
2468f22ef01cSRoman Divacky 
2469f22ef01cSRoman Divacky   /* Check whether the normalized exponent is high enough to overflow
2470f22ef01cSRoman Divacky      max during the log-rebasing in the max-exponent check below. */
2471f22ef01cSRoman Divacky   } else if (D.normalizedExponent - 1 > INT_MAX / 42039) {
2472f22ef01cSRoman Divacky     fs = handleOverflow(rounding_mode);
2473f22ef01cSRoman Divacky 
2474f22ef01cSRoman Divacky   /* If it wasn't, then it also wasn't high enough to overflow max
2475f22ef01cSRoman Divacky      during the log-rebasing in the min-exponent check.  Check that it
2476f22ef01cSRoman Divacky      won't overflow min in either check, then perform the min-exponent
2477f22ef01cSRoman Divacky      check. */
2478f22ef01cSRoman Divacky   } else if (D.normalizedExponent - 1 < INT_MIN / 42039 ||
2479f22ef01cSRoman Divacky              (D.normalizedExponent + 1) * 28738 <=
2480f22ef01cSRoman Divacky                8651 * (semantics->minExponent - (int) semantics->precision)) {
2481f22ef01cSRoman Divacky     /* Underflow to zero and round.  */
2482f785676fSDimitry Andric     category = fcNormal;
2483f22ef01cSRoman Divacky     zeroSignificand();
2484f22ef01cSRoman Divacky     fs = normalize(rounding_mode, lfLessThanHalf);
2485f22ef01cSRoman Divacky 
2486f22ef01cSRoman Divacky   /* We can finally safely perform the max-exponent check. */
2487f22ef01cSRoman Divacky   } else if ((D.normalizedExponent - 1) * 42039
2488f22ef01cSRoman Divacky              >= 12655 * semantics->maxExponent) {
2489f22ef01cSRoman Divacky     /* Overflow and round.  */
2490f22ef01cSRoman Divacky     fs = handleOverflow(rounding_mode);
2491f22ef01cSRoman Divacky   } else {
2492f22ef01cSRoman Divacky     integerPart *decSignificand;
2493f22ef01cSRoman Divacky     unsigned int partCount;
2494f22ef01cSRoman Divacky 
2495f22ef01cSRoman Divacky     /* A tight upper bound on number of bits required to hold an
2496f22ef01cSRoman Divacky        N-digit decimal integer is N * 196 / 59.  Allocate enough space
2497f22ef01cSRoman Divacky        to hold the full significand, and an extra part required by
2498f22ef01cSRoman Divacky        tcMultiplyPart.  */
2499f22ef01cSRoman Divacky     partCount = static_cast<unsigned int>(D.lastSigDigit - D.firstSigDigit) + 1;
2500f22ef01cSRoman Divacky     partCount = partCountForBits(1 + 196 * partCount / 59);
2501f22ef01cSRoman Divacky     decSignificand = new integerPart[partCount + 1];
2502f22ef01cSRoman Divacky     partCount = 0;
2503f22ef01cSRoman Divacky 
2504f22ef01cSRoman Divacky     /* Convert to binary efficiently - we do almost all multiplication
2505f22ef01cSRoman Divacky        in an integerPart.  When this would overflow do we do a single
2506f22ef01cSRoman Divacky        bignum multiplication, and then revert again to multiplication
2507f22ef01cSRoman Divacky        in an integerPart.  */
2508f22ef01cSRoman Divacky     do {
2509f22ef01cSRoman Divacky       integerPart decValue, val, multiplier;
2510f22ef01cSRoman Divacky 
2511f22ef01cSRoman Divacky       val = 0;
2512f22ef01cSRoman Divacky       multiplier = 1;
2513f22ef01cSRoman Divacky 
2514f22ef01cSRoman Divacky       do {
2515f22ef01cSRoman Divacky         if (*p == '.') {
2516f22ef01cSRoman Divacky           p++;
2517f22ef01cSRoman Divacky           if (p == str.end()) {
2518f22ef01cSRoman Divacky             break;
2519f22ef01cSRoman Divacky           }
2520f22ef01cSRoman Divacky         }
2521f22ef01cSRoman Divacky         decValue = decDigitValue(*p++);
2522f22ef01cSRoman Divacky         assert(decValue < 10U && "Invalid character in significand");
2523f22ef01cSRoman Divacky         multiplier *= 10;
2524f22ef01cSRoman Divacky         val = val * 10 + decValue;
2525f22ef01cSRoman Divacky         /* The maximum number that can be multiplied by ten with any
2526f22ef01cSRoman Divacky            digit added without overflowing an integerPart.  */
2527f22ef01cSRoman Divacky       } while (p <= D.lastSigDigit && multiplier <= (~ (integerPart) 0 - 9) / 10);
2528f22ef01cSRoman Divacky 
2529f22ef01cSRoman Divacky       /* Multiply out the current part.  */
2530f22ef01cSRoman Divacky       APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val,
2531f22ef01cSRoman Divacky                             partCount, partCount + 1, false);
2532f22ef01cSRoman Divacky 
2533f22ef01cSRoman Divacky       /* If we used another part (likely but not guaranteed), increase
2534f22ef01cSRoman Divacky          the count.  */
2535f22ef01cSRoman Divacky       if (decSignificand[partCount])
2536f22ef01cSRoman Divacky         partCount++;
2537f22ef01cSRoman Divacky     } while (p <= D.lastSigDigit);
2538f22ef01cSRoman Divacky 
2539f22ef01cSRoman Divacky     category = fcNormal;
2540f22ef01cSRoman Divacky     fs = roundSignificandWithExponent(decSignificand, partCount,
2541f22ef01cSRoman Divacky                                       D.exponent, rounding_mode);
2542f22ef01cSRoman Divacky 
2543f22ef01cSRoman Divacky     delete [] decSignificand;
2544f22ef01cSRoman Divacky   }
2545f22ef01cSRoman Divacky 
2546f22ef01cSRoman Divacky   return fs;
2547f22ef01cSRoman Divacky }
2548f22ef01cSRoman Divacky 
convertFromStringSpecials(StringRef str)2549d88c1a5aSDimitry Andric bool IEEEFloat::convertFromStringSpecials(StringRef str) {
2550da09e106SDimitry Andric   if (str.equals("inf") || str.equals("INFINITY") || str.equals("+Inf")) {
2551f785676fSDimitry Andric     makeInf(false);
2552f785676fSDimitry Andric     return true;
2553f785676fSDimitry Andric   }
2554f785676fSDimitry Andric 
2555da09e106SDimitry Andric   if (str.equals("-inf") || str.equals("-INFINITY") || str.equals("-Inf")) {
2556f785676fSDimitry Andric     makeInf(true);
2557f785676fSDimitry Andric     return true;
2558f785676fSDimitry Andric   }
2559f785676fSDimitry Andric 
2560f785676fSDimitry Andric   if (str.equals("nan") || str.equals("NaN")) {
2561f785676fSDimitry Andric     makeNaN(false, false);
2562f785676fSDimitry Andric     return true;
2563f785676fSDimitry Andric   }
2564f785676fSDimitry Andric 
2565f785676fSDimitry Andric   if (str.equals("-nan") || str.equals("-NaN")) {
2566f785676fSDimitry Andric     makeNaN(false, true);
2567f785676fSDimitry Andric     return true;
2568f785676fSDimitry Andric   }
2569f785676fSDimitry Andric 
2570f785676fSDimitry Andric   return false;
2571f785676fSDimitry Andric }
2572f785676fSDimitry Andric 
convertFromString(StringRef str,roundingMode rounding_mode)2573d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::convertFromString(StringRef str,
2574d88c1a5aSDimitry Andric                                                  roundingMode rounding_mode) {
2575f22ef01cSRoman Divacky   assert(!str.empty() && "Invalid string length");
2576f22ef01cSRoman Divacky 
2577f785676fSDimitry Andric   // Handle special cases.
2578f785676fSDimitry Andric   if (convertFromStringSpecials(str))
2579f785676fSDimitry Andric     return opOK;
2580f785676fSDimitry Andric 
2581f22ef01cSRoman Divacky   /* Handle a leading minus sign.  */
2582f22ef01cSRoman Divacky   StringRef::iterator p = str.begin();
2583f22ef01cSRoman Divacky   size_t slen = str.size();
2584f22ef01cSRoman Divacky   sign = *p == '-' ? 1 : 0;
2585f22ef01cSRoman Divacky   if (*p == '-' || *p == '+') {
2586f22ef01cSRoman Divacky     p++;
2587f22ef01cSRoman Divacky     slen--;
2588f22ef01cSRoman Divacky     assert(slen && "String has no digits");
2589f22ef01cSRoman Divacky   }
2590f22ef01cSRoman Divacky 
2591f22ef01cSRoman Divacky   if (slen >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
2592f22ef01cSRoman Divacky     assert(slen - 2 && "Invalid string");
2593f22ef01cSRoman Divacky     return convertFromHexadecimalString(StringRef(p + 2, slen - 2),
2594f22ef01cSRoman Divacky                                         rounding_mode);
2595f22ef01cSRoman Divacky   }
2596f22ef01cSRoman Divacky 
2597f22ef01cSRoman Divacky   return convertFromDecimalString(StringRef(p, slen), rounding_mode);
2598f22ef01cSRoman Divacky }
2599f22ef01cSRoman Divacky 
2600f22ef01cSRoman Divacky /* Write out a hexadecimal representation of the floating point value
2601f22ef01cSRoman Divacky    to DST, which must be of sufficient size, in the C99 form
2602f22ef01cSRoman Divacky    [-]0xh.hhhhp[+-]d.  Return the number of characters written,
2603f22ef01cSRoman Divacky    excluding the terminating NUL.
2604f22ef01cSRoman Divacky 
2605f22ef01cSRoman Divacky    If UPPERCASE, the output is in upper case, otherwise in lower case.
2606f22ef01cSRoman Divacky 
2607f22ef01cSRoman Divacky    HEXDIGITS digits appear altogether, rounding the value if
2608f22ef01cSRoman Divacky    necessary.  If HEXDIGITS is 0, the minimal precision to display the
2609f22ef01cSRoman Divacky    number precisely is used instead.  If nothing would appear after
2610f22ef01cSRoman Divacky    the decimal point it is suppressed.
2611f22ef01cSRoman Divacky 
2612f22ef01cSRoman Divacky    The decimal exponent is always printed and has at least one digit.
2613f22ef01cSRoman Divacky    Zero values display an exponent of zero.  Infinities and NaNs
2614f22ef01cSRoman Divacky    appear as "infinity" or "nan" respectively.
2615f22ef01cSRoman Divacky 
2616f22ef01cSRoman Divacky    The above rules are as specified by C99.  There is ambiguity about
2617f22ef01cSRoman Divacky    what the leading hexadecimal digit should be.  This implementation
2618f22ef01cSRoman Divacky    uses whatever is necessary so that the exponent is displayed as
2619f22ef01cSRoman Divacky    stored.  This implies the exponent will fall within the IEEE format
2620f22ef01cSRoman Divacky    range, and the leading hexadecimal digit will be 0 (for denormals),
2621f22ef01cSRoman Divacky    1 (normal numbers) or 2 (normal numbers rounded-away-from-zero with
2622f22ef01cSRoman Divacky    any other digits zero).
2623f22ef01cSRoman Divacky */
convertToHexString(char * dst,unsigned int hexDigits,bool upperCase,roundingMode rounding_mode) const2624d88c1a5aSDimitry Andric unsigned int IEEEFloat::convertToHexString(char *dst, unsigned int hexDigits,
2625d88c1a5aSDimitry Andric                                            bool upperCase,
2626d88c1a5aSDimitry Andric                                            roundingMode rounding_mode) const {
2627f22ef01cSRoman Divacky   char *p;
2628f22ef01cSRoman Divacky 
2629f22ef01cSRoman Divacky   p = dst;
2630f22ef01cSRoman Divacky   if (sign)
2631f22ef01cSRoman Divacky     *dst++ = '-';
2632f22ef01cSRoman Divacky 
2633f22ef01cSRoman Divacky   switch (category) {
2634f22ef01cSRoman Divacky   case fcInfinity:
2635f22ef01cSRoman Divacky     memcpy (dst, upperCase ? infinityU: infinityL, sizeof infinityU - 1);
2636f22ef01cSRoman Divacky     dst += sizeof infinityL - 1;
2637f22ef01cSRoman Divacky     break;
2638f22ef01cSRoman Divacky 
2639f22ef01cSRoman Divacky   case fcNaN:
2640f22ef01cSRoman Divacky     memcpy (dst, upperCase ? NaNU: NaNL, sizeof NaNU - 1);
2641f22ef01cSRoman Divacky     dst += sizeof NaNU - 1;
2642f22ef01cSRoman Divacky     break;
2643f22ef01cSRoman Divacky 
2644f22ef01cSRoman Divacky   case fcZero:
2645f22ef01cSRoman Divacky     *dst++ = '0';
2646f22ef01cSRoman Divacky     *dst++ = upperCase ? 'X': 'x';
2647f22ef01cSRoman Divacky     *dst++ = '0';
2648f22ef01cSRoman Divacky     if (hexDigits > 1) {
2649f22ef01cSRoman Divacky       *dst++ = '.';
2650f22ef01cSRoman Divacky       memset (dst, '0', hexDigits - 1);
2651f22ef01cSRoman Divacky       dst += hexDigits - 1;
2652f22ef01cSRoman Divacky     }
2653f22ef01cSRoman Divacky     *dst++ = upperCase ? 'P': 'p';
2654f22ef01cSRoman Divacky     *dst++ = '0';
2655f22ef01cSRoman Divacky     break;
2656f22ef01cSRoman Divacky 
2657f22ef01cSRoman Divacky   case fcNormal:
2658f22ef01cSRoman Divacky     dst = convertNormalToHexString (dst, hexDigits, upperCase, rounding_mode);
2659f22ef01cSRoman Divacky     break;
2660f22ef01cSRoman Divacky   }
2661f22ef01cSRoman Divacky 
2662f22ef01cSRoman Divacky   *dst = 0;
2663f22ef01cSRoman Divacky 
2664f22ef01cSRoman Divacky   return static_cast<unsigned int>(dst - p);
2665f22ef01cSRoman Divacky }
2666f22ef01cSRoman Divacky 
2667f22ef01cSRoman Divacky /* Does the hard work of outputting the correctly rounded hexadecimal
2668f22ef01cSRoman Divacky    form of a normal floating point number with the specified number of
2669f22ef01cSRoman Divacky    hexadecimal digits.  If HEXDIGITS is zero the minimum number of
2670f22ef01cSRoman Divacky    digits necessary to print the value precisely is output.  */
convertNormalToHexString(char * dst,unsigned int hexDigits,bool upperCase,roundingMode rounding_mode) const2671d88c1a5aSDimitry Andric char *IEEEFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
2672f22ef01cSRoman Divacky                                           bool upperCase,
2673d88c1a5aSDimitry Andric                                           roundingMode rounding_mode) const {
2674f22ef01cSRoman Divacky   unsigned int count, valueBits, shift, partsCount, outputDigits;
2675f22ef01cSRoman Divacky   const char *hexDigitChars;
2676f22ef01cSRoman Divacky   const integerPart *significand;
2677f22ef01cSRoman Divacky   char *p;
2678f22ef01cSRoman Divacky   bool roundUp;
2679f22ef01cSRoman Divacky 
2680f22ef01cSRoman Divacky   *dst++ = '0';
2681f22ef01cSRoman Divacky   *dst++ = upperCase ? 'X': 'x';
2682f22ef01cSRoman Divacky 
2683f22ef01cSRoman Divacky   roundUp = false;
2684f22ef01cSRoman Divacky   hexDigitChars = upperCase ? hexDigitsUpper: hexDigitsLower;
2685f22ef01cSRoman Divacky 
2686f22ef01cSRoman Divacky   significand = significandParts();
2687f22ef01cSRoman Divacky   partsCount = partCount();
2688f22ef01cSRoman Divacky 
2689f22ef01cSRoman Divacky   /* +3 because the first digit only uses the single integer bit, so
2690f22ef01cSRoman Divacky      we have 3 virtual zero most-significant-bits.  */
2691f22ef01cSRoman Divacky   valueBits = semantics->precision + 3;
2692f22ef01cSRoman Divacky   shift = integerPartWidth - valueBits % integerPartWidth;
2693f22ef01cSRoman Divacky 
2694f22ef01cSRoman Divacky   /* The natural number of digits required ignoring trailing
2695f22ef01cSRoman Divacky      insignificant zeroes.  */
2696f22ef01cSRoman Divacky   outputDigits = (valueBits - significandLSB () + 3) / 4;
2697f22ef01cSRoman Divacky 
2698f22ef01cSRoman Divacky   /* hexDigits of zero means use the required number for the
2699f22ef01cSRoman Divacky      precision.  Otherwise, see if we are truncating.  If we are,
2700f22ef01cSRoman Divacky      find out if we need to round away from zero.  */
2701f22ef01cSRoman Divacky   if (hexDigits) {
2702f22ef01cSRoman Divacky     if (hexDigits < outputDigits) {
2703f22ef01cSRoman Divacky       /* We are dropping non-zero bits, so need to check how to round.
2704f22ef01cSRoman Divacky          "bits" is the number of dropped bits.  */
2705f22ef01cSRoman Divacky       unsigned int bits;
2706f22ef01cSRoman Divacky       lostFraction fraction;
2707f22ef01cSRoman Divacky 
2708f22ef01cSRoman Divacky       bits = valueBits - hexDigits * 4;
2709f22ef01cSRoman Divacky       fraction = lostFractionThroughTruncation (significand, partsCount, bits);
2710f22ef01cSRoman Divacky       roundUp = roundAwayFromZero(rounding_mode, fraction, bits);
2711f22ef01cSRoman Divacky     }
2712f22ef01cSRoman Divacky     outputDigits = hexDigits;
2713f22ef01cSRoman Divacky   }
2714f22ef01cSRoman Divacky 
2715f22ef01cSRoman Divacky   /* Write the digits consecutively, and start writing in the location
2716f22ef01cSRoman Divacky      of the hexadecimal point.  We move the most significant digit
2717f22ef01cSRoman Divacky      left and add the hexadecimal point later.  */
2718f22ef01cSRoman Divacky   p = ++dst;
2719f22ef01cSRoman Divacky 
2720f22ef01cSRoman Divacky   count = (valueBits + integerPartWidth - 1) / integerPartWidth;
2721f22ef01cSRoman Divacky 
2722f22ef01cSRoman Divacky   while (outputDigits && count) {
2723f22ef01cSRoman Divacky     integerPart part;
2724f22ef01cSRoman Divacky 
2725f22ef01cSRoman Divacky     /* Put the most significant integerPartWidth bits in "part".  */
2726f22ef01cSRoman Divacky     if (--count == partsCount)
2727f22ef01cSRoman Divacky       part = 0;  /* An imaginary higher zero part.  */
2728f22ef01cSRoman Divacky     else
2729f22ef01cSRoman Divacky       part = significand[count] << shift;
2730f22ef01cSRoman Divacky 
2731f22ef01cSRoman Divacky     if (count && shift)
2732f22ef01cSRoman Divacky       part |= significand[count - 1] >> (integerPartWidth - shift);
2733f22ef01cSRoman Divacky 
2734f22ef01cSRoman Divacky     /* Convert as much of "part" to hexdigits as we can.  */
2735f22ef01cSRoman Divacky     unsigned int curDigits = integerPartWidth / 4;
2736f22ef01cSRoman Divacky 
2737f22ef01cSRoman Divacky     if (curDigits > outputDigits)
2738f22ef01cSRoman Divacky       curDigits = outputDigits;
2739f22ef01cSRoman Divacky     dst += partAsHex (dst, part, curDigits, hexDigitChars);
2740f22ef01cSRoman Divacky     outputDigits -= curDigits;
2741f22ef01cSRoman Divacky   }
2742f22ef01cSRoman Divacky 
2743f22ef01cSRoman Divacky   if (roundUp) {
2744f22ef01cSRoman Divacky     char *q = dst;
2745f22ef01cSRoman Divacky 
2746f22ef01cSRoman Divacky     /* Note that hexDigitChars has a trailing '0'.  */
2747f22ef01cSRoman Divacky     do {
2748f22ef01cSRoman Divacky       q--;
2749f22ef01cSRoman Divacky       *q = hexDigitChars[hexDigitValue (*q) + 1];
2750f22ef01cSRoman Divacky     } while (*q == '0');
2751f22ef01cSRoman Divacky     assert(q >= p);
2752f22ef01cSRoman Divacky   } else {
2753f22ef01cSRoman Divacky     /* Add trailing zeroes.  */
2754f22ef01cSRoman Divacky     memset (dst, '0', outputDigits);
2755f22ef01cSRoman Divacky     dst += outputDigits;
2756f22ef01cSRoman Divacky   }
2757f22ef01cSRoman Divacky 
2758f22ef01cSRoman Divacky   /* Move the most significant digit to before the point, and if there
2759f22ef01cSRoman Divacky      is something after the decimal point add it.  This must come
2760f22ef01cSRoman Divacky      after rounding above.  */
2761f22ef01cSRoman Divacky   p[-1] = p[0];
2762f22ef01cSRoman Divacky   if (dst -1 == p)
2763f22ef01cSRoman Divacky     dst--;
2764f22ef01cSRoman Divacky   else
2765f22ef01cSRoman Divacky     p[0] = '.';
2766f22ef01cSRoman Divacky 
2767f22ef01cSRoman Divacky   /* Finally output the exponent.  */
2768f22ef01cSRoman Divacky   *dst++ = upperCase ? 'P': 'p';
2769f22ef01cSRoman Divacky 
2770f22ef01cSRoman Divacky   return writeSignedDecimal (dst, exponent);
2771f22ef01cSRoman Divacky }
2772f22ef01cSRoman Divacky 
hash_value(const IEEEFloat & Arg)2773d88c1a5aSDimitry Andric hash_code hash_value(const IEEEFloat &Arg) {
2774f785676fSDimitry Andric   if (!Arg.isFiniteNonZero())
2775dff0c46cSDimitry Andric     return hash_combine((uint8_t)Arg.category,
2776dff0c46cSDimitry Andric                         // NaN has no sign, fix it at zero.
2777dff0c46cSDimitry Andric                         Arg.isNaN() ? (uint8_t)0 : (uint8_t)Arg.sign,
2778dff0c46cSDimitry Andric                         Arg.semantics->precision);
2779dff0c46cSDimitry Andric 
2780dff0c46cSDimitry Andric   // Normal floats need their exponent and significand hashed.
2781dff0c46cSDimitry Andric   return hash_combine((uint8_t)Arg.category, (uint8_t)Arg.sign,
2782dff0c46cSDimitry Andric                       Arg.semantics->precision, Arg.exponent,
2783dff0c46cSDimitry Andric                       hash_combine_range(
2784dff0c46cSDimitry Andric                         Arg.significandParts(),
2785dff0c46cSDimitry Andric                         Arg.significandParts() + Arg.partCount()));
2786f22ef01cSRoman Divacky }
2787f22ef01cSRoman Divacky 
2788f22ef01cSRoman Divacky // Conversion from APFloat to/from host float/double.  It may eventually be
2789f22ef01cSRoman Divacky // possible to eliminate these and have everybody deal with APFloats, but that
2790f22ef01cSRoman Divacky // will take a while.  This approach will not easily extend to long double.
2791f22ef01cSRoman Divacky // Current implementation requires integerPartWidth==64, which is correct at
2792f22ef01cSRoman Divacky // the moment but could be made more general.
2793f22ef01cSRoman Divacky 
2794f22ef01cSRoman Divacky // Denormals have exponent minExponent in APFloat, but minExponent-1 in
2795f22ef01cSRoman Divacky // the actual IEEE respresentations.  We compensate for that here.
2796f22ef01cSRoman Divacky 
convertF80LongDoubleAPFloatToAPInt() const2797d88c1a5aSDimitry Andric APInt IEEEFloat::convertF80LongDoubleAPFloatToAPInt() const {
2798d88c1a5aSDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended);
2799f22ef01cSRoman Divacky   assert(partCount()==2);
2800f22ef01cSRoman Divacky 
2801f22ef01cSRoman Divacky   uint64_t myexponent, mysignificand;
2802f22ef01cSRoman Divacky 
2803f785676fSDimitry Andric   if (isFiniteNonZero()) {
2804f22ef01cSRoman Divacky     myexponent = exponent+16383; //bias
2805f22ef01cSRoman Divacky     mysignificand = significandParts()[0];
2806f22ef01cSRoman Divacky     if (myexponent==1 && !(mysignificand & 0x8000000000000000ULL))
2807f22ef01cSRoman Divacky       myexponent = 0;   // denormal
2808f22ef01cSRoman Divacky   } else if (category==fcZero) {
2809f22ef01cSRoman Divacky     myexponent = 0;
2810f22ef01cSRoman Divacky     mysignificand = 0;
2811f22ef01cSRoman Divacky   } else if (category==fcInfinity) {
2812f22ef01cSRoman Divacky     myexponent = 0x7fff;
2813f22ef01cSRoman Divacky     mysignificand = 0x8000000000000000ULL;
2814f22ef01cSRoman Divacky   } else {
2815f22ef01cSRoman Divacky     assert(category == fcNaN && "Unknown category");
2816f22ef01cSRoman Divacky     myexponent = 0x7fff;
2817f22ef01cSRoman Divacky     mysignificand = significandParts()[0];
2818f22ef01cSRoman Divacky   }
2819f22ef01cSRoman Divacky 
2820f22ef01cSRoman Divacky   uint64_t words[2];
2821f22ef01cSRoman Divacky   words[0] = mysignificand;
2822f22ef01cSRoman Divacky   words[1] =  ((uint64_t)(sign & 1) << 15) |
2823f22ef01cSRoman Divacky               (myexponent & 0x7fffLL);
28246122f3e6SDimitry Andric   return APInt(80, words);
2825f22ef01cSRoman Divacky }
2826f22ef01cSRoman Divacky 
convertPPCDoubleDoubleAPFloatToAPInt() const2827d88c1a5aSDimitry Andric APInt IEEEFloat::convertPPCDoubleDoubleAPFloatToAPInt() const {
28287a7e6055SDimitry Andric   assert(semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy);
2829f22ef01cSRoman Divacky   assert(partCount()==2);
2830f22ef01cSRoman Divacky 
28313861d79fSDimitry Andric   uint64_t words[2];
28323861d79fSDimitry Andric   opStatus fs;
28333861d79fSDimitry Andric   bool losesInfo;
2834f22ef01cSRoman Divacky 
28353861d79fSDimitry Andric   // Convert number to double.  To avoid spurious underflows, we re-
28363861d79fSDimitry Andric   // normalize against the "double" minExponent first, and only *then*
28373861d79fSDimitry Andric   // truncate the mantissa.  The result of that second conversion
28383861d79fSDimitry Andric   // may be inexact, but should never underflow.
2839139f7f9bSDimitry Andric   // Declare fltSemantics before APFloat that uses it (and
2840139f7f9bSDimitry Andric   // saves pointer to it) to ensure correct destruction order.
28413861d79fSDimitry Andric   fltSemantics extendedSemantics = *semantics;
2842d88c1a5aSDimitry Andric   extendedSemantics.minExponent = semIEEEdouble.minExponent;
2843d88c1a5aSDimitry Andric   IEEEFloat extended(*this);
28443861d79fSDimitry Andric   fs = extended.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
28453861d79fSDimitry Andric   assert(fs == opOK && !losesInfo);
28463861d79fSDimitry Andric   (void)fs;
28473861d79fSDimitry Andric 
2848d88c1a5aSDimitry Andric   IEEEFloat u(extended);
2849d88c1a5aSDimitry Andric   fs = u.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo);
28503861d79fSDimitry Andric   assert(fs == opOK || fs == opInexact);
28513861d79fSDimitry Andric   (void)fs;
28523861d79fSDimitry Andric   words[0] = *u.convertDoubleAPFloatToAPInt().getRawData();
28533861d79fSDimitry Andric 
28543861d79fSDimitry Andric   // If conversion was exact or resulted in a special case, we're done;
28553861d79fSDimitry Andric   // just set the second double to zero.  Otherwise, re-convert back to
28563861d79fSDimitry Andric   // the extended format and compute the difference.  This now should
28573861d79fSDimitry Andric   // convert exactly to double.
2858f785676fSDimitry Andric   if (u.isFiniteNonZero() && losesInfo) {
28593861d79fSDimitry Andric     fs = u.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
28603861d79fSDimitry Andric     assert(fs == opOK && !losesInfo);
28613861d79fSDimitry Andric     (void)fs;
28623861d79fSDimitry Andric 
2863d88c1a5aSDimitry Andric     IEEEFloat v(extended);
28643861d79fSDimitry Andric     v.subtract(u, rmNearestTiesToEven);
2865d88c1a5aSDimitry Andric     fs = v.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo);
28663861d79fSDimitry Andric     assert(fs == opOK && !losesInfo);
28673861d79fSDimitry Andric     (void)fs;
28683861d79fSDimitry Andric     words[1] = *v.convertDoubleAPFloatToAPInt().getRawData();
2869f22ef01cSRoman Divacky   } else {
28703861d79fSDimitry Andric     words[1] = 0;
2871f22ef01cSRoman Divacky   }
2872f22ef01cSRoman Divacky 
28736122f3e6SDimitry Andric   return APInt(128, words);
2874f22ef01cSRoman Divacky }
2875f22ef01cSRoman Divacky 
convertQuadrupleAPFloatToAPInt() const2876d88c1a5aSDimitry Andric APInt IEEEFloat::convertQuadrupleAPFloatToAPInt() const {
2877d88c1a5aSDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semIEEEquad);
2878f22ef01cSRoman Divacky   assert(partCount()==2);
2879f22ef01cSRoman Divacky 
2880f22ef01cSRoman Divacky   uint64_t myexponent, mysignificand, mysignificand2;
2881f22ef01cSRoman Divacky 
2882f785676fSDimitry Andric   if (isFiniteNonZero()) {
2883f22ef01cSRoman Divacky     myexponent = exponent+16383; //bias
2884f22ef01cSRoman Divacky     mysignificand = significandParts()[0];
2885f22ef01cSRoman Divacky     mysignificand2 = significandParts()[1];
2886f22ef01cSRoman Divacky     if (myexponent==1 && !(mysignificand2 & 0x1000000000000LL))
2887f22ef01cSRoman Divacky       myexponent = 0;   // denormal
2888f22ef01cSRoman Divacky   } else if (category==fcZero) {
2889f22ef01cSRoman Divacky     myexponent = 0;
2890f22ef01cSRoman Divacky     mysignificand = mysignificand2 = 0;
2891f22ef01cSRoman Divacky   } else if (category==fcInfinity) {
2892f22ef01cSRoman Divacky     myexponent = 0x7fff;
2893f22ef01cSRoman Divacky     mysignificand = mysignificand2 = 0;
2894f22ef01cSRoman Divacky   } else {
2895f22ef01cSRoman Divacky     assert(category == fcNaN && "Unknown category!");
2896f22ef01cSRoman Divacky     myexponent = 0x7fff;
2897f22ef01cSRoman Divacky     mysignificand = significandParts()[0];
2898f22ef01cSRoman Divacky     mysignificand2 = significandParts()[1];
2899f22ef01cSRoman Divacky   }
2900f22ef01cSRoman Divacky 
2901f22ef01cSRoman Divacky   uint64_t words[2];
2902f22ef01cSRoman Divacky   words[0] = mysignificand;
2903f22ef01cSRoman Divacky   words[1] = ((uint64_t)(sign & 1) << 63) |
2904f22ef01cSRoman Divacky              ((myexponent & 0x7fff) << 48) |
2905f22ef01cSRoman Divacky              (mysignificand2 & 0xffffffffffffLL);
2906f22ef01cSRoman Divacky 
29076122f3e6SDimitry Andric   return APInt(128, words);
2908f22ef01cSRoman Divacky }
2909f22ef01cSRoman Divacky 
convertDoubleAPFloatToAPInt() const2910d88c1a5aSDimitry Andric APInt IEEEFloat::convertDoubleAPFloatToAPInt() const {
2911d88c1a5aSDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semIEEEdouble);
2912f22ef01cSRoman Divacky   assert(partCount()==1);
2913f22ef01cSRoman Divacky 
2914f22ef01cSRoman Divacky   uint64_t myexponent, mysignificand;
2915f22ef01cSRoman Divacky 
2916f785676fSDimitry Andric   if (isFiniteNonZero()) {
2917f22ef01cSRoman Divacky     myexponent = exponent+1023; //bias
2918f22ef01cSRoman Divacky     mysignificand = *significandParts();
2919f22ef01cSRoman Divacky     if (myexponent==1 && !(mysignificand & 0x10000000000000LL))
2920f22ef01cSRoman Divacky       myexponent = 0;   // denormal
2921f22ef01cSRoman Divacky   } else if (category==fcZero) {
2922f22ef01cSRoman Divacky     myexponent = 0;
2923f22ef01cSRoman Divacky     mysignificand = 0;
2924f22ef01cSRoman Divacky   } else if (category==fcInfinity) {
2925f22ef01cSRoman Divacky     myexponent = 0x7ff;
2926f22ef01cSRoman Divacky     mysignificand = 0;
2927f22ef01cSRoman Divacky   } else {
2928f22ef01cSRoman Divacky     assert(category == fcNaN && "Unknown category!");
2929f22ef01cSRoman Divacky     myexponent = 0x7ff;
2930f22ef01cSRoman Divacky     mysignificand = *significandParts();
2931f22ef01cSRoman Divacky   }
2932f22ef01cSRoman Divacky 
2933f22ef01cSRoman Divacky   return APInt(64, ((((uint64_t)(sign & 1) << 63) |
2934f22ef01cSRoman Divacky                      ((myexponent & 0x7ff) <<  52) |
2935f22ef01cSRoman Divacky                      (mysignificand & 0xfffffffffffffLL))));
2936f22ef01cSRoman Divacky }
2937f22ef01cSRoman Divacky 
convertFloatAPFloatToAPInt() const2938d88c1a5aSDimitry Andric APInt IEEEFloat::convertFloatAPFloatToAPInt() const {
2939d88c1a5aSDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semIEEEsingle);
2940f22ef01cSRoman Divacky   assert(partCount()==1);
2941f22ef01cSRoman Divacky 
2942f22ef01cSRoman Divacky   uint32_t myexponent, mysignificand;
2943f22ef01cSRoman Divacky 
2944f785676fSDimitry Andric   if (isFiniteNonZero()) {
2945f22ef01cSRoman Divacky     myexponent = exponent+127; //bias
2946f22ef01cSRoman Divacky     mysignificand = (uint32_t)*significandParts();
2947f22ef01cSRoman Divacky     if (myexponent == 1 && !(mysignificand & 0x800000))
2948f22ef01cSRoman Divacky       myexponent = 0;   // denormal
2949f22ef01cSRoman Divacky   } else if (category==fcZero) {
2950f22ef01cSRoman Divacky     myexponent = 0;
2951f22ef01cSRoman Divacky     mysignificand = 0;
2952f22ef01cSRoman Divacky   } else if (category==fcInfinity) {
2953f22ef01cSRoman Divacky     myexponent = 0xff;
2954f22ef01cSRoman Divacky     mysignificand = 0;
2955f22ef01cSRoman Divacky   } else {
2956f22ef01cSRoman Divacky     assert(category == fcNaN && "Unknown category!");
2957f22ef01cSRoman Divacky     myexponent = 0xff;
2958f22ef01cSRoman Divacky     mysignificand = (uint32_t)*significandParts();
2959f22ef01cSRoman Divacky   }
2960f22ef01cSRoman Divacky 
2961f22ef01cSRoman Divacky   return APInt(32, (((sign&1) << 31) | ((myexponent&0xff) << 23) |
2962f22ef01cSRoman Divacky                     (mysignificand & 0x7fffff)));
2963f22ef01cSRoman Divacky }
2964f22ef01cSRoman Divacky 
convertHalfAPFloatToAPInt() const2965d88c1a5aSDimitry Andric APInt IEEEFloat::convertHalfAPFloatToAPInt() const {
2966d88c1a5aSDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semIEEEhalf);
2967f22ef01cSRoman Divacky   assert(partCount()==1);
2968f22ef01cSRoman Divacky 
2969f22ef01cSRoman Divacky   uint32_t myexponent, mysignificand;
2970f22ef01cSRoman Divacky 
2971f785676fSDimitry Andric   if (isFiniteNonZero()) {
2972f22ef01cSRoman Divacky     myexponent = exponent+15; //bias
2973f22ef01cSRoman Divacky     mysignificand = (uint32_t)*significandParts();
2974f22ef01cSRoman Divacky     if (myexponent == 1 && !(mysignificand & 0x400))
2975f22ef01cSRoman Divacky       myexponent = 0;   // denormal
2976f22ef01cSRoman Divacky   } else if (category==fcZero) {
2977f22ef01cSRoman Divacky     myexponent = 0;
2978f22ef01cSRoman Divacky     mysignificand = 0;
2979f22ef01cSRoman Divacky   } else if (category==fcInfinity) {
2980f22ef01cSRoman Divacky     myexponent = 0x1f;
2981f22ef01cSRoman Divacky     mysignificand = 0;
2982f22ef01cSRoman Divacky   } else {
2983f22ef01cSRoman Divacky     assert(category == fcNaN && "Unknown category!");
2984f22ef01cSRoman Divacky     myexponent = 0x1f;
2985f22ef01cSRoman Divacky     mysignificand = (uint32_t)*significandParts();
2986f22ef01cSRoman Divacky   }
2987f22ef01cSRoman Divacky 
2988f22ef01cSRoman Divacky   return APInt(16, (((sign&1) << 15) | ((myexponent&0x1f) << 10) |
2989f22ef01cSRoman Divacky                     (mysignificand & 0x3ff)));
2990f22ef01cSRoman Divacky }
2991f22ef01cSRoman Divacky 
2992f22ef01cSRoman Divacky // This function creates an APInt that is just a bit map of the floating
2993f22ef01cSRoman Divacky // point constant as it would appear in memory.  It is not a conversion,
2994f22ef01cSRoman Divacky // and treating the result as a normal integer is unlikely to be useful.
2995f22ef01cSRoman Divacky 
bitcastToAPInt() const2996d88c1a5aSDimitry Andric APInt IEEEFloat::bitcastToAPInt() const {
2997d88c1a5aSDimitry Andric   if (semantics == (const llvm::fltSemantics*)&semIEEEhalf)
2998f22ef01cSRoman Divacky     return convertHalfAPFloatToAPInt();
2999f22ef01cSRoman Divacky 
3000d88c1a5aSDimitry Andric   if (semantics == (const llvm::fltSemantics*)&semIEEEsingle)
3001f22ef01cSRoman Divacky     return convertFloatAPFloatToAPInt();
3002f22ef01cSRoman Divacky 
3003d88c1a5aSDimitry Andric   if (semantics == (const llvm::fltSemantics*)&semIEEEdouble)
3004f22ef01cSRoman Divacky     return convertDoubleAPFloatToAPInt();
3005f22ef01cSRoman Divacky 
3006d88c1a5aSDimitry Andric   if (semantics == (const llvm::fltSemantics*)&semIEEEquad)
3007f22ef01cSRoman Divacky     return convertQuadrupleAPFloatToAPInt();
3008f22ef01cSRoman Divacky 
30097a7e6055SDimitry Andric   if (semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy)
3010f22ef01cSRoman Divacky     return convertPPCDoubleDoubleAPFloatToAPInt();
3011f22ef01cSRoman Divacky 
3012d88c1a5aSDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended &&
3013f22ef01cSRoman Divacky          "unknown format!");
3014f22ef01cSRoman Divacky   return convertF80LongDoubleAPFloatToAPInt();
3015f22ef01cSRoman Divacky }
3016f22ef01cSRoman Divacky 
convertToFloat() const3017d88c1a5aSDimitry Andric float IEEEFloat::convertToFloat() const {
3018d88c1a5aSDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semIEEEsingle &&
3019f22ef01cSRoman Divacky          "Float semantics are not IEEEsingle");
3020f22ef01cSRoman Divacky   APInt api = bitcastToAPInt();
3021f22ef01cSRoman Divacky   return api.bitsToFloat();
3022f22ef01cSRoman Divacky }
3023f22ef01cSRoman Divacky 
convertToDouble() const3024d88c1a5aSDimitry Andric double IEEEFloat::convertToDouble() const {
3025d88c1a5aSDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semIEEEdouble &&
3026f22ef01cSRoman Divacky          "Float semantics are not IEEEdouble");
3027f22ef01cSRoman Divacky   APInt api = bitcastToAPInt();
3028f22ef01cSRoman Divacky   return api.bitsToDouble();
3029f22ef01cSRoman Divacky }
3030f22ef01cSRoman Divacky 
3031f22ef01cSRoman Divacky /// Integer bit is explicit in this format.  Intel hardware (387 and later)
3032f22ef01cSRoman Divacky /// does not support these bit patterns:
3033f22ef01cSRoman Divacky ///  exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity")
3034f22ef01cSRoman Divacky ///  exponent = all 1's, integer bit 0, significand nonzero ("pseudoNaN")
3035f22ef01cSRoman Divacky ///  exponent!=0 nor all 1's, integer bit 0 ("unnormal")
3036*4ba319b5SDimitry Andric ///  exponent = 0, integer bit 1 ("pseudodenormal")
3037*4ba319b5SDimitry Andric /// At the moment, the first three are treated as NaNs, the last one as Normal.
initFromF80LongDoubleAPInt(const APInt & api)3038d88c1a5aSDimitry Andric void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) {
3039f22ef01cSRoman Divacky   assert(api.getBitWidth()==80);
3040f22ef01cSRoman Divacky   uint64_t i1 = api.getRawData()[0];
3041f22ef01cSRoman Divacky   uint64_t i2 = api.getRawData()[1];
3042f22ef01cSRoman Divacky   uint64_t myexponent = (i2 & 0x7fff);
3043f22ef01cSRoman Divacky   uint64_t mysignificand = i1;
3044*4ba319b5SDimitry Andric   uint8_t myintegerbit = mysignificand >> 63;
3045f22ef01cSRoman Divacky 
3046d88c1a5aSDimitry Andric   initialize(&semX87DoubleExtended);
3047f22ef01cSRoman Divacky   assert(partCount()==2);
3048f22ef01cSRoman Divacky 
3049f22ef01cSRoman Divacky   sign = static_cast<unsigned int>(i2>>15);
3050f22ef01cSRoman Divacky   if (myexponent == 0 && mysignificand == 0) {
3051f22ef01cSRoman Divacky     // exponent, significand meaningless
3052f22ef01cSRoman Divacky     category = fcZero;
3053f22ef01cSRoman Divacky   } else if (myexponent==0x7fff && mysignificand==0x8000000000000000ULL) {
3054f22ef01cSRoman Divacky     // exponent, significand meaningless
3055f22ef01cSRoman Divacky     category = fcInfinity;
3056*4ba319b5SDimitry Andric   } else if ((myexponent == 0x7fff && mysignificand != 0x8000000000000000ULL) ||
3057*4ba319b5SDimitry Andric              (myexponent != 0x7fff && myexponent != 0 && myintegerbit == 0)) {
3058f22ef01cSRoman Divacky     // exponent meaningless
3059f22ef01cSRoman Divacky     category = fcNaN;
3060f22ef01cSRoman Divacky     significandParts()[0] = mysignificand;
3061f22ef01cSRoman Divacky     significandParts()[1] = 0;
3062f22ef01cSRoman Divacky   } else {
3063f22ef01cSRoman Divacky     category = fcNormal;
3064f22ef01cSRoman Divacky     exponent = myexponent - 16383;
3065f22ef01cSRoman Divacky     significandParts()[0] = mysignificand;
3066f22ef01cSRoman Divacky     significandParts()[1] = 0;
3067f22ef01cSRoman Divacky     if (myexponent==0)          // denormal
3068f22ef01cSRoman Divacky       exponent = -16382;
3069f22ef01cSRoman Divacky   }
3070f22ef01cSRoman Divacky }
3071f22ef01cSRoman Divacky 
initFromPPCDoubleDoubleAPInt(const APInt & api)3072d88c1a5aSDimitry Andric void IEEEFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) {
3073f22ef01cSRoman Divacky   assert(api.getBitWidth()==128);
3074f22ef01cSRoman Divacky   uint64_t i1 = api.getRawData()[0];
3075f22ef01cSRoman Divacky   uint64_t i2 = api.getRawData()[1];
30763861d79fSDimitry Andric   opStatus fs;
30773861d79fSDimitry Andric   bool losesInfo;
3078f22ef01cSRoman Divacky 
30793861d79fSDimitry Andric   // Get the first double and convert to our format.
30803861d79fSDimitry Andric   initFromDoubleAPInt(APInt(64, i1));
30817a7e6055SDimitry Andric   fs = convert(semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo);
30823861d79fSDimitry Andric   assert(fs == opOK && !losesInfo);
30833861d79fSDimitry Andric   (void)fs;
3084f22ef01cSRoman Divacky 
30853861d79fSDimitry Andric   // Unless we have a special case, add in second double.
3086f785676fSDimitry Andric   if (isFiniteNonZero()) {
3087d88c1a5aSDimitry Andric     IEEEFloat v(semIEEEdouble, APInt(64, i2));
30887a7e6055SDimitry Andric     fs = v.convert(semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo);
30893861d79fSDimitry Andric     assert(fs == opOK && !losesInfo);
30903861d79fSDimitry Andric     (void)fs;
30913861d79fSDimitry Andric 
30923861d79fSDimitry Andric     add(v, rmNearestTiesToEven);
3093f22ef01cSRoman Divacky   }
3094f22ef01cSRoman Divacky }
3095f22ef01cSRoman Divacky 
initFromQuadrupleAPInt(const APInt & api)3096d88c1a5aSDimitry Andric void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) {
3097f22ef01cSRoman Divacky   assert(api.getBitWidth()==128);
3098f22ef01cSRoman Divacky   uint64_t i1 = api.getRawData()[0];
3099f22ef01cSRoman Divacky   uint64_t i2 = api.getRawData()[1];
3100f22ef01cSRoman Divacky   uint64_t myexponent = (i2 >> 48) & 0x7fff;
3101f22ef01cSRoman Divacky   uint64_t mysignificand  = i1;
3102f22ef01cSRoman Divacky   uint64_t mysignificand2 = i2 & 0xffffffffffffLL;
3103f22ef01cSRoman Divacky 
3104d88c1a5aSDimitry Andric   initialize(&semIEEEquad);
3105f22ef01cSRoman Divacky   assert(partCount()==2);
3106f22ef01cSRoman Divacky 
3107f22ef01cSRoman Divacky   sign = static_cast<unsigned int>(i2>>63);
3108f22ef01cSRoman Divacky   if (myexponent==0 &&
3109f22ef01cSRoman Divacky       (mysignificand==0 && mysignificand2==0)) {
3110f22ef01cSRoman Divacky     // exponent, significand meaningless
3111f22ef01cSRoman Divacky     category = fcZero;
3112f22ef01cSRoman Divacky   } else if (myexponent==0x7fff &&
3113f22ef01cSRoman Divacky              (mysignificand==0 && mysignificand2==0)) {
3114f22ef01cSRoman Divacky     // exponent, significand meaningless
3115f22ef01cSRoman Divacky     category = fcInfinity;
3116f22ef01cSRoman Divacky   } else if (myexponent==0x7fff &&
3117f22ef01cSRoman Divacky              (mysignificand!=0 || mysignificand2 !=0)) {
3118f22ef01cSRoman Divacky     // exponent meaningless
3119f22ef01cSRoman Divacky     category = fcNaN;
3120f22ef01cSRoman Divacky     significandParts()[0] = mysignificand;
3121f22ef01cSRoman Divacky     significandParts()[1] = mysignificand2;
3122f22ef01cSRoman Divacky   } else {
3123f22ef01cSRoman Divacky     category = fcNormal;
3124f22ef01cSRoman Divacky     exponent = myexponent - 16383;
3125f22ef01cSRoman Divacky     significandParts()[0] = mysignificand;
3126f22ef01cSRoman Divacky     significandParts()[1] = mysignificand2;
3127f22ef01cSRoman Divacky     if (myexponent==0)          // denormal
3128f22ef01cSRoman Divacky       exponent = -16382;
3129f22ef01cSRoman Divacky     else
3130f22ef01cSRoman Divacky       significandParts()[1] |= 0x1000000000000LL;  // integer bit
3131f22ef01cSRoman Divacky   }
3132f22ef01cSRoman Divacky }
3133f22ef01cSRoman Divacky 
initFromDoubleAPInt(const APInt & api)3134d88c1a5aSDimitry Andric void IEEEFloat::initFromDoubleAPInt(const APInt &api) {
3135f22ef01cSRoman Divacky   assert(api.getBitWidth()==64);
3136f22ef01cSRoman Divacky   uint64_t i = *api.getRawData();
3137f22ef01cSRoman Divacky   uint64_t myexponent = (i >> 52) & 0x7ff;
3138f22ef01cSRoman Divacky   uint64_t mysignificand = i & 0xfffffffffffffLL;
3139f22ef01cSRoman Divacky 
3140d88c1a5aSDimitry Andric   initialize(&semIEEEdouble);
3141f22ef01cSRoman Divacky   assert(partCount()==1);
3142f22ef01cSRoman Divacky 
3143f22ef01cSRoman Divacky   sign = static_cast<unsigned int>(i>>63);
3144f22ef01cSRoman Divacky   if (myexponent==0 && mysignificand==0) {
3145f22ef01cSRoman Divacky     // exponent, significand meaningless
3146f22ef01cSRoman Divacky     category = fcZero;
3147f22ef01cSRoman Divacky   } else if (myexponent==0x7ff && mysignificand==0) {
3148f22ef01cSRoman Divacky     // exponent, significand meaningless
3149f22ef01cSRoman Divacky     category = fcInfinity;
3150f22ef01cSRoman Divacky   } else if (myexponent==0x7ff && mysignificand!=0) {
3151f22ef01cSRoman Divacky     // exponent meaningless
3152f22ef01cSRoman Divacky     category = fcNaN;
3153f22ef01cSRoman Divacky     *significandParts() = mysignificand;
3154f22ef01cSRoman Divacky   } else {
3155f22ef01cSRoman Divacky     category = fcNormal;
3156f22ef01cSRoman Divacky     exponent = myexponent - 1023;
3157f22ef01cSRoman Divacky     *significandParts() = mysignificand;
3158f22ef01cSRoman Divacky     if (myexponent==0)          // denormal
3159f22ef01cSRoman Divacky       exponent = -1022;
3160f22ef01cSRoman Divacky     else
3161f22ef01cSRoman Divacky       *significandParts() |= 0x10000000000000LL;  // integer bit
3162f22ef01cSRoman Divacky   }
3163f22ef01cSRoman Divacky }
3164f22ef01cSRoman Divacky 
initFromFloatAPInt(const APInt & api)3165d88c1a5aSDimitry Andric void IEEEFloat::initFromFloatAPInt(const APInt &api) {
3166f22ef01cSRoman Divacky   assert(api.getBitWidth()==32);
3167f22ef01cSRoman Divacky   uint32_t i = (uint32_t)*api.getRawData();
3168f22ef01cSRoman Divacky   uint32_t myexponent = (i >> 23) & 0xff;
3169f22ef01cSRoman Divacky   uint32_t mysignificand = i & 0x7fffff;
3170f22ef01cSRoman Divacky 
3171d88c1a5aSDimitry Andric   initialize(&semIEEEsingle);
3172f22ef01cSRoman Divacky   assert(partCount()==1);
3173f22ef01cSRoman Divacky 
3174f22ef01cSRoman Divacky   sign = i >> 31;
3175f22ef01cSRoman Divacky   if (myexponent==0 && mysignificand==0) {
3176f22ef01cSRoman Divacky     // exponent, significand meaningless
3177f22ef01cSRoman Divacky     category = fcZero;
3178f22ef01cSRoman Divacky   } else if (myexponent==0xff && mysignificand==0) {
3179f22ef01cSRoman Divacky     // exponent, significand meaningless
3180f22ef01cSRoman Divacky     category = fcInfinity;
3181f22ef01cSRoman Divacky   } else if (myexponent==0xff && mysignificand!=0) {
3182f22ef01cSRoman Divacky     // sign, exponent, significand meaningless
3183f22ef01cSRoman Divacky     category = fcNaN;
3184f22ef01cSRoman Divacky     *significandParts() = mysignificand;
3185f22ef01cSRoman Divacky   } else {
3186f22ef01cSRoman Divacky     category = fcNormal;
3187f22ef01cSRoman Divacky     exponent = myexponent - 127;  //bias
3188f22ef01cSRoman Divacky     *significandParts() = mysignificand;
3189f22ef01cSRoman Divacky     if (myexponent==0)    // denormal
3190f22ef01cSRoman Divacky       exponent = -126;
3191f22ef01cSRoman Divacky     else
3192f22ef01cSRoman Divacky       *significandParts() |= 0x800000; // integer bit
3193f22ef01cSRoman Divacky   }
3194f22ef01cSRoman Divacky }
3195f22ef01cSRoman Divacky 
initFromHalfAPInt(const APInt & api)3196d88c1a5aSDimitry Andric void IEEEFloat::initFromHalfAPInt(const APInt &api) {
3197f22ef01cSRoman Divacky   assert(api.getBitWidth()==16);
3198f22ef01cSRoman Divacky   uint32_t i = (uint32_t)*api.getRawData();
3199f22ef01cSRoman Divacky   uint32_t myexponent = (i >> 10) & 0x1f;
3200f22ef01cSRoman Divacky   uint32_t mysignificand = i & 0x3ff;
3201f22ef01cSRoman Divacky 
3202d88c1a5aSDimitry Andric   initialize(&semIEEEhalf);
3203f22ef01cSRoman Divacky   assert(partCount()==1);
3204f22ef01cSRoman Divacky 
3205f22ef01cSRoman Divacky   sign = i >> 15;
3206f22ef01cSRoman Divacky   if (myexponent==0 && mysignificand==0) {
3207f22ef01cSRoman Divacky     // exponent, significand meaningless
3208f22ef01cSRoman Divacky     category = fcZero;
3209f22ef01cSRoman Divacky   } else if (myexponent==0x1f && mysignificand==0) {
3210f22ef01cSRoman Divacky     // exponent, significand meaningless
3211f22ef01cSRoman Divacky     category = fcInfinity;
3212f22ef01cSRoman Divacky   } else if (myexponent==0x1f && mysignificand!=0) {
3213f22ef01cSRoman Divacky     // sign, exponent, significand meaningless
3214f22ef01cSRoman Divacky     category = fcNaN;
3215f22ef01cSRoman Divacky     *significandParts() = mysignificand;
3216f22ef01cSRoman Divacky   } else {
3217f22ef01cSRoman Divacky     category = fcNormal;
3218f22ef01cSRoman Divacky     exponent = myexponent - 15;  //bias
3219f22ef01cSRoman Divacky     *significandParts() = mysignificand;
3220f22ef01cSRoman Divacky     if (myexponent==0)    // denormal
3221f22ef01cSRoman Divacky       exponent = -14;
3222f22ef01cSRoman Divacky     else
3223f22ef01cSRoman Divacky       *significandParts() |= 0x400; // integer bit
3224f22ef01cSRoman Divacky   }
3225f22ef01cSRoman Divacky }
3226f22ef01cSRoman Divacky 
3227f22ef01cSRoman Divacky /// Treat api as containing the bits of a floating point number.  Currently
3228f22ef01cSRoman Divacky /// we infer the floating point type from the size of the APInt.  The
3229f22ef01cSRoman Divacky /// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful
3230f22ef01cSRoman Divacky /// when the size is anything else).
initFromAPInt(const fltSemantics * Sem,const APInt & api)3231d88c1a5aSDimitry Andric void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
3232d88c1a5aSDimitry Andric   if (Sem == &semIEEEhalf)
3233f22ef01cSRoman Divacky     return initFromHalfAPInt(api);
3234d88c1a5aSDimitry Andric   if (Sem == &semIEEEsingle)
3235f22ef01cSRoman Divacky     return initFromFloatAPInt(api);
3236d88c1a5aSDimitry Andric   if (Sem == &semIEEEdouble)
3237f22ef01cSRoman Divacky     return initFromDoubleAPInt(api);
3238d88c1a5aSDimitry Andric   if (Sem == &semX87DoubleExtended)
3239f22ef01cSRoman Divacky     return initFromF80LongDoubleAPInt(api);
3240d88c1a5aSDimitry Andric   if (Sem == &semIEEEquad)
3241139f7f9bSDimitry Andric     return initFromQuadrupleAPInt(api);
32427a7e6055SDimitry Andric   if (Sem == &semPPCDoubleDoubleLegacy)
3243139f7f9bSDimitry Andric     return initFromPPCDoubleDoubleAPInt(api);
3244139f7f9bSDimitry Andric 
324591bc56edSDimitry Andric   llvm_unreachable(nullptr);
3246f22ef01cSRoman Divacky }
3247f22ef01cSRoman Divacky 
3248f785676fSDimitry Andric /// Make this number the largest magnitude normal number in the given
3249f785676fSDimitry Andric /// semantics.
makeLargest(bool Negative)3250d88c1a5aSDimitry Andric void IEEEFloat::makeLargest(bool Negative) {
3251f22ef01cSRoman Divacky   // We want (in interchange format):
3252f22ef01cSRoman Divacky   //   sign = {Negative}
3253f22ef01cSRoman Divacky   //   exponent = 1..10
3254f22ef01cSRoman Divacky   //   significand = 1..1
3255f785676fSDimitry Andric   category = fcNormal;
3256f785676fSDimitry Andric   sign = Negative;
3257f785676fSDimitry Andric   exponent = semantics->maxExponent;
3258f22ef01cSRoman Divacky 
3259f785676fSDimitry Andric   // Use memset to set all but the highest integerPart to all ones.
3260f785676fSDimitry Andric   integerPart *significand = significandParts();
3261f785676fSDimitry Andric   unsigned PartCount = partCount();
3262f785676fSDimitry Andric   memset(significand, 0xFF, sizeof(integerPart)*(PartCount - 1));
3263f22ef01cSRoman Divacky 
3264f785676fSDimitry Andric   // Set the high integerPart especially setting all unused top bits for
3265f785676fSDimitry Andric   // internal consistency.
3266f785676fSDimitry Andric   const unsigned NumUnusedHighBits =
3267f785676fSDimitry Andric     PartCount*integerPartWidth - semantics->precision;
326839d628a0SDimitry Andric   significand[PartCount - 1] = (NumUnusedHighBits < integerPartWidth)
326939d628a0SDimitry Andric                                    ? (~integerPart(0) >> NumUnusedHighBits)
327039d628a0SDimitry Andric                                    : 0;
3271f22ef01cSRoman Divacky }
3272f22ef01cSRoman Divacky 
3273f785676fSDimitry Andric /// Make this number the smallest magnitude denormal number in the given
3274f785676fSDimitry Andric /// semantics.
makeSmallest(bool Negative)3275d88c1a5aSDimitry Andric void IEEEFloat::makeSmallest(bool Negative) {
3276f22ef01cSRoman Divacky   // We want (in interchange format):
3277f22ef01cSRoman Divacky   //   sign = {Negative}
3278f22ef01cSRoman Divacky   //   exponent = 0..0
3279f22ef01cSRoman Divacky   //   significand = 0..01
3280f785676fSDimitry Andric   category = fcNormal;
3281f785676fSDimitry Andric   sign = Negative;
3282f785676fSDimitry Andric   exponent = semantics->minExponent;
3283f785676fSDimitry Andric   APInt::tcSet(significandParts(), 1, partCount());
3284f785676fSDimitry Andric }
3285f22ef01cSRoman Divacky 
makeSmallestNormalized(bool Negative)3286d88c1a5aSDimitry Andric void IEEEFloat::makeSmallestNormalized(bool Negative) {
3287f22ef01cSRoman Divacky   // We want (in interchange format):
3288f22ef01cSRoman Divacky   //   sign = {Negative}
3289f22ef01cSRoman Divacky   //   exponent = 0..0
3290f22ef01cSRoman Divacky   //   significand = 10..0
3291f22ef01cSRoman Divacky 
3292d88c1a5aSDimitry Andric   category = fcNormal;
3293d88c1a5aSDimitry Andric   zeroSignificand();
3294d88c1a5aSDimitry Andric   sign = Negative;
3295d88c1a5aSDimitry Andric   exponent = semantics->minExponent;
3296d88c1a5aSDimitry Andric   significandParts()[partCountForBits(semantics->precision) - 1] |=
3297d88c1a5aSDimitry Andric       (((integerPart)1) << ((semantics->precision - 1) % integerPartWidth));
3298f22ef01cSRoman Divacky }
3299f22ef01cSRoman Divacky 
IEEEFloat(const fltSemantics & Sem,const APInt & API)3300d88c1a5aSDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &Sem, const APInt &API) {
3301139f7f9bSDimitry Andric   initFromAPInt(&Sem, API);
3302f22ef01cSRoman Divacky }
3303f22ef01cSRoman Divacky 
IEEEFloat(float f)3304d88c1a5aSDimitry Andric IEEEFloat::IEEEFloat(float f) {
3305d88c1a5aSDimitry Andric   initFromAPInt(&semIEEEsingle, APInt::floatToBits(f));
3306f22ef01cSRoman Divacky }
3307f22ef01cSRoman Divacky 
IEEEFloat(double d)3308d88c1a5aSDimitry Andric IEEEFloat::IEEEFloat(double d) {
3309d88c1a5aSDimitry Andric   initFromAPInt(&semIEEEdouble, APInt::doubleToBits(d));
3310f22ef01cSRoman Divacky }
3311f22ef01cSRoman Divacky 
3312f22ef01cSRoman Divacky namespace {
append(SmallVectorImpl<char> & Buffer,StringRef Str)33137ae0e2c9SDimitry Andric   void append(SmallVectorImpl<char> &Buffer, StringRef Str) {
33147ae0e2c9SDimitry Andric     Buffer.append(Str.begin(), Str.end());
3315f22ef01cSRoman Divacky   }
3316f22ef01cSRoman Divacky 
3317f22ef01cSRoman Divacky   /// Removes data from the given significand until it is no more
3318f22ef01cSRoman Divacky   /// precise than is required for the desired precision.
AdjustToPrecision(APInt & significand,int & exp,unsigned FormatPrecision)3319f22ef01cSRoman Divacky   void AdjustToPrecision(APInt &significand,
3320f22ef01cSRoman Divacky                          int &exp, unsigned FormatPrecision) {
3321f22ef01cSRoman Divacky     unsigned bits = significand.getActiveBits();
3322f22ef01cSRoman Divacky 
3323f22ef01cSRoman Divacky     // 196/59 is a very slight overestimate of lg_2(10).
3324f22ef01cSRoman Divacky     unsigned bitsRequired = (FormatPrecision * 196 + 58) / 59;
3325f22ef01cSRoman Divacky 
3326f22ef01cSRoman Divacky     if (bits <= bitsRequired) return;
3327f22ef01cSRoman Divacky 
3328f22ef01cSRoman Divacky     unsigned tensRemovable = (bits - bitsRequired) * 59 / 196;
3329f22ef01cSRoman Divacky     if (!tensRemovable) return;
3330f22ef01cSRoman Divacky 
3331f22ef01cSRoman Divacky     exp += tensRemovable;
3332f22ef01cSRoman Divacky 
3333f22ef01cSRoman Divacky     APInt divisor(significand.getBitWidth(), 1);
3334f22ef01cSRoman Divacky     APInt powten(significand.getBitWidth(), 10);
3335f22ef01cSRoman Divacky     while (true) {
3336f22ef01cSRoman Divacky       if (tensRemovable & 1)
3337f22ef01cSRoman Divacky         divisor *= powten;
3338f22ef01cSRoman Divacky       tensRemovable >>= 1;
3339f22ef01cSRoman Divacky       if (!tensRemovable) break;
3340f22ef01cSRoman Divacky       powten *= powten;
3341f22ef01cSRoman Divacky     }
3342f22ef01cSRoman Divacky 
3343f22ef01cSRoman Divacky     significand = significand.udiv(divisor);
3344f22ef01cSRoman Divacky 
3345139f7f9bSDimitry Andric     // Truncate the significand down to its active bit count.
3346139f7f9bSDimitry Andric     significand = significand.trunc(significand.getActiveBits());
3347f22ef01cSRoman Divacky   }
3348f22ef01cSRoman Divacky 
3349f22ef01cSRoman Divacky 
AdjustToPrecision(SmallVectorImpl<char> & buffer,int & exp,unsigned FormatPrecision)3350f22ef01cSRoman Divacky   void AdjustToPrecision(SmallVectorImpl<char> &buffer,
3351f22ef01cSRoman Divacky                          int &exp, unsigned FormatPrecision) {
3352f22ef01cSRoman Divacky     unsigned N = buffer.size();
3353f22ef01cSRoman Divacky     if (N <= FormatPrecision) return;
3354f22ef01cSRoman Divacky 
3355f22ef01cSRoman Divacky     // The most significant figures are the last ones in the buffer.
3356f22ef01cSRoman Divacky     unsigned FirstSignificant = N - FormatPrecision;
3357f22ef01cSRoman Divacky 
3358f22ef01cSRoman Divacky     // Round.
3359f22ef01cSRoman Divacky     // FIXME: this probably shouldn't use 'round half up'.
3360f22ef01cSRoman Divacky 
3361f22ef01cSRoman Divacky     // Rounding down is just a truncation, except we also want to drop
3362f22ef01cSRoman Divacky     // trailing zeros from the new result.
3363f22ef01cSRoman Divacky     if (buffer[FirstSignificant - 1] < '5') {
3364dff0c46cSDimitry Andric       while (FirstSignificant < N && buffer[FirstSignificant] == '0')
3365f22ef01cSRoman Divacky         FirstSignificant++;
3366f22ef01cSRoman Divacky 
3367f22ef01cSRoman Divacky       exp += FirstSignificant;
3368f22ef01cSRoman Divacky       buffer.erase(&buffer[0], &buffer[FirstSignificant]);
3369f22ef01cSRoman Divacky       return;
3370f22ef01cSRoman Divacky     }
3371f22ef01cSRoman Divacky 
3372f22ef01cSRoman Divacky     // Rounding up requires a decimal add-with-carry.  If we continue
3373f22ef01cSRoman Divacky     // the carry, the newly-introduced zeros will just be truncated.
3374f22ef01cSRoman Divacky     for (unsigned I = FirstSignificant; I != N; ++I) {
3375f22ef01cSRoman Divacky       if (buffer[I] == '9') {
3376f22ef01cSRoman Divacky         FirstSignificant++;
3377f22ef01cSRoman Divacky       } else {
3378f22ef01cSRoman Divacky         buffer[I]++;
3379f22ef01cSRoman Divacky         break;
3380f22ef01cSRoman Divacky       }
3381f22ef01cSRoman Divacky     }
3382f22ef01cSRoman Divacky 
3383f22ef01cSRoman Divacky     // If we carried through, we have exactly one digit of precision.
3384f22ef01cSRoman Divacky     if (FirstSignificant == N) {
3385f22ef01cSRoman Divacky       exp += FirstSignificant;
3386f22ef01cSRoman Divacky       buffer.clear();
3387f22ef01cSRoman Divacky       buffer.push_back('1');
3388f22ef01cSRoman Divacky       return;
3389f22ef01cSRoman Divacky     }
3390f22ef01cSRoman Divacky 
3391f22ef01cSRoman Divacky     exp += FirstSignificant;
3392f22ef01cSRoman Divacky     buffer.erase(&buffer[0], &buffer[FirstSignificant]);
3393f22ef01cSRoman Divacky   }
33943dac3a9bSDimitry Andric }
3395f22ef01cSRoman Divacky 
toString(SmallVectorImpl<char> & Str,unsigned FormatPrecision,unsigned FormatMaxPadding,bool TruncateZero) const3396d88c1a5aSDimitry Andric void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
339751690af2SDimitry Andric                          unsigned FormatMaxPadding, bool TruncateZero) const {
3398f22ef01cSRoman Divacky   switch (category) {
3399f22ef01cSRoman Divacky   case fcInfinity:
3400f22ef01cSRoman Divacky     if (isNegative())
3401f22ef01cSRoman Divacky       return append(Str, "-Inf");
3402f22ef01cSRoman Divacky     else
3403f22ef01cSRoman Divacky       return append(Str, "+Inf");
3404f22ef01cSRoman Divacky 
3405f22ef01cSRoman Divacky   case fcNaN: return append(Str, "NaN");
3406f22ef01cSRoman Divacky 
3407f22ef01cSRoman Divacky   case fcZero:
3408f22ef01cSRoman Divacky     if (isNegative())
3409f22ef01cSRoman Divacky       Str.push_back('-');
3410f22ef01cSRoman Divacky 
341151690af2SDimitry Andric     if (!FormatMaxPadding) {
341251690af2SDimitry Andric       if (TruncateZero)
3413f22ef01cSRoman Divacky         append(Str, "0.0E+0");
341451690af2SDimitry Andric       else {
341551690af2SDimitry Andric         append(Str, "0.0");
341651690af2SDimitry Andric         if (FormatPrecision > 1)
341751690af2SDimitry Andric           Str.append(FormatPrecision - 1, '0');
341851690af2SDimitry Andric         append(Str, "e+00");
341951690af2SDimitry Andric       }
342051690af2SDimitry Andric     } else
3421f22ef01cSRoman Divacky       Str.push_back('0');
3422f22ef01cSRoman Divacky     return;
3423f22ef01cSRoman Divacky 
3424f22ef01cSRoman Divacky   case fcNormal:
3425f22ef01cSRoman Divacky     break;
3426f22ef01cSRoman Divacky   }
3427f22ef01cSRoman Divacky 
3428f22ef01cSRoman Divacky   if (isNegative())
3429f22ef01cSRoman Divacky     Str.push_back('-');
3430f22ef01cSRoman Divacky 
3431f22ef01cSRoman Divacky   // Decompose the number into an APInt and an exponent.
3432f22ef01cSRoman Divacky   int exp = exponent - ((int) semantics->precision - 1);
3433f22ef01cSRoman Divacky   APInt significand(semantics->precision,
34346122f3e6SDimitry Andric                     makeArrayRef(significandParts(),
34356122f3e6SDimitry Andric                                  partCountForBits(semantics->precision)));
3436f22ef01cSRoman Divacky 
3437f22ef01cSRoman Divacky   // Set FormatPrecision if zero.  We want to do this before we
3438f22ef01cSRoman Divacky   // truncate trailing zeros, as those are part of the precision.
3439f22ef01cSRoman Divacky   if (!FormatPrecision) {
3440f785676fSDimitry Andric     // We use enough digits so the number can be round-tripped back to an
3441f785676fSDimitry Andric     // APFloat. The formula comes from "How to Print Floating-Point Numbers
3442f785676fSDimitry Andric     // Accurately" by Steele and White.
3443f785676fSDimitry Andric     // FIXME: Using a formula based purely on the precision is conservative;
3444f785676fSDimitry Andric     // we can print fewer digits depending on the actual value being printed.
3445f22ef01cSRoman Divacky 
3446f785676fSDimitry Andric     // FormatPrecision = 2 + floor(significandBits / lg_2(10))
3447f785676fSDimitry Andric     FormatPrecision = 2 + semantics->precision * 59 / 196;
3448f22ef01cSRoman Divacky   }
3449f22ef01cSRoman Divacky 
3450f22ef01cSRoman Divacky   // Ignore trailing binary zeros.
3451f22ef01cSRoman Divacky   int trailingZeros = significand.countTrailingZeros();
3452f22ef01cSRoman Divacky   exp += trailingZeros;
34536bc11b14SDimitry Andric   significand.lshrInPlace(trailingZeros);
3454f22ef01cSRoman Divacky 
3455f22ef01cSRoman Divacky   // Change the exponent from 2^e to 10^e.
3456f22ef01cSRoman Divacky   if (exp == 0) {
3457f22ef01cSRoman Divacky     // Nothing to do.
3458f22ef01cSRoman Divacky   } else if (exp > 0) {
3459f22ef01cSRoman Divacky     // Just shift left.
34602754fe60SDimitry Andric     significand = significand.zext(semantics->precision + exp);
3461f22ef01cSRoman Divacky     significand <<= exp;
3462f22ef01cSRoman Divacky     exp = 0;
3463f22ef01cSRoman Divacky   } else { /* exp < 0 */
3464f22ef01cSRoman Divacky     int texp = -exp;
3465f22ef01cSRoman Divacky 
3466f22ef01cSRoman Divacky     // We transform this using the identity:
3467f22ef01cSRoman Divacky     //   (N)(2^-e) == (N)(5^e)(10^-e)
3468f22ef01cSRoman Divacky     // This means we have to multiply N (the significand) by 5^e.
3469f22ef01cSRoman Divacky     // To avoid overflow, we have to operate on numbers large
3470f22ef01cSRoman Divacky     // enough to store N * 5^e:
3471f22ef01cSRoman Divacky     //   log2(N * 5^e) == log2(N) + e * log2(5)
3472f22ef01cSRoman Divacky     //                 <= semantics->precision + e * 137 / 59
3473f22ef01cSRoman Divacky     //   (log_2(5) ~ 2.321928 < 2.322034 ~ 137/59)
3474f22ef01cSRoman Divacky 
34756122f3e6SDimitry Andric     unsigned precision = semantics->precision + (137 * texp + 136) / 59;
3476f22ef01cSRoman Divacky 
3477f22ef01cSRoman Divacky     // Multiply significand by 5^e.
3478f22ef01cSRoman Divacky     //   N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8)
34792754fe60SDimitry Andric     significand = significand.zext(precision);
3480f22ef01cSRoman Divacky     APInt five_to_the_i(precision, 5);
3481f22ef01cSRoman Divacky     while (true) {
3482f22ef01cSRoman Divacky       if (texp & 1) significand *= five_to_the_i;
3483f22ef01cSRoman Divacky 
3484f22ef01cSRoman Divacky       texp >>= 1;
3485f22ef01cSRoman Divacky       if (!texp) break;
3486f22ef01cSRoman Divacky       five_to_the_i *= five_to_the_i;
3487f22ef01cSRoman Divacky     }
3488f22ef01cSRoman Divacky   }
3489f22ef01cSRoman Divacky 
3490f22ef01cSRoman Divacky   AdjustToPrecision(significand, exp, FormatPrecision);
3491f22ef01cSRoman Divacky 
3492139f7f9bSDimitry Andric   SmallVector<char, 256> buffer;
3493f22ef01cSRoman Divacky 
3494f22ef01cSRoman Divacky   // Fill the buffer.
3495f22ef01cSRoman Divacky   unsigned precision = significand.getBitWidth();
3496f22ef01cSRoman Divacky   APInt ten(precision, 10);
3497f22ef01cSRoman Divacky   APInt digit(precision, 0);
3498f22ef01cSRoman Divacky 
3499f22ef01cSRoman Divacky   bool inTrail = true;
3500f22ef01cSRoman Divacky   while (significand != 0) {
3501f22ef01cSRoman Divacky     // digit <- significand % 10
3502f22ef01cSRoman Divacky     // significand <- significand / 10
3503f22ef01cSRoman Divacky     APInt::udivrem(significand, ten, significand, digit);
3504f22ef01cSRoman Divacky 
3505f22ef01cSRoman Divacky     unsigned d = digit.getZExtValue();
3506f22ef01cSRoman Divacky 
3507f22ef01cSRoman Divacky     // Drop trailing zeros.
3508f22ef01cSRoman Divacky     if (inTrail && !d) exp++;
3509f22ef01cSRoman Divacky     else {
3510f22ef01cSRoman Divacky       buffer.push_back((char) ('0' + d));
3511f22ef01cSRoman Divacky       inTrail = false;
3512f22ef01cSRoman Divacky     }
3513f22ef01cSRoman Divacky   }
3514f22ef01cSRoman Divacky 
3515f22ef01cSRoman Divacky   assert(!buffer.empty() && "no characters in buffer!");
3516f22ef01cSRoman Divacky 
3517f22ef01cSRoman Divacky   // Drop down to FormatPrecision.
3518f22ef01cSRoman Divacky   // TODO: don't do more precise calculations above than are required.
3519f22ef01cSRoman Divacky   AdjustToPrecision(buffer, exp, FormatPrecision);
3520f22ef01cSRoman Divacky 
3521f22ef01cSRoman Divacky   unsigned NDigits = buffer.size();
3522f22ef01cSRoman Divacky 
3523f22ef01cSRoman Divacky   // Check whether we should use scientific notation.
3524f22ef01cSRoman Divacky   bool FormatScientific;
3525f22ef01cSRoman Divacky   if (!FormatMaxPadding)
3526f22ef01cSRoman Divacky     FormatScientific = true;
3527f22ef01cSRoman Divacky   else {
3528f22ef01cSRoman Divacky     if (exp >= 0) {
3529f22ef01cSRoman Divacky       // 765e3 --> 765000
3530f22ef01cSRoman Divacky       //              ^^^
3531f22ef01cSRoman Divacky       // But we shouldn't make the number look more precise than it is.
3532f22ef01cSRoman Divacky       FormatScientific = ((unsigned) exp > FormatMaxPadding ||
3533f22ef01cSRoman Divacky                           NDigits + (unsigned) exp > FormatPrecision);
3534f22ef01cSRoman Divacky     } else {
3535f22ef01cSRoman Divacky       // Power of the most significant digit.
3536f22ef01cSRoman Divacky       int MSD = exp + (int) (NDigits - 1);
3537f22ef01cSRoman Divacky       if (MSD >= 0) {
3538f22ef01cSRoman Divacky         // 765e-2 == 7.65
3539f22ef01cSRoman Divacky         FormatScientific = false;
3540f22ef01cSRoman Divacky       } else {
3541f22ef01cSRoman Divacky         // 765e-5 == 0.00765
3542f22ef01cSRoman Divacky         //           ^ ^^
3543f22ef01cSRoman Divacky         FormatScientific = ((unsigned) -MSD) > FormatMaxPadding;
3544f22ef01cSRoman Divacky       }
3545f22ef01cSRoman Divacky     }
3546f22ef01cSRoman Divacky   }
3547f22ef01cSRoman Divacky 
3548f22ef01cSRoman Divacky   // Scientific formatting is pretty straightforward.
3549f22ef01cSRoman Divacky   if (FormatScientific) {
3550f22ef01cSRoman Divacky     exp += (NDigits - 1);
3551f22ef01cSRoman Divacky 
3552f22ef01cSRoman Divacky     Str.push_back(buffer[NDigits-1]);
3553f22ef01cSRoman Divacky     Str.push_back('.');
355451690af2SDimitry Andric     if (NDigits == 1 && TruncateZero)
3555f22ef01cSRoman Divacky       Str.push_back('0');
3556f22ef01cSRoman Divacky     else
3557f22ef01cSRoman Divacky       for (unsigned I = 1; I != NDigits; ++I)
3558f22ef01cSRoman Divacky         Str.push_back(buffer[NDigits-1-I]);
355951690af2SDimitry Andric     // Fill with zeros up to FormatPrecision.
356051690af2SDimitry Andric     if (!TruncateZero && FormatPrecision > NDigits - 1)
356151690af2SDimitry Andric       Str.append(FormatPrecision - NDigits + 1, '0');
356251690af2SDimitry Andric     // For !TruncateZero we use lower 'e'.
356351690af2SDimitry Andric     Str.push_back(TruncateZero ? 'E' : 'e');
3564f22ef01cSRoman Divacky 
3565f22ef01cSRoman Divacky     Str.push_back(exp >= 0 ? '+' : '-');
3566f22ef01cSRoman Divacky     if (exp < 0) exp = -exp;
3567f22ef01cSRoman Divacky     SmallVector<char, 6> expbuf;
3568f22ef01cSRoman Divacky     do {
3569f22ef01cSRoman Divacky       expbuf.push_back((char) ('0' + (exp % 10)));
3570f22ef01cSRoman Divacky       exp /= 10;
3571f22ef01cSRoman Divacky     } while (exp);
357251690af2SDimitry Andric     // Exponent always at least two digits if we do not truncate zeros.
357351690af2SDimitry Andric     if (!TruncateZero && expbuf.size() < 2)
357451690af2SDimitry Andric       expbuf.push_back('0');
3575f22ef01cSRoman Divacky     for (unsigned I = 0, E = expbuf.size(); I != E; ++I)
3576f22ef01cSRoman Divacky       Str.push_back(expbuf[E-1-I]);
3577f22ef01cSRoman Divacky     return;
3578f22ef01cSRoman Divacky   }
3579f22ef01cSRoman Divacky 
3580f22ef01cSRoman Divacky   // Non-scientific, positive exponents.
3581f22ef01cSRoman Divacky   if (exp >= 0) {
3582f22ef01cSRoman Divacky     for (unsigned I = 0; I != NDigits; ++I)
3583f22ef01cSRoman Divacky       Str.push_back(buffer[NDigits-1-I]);
3584f22ef01cSRoman Divacky     for (unsigned I = 0; I != (unsigned) exp; ++I)
3585f22ef01cSRoman Divacky       Str.push_back('0');
3586f22ef01cSRoman Divacky     return;
3587f22ef01cSRoman Divacky   }
3588f22ef01cSRoman Divacky 
3589f22ef01cSRoman Divacky   // Non-scientific, negative exponents.
3590f22ef01cSRoman Divacky 
3591f22ef01cSRoman Divacky   // The number of digits to the left of the decimal point.
3592f22ef01cSRoman Divacky   int NWholeDigits = exp + (int) NDigits;
3593f22ef01cSRoman Divacky 
3594f22ef01cSRoman Divacky   unsigned I = 0;
3595f22ef01cSRoman Divacky   if (NWholeDigits > 0) {
3596f22ef01cSRoman Divacky     for (; I != (unsigned) NWholeDigits; ++I)
3597f22ef01cSRoman Divacky       Str.push_back(buffer[NDigits-I-1]);
3598f22ef01cSRoman Divacky     Str.push_back('.');
3599f22ef01cSRoman Divacky   } else {
3600f22ef01cSRoman Divacky     unsigned NZeros = 1 + (unsigned) -NWholeDigits;
3601f22ef01cSRoman Divacky 
3602f22ef01cSRoman Divacky     Str.push_back('0');
3603f22ef01cSRoman Divacky     Str.push_back('.');
3604f22ef01cSRoman Divacky     for (unsigned Z = 1; Z != NZeros; ++Z)
3605f22ef01cSRoman Divacky       Str.push_back('0');
3606f22ef01cSRoman Divacky   }
3607f22ef01cSRoman Divacky 
3608f22ef01cSRoman Divacky   for (; I != NDigits; ++I)
3609f22ef01cSRoman Divacky     Str.push_back(buffer[NDigits-I-1]);
3610f22ef01cSRoman Divacky }
36113b0f4066SDimitry Andric 
getExactInverse(APFloat * inv) const36127a7e6055SDimitry Andric bool IEEEFloat::getExactInverse(APFloat *inv) const {
36133b0f4066SDimitry Andric   // Special floats and denormals have no exact inverse.
3614f785676fSDimitry Andric   if (!isFiniteNonZero())
36153b0f4066SDimitry Andric     return false;
36163b0f4066SDimitry Andric 
36173b0f4066SDimitry Andric   // Check that the number is a power of two by making sure that only the
36183b0f4066SDimitry Andric   // integer bit is set in the significand.
36193b0f4066SDimitry Andric   if (significandLSB() != semantics->precision - 1)
36203b0f4066SDimitry Andric     return false;
36213b0f4066SDimitry Andric 
36223b0f4066SDimitry Andric   // Get the inverse.
3623d88c1a5aSDimitry Andric   IEEEFloat reciprocal(*semantics, 1ULL);
36243b0f4066SDimitry Andric   if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
36253b0f4066SDimitry Andric     return false;
36263b0f4066SDimitry Andric 
36273b0f4066SDimitry Andric   // Avoid multiplication with a denormal, it is not safe on all platforms and
36283b0f4066SDimitry Andric   // may be slower than a normal division.
3629f785676fSDimitry Andric   if (reciprocal.isDenormal())
36303b0f4066SDimitry Andric     return false;
36313b0f4066SDimitry Andric 
3632f785676fSDimitry Andric   assert(reciprocal.isFiniteNonZero() &&
36333b0f4066SDimitry Andric          reciprocal.significandLSB() == reciprocal.semantics->precision - 1);
36343b0f4066SDimitry Andric 
36353b0f4066SDimitry Andric   if (inv)
36367a7e6055SDimitry Andric     *inv = APFloat(reciprocal, *semantics);
36373b0f4066SDimitry Andric 
36383b0f4066SDimitry Andric   return true;
36393b0f4066SDimitry Andric }
3640f785676fSDimitry Andric 
isSignaling() const3641d88c1a5aSDimitry Andric bool IEEEFloat::isSignaling() const {
3642f785676fSDimitry Andric   if (!isNaN())
3643f785676fSDimitry Andric     return false;
3644f785676fSDimitry Andric 
3645f785676fSDimitry Andric   // IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded with the
3646f785676fSDimitry Andric   // first bit of the trailing significand being 0.
3647f785676fSDimitry Andric   return !APInt::tcExtractBit(significandParts(), semantics->precision - 2);
3648f785676fSDimitry Andric }
3649f785676fSDimitry Andric 
3650f785676fSDimitry Andric /// IEEE-754R 2008 5.3.1: nextUp/nextDown.
3651f785676fSDimitry Andric ///
3652f785676fSDimitry Andric /// *NOTE* since nextDown(x) = -nextUp(-x), we only implement nextUp with
3653f785676fSDimitry Andric /// appropriate sign switching before/after the computation.
next(bool nextDown)3654d88c1a5aSDimitry Andric IEEEFloat::opStatus IEEEFloat::next(bool nextDown) {
3655f785676fSDimitry Andric   // If we are performing nextDown, swap sign so we have -x.
3656f785676fSDimitry Andric   if (nextDown)
3657f785676fSDimitry Andric     changeSign();
3658f785676fSDimitry Andric 
3659f785676fSDimitry Andric   // Compute nextUp(x)
3660f785676fSDimitry Andric   opStatus result = opOK;
3661f785676fSDimitry Andric 
3662f785676fSDimitry Andric   // Handle each float category separately.
3663f785676fSDimitry Andric   switch (category) {
3664f785676fSDimitry Andric   case fcInfinity:
3665f785676fSDimitry Andric     // nextUp(+inf) = +inf
3666f785676fSDimitry Andric     if (!isNegative())
3667f785676fSDimitry Andric       break;
3668f785676fSDimitry Andric     // nextUp(-inf) = -getLargest()
3669f785676fSDimitry Andric     makeLargest(true);
3670f785676fSDimitry Andric     break;
3671f785676fSDimitry Andric   case fcNaN:
3672f785676fSDimitry Andric     // IEEE-754R 2008 6.2 Par 2: nextUp(sNaN) = qNaN. Set Invalid flag.
3673f785676fSDimitry Andric     // IEEE-754R 2008 6.2: nextUp(qNaN) = qNaN. Must be identity so we do not
3674f785676fSDimitry Andric     //                     change the payload.
3675f785676fSDimitry Andric     if (isSignaling()) {
3676f785676fSDimitry Andric       result = opInvalidOp;
367791bc56edSDimitry Andric       // For consistency, propagate the sign of the sNaN to the qNaN.
367891bc56edSDimitry Andric       makeNaN(false, isNegative(), nullptr);
3679f785676fSDimitry Andric     }
3680f785676fSDimitry Andric     break;
3681f785676fSDimitry Andric   case fcZero:
3682f785676fSDimitry Andric     // nextUp(pm 0) = +getSmallest()
3683f785676fSDimitry Andric     makeSmallest(false);
3684f785676fSDimitry Andric     break;
3685f785676fSDimitry Andric   case fcNormal:
3686f785676fSDimitry Andric     // nextUp(-getSmallest()) = -0
3687f785676fSDimitry Andric     if (isSmallest() && isNegative()) {
3688f785676fSDimitry Andric       APInt::tcSet(significandParts(), 0, partCount());
3689f785676fSDimitry Andric       category = fcZero;
3690f785676fSDimitry Andric       exponent = 0;
3691f785676fSDimitry Andric       break;
3692f785676fSDimitry Andric     }
3693f785676fSDimitry Andric 
3694f785676fSDimitry Andric     // nextUp(getLargest()) == INFINITY
3695f785676fSDimitry Andric     if (isLargest() && !isNegative()) {
3696f785676fSDimitry Andric       APInt::tcSet(significandParts(), 0, partCount());
3697f785676fSDimitry Andric       category = fcInfinity;
3698f785676fSDimitry Andric       exponent = semantics->maxExponent + 1;
3699f785676fSDimitry Andric       break;
3700f785676fSDimitry Andric     }
3701f785676fSDimitry Andric 
3702f785676fSDimitry Andric     // nextUp(normal) == normal + inc.
3703f785676fSDimitry Andric     if (isNegative()) {
3704f785676fSDimitry Andric       // If we are negative, we need to decrement the significand.
3705f785676fSDimitry Andric 
3706f785676fSDimitry Andric       // We only cross a binade boundary that requires adjusting the exponent
3707f785676fSDimitry Andric       // if:
3708f785676fSDimitry Andric       //   1. exponent != semantics->minExponent. This implies we are not in the
3709f785676fSDimitry Andric       //   smallest binade or are dealing with denormals.
3710f785676fSDimitry Andric       //   2. Our significand excluding the integral bit is all zeros.
3711f785676fSDimitry Andric       bool WillCrossBinadeBoundary =
3712f785676fSDimitry Andric         exponent != semantics->minExponent && isSignificandAllZeros();
3713f785676fSDimitry Andric 
3714f785676fSDimitry Andric       // Decrement the significand.
3715f785676fSDimitry Andric       //
3716f785676fSDimitry Andric       // We always do this since:
371791bc56edSDimitry Andric       //   1. If we are dealing with a non-binade decrement, by definition we
3718f785676fSDimitry Andric       //   just decrement the significand.
3719f785676fSDimitry Andric       //   2. If we are dealing with a normal -> normal binade decrement, since
3720f785676fSDimitry Andric       //   we have an explicit integral bit the fact that all bits but the
3721f785676fSDimitry Andric       //   integral bit are zero implies that subtracting one will yield a
3722f785676fSDimitry Andric       //   significand with 0 integral bit and 1 in all other spots. Thus we
3723f785676fSDimitry Andric       //   must just adjust the exponent and set the integral bit to 1.
3724f785676fSDimitry Andric       //   3. If we are dealing with a normal -> denormal binade decrement,
3725f785676fSDimitry Andric       //   since we set the integral bit to 0 when we represent denormals, we
3726f785676fSDimitry Andric       //   just decrement the significand.
3727f785676fSDimitry Andric       integerPart *Parts = significandParts();
3728f785676fSDimitry Andric       APInt::tcDecrement(Parts, partCount());
3729f785676fSDimitry Andric 
3730f785676fSDimitry Andric       if (WillCrossBinadeBoundary) {
3731f785676fSDimitry Andric         // Our result is a normal number. Do the following:
3732f785676fSDimitry Andric         // 1. Set the integral bit to 1.
3733f785676fSDimitry Andric         // 2. Decrement the exponent.
3734f785676fSDimitry Andric         APInt::tcSetBit(Parts, semantics->precision - 1);
3735f785676fSDimitry Andric         exponent--;
3736f785676fSDimitry Andric       }
3737f785676fSDimitry Andric     } else {
3738f785676fSDimitry Andric       // If we are positive, we need to increment the significand.
3739f785676fSDimitry Andric 
3740f785676fSDimitry Andric       // We only cross a binade boundary that requires adjusting the exponent if
3741f785676fSDimitry Andric       // the input is not a denormal and all of said input's significand bits
3742f785676fSDimitry Andric       // are set. If all of said conditions are true: clear the significand, set
3743f785676fSDimitry Andric       // the integral bit to 1, and increment the exponent. If we have a
3744f785676fSDimitry Andric       // denormal always increment since moving denormals and the numbers in the
3745f785676fSDimitry Andric       // smallest normal binade have the same exponent in our representation.
3746f785676fSDimitry Andric       bool WillCrossBinadeBoundary = !isDenormal() && isSignificandAllOnes();
3747f785676fSDimitry Andric 
3748f785676fSDimitry Andric       if (WillCrossBinadeBoundary) {
3749f785676fSDimitry Andric         integerPart *Parts = significandParts();
3750f785676fSDimitry Andric         APInt::tcSet(Parts, 0, partCount());
3751f785676fSDimitry Andric         APInt::tcSetBit(Parts, semantics->precision - 1);
3752f785676fSDimitry Andric         assert(exponent != semantics->maxExponent &&
3753f785676fSDimitry Andric                "We can not increment an exponent beyond the maxExponent allowed"
3754f785676fSDimitry Andric                " by the given floating point semantics.");
3755f785676fSDimitry Andric         exponent++;
3756f785676fSDimitry Andric       } else {
3757f785676fSDimitry Andric         incrementSignificand();
3758f785676fSDimitry Andric       }
3759f785676fSDimitry Andric     }
3760f785676fSDimitry Andric     break;
3761f785676fSDimitry Andric   }
3762f785676fSDimitry Andric 
3763f785676fSDimitry Andric   // If we are performing nextDown, swap sign so we have -nextUp(-x)
3764f785676fSDimitry Andric   if (nextDown)
3765f785676fSDimitry Andric     changeSign();
3766f785676fSDimitry Andric 
3767f785676fSDimitry Andric   return result;
3768f785676fSDimitry Andric }
3769f785676fSDimitry Andric 
makeInf(bool Negative)3770d88c1a5aSDimitry Andric void IEEEFloat::makeInf(bool Negative) {
3771f785676fSDimitry Andric   category = fcInfinity;
3772f785676fSDimitry Andric   sign = Negative;
3773f785676fSDimitry Andric   exponent = semantics->maxExponent + 1;
3774f785676fSDimitry Andric   APInt::tcSet(significandParts(), 0, partCount());
3775f785676fSDimitry Andric }
3776f785676fSDimitry Andric 
makeZero(bool Negative)3777d88c1a5aSDimitry Andric void IEEEFloat::makeZero(bool Negative) {
3778f785676fSDimitry Andric   category = fcZero;
3779f785676fSDimitry Andric   sign = Negative;
3780f785676fSDimitry Andric   exponent = semantics->minExponent-1;
3781f785676fSDimitry Andric   APInt::tcSet(significandParts(), 0, partCount());
3782f785676fSDimitry Andric }
378339d628a0SDimitry Andric 
makeQuiet()3784d88c1a5aSDimitry Andric void IEEEFloat::makeQuiet() {
37853ca95b02SDimitry Andric   assert(isNaN());
37863ca95b02SDimitry Andric   APInt::tcSetBit(significandParts(), semantics->precision - 2);
37873ca95b02SDimitry Andric }
378839d628a0SDimitry Andric 
ilogb(const IEEEFloat & Arg)3789d88c1a5aSDimitry Andric int ilogb(const IEEEFloat &Arg) {
37903ca95b02SDimitry Andric   if (Arg.isNaN())
3791d88c1a5aSDimitry Andric     return IEEEFloat::IEK_NaN;
37923ca95b02SDimitry Andric   if (Arg.isZero())
3793d88c1a5aSDimitry Andric     return IEEEFloat::IEK_Zero;
37943ca95b02SDimitry Andric   if (Arg.isInfinity())
3795d88c1a5aSDimitry Andric     return IEEEFloat::IEK_Inf;
37963ca95b02SDimitry Andric   if (!Arg.isDenormal())
37973ca95b02SDimitry Andric     return Arg.exponent;
37983ca95b02SDimitry Andric 
3799d88c1a5aSDimitry Andric   IEEEFloat Normalized(Arg);
38003ca95b02SDimitry Andric   int SignificandBits = Arg.getSemantics().precision - 1;
38013ca95b02SDimitry Andric 
38023ca95b02SDimitry Andric   Normalized.exponent += SignificandBits;
3803d88c1a5aSDimitry Andric   Normalized.normalize(IEEEFloat::rmNearestTiesToEven, lfExactlyZero);
38043ca95b02SDimitry Andric   return Normalized.exponent - SignificandBits;
38053ca95b02SDimitry Andric }
38063ca95b02SDimitry Andric 
scalbn(IEEEFloat X,int Exp,IEEEFloat::roundingMode RoundingMode)3807d88c1a5aSDimitry Andric IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode RoundingMode) {
380839d628a0SDimitry Andric   auto MaxExp = X.getSemantics().maxExponent;
380939d628a0SDimitry Andric   auto MinExp = X.getSemantics().minExponent;
381039d628a0SDimitry Andric 
38113ca95b02SDimitry Andric   // If Exp is wildly out-of-scale, simply adding it to X.exponent will
38123ca95b02SDimitry Andric   // overflow; clamp it to a safe range before adding, but ensure that the range
38133ca95b02SDimitry Andric   // is large enough that the clamp does not change the result. The range we
38143ca95b02SDimitry Andric   // need to support is the difference between the largest possible exponent and
38153ca95b02SDimitry Andric   // the normalized exponent of half the smallest denormal.
38163ca95b02SDimitry Andric 
38173ca95b02SDimitry Andric   int SignificandBits = X.getSemantics().precision - 1;
38183ca95b02SDimitry Andric   int MaxIncrement = MaxExp - (MinExp - SignificandBits) + 1;
38193ca95b02SDimitry Andric 
38203ca95b02SDimitry Andric   // Clamp to one past the range ends to let normalize handle overlflow.
38213ca95b02SDimitry Andric   X.exponent += std::min(std::max(Exp, -MaxIncrement - 1), MaxIncrement);
38223ca95b02SDimitry Andric   X.normalize(RoundingMode, lfExactlyZero);
38233ca95b02SDimitry Andric   if (X.isNaN())
38243ca95b02SDimitry Andric     X.makeQuiet();
3825ff0cc061SDimitry Andric   return X;
382639d628a0SDimitry Andric }
38273ca95b02SDimitry Andric 
frexp(const IEEEFloat & Val,int & Exp,IEEEFloat::roundingMode RM)3828d88c1a5aSDimitry Andric IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM) {
38293ca95b02SDimitry Andric   Exp = ilogb(Val);
38303ca95b02SDimitry Andric 
38313ca95b02SDimitry Andric   // Quiet signalling nans.
3832d88c1a5aSDimitry Andric   if (Exp == IEEEFloat::IEK_NaN) {
3833d88c1a5aSDimitry Andric     IEEEFloat Quiet(Val);
38343ca95b02SDimitry Andric     Quiet.makeQuiet();
38353ca95b02SDimitry Andric     return Quiet;
38363ca95b02SDimitry Andric   }
38373ca95b02SDimitry Andric 
3838d88c1a5aSDimitry Andric   if (Exp == IEEEFloat::IEK_Inf)
38393ca95b02SDimitry Andric     return Val;
38403ca95b02SDimitry Andric 
38413ca95b02SDimitry Andric   // 1 is added because frexp is defined to return a normalized fraction in
38423ca95b02SDimitry Andric   // +/-[0.5, 1.0), rather than the usual +/-[1.0, 2.0).
3843d88c1a5aSDimitry Andric   Exp = Exp == IEEEFloat::IEK_Zero ? 0 : Exp + 1;
38443ca95b02SDimitry Andric   return scalbn(Val, -Exp, RM);
38453ca95b02SDimitry Andric }
3846d88c1a5aSDimitry Andric 
DoubleAPFloat(const fltSemantics & S)3847d88c1a5aSDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S)
38487a7e6055SDimitry Andric     : Semantics(&S),
38497a7e6055SDimitry Andric       Floats(new APFloat[2]{APFloat(semIEEEdouble), APFloat(semIEEEdouble)}) {
3850d88c1a5aSDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
3851d88c1a5aSDimitry Andric }
3852d88c1a5aSDimitry Andric 
DoubleAPFloat(const fltSemantics & S,uninitializedTag)3853d88c1a5aSDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, uninitializedTag)
3854d88c1a5aSDimitry Andric     : Semantics(&S),
38557a7e6055SDimitry Andric       Floats(new APFloat[2]{APFloat(semIEEEdouble, uninitialized),
3856d88c1a5aSDimitry Andric                             APFloat(semIEEEdouble, uninitialized)}) {
3857d88c1a5aSDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
3858d88c1a5aSDimitry Andric }
3859d88c1a5aSDimitry Andric 
DoubleAPFloat(const fltSemantics & S,integerPart I)3860d88c1a5aSDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, integerPart I)
38617a7e6055SDimitry Andric     : Semantics(&S), Floats(new APFloat[2]{APFloat(semIEEEdouble, I),
3862d88c1a5aSDimitry Andric                                            APFloat(semIEEEdouble)}) {
3863d88c1a5aSDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
3864d88c1a5aSDimitry Andric }
3865d88c1a5aSDimitry Andric 
DoubleAPFloat(const fltSemantics & S,const APInt & I)3866d88c1a5aSDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, const APInt &I)
38677a7e6055SDimitry Andric     : Semantics(&S),
38687a7e6055SDimitry Andric       Floats(new APFloat[2]{
38697a7e6055SDimitry Andric           APFloat(semIEEEdouble, APInt(64, I.getRawData()[0])),
3870d88c1a5aSDimitry Andric           APFloat(semIEEEdouble, APInt(64, I.getRawData()[1]))}) {
3871d88c1a5aSDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
3872d88c1a5aSDimitry Andric }
3873d88c1a5aSDimitry Andric 
DoubleAPFloat(const fltSemantics & S,APFloat && First,APFloat && Second)3874d88c1a5aSDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, APFloat &&First,
3875d88c1a5aSDimitry Andric                              APFloat &&Second)
3876d88c1a5aSDimitry Andric     : Semantics(&S),
3877d88c1a5aSDimitry Andric       Floats(new APFloat[2]{std::move(First), std::move(Second)}) {
3878d88c1a5aSDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
38797a7e6055SDimitry Andric   assert(&Floats[0].getSemantics() == &semIEEEdouble);
3880d88c1a5aSDimitry Andric   assert(&Floats[1].getSemantics() == &semIEEEdouble);
3881d88c1a5aSDimitry Andric }
3882d88c1a5aSDimitry Andric 
DoubleAPFloat(const DoubleAPFloat & RHS)3883d88c1a5aSDimitry Andric DoubleAPFloat::DoubleAPFloat(const DoubleAPFloat &RHS)
3884d88c1a5aSDimitry Andric     : Semantics(RHS.Semantics),
3885d88c1a5aSDimitry Andric       Floats(RHS.Floats ? new APFloat[2]{APFloat(RHS.Floats[0]),
3886d88c1a5aSDimitry Andric                                          APFloat(RHS.Floats[1])}
3887d88c1a5aSDimitry Andric                         : nullptr) {
3888d88c1a5aSDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
3889d88c1a5aSDimitry Andric }
3890d88c1a5aSDimitry Andric 
DoubleAPFloat(DoubleAPFloat && RHS)3891d88c1a5aSDimitry Andric DoubleAPFloat::DoubleAPFloat(DoubleAPFloat &&RHS)
3892d88c1a5aSDimitry Andric     : Semantics(RHS.Semantics), Floats(std::move(RHS.Floats)) {
3893d88c1a5aSDimitry Andric   RHS.Semantics = &semBogus;
3894d88c1a5aSDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
3895d88c1a5aSDimitry Andric }
3896d88c1a5aSDimitry Andric 
operator =(const DoubleAPFloat & RHS)3897d88c1a5aSDimitry Andric DoubleAPFloat &DoubleAPFloat::operator=(const DoubleAPFloat &RHS) {
3898d88c1a5aSDimitry Andric   if (Semantics == RHS.Semantics && RHS.Floats) {
3899d88c1a5aSDimitry Andric     Floats[0] = RHS.Floats[0];
3900d88c1a5aSDimitry Andric     Floats[1] = RHS.Floats[1];
3901d88c1a5aSDimitry Andric   } else if (this != &RHS) {
3902d88c1a5aSDimitry Andric     this->~DoubleAPFloat();
3903d88c1a5aSDimitry Andric     new (this) DoubleAPFloat(RHS);
3904d88c1a5aSDimitry Andric   }
3905d88c1a5aSDimitry Andric   return *this;
3906d88c1a5aSDimitry Andric }
3907d88c1a5aSDimitry Andric 
39087a7e6055SDimitry Andric // Implement addition, subtraction, multiplication and division based on:
3909d88c1a5aSDimitry Andric // "Software for Doubled-Precision Floating-Point Computations",
3910d88c1a5aSDimitry Andric // by Seppo Linnainmaa, ACM TOMS vol 7 no 3, September 1981, pages 272-283.
addImpl(const APFloat & a,const APFloat & aa,const APFloat & c,const APFloat & cc,roundingMode RM)3911d88c1a5aSDimitry Andric APFloat::opStatus DoubleAPFloat::addImpl(const APFloat &a, const APFloat &aa,
3912d88c1a5aSDimitry Andric                                          const APFloat &c, const APFloat &cc,
3913d88c1a5aSDimitry Andric                                          roundingMode RM) {
3914d88c1a5aSDimitry Andric   int Status = opOK;
3915d88c1a5aSDimitry Andric   APFloat z = a;
3916d88c1a5aSDimitry Andric   Status |= z.add(c, RM);
3917d88c1a5aSDimitry Andric   if (!z.isFinite()) {
3918d88c1a5aSDimitry Andric     if (!z.isInfinity()) {
3919d88c1a5aSDimitry Andric       Floats[0] = std::move(z);
39207a7e6055SDimitry Andric       Floats[1].makeZero(/* Neg = */ false);
3921d88c1a5aSDimitry Andric       return (opStatus)Status;
3922d88c1a5aSDimitry Andric     }
3923d88c1a5aSDimitry Andric     Status = opOK;
3924d88c1a5aSDimitry Andric     auto AComparedToC = a.compareAbsoluteValue(c);
3925d88c1a5aSDimitry Andric     z = cc;
3926d88c1a5aSDimitry Andric     Status |= z.add(aa, RM);
3927d88c1a5aSDimitry Andric     if (AComparedToC == APFloat::cmpGreaterThan) {
3928d88c1a5aSDimitry Andric       // z = cc + aa + c + a;
3929d88c1a5aSDimitry Andric       Status |= z.add(c, RM);
3930d88c1a5aSDimitry Andric       Status |= z.add(a, RM);
3931d88c1a5aSDimitry Andric     } else {
3932d88c1a5aSDimitry Andric       // z = cc + aa + a + c;
3933d88c1a5aSDimitry Andric       Status |= z.add(a, RM);
3934d88c1a5aSDimitry Andric       Status |= z.add(c, RM);
3935d88c1a5aSDimitry Andric     }
3936d88c1a5aSDimitry Andric     if (!z.isFinite()) {
3937d88c1a5aSDimitry Andric       Floats[0] = std::move(z);
39387a7e6055SDimitry Andric       Floats[1].makeZero(/* Neg = */ false);
3939d88c1a5aSDimitry Andric       return (opStatus)Status;
3940d88c1a5aSDimitry Andric     }
3941d88c1a5aSDimitry Andric     Floats[0] = z;
3942d88c1a5aSDimitry Andric     APFloat zz = aa;
3943d88c1a5aSDimitry Andric     Status |= zz.add(cc, RM);
3944d88c1a5aSDimitry Andric     if (AComparedToC == APFloat::cmpGreaterThan) {
3945d88c1a5aSDimitry Andric       // Floats[1] = a - z + c + zz;
3946d88c1a5aSDimitry Andric       Floats[1] = a;
3947d88c1a5aSDimitry Andric       Status |= Floats[1].subtract(z, RM);
3948d88c1a5aSDimitry Andric       Status |= Floats[1].add(c, RM);
3949d88c1a5aSDimitry Andric       Status |= Floats[1].add(zz, RM);
3950d88c1a5aSDimitry Andric     } else {
3951d88c1a5aSDimitry Andric       // Floats[1] = c - z + a + zz;
3952d88c1a5aSDimitry Andric       Floats[1] = c;
3953d88c1a5aSDimitry Andric       Status |= Floats[1].subtract(z, RM);
3954d88c1a5aSDimitry Andric       Status |= Floats[1].add(a, RM);
3955d88c1a5aSDimitry Andric       Status |= Floats[1].add(zz, RM);
3956d88c1a5aSDimitry Andric     }
3957d88c1a5aSDimitry Andric   } else {
3958d88c1a5aSDimitry Andric     // q = a - z;
3959d88c1a5aSDimitry Andric     APFloat q = a;
3960d88c1a5aSDimitry Andric     Status |= q.subtract(z, RM);
3961d88c1a5aSDimitry Andric 
3962d88c1a5aSDimitry Andric     // zz = q + c + (a - (q + z)) + aa + cc;
3963d88c1a5aSDimitry Andric     // Compute a - (q + z) as -((q + z) - a) to avoid temporary copies.
3964d88c1a5aSDimitry Andric     auto zz = q;
3965d88c1a5aSDimitry Andric     Status |= zz.add(c, RM);
3966d88c1a5aSDimitry Andric     Status |= q.add(z, RM);
3967d88c1a5aSDimitry Andric     Status |= q.subtract(a, RM);
3968d88c1a5aSDimitry Andric     q.changeSign();
3969d88c1a5aSDimitry Andric     Status |= zz.add(q, RM);
3970d88c1a5aSDimitry Andric     Status |= zz.add(aa, RM);
3971d88c1a5aSDimitry Andric     Status |= zz.add(cc, RM);
3972d88c1a5aSDimitry Andric     if (zz.isZero() && !zz.isNegative()) {
3973d88c1a5aSDimitry Andric       Floats[0] = std::move(z);
39747a7e6055SDimitry Andric       Floats[1].makeZero(/* Neg = */ false);
3975d88c1a5aSDimitry Andric       return opOK;
3976d88c1a5aSDimitry Andric     }
3977d88c1a5aSDimitry Andric     Floats[0] = z;
3978d88c1a5aSDimitry Andric     Status |= Floats[0].add(zz, RM);
3979d88c1a5aSDimitry Andric     if (!Floats[0].isFinite()) {
39807a7e6055SDimitry Andric       Floats[1].makeZero(/* Neg = */ false);
3981d88c1a5aSDimitry Andric       return (opStatus)Status;
3982d88c1a5aSDimitry Andric     }
3983d88c1a5aSDimitry Andric     Floats[1] = std::move(z);
3984d88c1a5aSDimitry Andric     Status |= Floats[1].subtract(Floats[0], RM);
3985d88c1a5aSDimitry Andric     Status |= Floats[1].add(zz, RM);
3986d88c1a5aSDimitry Andric   }
3987d88c1a5aSDimitry Andric   return (opStatus)Status;
3988d88c1a5aSDimitry Andric }
3989d88c1a5aSDimitry Andric 
addWithSpecial(const DoubleAPFloat & LHS,const DoubleAPFloat & RHS,DoubleAPFloat & Out,roundingMode RM)3990d88c1a5aSDimitry Andric APFloat::opStatus DoubleAPFloat::addWithSpecial(const DoubleAPFloat &LHS,
3991d88c1a5aSDimitry Andric                                                 const DoubleAPFloat &RHS,
3992d88c1a5aSDimitry Andric                                                 DoubleAPFloat &Out,
3993d88c1a5aSDimitry Andric                                                 roundingMode RM) {
3994d88c1a5aSDimitry Andric   if (LHS.getCategory() == fcNaN) {
3995d88c1a5aSDimitry Andric     Out = LHS;
3996d88c1a5aSDimitry Andric     return opOK;
3997d88c1a5aSDimitry Andric   }
3998d88c1a5aSDimitry Andric   if (RHS.getCategory() == fcNaN) {
3999d88c1a5aSDimitry Andric     Out = RHS;
4000d88c1a5aSDimitry Andric     return opOK;
4001d88c1a5aSDimitry Andric   }
4002d88c1a5aSDimitry Andric   if (LHS.getCategory() == fcZero) {
4003d88c1a5aSDimitry Andric     Out = RHS;
4004d88c1a5aSDimitry Andric     return opOK;
4005d88c1a5aSDimitry Andric   }
4006d88c1a5aSDimitry Andric   if (RHS.getCategory() == fcZero) {
4007d88c1a5aSDimitry Andric     Out = LHS;
4008d88c1a5aSDimitry Andric     return opOK;
4009d88c1a5aSDimitry Andric   }
4010d88c1a5aSDimitry Andric   if (LHS.getCategory() == fcInfinity && RHS.getCategory() == fcInfinity &&
4011d88c1a5aSDimitry Andric       LHS.isNegative() != RHS.isNegative()) {
4012d88c1a5aSDimitry Andric     Out.makeNaN(false, Out.isNegative(), nullptr);
4013d88c1a5aSDimitry Andric     return opInvalidOp;
4014d88c1a5aSDimitry Andric   }
4015d88c1a5aSDimitry Andric   if (LHS.getCategory() == fcInfinity) {
4016d88c1a5aSDimitry Andric     Out = LHS;
4017d88c1a5aSDimitry Andric     return opOK;
4018d88c1a5aSDimitry Andric   }
4019d88c1a5aSDimitry Andric   if (RHS.getCategory() == fcInfinity) {
4020d88c1a5aSDimitry Andric     Out = RHS;
4021d88c1a5aSDimitry Andric     return opOK;
4022d88c1a5aSDimitry Andric   }
4023d88c1a5aSDimitry Andric   assert(LHS.getCategory() == fcNormal && RHS.getCategory() == fcNormal);
4024d88c1a5aSDimitry Andric 
40257a7e6055SDimitry Andric   APFloat A(LHS.Floats[0]), AA(LHS.Floats[1]), C(RHS.Floats[0]),
4026d88c1a5aSDimitry Andric       CC(RHS.Floats[1]);
40277a7e6055SDimitry Andric   assert(&A.getSemantics() == &semIEEEdouble);
4028d88c1a5aSDimitry Andric   assert(&AA.getSemantics() == &semIEEEdouble);
40297a7e6055SDimitry Andric   assert(&C.getSemantics() == &semIEEEdouble);
4030d88c1a5aSDimitry Andric   assert(&CC.getSemantics() == &semIEEEdouble);
40317a7e6055SDimitry Andric   assert(&Out.Floats[0].getSemantics() == &semIEEEdouble);
4032d88c1a5aSDimitry Andric   assert(&Out.Floats[1].getSemantics() == &semIEEEdouble);
40337a7e6055SDimitry Andric   return Out.addImpl(A, AA, C, CC, RM);
4034d88c1a5aSDimitry Andric }
4035d88c1a5aSDimitry Andric 
add(const DoubleAPFloat & RHS,roundingMode RM)4036d88c1a5aSDimitry Andric APFloat::opStatus DoubleAPFloat::add(const DoubleAPFloat &RHS,
4037d88c1a5aSDimitry Andric                                      roundingMode RM) {
4038d88c1a5aSDimitry Andric   return addWithSpecial(*this, RHS, *this, RM);
4039d88c1a5aSDimitry Andric }
4040d88c1a5aSDimitry Andric 
subtract(const DoubleAPFloat & RHS,roundingMode RM)4041d88c1a5aSDimitry Andric APFloat::opStatus DoubleAPFloat::subtract(const DoubleAPFloat &RHS,
4042d88c1a5aSDimitry Andric                                           roundingMode RM) {
4043d88c1a5aSDimitry Andric   changeSign();
4044d88c1a5aSDimitry Andric   auto Ret = add(RHS, RM);
4045d88c1a5aSDimitry Andric   changeSign();
4046d88c1a5aSDimitry Andric   return Ret;
4047d88c1a5aSDimitry Andric }
4048d88c1a5aSDimitry Andric 
multiply(const DoubleAPFloat & RHS,APFloat::roundingMode RM)40497a7e6055SDimitry Andric APFloat::opStatus DoubleAPFloat::multiply(const DoubleAPFloat &RHS,
40507a7e6055SDimitry Andric                                           APFloat::roundingMode RM) {
40517a7e6055SDimitry Andric   const auto &LHS = *this;
40527a7e6055SDimitry Andric   auto &Out = *this;
40537a7e6055SDimitry Andric   /* Interesting observation: For special categories, finding the lowest
40547a7e6055SDimitry Andric      common ancestor of the following layered graph gives the correct
40557a7e6055SDimitry Andric      return category:
40567a7e6055SDimitry Andric 
40577a7e6055SDimitry Andric         NaN
40587a7e6055SDimitry Andric        /   \
40597a7e6055SDimitry Andric      Zero  Inf
40607a7e6055SDimitry Andric        \   /
40617a7e6055SDimitry Andric        Normal
40627a7e6055SDimitry Andric 
40637a7e6055SDimitry Andric      e.g. NaN * NaN = NaN
40647a7e6055SDimitry Andric           Zero * Inf = NaN
40657a7e6055SDimitry Andric           Normal * Zero = Zero
40667a7e6055SDimitry Andric           Normal * Inf = Inf
40677a7e6055SDimitry Andric   */
40687a7e6055SDimitry Andric   if (LHS.getCategory() == fcNaN) {
40697a7e6055SDimitry Andric     Out = LHS;
40707a7e6055SDimitry Andric     return opOK;
40717a7e6055SDimitry Andric   }
40727a7e6055SDimitry Andric   if (RHS.getCategory() == fcNaN) {
40737a7e6055SDimitry Andric     Out = RHS;
40747a7e6055SDimitry Andric     return opOK;
40757a7e6055SDimitry Andric   }
40767a7e6055SDimitry Andric   if ((LHS.getCategory() == fcZero && RHS.getCategory() == fcInfinity) ||
40777a7e6055SDimitry Andric       (LHS.getCategory() == fcInfinity && RHS.getCategory() == fcZero)) {
40787a7e6055SDimitry Andric     Out.makeNaN(false, false, nullptr);
40797a7e6055SDimitry Andric     return opOK;
40807a7e6055SDimitry Andric   }
40817a7e6055SDimitry Andric   if (LHS.getCategory() == fcZero || LHS.getCategory() == fcInfinity) {
40827a7e6055SDimitry Andric     Out = LHS;
40837a7e6055SDimitry Andric     return opOK;
40847a7e6055SDimitry Andric   }
40857a7e6055SDimitry Andric   if (RHS.getCategory() == fcZero || RHS.getCategory() == fcInfinity) {
40867a7e6055SDimitry Andric     Out = RHS;
40877a7e6055SDimitry Andric     return opOK;
40887a7e6055SDimitry Andric   }
40897a7e6055SDimitry Andric   assert(LHS.getCategory() == fcNormal && RHS.getCategory() == fcNormal &&
40907a7e6055SDimitry Andric          "Special cases not handled exhaustively");
40917a7e6055SDimitry Andric 
40927a7e6055SDimitry Andric   int Status = opOK;
40937a7e6055SDimitry Andric   APFloat A = Floats[0], B = Floats[1], C = RHS.Floats[0], D = RHS.Floats[1];
40947a7e6055SDimitry Andric   // t = a * c
40957a7e6055SDimitry Andric   APFloat T = A;
40967a7e6055SDimitry Andric   Status |= T.multiply(C, RM);
40977a7e6055SDimitry Andric   if (!T.isFiniteNonZero()) {
40987a7e6055SDimitry Andric     Floats[0] = T;
40997a7e6055SDimitry Andric     Floats[1].makeZero(/* Neg = */ false);
41007a7e6055SDimitry Andric     return (opStatus)Status;
41017a7e6055SDimitry Andric   }
41027a7e6055SDimitry Andric 
41037a7e6055SDimitry Andric   // tau = fmsub(a, c, t), that is -fmadd(-a, c, t).
41047a7e6055SDimitry Andric   APFloat Tau = A;
41057a7e6055SDimitry Andric   T.changeSign();
41067a7e6055SDimitry Andric   Status |= Tau.fusedMultiplyAdd(C, T, RM);
41077a7e6055SDimitry Andric   T.changeSign();
41087a7e6055SDimitry Andric   {
41097a7e6055SDimitry Andric     // v = a * d
41107a7e6055SDimitry Andric     APFloat V = A;
41117a7e6055SDimitry Andric     Status |= V.multiply(D, RM);
41127a7e6055SDimitry Andric     // w = b * c
41137a7e6055SDimitry Andric     APFloat W = B;
41147a7e6055SDimitry Andric     Status |= W.multiply(C, RM);
41157a7e6055SDimitry Andric     Status |= V.add(W, RM);
41167a7e6055SDimitry Andric     // tau += v + w
41177a7e6055SDimitry Andric     Status |= Tau.add(V, RM);
41187a7e6055SDimitry Andric   }
41197a7e6055SDimitry Andric   // u = t + tau
41207a7e6055SDimitry Andric   APFloat U = T;
41217a7e6055SDimitry Andric   Status |= U.add(Tau, RM);
41227a7e6055SDimitry Andric 
41237a7e6055SDimitry Andric   Floats[0] = U;
41247a7e6055SDimitry Andric   if (!U.isFinite()) {
41257a7e6055SDimitry Andric     Floats[1].makeZero(/* Neg = */ false);
41267a7e6055SDimitry Andric   } else {
41277a7e6055SDimitry Andric     // Floats[1] = (t - u) + tau
41287a7e6055SDimitry Andric     Status |= T.subtract(U, RM);
41297a7e6055SDimitry Andric     Status |= T.add(Tau, RM);
41307a7e6055SDimitry Andric     Floats[1] = T;
41317a7e6055SDimitry Andric   }
41327a7e6055SDimitry Andric   return (opStatus)Status;
41337a7e6055SDimitry Andric }
41347a7e6055SDimitry Andric 
divide(const DoubleAPFloat & RHS,APFloat::roundingMode RM)41357a7e6055SDimitry Andric APFloat::opStatus DoubleAPFloat::divide(const DoubleAPFloat &RHS,
41367a7e6055SDimitry Andric                                         APFloat::roundingMode RM) {
41377a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
41387a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
41397a7e6055SDimitry Andric   auto Ret =
41407a7e6055SDimitry Andric       Tmp.divide(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()), RM);
41417a7e6055SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
41427a7e6055SDimitry Andric   return Ret;
41437a7e6055SDimitry Andric }
41447a7e6055SDimitry Andric 
remainder(const DoubleAPFloat & RHS)41457a7e6055SDimitry Andric APFloat::opStatus DoubleAPFloat::remainder(const DoubleAPFloat &RHS) {
41467a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
41477a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
41487a7e6055SDimitry Andric   auto Ret =
41497a7e6055SDimitry Andric       Tmp.remainder(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()));
41507a7e6055SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
41517a7e6055SDimitry Andric   return Ret;
41527a7e6055SDimitry Andric }
41537a7e6055SDimitry Andric 
mod(const DoubleAPFloat & RHS)41547a7e6055SDimitry Andric APFloat::opStatus DoubleAPFloat::mod(const DoubleAPFloat &RHS) {
41557a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
41567a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
41577a7e6055SDimitry Andric   auto Ret = Tmp.mod(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()));
41587a7e6055SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
41597a7e6055SDimitry Andric   return Ret;
41607a7e6055SDimitry Andric }
41617a7e6055SDimitry Andric 
41627a7e6055SDimitry Andric APFloat::opStatus
fusedMultiplyAdd(const DoubleAPFloat & Multiplicand,const DoubleAPFloat & Addend,APFloat::roundingMode RM)41637a7e6055SDimitry Andric DoubleAPFloat::fusedMultiplyAdd(const DoubleAPFloat &Multiplicand,
41647a7e6055SDimitry Andric                                 const DoubleAPFloat &Addend,
41657a7e6055SDimitry Andric                                 APFloat::roundingMode RM) {
41667a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
41677a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
41687a7e6055SDimitry Andric   auto Ret = Tmp.fusedMultiplyAdd(
41697a7e6055SDimitry Andric       APFloat(semPPCDoubleDoubleLegacy, Multiplicand.bitcastToAPInt()),
41707a7e6055SDimitry Andric       APFloat(semPPCDoubleDoubleLegacy, Addend.bitcastToAPInt()), RM);
41717a7e6055SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
41727a7e6055SDimitry Andric   return Ret;
41737a7e6055SDimitry Andric }
41747a7e6055SDimitry Andric 
roundToIntegral(APFloat::roundingMode RM)41757a7e6055SDimitry Andric APFloat::opStatus DoubleAPFloat::roundToIntegral(APFloat::roundingMode RM) {
41767a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
41777a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
41787a7e6055SDimitry Andric   auto Ret = Tmp.roundToIntegral(RM);
41797a7e6055SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
41807a7e6055SDimitry Andric   return Ret;
41817a7e6055SDimitry Andric }
41827a7e6055SDimitry Andric 
changeSign()4183d88c1a5aSDimitry Andric void DoubleAPFloat::changeSign() {
4184d88c1a5aSDimitry Andric   Floats[0].changeSign();
4185d88c1a5aSDimitry Andric   Floats[1].changeSign();
4186d88c1a5aSDimitry Andric }
4187d88c1a5aSDimitry Andric 
4188d88c1a5aSDimitry Andric APFloat::cmpResult
compareAbsoluteValue(const DoubleAPFloat & RHS) const4189d88c1a5aSDimitry Andric DoubleAPFloat::compareAbsoluteValue(const DoubleAPFloat &RHS) const {
4190d88c1a5aSDimitry Andric   auto Result = Floats[0].compareAbsoluteValue(RHS.Floats[0]);
4191d88c1a5aSDimitry Andric   if (Result != cmpEqual)
4192d88c1a5aSDimitry Andric     return Result;
4193d88c1a5aSDimitry Andric   Result = Floats[1].compareAbsoluteValue(RHS.Floats[1]);
4194d88c1a5aSDimitry Andric   if (Result == cmpLessThan || Result == cmpGreaterThan) {
4195d88c1a5aSDimitry Andric     auto Against = Floats[0].isNegative() ^ Floats[1].isNegative();
4196d88c1a5aSDimitry Andric     auto RHSAgainst = RHS.Floats[0].isNegative() ^ RHS.Floats[1].isNegative();
4197d88c1a5aSDimitry Andric     if (Against && !RHSAgainst)
4198d88c1a5aSDimitry Andric       return cmpLessThan;
4199d88c1a5aSDimitry Andric     if (!Against && RHSAgainst)
4200d88c1a5aSDimitry Andric       return cmpGreaterThan;
4201d88c1a5aSDimitry Andric     if (!Against && !RHSAgainst)
4202d88c1a5aSDimitry Andric       return Result;
4203d88c1a5aSDimitry Andric     if (Against && RHSAgainst)
4204d88c1a5aSDimitry Andric       return (cmpResult)(cmpLessThan + cmpGreaterThan - Result);
4205d88c1a5aSDimitry Andric   }
4206d88c1a5aSDimitry Andric   return Result;
4207d88c1a5aSDimitry Andric }
4208d88c1a5aSDimitry Andric 
getCategory() const4209d88c1a5aSDimitry Andric APFloat::fltCategory DoubleAPFloat::getCategory() const {
4210d88c1a5aSDimitry Andric   return Floats[0].getCategory();
4211d88c1a5aSDimitry Andric }
4212d88c1a5aSDimitry Andric 
isNegative() const4213d88c1a5aSDimitry Andric bool DoubleAPFloat::isNegative() const { return Floats[0].isNegative(); }
4214d88c1a5aSDimitry Andric 
makeInf(bool Neg)4215d88c1a5aSDimitry Andric void DoubleAPFloat::makeInf(bool Neg) {
4216d88c1a5aSDimitry Andric   Floats[0].makeInf(Neg);
42177a7e6055SDimitry Andric   Floats[1].makeZero(/* Neg = */ false);
42187a7e6055SDimitry Andric }
42197a7e6055SDimitry Andric 
makeZero(bool Neg)42207a7e6055SDimitry Andric void DoubleAPFloat::makeZero(bool Neg) {
42217a7e6055SDimitry Andric   Floats[0].makeZero(Neg);
42227a7e6055SDimitry Andric   Floats[1].makeZero(/* Neg = */ false);
42237a7e6055SDimitry Andric }
42247a7e6055SDimitry Andric 
makeLargest(bool Neg)42257a7e6055SDimitry Andric void DoubleAPFloat::makeLargest(bool Neg) {
42267a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
42277a7e6055SDimitry Andric   Floats[0] = APFloat(semIEEEdouble, APInt(64, 0x7fefffffffffffffull));
42287a7e6055SDimitry Andric   Floats[1] = APFloat(semIEEEdouble, APInt(64, 0x7c8ffffffffffffeull));
42297a7e6055SDimitry Andric   if (Neg)
42307a7e6055SDimitry Andric     changeSign();
42317a7e6055SDimitry Andric }
42327a7e6055SDimitry Andric 
makeSmallest(bool Neg)42337a7e6055SDimitry Andric void DoubleAPFloat::makeSmallest(bool Neg) {
42347a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
42357a7e6055SDimitry Andric   Floats[0].makeSmallest(Neg);
42367a7e6055SDimitry Andric   Floats[1].makeZero(/* Neg = */ false);
42377a7e6055SDimitry Andric }
42387a7e6055SDimitry Andric 
makeSmallestNormalized(bool Neg)42397a7e6055SDimitry Andric void DoubleAPFloat::makeSmallestNormalized(bool Neg) {
42407a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
42417a7e6055SDimitry Andric   Floats[0] = APFloat(semIEEEdouble, APInt(64, 0x0360000000000000ull));
42427a7e6055SDimitry Andric   if (Neg)
42437a7e6055SDimitry Andric     Floats[0].changeSign();
42447a7e6055SDimitry Andric   Floats[1].makeZero(/* Neg = */ false);
4245d88c1a5aSDimitry Andric }
4246d88c1a5aSDimitry Andric 
makeNaN(bool SNaN,bool Neg,const APInt * fill)4247d88c1a5aSDimitry Andric void DoubleAPFloat::makeNaN(bool SNaN, bool Neg, const APInt *fill) {
4248d88c1a5aSDimitry Andric   Floats[0].makeNaN(SNaN, Neg, fill);
42497a7e6055SDimitry Andric   Floats[1].makeZero(/* Neg = */ false);
42507a7e6055SDimitry Andric }
42517a7e6055SDimitry Andric 
compare(const DoubleAPFloat & RHS) const42527a7e6055SDimitry Andric APFloat::cmpResult DoubleAPFloat::compare(const DoubleAPFloat &RHS) const {
42537a7e6055SDimitry Andric   auto Result = Floats[0].compare(RHS.Floats[0]);
42547a7e6055SDimitry Andric   // |Float[0]| > |Float[1]|
42557a7e6055SDimitry Andric   if (Result == APFloat::cmpEqual)
42567a7e6055SDimitry Andric     return Floats[1].compare(RHS.Floats[1]);
42577a7e6055SDimitry Andric   return Result;
42587a7e6055SDimitry Andric }
42597a7e6055SDimitry Andric 
bitwiseIsEqual(const DoubleAPFloat & RHS) const42607a7e6055SDimitry Andric bool DoubleAPFloat::bitwiseIsEqual(const DoubleAPFloat &RHS) const {
42617a7e6055SDimitry Andric   return Floats[0].bitwiseIsEqual(RHS.Floats[0]) &&
42627a7e6055SDimitry Andric          Floats[1].bitwiseIsEqual(RHS.Floats[1]);
42637a7e6055SDimitry Andric }
42647a7e6055SDimitry Andric 
hash_value(const DoubleAPFloat & Arg)42657a7e6055SDimitry Andric hash_code hash_value(const DoubleAPFloat &Arg) {
42667a7e6055SDimitry Andric   if (Arg.Floats)
42677a7e6055SDimitry Andric     return hash_combine(hash_value(Arg.Floats[0]), hash_value(Arg.Floats[1]));
42687a7e6055SDimitry Andric   return hash_combine(Arg.Semantics);
42697a7e6055SDimitry Andric }
42707a7e6055SDimitry Andric 
bitcastToAPInt() const42717a7e6055SDimitry Andric APInt DoubleAPFloat::bitcastToAPInt() const {
42727a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
42737a7e6055SDimitry Andric   uint64_t Data[] = {
42747a7e6055SDimitry Andric       Floats[0].bitcastToAPInt().getRawData()[0],
42757a7e6055SDimitry Andric       Floats[1].bitcastToAPInt().getRawData()[0],
42767a7e6055SDimitry Andric   };
42777a7e6055SDimitry Andric   return APInt(128, 2, Data);
42787a7e6055SDimitry Andric }
42797a7e6055SDimitry Andric 
convertFromString(StringRef S,roundingMode RM)42807a7e6055SDimitry Andric APFloat::opStatus DoubleAPFloat::convertFromString(StringRef S,
42817a7e6055SDimitry Andric                                                    roundingMode RM) {
42827a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
42837a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy);
42847a7e6055SDimitry Andric   auto Ret = Tmp.convertFromString(S, RM);
42857a7e6055SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
42867a7e6055SDimitry Andric   return Ret;
42877a7e6055SDimitry Andric }
42887a7e6055SDimitry Andric 
next(bool nextDown)42897a7e6055SDimitry Andric APFloat::opStatus DoubleAPFloat::next(bool nextDown) {
42907a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
42917a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
42927a7e6055SDimitry Andric   auto Ret = Tmp.next(nextDown);
42937a7e6055SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
42947a7e6055SDimitry Andric   return Ret;
42957a7e6055SDimitry Andric }
42967a7e6055SDimitry Andric 
42977a7e6055SDimitry Andric APFloat::opStatus
convertToInteger(MutableArrayRef<integerPart> Input,unsigned int Width,bool IsSigned,roundingMode RM,bool * IsExact) const42987a7e6055SDimitry Andric DoubleAPFloat::convertToInteger(MutableArrayRef<integerPart> Input,
42997a7e6055SDimitry Andric                                 unsigned int Width, bool IsSigned,
43007a7e6055SDimitry Andric                                 roundingMode RM, bool *IsExact) const {
43017a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
43027a7e6055SDimitry Andric   return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
43037a7e6055SDimitry Andric       .convertToInteger(Input, Width, IsSigned, RM, IsExact);
43047a7e6055SDimitry Andric }
43057a7e6055SDimitry Andric 
convertFromAPInt(const APInt & Input,bool IsSigned,roundingMode RM)43067a7e6055SDimitry Andric APFloat::opStatus DoubleAPFloat::convertFromAPInt(const APInt &Input,
43077a7e6055SDimitry Andric                                                   bool IsSigned,
43087a7e6055SDimitry Andric                                                   roundingMode RM) {
43097a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
43107a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy);
43117a7e6055SDimitry Andric   auto Ret = Tmp.convertFromAPInt(Input, IsSigned, RM);
43127a7e6055SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
43137a7e6055SDimitry Andric   return Ret;
43147a7e6055SDimitry Andric }
43157a7e6055SDimitry Andric 
43167a7e6055SDimitry Andric APFloat::opStatus
convertFromSignExtendedInteger(const integerPart * Input,unsigned int InputSize,bool IsSigned,roundingMode RM)43177a7e6055SDimitry Andric DoubleAPFloat::convertFromSignExtendedInteger(const integerPart *Input,
43187a7e6055SDimitry Andric                                               unsigned int InputSize,
43197a7e6055SDimitry Andric                                               bool IsSigned, roundingMode RM) {
43207a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
43217a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy);
43227a7e6055SDimitry Andric   auto Ret = Tmp.convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM);
43237a7e6055SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
43247a7e6055SDimitry Andric   return Ret;
43257a7e6055SDimitry Andric }
43267a7e6055SDimitry Andric 
43277a7e6055SDimitry Andric APFloat::opStatus
convertFromZeroExtendedInteger(const integerPart * Input,unsigned int InputSize,bool IsSigned,roundingMode RM)43287a7e6055SDimitry Andric DoubleAPFloat::convertFromZeroExtendedInteger(const integerPart *Input,
43297a7e6055SDimitry Andric                                               unsigned int InputSize,
43307a7e6055SDimitry Andric                                               bool IsSigned, roundingMode RM) {
43317a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
43327a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy);
43337a7e6055SDimitry Andric   auto Ret = Tmp.convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM);
43347a7e6055SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
43357a7e6055SDimitry Andric   return Ret;
43367a7e6055SDimitry Andric }
43377a7e6055SDimitry Andric 
convertToHexString(char * DST,unsigned int HexDigits,bool UpperCase,roundingMode RM) const43387a7e6055SDimitry Andric unsigned int DoubleAPFloat::convertToHexString(char *DST,
43397a7e6055SDimitry Andric                                                unsigned int HexDigits,
43407a7e6055SDimitry Andric                                                bool UpperCase,
43417a7e6055SDimitry Andric                                                roundingMode RM) const {
43427a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
43437a7e6055SDimitry Andric   return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
43447a7e6055SDimitry Andric       .convertToHexString(DST, HexDigits, UpperCase, RM);
43457a7e6055SDimitry Andric }
43467a7e6055SDimitry Andric 
isDenormal() const43477a7e6055SDimitry Andric bool DoubleAPFloat::isDenormal() const {
43487a7e6055SDimitry Andric   return getCategory() == fcNormal &&
43497a7e6055SDimitry Andric          (Floats[0].isDenormal() || Floats[1].isDenormal() ||
43507a7e6055SDimitry Andric           // (double)(Hi + Lo) == Hi defines a normal number.
43517a7e6055SDimitry Andric           Floats[0].compare(Floats[0] + Floats[1]) != cmpEqual);
43527a7e6055SDimitry Andric }
43537a7e6055SDimitry Andric 
isSmallest() const43547a7e6055SDimitry Andric bool DoubleAPFloat::isSmallest() const {
43557a7e6055SDimitry Andric   if (getCategory() != fcNormal)
43567a7e6055SDimitry Andric     return false;
43577a7e6055SDimitry Andric   DoubleAPFloat Tmp(*this);
43587a7e6055SDimitry Andric   Tmp.makeSmallest(this->isNegative());
43597a7e6055SDimitry Andric   return Tmp.compare(*this) == cmpEqual;
43607a7e6055SDimitry Andric }
43617a7e6055SDimitry Andric 
isLargest() const43627a7e6055SDimitry Andric bool DoubleAPFloat::isLargest() const {
43637a7e6055SDimitry Andric   if (getCategory() != fcNormal)
43647a7e6055SDimitry Andric     return false;
43657a7e6055SDimitry Andric   DoubleAPFloat Tmp(*this);
43667a7e6055SDimitry Andric   Tmp.makeLargest(this->isNegative());
43677a7e6055SDimitry Andric   return Tmp.compare(*this) == cmpEqual;
43687a7e6055SDimitry Andric }
43697a7e6055SDimitry Andric 
isInteger() const43707a7e6055SDimitry Andric bool DoubleAPFloat::isInteger() const {
43717a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
43722cab237bSDimitry Andric   return Floats[0].isInteger() && Floats[1].isInteger();
43737a7e6055SDimitry Andric }
43747a7e6055SDimitry Andric 
toString(SmallVectorImpl<char> & Str,unsigned FormatPrecision,unsigned FormatMaxPadding,bool TruncateZero) const43757a7e6055SDimitry Andric void DoubleAPFloat::toString(SmallVectorImpl<char> &Str,
43767a7e6055SDimitry Andric                              unsigned FormatPrecision,
437751690af2SDimitry Andric                              unsigned FormatMaxPadding,
437851690af2SDimitry Andric                              bool TruncateZero) const {
43797a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
43807a7e6055SDimitry Andric   APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
438151690af2SDimitry Andric       .toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero);
43827a7e6055SDimitry Andric }
43837a7e6055SDimitry Andric 
getExactInverse(APFloat * inv) const43847a7e6055SDimitry Andric bool DoubleAPFloat::getExactInverse(APFloat *inv) const {
43857a7e6055SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
43867a7e6055SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
43877a7e6055SDimitry Andric   if (!inv)
43887a7e6055SDimitry Andric     return Tmp.getExactInverse(nullptr);
43897a7e6055SDimitry Andric   APFloat Inv(semPPCDoubleDoubleLegacy);
43907a7e6055SDimitry Andric   auto Ret = Tmp.getExactInverse(&Inv);
43917a7e6055SDimitry Andric   *inv = APFloat(semPPCDoubleDouble, Inv.bitcastToAPInt());
43927a7e6055SDimitry Andric   return Ret;
43937a7e6055SDimitry Andric }
43947a7e6055SDimitry Andric 
scalbn(DoubleAPFloat Arg,int Exp,APFloat::roundingMode RM)43957a7e6055SDimitry Andric DoubleAPFloat scalbn(DoubleAPFloat Arg, int Exp, APFloat::roundingMode RM) {
43967a7e6055SDimitry Andric   assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
43977a7e6055SDimitry Andric   return DoubleAPFloat(semPPCDoubleDouble, scalbn(Arg.Floats[0], Exp, RM),
43987a7e6055SDimitry Andric                        scalbn(Arg.Floats[1], Exp, RM));
43997a7e6055SDimitry Andric }
44007a7e6055SDimitry Andric 
frexp(const DoubleAPFloat & Arg,int & Exp,APFloat::roundingMode RM)44017a7e6055SDimitry Andric DoubleAPFloat frexp(const DoubleAPFloat &Arg, int &Exp,
44027a7e6055SDimitry Andric                     APFloat::roundingMode RM) {
44037a7e6055SDimitry Andric   assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
44047a7e6055SDimitry Andric   APFloat First = frexp(Arg.Floats[0], Exp, RM);
44057a7e6055SDimitry Andric   APFloat Second = Arg.Floats[1];
44067a7e6055SDimitry Andric   if (Arg.getCategory() == APFloat::fcNormal)
44077a7e6055SDimitry Andric     Second = scalbn(Second, -Exp, RM);
44087a7e6055SDimitry Andric   return DoubleAPFloat(semPPCDoubleDouble, std::move(First), std::move(Second));
4409d88c1a5aSDimitry Andric }
4410d88c1a5aSDimitry Andric 
4411d88c1a5aSDimitry Andric } // End detail namespace
4412d88c1a5aSDimitry Andric 
Storage(IEEEFloat F,const fltSemantics & Semantics)4413d88c1a5aSDimitry Andric APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) {
4414d88c1a5aSDimitry Andric   if (usesLayout<IEEEFloat>(Semantics)) {
4415d88c1a5aSDimitry Andric     new (&IEEE) IEEEFloat(std::move(F));
4416d88c1a5aSDimitry Andric     return;
4417d88c1a5aSDimitry Andric   }
4418d88c1a5aSDimitry Andric   if (usesLayout<DoubleAPFloat>(Semantics)) {
4419d88c1a5aSDimitry Andric     new (&Double)
4420d88c1a5aSDimitry Andric         DoubleAPFloat(Semantics, APFloat(std::move(F), F.getSemantics()),
4421d88c1a5aSDimitry Andric                       APFloat(semIEEEdouble));
4422d88c1a5aSDimitry Andric     return;
4423d88c1a5aSDimitry Andric   }
4424d88c1a5aSDimitry Andric   llvm_unreachable("Unexpected semantics");
4425d88c1a5aSDimitry Andric }
4426d88c1a5aSDimitry Andric 
convertFromString(StringRef Str,roundingMode RM)4427d88c1a5aSDimitry Andric APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) {
44287a7e6055SDimitry Andric   APFLOAT_DISPATCH_ON_SEMANTICS(convertFromString(Str, RM));
4429d88c1a5aSDimitry Andric }
4430d88c1a5aSDimitry Andric 
hash_value(const APFloat & Arg)44317a7e6055SDimitry Andric hash_code hash_value(const APFloat &Arg) {
44327a7e6055SDimitry Andric   if (APFloat::usesLayout<detail::IEEEFloat>(Arg.getSemantics()))
44337a7e6055SDimitry Andric     return hash_value(Arg.U.IEEE);
44347a7e6055SDimitry Andric   if (APFloat::usesLayout<detail::DoubleAPFloat>(Arg.getSemantics()))
44357a7e6055SDimitry Andric     return hash_value(Arg.U.Double);
44367a7e6055SDimitry Andric   llvm_unreachable("Unexpected semantics");
44377a7e6055SDimitry Andric }
4438d88c1a5aSDimitry Andric 
APFloat(const fltSemantics & Semantics,StringRef S)4439d88c1a5aSDimitry Andric APFloat::APFloat(const fltSemantics &Semantics, StringRef S)
4440d88c1a5aSDimitry Andric     : APFloat(Semantics) {
4441d88c1a5aSDimitry Andric   convertFromString(S, rmNearestTiesToEven);
4442d88c1a5aSDimitry Andric }
4443d88c1a5aSDimitry Andric 
convert(const fltSemantics & ToSemantics,roundingMode RM,bool * losesInfo)4444d88c1a5aSDimitry Andric APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics,
4445d88c1a5aSDimitry Andric                                    roundingMode RM, bool *losesInfo) {
4446*4ba319b5SDimitry Andric   if (&getSemantics() == &ToSemantics) {
4447*4ba319b5SDimitry Andric     *losesInfo = false;
4448d88c1a5aSDimitry Andric     return opOK;
4449*4ba319b5SDimitry Andric   }
4450d88c1a5aSDimitry Andric   if (usesLayout<IEEEFloat>(getSemantics()) &&
4451d88c1a5aSDimitry Andric       usesLayout<IEEEFloat>(ToSemantics))
4452d88c1a5aSDimitry Andric     return U.IEEE.convert(ToSemantics, RM, losesInfo);
4453d88c1a5aSDimitry Andric   if (usesLayout<IEEEFloat>(getSemantics()) &&
4454d88c1a5aSDimitry Andric       usesLayout<DoubleAPFloat>(ToSemantics)) {
4455d88c1a5aSDimitry Andric     assert(&ToSemantics == &semPPCDoubleDouble);
44567a7e6055SDimitry Andric     auto Ret = U.IEEE.convert(semPPCDoubleDoubleLegacy, RM, losesInfo);
44577a7e6055SDimitry Andric     *this = APFloat(ToSemantics, U.IEEE.bitcastToAPInt());
4458d88c1a5aSDimitry Andric     return Ret;
4459d88c1a5aSDimitry Andric   }
4460d88c1a5aSDimitry Andric   if (usesLayout<DoubleAPFloat>(getSemantics()) &&
4461d88c1a5aSDimitry Andric       usesLayout<IEEEFloat>(ToSemantics)) {
4462d88c1a5aSDimitry Andric     auto Ret = getIEEE().convert(ToSemantics, RM, losesInfo);
4463d88c1a5aSDimitry Andric     *this = APFloat(std::move(getIEEE()), ToSemantics);
4464d88c1a5aSDimitry Andric     return Ret;
4465d88c1a5aSDimitry Andric   }
4466d88c1a5aSDimitry Andric   llvm_unreachable("Unexpected semantics");
4467d88c1a5aSDimitry Andric }
4468d88c1a5aSDimitry Andric 
getAllOnesValue(unsigned BitWidth,bool isIEEE)4469d88c1a5aSDimitry Andric APFloat APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE) {
4470d88c1a5aSDimitry Andric   if (isIEEE) {
4471d88c1a5aSDimitry Andric     switch (BitWidth) {
4472d88c1a5aSDimitry Andric     case 16:
4473d88c1a5aSDimitry Andric       return APFloat(semIEEEhalf, APInt::getAllOnesValue(BitWidth));
4474d88c1a5aSDimitry Andric     case 32:
4475d88c1a5aSDimitry Andric       return APFloat(semIEEEsingle, APInt::getAllOnesValue(BitWidth));
4476d88c1a5aSDimitry Andric     case 64:
4477d88c1a5aSDimitry Andric       return APFloat(semIEEEdouble, APInt::getAllOnesValue(BitWidth));
4478d88c1a5aSDimitry Andric     case 80:
4479d88c1a5aSDimitry Andric       return APFloat(semX87DoubleExtended, APInt::getAllOnesValue(BitWidth));
4480d88c1a5aSDimitry Andric     case 128:
4481d88c1a5aSDimitry Andric       return APFloat(semIEEEquad, APInt::getAllOnesValue(BitWidth));
4482d88c1a5aSDimitry Andric     default:
4483d88c1a5aSDimitry Andric       llvm_unreachable("Unknown floating bit width");
4484d88c1a5aSDimitry Andric     }
4485d88c1a5aSDimitry Andric   } else {
4486d88c1a5aSDimitry Andric     assert(BitWidth == 128);
4487d88c1a5aSDimitry Andric     return APFloat(semPPCDoubleDouble, APInt::getAllOnesValue(BitWidth));
4488d88c1a5aSDimitry Andric   }
4489d88c1a5aSDimitry Andric }
4490d88c1a5aSDimitry Andric 
print(raw_ostream & OS) const4491d88c1a5aSDimitry Andric void APFloat::print(raw_ostream &OS) const {
4492d88c1a5aSDimitry Andric   SmallVector<char, 16> Buffer;
4493d88c1a5aSDimitry Andric   toString(Buffer);
4494d88c1a5aSDimitry Andric   OS << Buffer << "\n";
4495d88c1a5aSDimitry Andric }
4496d88c1a5aSDimitry Andric 
44977a7e6055SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const44987a7e6055SDimitry Andric LLVM_DUMP_METHOD void APFloat::dump() const { print(dbgs()); }
44997a7e6055SDimitry Andric #endif
45007a7e6055SDimitry Andric 
Profile(FoldingSetNodeID & NID) const45017a7e6055SDimitry Andric void APFloat::Profile(FoldingSetNodeID &NID) const {
45027a7e6055SDimitry Andric   NID.Add(bitcastToAPInt());
45037a7e6055SDimitry Andric }
45047a7e6055SDimitry Andric 
45057a7e6055SDimitry Andric /* Same as convertToInteger(integerPart*, ...), except the result is returned in
45067a7e6055SDimitry Andric    an APSInt, whose initial bit-width and signed-ness are used to determine the
45077a7e6055SDimitry Andric    precision of the conversion.
45087a7e6055SDimitry Andric  */
convertToInteger(APSInt & result,roundingMode rounding_mode,bool * isExact) const45097a7e6055SDimitry Andric APFloat::opStatus APFloat::convertToInteger(APSInt &result,
45107a7e6055SDimitry Andric                                             roundingMode rounding_mode,
45117a7e6055SDimitry Andric                                             bool *isExact) const {
45127a7e6055SDimitry Andric   unsigned bitWidth = result.getBitWidth();
45137a7e6055SDimitry Andric   SmallVector<uint64_t, 4> parts(result.getNumWords());
45147a7e6055SDimitry Andric   opStatus status = convertToInteger(parts, bitWidth, result.isSigned(),
45157a7e6055SDimitry Andric                                      rounding_mode, isExact);
45167a7e6055SDimitry Andric   // Keeps the original signed-ness.
45177a7e6055SDimitry Andric   result = APInt(bitWidth, parts);
45187a7e6055SDimitry Andric   return status;
45197a7e6055SDimitry Andric }
4520d88c1a5aSDimitry Andric 
4521d88c1a5aSDimitry Andric } // End llvm namespace
45227a7e6055SDimitry Andric 
45237a7e6055SDimitry Andric #undef APFLOAT_DISPATCH_ON_SEMANTICS
4524