10b57cec5SDimitry Andric //===-- APFloat.cpp - Implement APFloat class -----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements a class to represent arbitrary precision floating
100b57cec5SDimitry Andric // point values and provide a variety of arithmetic operations on them.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h"
150b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h"
160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
17fe013be4SDimitry Andric #include "llvm/ADT/FloatingPointMode.h"
180b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h"
190b57cec5SDimitry Andric #include "llvm/ADT/Hashing.h"
20fe013be4SDimitry Andric #include "llvm/ADT/STLExtras.h"
210b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
220b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
230b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
240b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
25480093f4SDimitry Andric #include "llvm/Support/Error.h"
260b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
270b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
280b57cec5SDimitry Andric #include <cstring>
290b57cec5SDimitry Andric #include <limits.h>
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric #define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL)                             \
320b57cec5SDimitry Andric   do {                                                                         \
330b57cec5SDimitry Andric     if (usesLayout<IEEEFloat>(getSemantics()))                                 \
340b57cec5SDimitry Andric       return U.IEEE.METHOD_CALL;                                               \
350b57cec5SDimitry Andric     if (usesLayout<DoubleAPFloat>(getSemantics()))                             \
360b57cec5SDimitry Andric       return U.Double.METHOD_CALL;                                             \
370b57cec5SDimitry Andric     llvm_unreachable("Unexpected semantics");                                  \
380b57cec5SDimitry Andric   } while (false)
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric using namespace llvm;
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric /// A macro used to combine two fcCategory enums into one key which can be used
430b57cec5SDimitry Andric /// in a switch statement to classify how the interaction of two APFloat's
440b57cec5SDimitry Andric /// categories affects an operation.
450b57cec5SDimitry Andric ///
460b57cec5SDimitry Andric /// TODO: If clang source code is ever allowed to use constexpr in its own
470b57cec5SDimitry Andric /// codebase, change this into a static inline function.
480b57cec5SDimitry Andric #define PackCategoriesIntoKey(_lhs, _rhs) ((_lhs) * 4 + (_rhs))
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric /* Assumed in hexadecimal significand parsing, and conversion to
510b57cec5SDimitry Andric    hexadecimal strings.  */
520b57cec5SDimitry Andric static_assert(APFloatBase::integerPartWidth % 4 == 0, "Part width must be divisible by 4!");
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric namespace llvm {
55bdd1243dSDimitry Andric 
56bdd1243dSDimitry Andric // How the nonfinite values Inf and NaN are represented.
57bdd1243dSDimitry Andric enum class fltNonfiniteBehavior {
58bdd1243dSDimitry Andric   // Represents standard IEEE 754 behavior. A value is nonfinite if the
59bdd1243dSDimitry Andric   // exponent field is all 1s. In such cases, a value is Inf if the
60bdd1243dSDimitry Andric   // significand bits are all zero, and NaN otherwise
61bdd1243dSDimitry Andric   IEEE754,
62bdd1243dSDimitry Andric 
63fe013be4SDimitry Andric   // This behavior is present in the Float8ExMyFN* types (Float8E4M3FN,
64fe013be4SDimitry Andric   // Float8E5M2FNUZ, Float8E4M3FNUZ, and Float8E4M3B11FNUZ). There is no
65fe013be4SDimitry Andric   // representation for Inf, and operations that would ordinarily produce Inf
66fe013be4SDimitry Andric   // produce NaN instead.
67fe013be4SDimitry Andric   // The details of the NaN representation(s) in this form are determined by the
68fe013be4SDimitry Andric   // `fltNanEncoding` enum. We treat all NaNs as quiet, as the available
69fe013be4SDimitry Andric   // encodings do not distinguish between signalling and quiet NaN.
70fe013be4SDimitry Andric   NanOnly,
71fe013be4SDimitry Andric };
72fe013be4SDimitry Andric 
73fe013be4SDimitry Andric // How NaN values are represented. This is curently only used in combination
74fe013be4SDimitry Andric // with fltNonfiniteBehavior::NanOnly, and using a variant other than IEEE
75fe013be4SDimitry Andric // while having IEEE non-finite behavior is liable to lead to unexpected
76fe013be4SDimitry Andric // results.
77fe013be4SDimitry Andric enum class fltNanEncoding {
78fe013be4SDimitry Andric   // Represents the standard IEEE behavior where a value is NaN if its
79fe013be4SDimitry Andric   // exponent is all 1s and the significand is non-zero.
80fe013be4SDimitry Andric   IEEE,
81fe013be4SDimitry Andric 
82fe013be4SDimitry Andric   // Represents the behavior in the Float8E4M3 floating point type where NaN is
83fe013be4SDimitry Andric   // represented by having the exponent and mantissa set to all 1s.
84bdd1243dSDimitry Andric   // This behavior matches the FP8 E4M3 type described in
85bdd1243dSDimitry Andric   // https://arxiv.org/abs/2209.05433. We treat both signed and unsigned NaNs
86bdd1243dSDimitry Andric   // as non-signalling, although the paper does not state whether the NaN
87bdd1243dSDimitry Andric   // values are signalling or not.
88fe013be4SDimitry Andric   AllOnes,
89fe013be4SDimitry Andric 
90fe013be4SDimitry Andric   // Represents the behavior in Float8E{5,4}E{2,3}FNUZ floating point types
91fe013be4SDimitry Andric   // where NaN is represented by a sign bit of 1 and all 0s in the exponent
92fe013be4SDimitry Andric   // and mantissa (i.e. the negative zero encoding in a IEEE float). Since
93fe013be4SDimitry Andric   // there is only one NaN value, it is treated as quiet NaN. This matches the
94fe013be4SDimitry Andric   // behavior described in https://arxiv.org/abs/2206.02915 .
95fe013be4SDimitry Andric   NegativeZero,
96bdd1243dSDimitry Andric };
97bdd1243dSDimitry Andric 
980b57cec5SDimitry Andric /* Represents floating point arithmetic semantics.  */
990b57cec5SDimitry Andric struct fltSemantics {
1000b57cec5SDimitry Andric   /* The largest E such that 2^E is representable; this matches the
1010b57cec5SDimitry Andric      definition of IEEE 754.  */
1020b57cec5SDimitry Andric   APFloatBase::ExponentType maxExponent;
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   /* The smallest E such that 2^E is a normalized number; this
1050b57cec5SDimitry Andric      matches the definition of IEEE 754.  */
1060b57cec5SDimitry Andric   APFloatBase::ExponentType minExponent;
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   /* Number of bits in the significand.  This includes the integer
1090b57cec5SDimitry Andric      bit.  */
1100b57cec5SDimitry Andric   unsigned int precision;
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   /* Number of bits actually used in the semantics. */
1130b57cec5SDimitry Andric   unsigned int sizeInBits;
114fe6060f1SDimitry Andric 
115bdd1243dSDimitry Andric   fltNonfiniteBehavior nonFiniteBehavior = fltNonfiniteBehavior::IEEE754;
116bdd1243dSDimitry Andric 
117fe013be4SDimitry Andric   fltNanEncoding nanEncoding = fltNanEncoding::IEEE;
118fe6060f1SDimitry Andric   // Returns true if any number described by this semantics can be precisely
119bdd1243dSDimitry Andric   // represented by the specified semantics. Does not take into account
120bdd1243dSDimitry Andric   // the value of fltNonfiniteBehavior.
isRepresentableByllvm::fltSemantics121fe6060f1SDimitry Andric   bool isRepresentableBy(const fltSemantics &S) const {
122fe6060f1SDimitry Andric     return maxExponent <= S.maxExponent && minExponent >= S.minExponent &&
123fe6060f1SDimitry Andric            precision <= S.precision;
124fe6060f1SDimitry Andric   }
1250b57cec5SDimitry Andric };
1260b57cec5SDimitry Andric 
127fe013be4SDimitry Andric static constexpr fltSemantics semIEEEhalf = {15, -14, 11, 16};
128fe013be4SDimitry Andric static constexpr fltSemantics semBFloat = {127, -126, 8, 16};
129fe013be4SDimitry Andric static constexpr fltSemantics semIEEEsingle = {127, -126, 24, 32};
130fe013be4SDimitry Andric static constexpr fltSemantics semIEEEdouble = {1023, -1022, 53, 64};
131fe013be4SDimitry Andric static constexpr fltSemantics semIEEEquad = {16383, -16382, 113, 128};
132fe013be4SDimitry Andric static constexpr fltSemantics semFloat8E5M2 = {15, -14, 3, 8};
133fe013be4SDimitry Andric static constexpr fltSemantics semFloat8E5M2FNUZ = {
134fe013be4SDimitry Andric     15, -15, 3, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero};
135fe013be4SDimitry Andric static constexpr fltSemantics semFloat8E4M3FN = {
136fe013be4SDimitry Andric     8, -6, 4, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::AllOnes};
137fe013be4SDimitry Andric static constexpr fltSemantics semFloat8E4M3FNUZ = {
138fe013be4SDimitry Andric     7, -7, 4, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero};
139fe013be4SDimitry Andric static constexpr fltSemantics semFloat8E4M3B11FNUZ = {
140fe013be4SDimitry Andric     4, -10, 4, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero};
141fe013be4SDimitry Andric static constexpr fltSemantics semFloatTF32 = {127, -126, 11, 19};
142fe013be4SDimitry Andric static constexpr fltSemantics semX87DoubleExtended = {16383, -16382, 64, 80};
143fe013be4SDimitry Andric static constexpr fltSemantics semBogus = {0, 0, 0, 0};
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric /* The IBM double-double semantics. Such a number consists of a pair of IEEE
1460b57cec5SDimitry Andric    64-bit doubles (Hi, Lo), where |Hi| > |Lo|, and if normal,
1470b57cec5SDimitry Andric    (double)(Hi + Lo) == Hi. The numeric value it's modeling is Hi + Lo.
1480b57cec5SDimitry Andric    Therefore it has two 53-bit mantissa parts that aren't necessarily adjacent
1490b57cec5SDimitry Andric    to each other, and two 11-bit exponents.
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric    Note: we need to make the value different from semBogus as otherwise
1520b57cec5SDimitry Andric    an unsafe optimization may collapse both values to a single address,
1530b57cec5SDimitry Andric    and we heavily rely on them having distinct addresses.             */
154fe013be4SDimitry Andric static constexpr fltSemantics semPPCDoubleDouble = {-1, 0, 0, 128};
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric /* These are legacy semantics for the fallback, inaccrurate implementation of
1570b57cec5SDimitry Andric    IBM double-double, if the accurate semPPCDoubleDouble doesn't handle the
1580b57cec5SDimitry Andric    operation. It's equivalent to having an IEEE number with consecutive 106
1590b57cec5SDimitry Andric    bits of mantissa and 11 bits of exponent.
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric    It's not equivalent to IBM double-double. For example, a legit IBM
1620b57cec5SDimitry Andric    double-double, 1 + epsilon:
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric      1 + epsilon = 1 + (1 >> 1076)
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric    is not representable by a consecutive 106 bits of mantissa.
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric    Currently, these semantics are used in the following way:
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric      semPPCDoubleDouble -> (IEEEdouble, IEEEdouble) ->
1710b57cec5SDimitry Andric      (64-bit APInt, 64-bit APInt) -> (128-bit APInt) ->
1720b57cec5SDimitry Andric      semPPCDoubleDoubleLegacy -> IEEE operations
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric    We use bitcastToAPInt() to get the bit representation (in APInt) of the
1750b57cec5SDimitry Andric    underlying IEEEdouble, then use the APInt constructor to construct the
1760b57cec5SDimitry Andric    legacy IEEE float.
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric    TODO: Implement all operations in semPPCDoubleDouble, and delete these
1790b57cec5SDimitry Andric    semantics.  */
180fe013be4SDimitry Andric static constexpr fltSemantics semPPCDoubleDoubleLegacy = {1023, -1022 + 53,
1810b57cec5SDimitry Andric                                                           53 + 53, 128};
1820b57cec5SDimitry Andric 
EnumToSemantics(Semantics S)1830b57cec5SDimitry Andric const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) {
1840b57cec5SDimitry Andric   switch (S) {
1850b57cec5SDimitry Andric   case S_IEEEhalf:
1860b57cec5SDimitry Andric     return IEEEhalf();
1875ffd83dbSDimitry Andric   case S_BFloat:
1885ffd83dbSDimitry Andric     return BFloat();
1890b57cec5SDimitry Andric   case S_IEEEsingle:
1900b57cec5SDimitry Andric     return IEEEsingle();
1910b57cec5SDimitry Andric   case S_IEEEdouble:
1920b57cec5SDimitry Andric     return IEEEdouble();
1930b57cec5SDimitry Andric   case S_IEEEquad:
1940b57cec5SDimitry Andric     return IEEEquad();
1950b57cec5SDimitry Andric   case S_PPCDoubleDouble:
1960b57cec5SDimitry Andric     return PPCDoubleDouble();
197bdd1243dSDimitry Andric   case S_Float8E5M2:
198bdd1243dSDimitry Andric     return Float8E5M2();
199fe013be4SDimitry Andric   case S_Float8E5M2FNUZ:
200fe013be4SDimitry Andric     return Float8E5M2FNUZ();
201bdd1243dSDimitry Andric   case S_Float8E4M3FN:
202bdd1243dSDimitry Andric     return Float8E4M3FN();
203fe013be4SDimitry Andric   case S_Float8E4M3FNUZ:
204fe013be4SDimitry Andric     return Float8E4M3FNUZ();
205fe013be4SDimitry Andric   case S_Float8E4M3B11FNUZ:
206fe013be4SDimitry Andric     return Float8E4M3B11FNUZ();
207fe013be4SDimitry Andric   case S_FloatTF32:
208fe013be4SDimitry Andric     return FloatTF32();
209bdd1243dSDimitry Andric   case S_x87DoubleExtended:
210bdd1243dSDimitry Andric     return x87DoubleExtended();
2110b57cec5SDimitry Andric   }
2120b57cec5SDimitry Andric   llvm_unreachable("Unrecognised floating semantics");
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric APFloatBase::Semantics
SemanticsToEnum(const llvm::fltSemantics & Sem)2160b57cec5SDimitry Andric APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) {
2170b57cec5SDimitry Andric   if (&Sem == &llvm::APFloat::IEEEhalf())
2180b57cec5SDimitry Andric     return S_IEEEhalf;
2195ffd83dbSDimitry Andric   else if (&Sem == &llvm::APFloat::BFloat())
2205ffd83dbSDimitry Andric     return S_BFloat;
2210b57cec5SDimitry Andric   else if (&Sem == &llvm::APFloat::IEEEsingle())
2220b57cec5SDimitry Andric     return S_IEEEsingle;
2230b57cec5SDimitry Andric   else if (&Sem == &llvm::APFloat::IEEEdouble())
2240b57cec5SDimitry Andric     return S_IEEEdouble;
2250b57cec5SDimitry Andric   else if (&Sem == &llvm::APFloat::IEEEquad())
2260b57cec5SDimitry Andric     return S_IEEEquad;
2270b57cec5SDimitry Andric   else if (&Sem == &llvm::APFloat::PPCDoubleDouble())
2280b57cec5SDimitry Andric     return S_PPCDoubleDouble;
229bdd1243dSDimitry Andric   else if (&Sem == &llvm::APFloat::Float8E5M2())
230bdd1243dSDimitry Andric     return S_Float8E5M2;
231fe013be4SDimitry Andric   else if (&Sem == &llvm::APFloat::Float8E5M2FNUZ())
232fe013be4SDimitry Andric     return S_Float8E5M2FNUZ;
233bdd1243dSDimitry Andric   else if (&Sem == &llvm::APFloat::Float8E4M3FN())
234bdd1243dSDimitry Andric     return S_Float8E4M3FN;
235fe013be4SDimitry Andric   else if (&Sem == &llvm::APFloat::Float8E4M3FNUZ())
236fe013be4SDimitry Andric     return S_Float8E4M3FNUZ;
237fe013be4SDimitry Andric   else if (&Sem == &llvm::APFloat::Float8E4M3B11FNUZ())
238fe013be4SDimitry Andric     return S_Float8E4M3B11FNUZ;
239fe013be4SDimitry Andric   else if (&Sem == &llvm::APFloat::FloatTF32())
240fe013be4SDimitry Andric     return S_FloatTF32;
241bdd1243dSDimitry Andric   else if (&Sem == &llvm::APFloat::x87DoubleExtended())
242bdd1243dSDimitry Andric     return S_x87DoubleExtended;
2430b57cec5SDimitry Andric   else
2440b57cec5SDimitry Andric     llvm_unreachable("Unknown floating semantics");
2450b57cec5SDimitry Andric }
2460b57cec5SDimitry Andric 
IEEEhalf()247fe013be4SDimitry Andric const fltSemantics &APFloatBase::IEEEhalf() { return semIEEEhalf; }
BFloat()248fe013be4SDimitry Andric const fltSemantics &APFloatBase::BFloat() { return semBFloat; }
IEEEsingle()249fe013be4SDimitry Andric const fltSemantics &APFloatBase::IEEEsingle() { return semIEEEsingle; }
IEEEdouble()250fe013be4SDimitry Andric const fltSemantics &APFloatBase::IEEEdouble() { return semIEEEdouble; }
IEEEquad()251bdd1243dSDimitry Andric const fltSemantics &APFloatBase::IEEEquad() { return semIEEEquad; }
PPCDoubleDouble()2520b57cec5SDimitry Andric const fltSemantics &APFloatBase::PPCDoubleDouble() {
2530b57cec5SDimitry Andric   return semPPCDoubleDouble;
2540b57cec5SDimitry Andric }
Float8E5M2()255bdd1243dSDimitry Andric const fltSemantics &APFloatBase::Float8E5M2() { return semFloat8E5M2; }
Float8E5M2FNUZ()256fe013be4SDimitry Andric const fltSemantics &APFloatBase::Float8E5M2FNUZ() { return semFloat8E5M2FNUZ; }
Float8E4M3FN()257bdd1243dSDimitry Andric const fltSemantics &APFloatBase::Float8E4M3FN() { return semFloat8E4M3FN; }
Float8E4M3FNUZ()258fe013be4SDimitry Andric const fltSemantics &APFloatBase::Float8E4M3FNUZ() { return semFloat8E4M3FNUZ; }
Float8E4M3B11FNUZ()259fe013be4SDimitry Andric const fltSemantics &APFloatBase::Float8E4M3B11FNUZ() {
260fe013be4SDimitry Andric   return semFloat8E4M3B11FNUZ;
261fe013be4SDimitry Andric }
FloatTF32()262fe013be4SDimitry Andric const fltSemantics &APFloatBase::FloatTF32() { return semFloatTF32; }
x87DoubleExtended()263bdd1243dSDimitry Andric const fltSemantics &APFloatBase::x87DoubleExtended() {
264bdd1243dSDimitry Andric   return semX87DoubleExtended;
265bdd1243dSDimitry Andric }
Bogus()266bdd1243dSDimitry Andric const fltSemantics &APFloatBase::Bogus() { return semBogus; }
2670b57cec5SDimitry Andric 
2685ffd83dbSDimitry Andric constexpr RoundingMode APFloatBase::rmNearestTiesToEven;
2695ffd83dbSDimitry Andric constexpr RoundingMode APFloatBase::rmTowardPositive;
2705ffd83dbSDimitry Andric constexpr RoundingMode APFloatBase::rmTowardNegative;
2715ffd83dbSDimitry Andric constexpr RoundingMode APFloatBase::rmTowardZero;
2725ffd83dbSDimitry Andric constexpr RoundingMode APFloatBase::rmNearestTiesToAway;
2735ffd83dbSDimitry Andric 
2740b57cec5SDimitry Andric /* A tight upper bound on number of parts required to hold the value
2750b57cec5SDimitry Andric    pow(5, power) is
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric      power * 815 / (351 * integerPartWidth) + 1
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric    However, whilst the result may require only this many parts,
2800b57cec5SDimitry Andric    because we are multiplying two values to get it, the
2810b57cec5SDimitry Andric    multiplication may require an extra part with the excess part
2820b57cec5SDimitry Andric    being zero (consider the trivial case of 1 * 1, tcFullMultiply
2830b57cec5SDimitry Andric    requires two parts to hold the single-part result).  So we add an
2840b57cec5SDimitry Andric    extra one to guarantee enough space whilst multiplying.  */
2850b57cec5SDimitry Andric const unsigned int maxExponent = 16383;
2860b57cec5SDimitry Andric const unsigned int maxPrecision = 113;
2870b57cec5SDimitry Andric const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1;
288fe013be4SDimitry Andric const unsigned int maxPowerOfFiveParts =
289fe013be4SDimitry Andric     2 +
290fe013be4SDimitry Andric     ((maxPowerOfFiveExponent * 815) / (351 * APFloatBase::integerPartWidth));
2910b57cec5SDimitry Andric 
semanticsPrecision(const fltSemantics & semantics)2920b57cec5SDimitry Andric unsigned int APFloatBase::semanticsPrecision(const fltSemantics &semantics) {
2930b57cec5SDimitry Andric   return semantics.precision;
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric APFloatBase::ExponentType
semanticsMaxExponent(const fltSemantics & semantics)2960b57cec5SDimitry Andric APFloatBase::semanticsMaxExponent(const fltSemantics &semantics) {
2970b57cec5SDimitry Andric   return semantics.maxExponent;
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric APFloatBase::ExponentType
semanticsMinExponent(const fltSemantics & semantics)3000b57cec5SDimitry Andric APFloatBase::semanticsMinExponent(const fltSemantics &semantics) {
3010b57cec5SDimitry Andric   return semantics.minExponent;
3020b57cec5SDimitry Andric }
semanticsSizeInBits(const fltSemantics & semantics)3030b57cec5SDimitry Andric unsigned int APFloatBase::semanticsSizeInBits(const fltSemantics &semantics) {
3040b57cec5SDimitry Andric   return semantics.sizeInBits;
3050b57cec5SDimitry Andric }
semanticsIntSizeInBits(const fltSemantics & semantics,bool isSigned)306fe013be4SDimitry Andric unsigned int APFloatBase::semanticsIntSizeInBits(const fltSemantics &semantics,
307fe013be4SDimitry Andric                                                  bool isSigned) {
308fe013be4SDimitry Andric   // The max FP value is pow(2, MaxExponent) * (1 + MaxFraction), so we need
309fe013be4SDimitry Andric   // at least one more bit than the MaxExponent to hold the max FP value.
310fe013be4SDimitry Andric   unsigned int MinBitWidth = semanticsMaxExponent(semantics) + 1;
311fe013be4SDimitry Andric   // Extra sign bit needed.
312fe013be4SDimitry Andric   if (isSigned)
313fe013be4SDimitry Andric     ++MinBitWidth;
314fe013be4SDimitry Andric   return MinBitWidth;
315fe013be4SDimitry Andric }
316fe013be4SDimitry Andric 
isRepresentableAsNormalIn(const fltSemantics & Src,const fltSemantics & Dst)317fe013be4SDimitry Andric bool APFloatBase::isRepresentableAsNormalIn(const fltSemantics &Src,
318fe013be4SDimitry Andric                                             const fltSemantics &Dst) {
319fe013be4SDimitry Andric   // Exponent range must be larger.
320fe013be4SDimitry Andric   if (Src.maxExponent >= Dst.maxExponent || Src.minExponent <= Dst.minExponent)
321fe013be4SDimitry Andric     return false;
322fe013be4SDimitry Andric 
323fe013be4SDimitry Andric   // If the mantissa is long enough, the result value could still be denormal
324fe013be4SDimitry Andric   // with a larger exponent range.
325fe013be4SDimitry Andric   //
326fe013be4SDimitry Andric   // FIXME: This condition is probably not accurate but also shouldn't be a
327fe013be4SDimitry Andric   // practical concern with existing types.
328fe013be4SDimitry Andric   return Dst.precision >= Src.precision;
329fe013be4SDimitry Andric }
3300b57cec5SDimitry Andric 
getSizeInBits(const fltSemantics & Sem)3310b57cec5SDimitry Andric unsigned APFloatBase::getSizeInBits(const fltSemantics &Sem) {
3320b57cec5SDimitry Andric   return Sem.sizeInBits;
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric 
335fe013be4SDimitry Andric static constexpr APFloatBase::ExponentType
exponentZero(const fltSemantics & semantics)336fe013be4SDimitry Andric exponentZero(const fltSemantics &semantics) {
337fe013be4SDimitry Andric   return semantics.minExponent - 1;
338fe013be4SDimitry Andric }
339fe013be4SDimitry Andric 
340fe013be4SDimitry Andric static constexpr APFloatBase::ExponentType
exponentInf(const fltSemantics & semantics)341fe013be4SDimitry Andric exponentInf(const fltSemantics &semantics) {
342fe013be4SDimitry Andric   return semantics.maxExponent + 1;
343fe013be4SDimitry Andric }
344fe013be4SDimitry Andric 
345fe013be4SDimitry Andric static constexpr APFloatBase::ExponentType
exponentNaN(const fltSemantics & semantics)346fe013be4SDimitry Andric exponentNaN(const fltSemantics &semantics) {
347fe013be4SDimitry Andric   if (semantics.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
348fe013be4SDimitry Andric     if (semantics.nanEncoding == fltNanEncoding::NegativeZero)
349fe013be4SDimitry Andric       return exponentZero(semantics);
350fe013be4SDimitry Andric     return semantics.maxExponent;
351fe013be4SDimitry Andric   }
352fe013be4SDimitry Andric   return semantics.maxExponent + 1;
353fe013be4SDimitry Andric }
354fe013be4SDimitry Andric 
3550b57cec5SDimitry Andric /* A bunch of private, handy routines.  */
3560b57cec5SDimitry Andric 
createError(const Twine & Err)357480093f4SDimitry Andric static inline Error createError(const Twine &Err) {
358480093f4SDimitry Andric   return make_error<StringError>(Err, inconvertibleErrorCode());
359480093f4SDimitry Andric }
360480093f4SDimitry Andric 
partCountForBits(unsigned int bits)361fe013be4SDimitry Andric static constexpr inline unsigned int partCountForBits(unsigned int bits) {
3620b57cec5SDimitry Andric   return ((bits) + APFloatBase::integerPartWidth - 1) / APFloatBase::integerPartWidth;
3630b57cec5SDimitry Andric }
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric /* Returns 0U-9U.  Return values >= 10U are not digits.  */
3660b57cec5SDimitry Andric static inline unsigned int
decDigitValue(unsigned int c)3670b57cec5SDimitry Andric decDigitValue(unsigned int c)
3680b57cec5SDimitry Andric {
3690b57cec5SDimitry Andric   return c - '0';
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric /* Return the value of a decimal exponent of the form
3730b57cec5SDimitry Andric    [+-]ddddddd.
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric    If the exponent overflows, returns a large exponent with the
3760b57cec5SDimitry Andric    appropriate sign.  */
readExponent(StringRef::iterator begin,StringRef::iterator end)377480093f4SDimitry Andric static Expected<int> readExponent(StringRef::iterator begin,
378480093f4SDimitry Andric                                   StringRef::iterator end) {
3790b57cec5SDimitry Andric   bool isNegative;
3800b57cec5SDimitry Andric   unsigned int absExponent;
3810b57cec5SDimitry Andric   const unsigned int overlargeExponent = 24000;  /* FIXME.  */
3820b57cec5SDimitry Andric   StringRef::iterator p = begin;
3830b57cec5SDimitry Andric 
3840b57cec5SDimitry Andric   // Treat no exponent as 0 to match binutils
3850b57cec5SDimitry Andric   if (p == end || ((*p == '-' || *p == '+') && (p + 1) == end)) {
3860b57cec5SDimitry Andric     return 0;
3870b57cec5SDimitry Andric   }
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric   isNegative = (*p == '-');
3900b57cec5SDimitry Andric   if (*p == '-' || *p == '+') {
3910b57cec5SDimitry Andric     p++;
392480093f4SDimitry Andric     if (p == end)
393480093f4SDimitry Andric       return createError("Exponent has no digits");
3940b57cec5SDimitry Andric   }
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   absExponent = decDigitValue(*p++);
397480093f4SDimitry Andric   if (absExponent >= 10U)
398480093f4SDimitry Andric     return createError("Invalid character in exponent");
3990b57cec5SDimitry Andric 
4000b57cec5SDimitry Andric   for (; p != end; ++p) {
4010b57cec5SDimitry Andric     unsigned int value;
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric     value = decDigitValue(*p);
404480093f4SDimitry Andric     if (value >= 10U)
405480093f4SDimitry Andric       return createError("Invalid character in exponent");
4060b57cec5SDimitry Andric 
407480093f4SDimitry Andric     absExponent = absExponent * 10U + value;
4080b57cec5SDimitry Andric     if (absExponent >= overlargeExponent) {
4090b57cec5SDimitry Andric       absExponent = overlargeExponent;
4100b57cec5SDimitry Andric       break;
4110b57cec5SDimitry Andric     }
4120b57cec5SDimitry Andric   }
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   if (isNegative)
4150b57cec5SDimitry Andric     return -(int) absExponent;
4160b57cec5SDimitry Andric   else
4170b57cec5SDimitry Andric     return (int) absExponent;
4180b57cec5SDimitry Andric }
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric /* This is ugly and needs cleaning up, but I don't immediately see
4210b57cec5SDimitry Andric    how whilst remaining safe.  */
totalExponent(StringRef::iterator p,StringRef::iterator end,int exponentAdjustment)422480093f4SDimitry Andric static Expected<int> totalExponent(StringRef::iterator p,
423480093f4SDimitry Andric                                    StringRef::iterator end,
424480093f4SDimitry Andric                                    int exponentAdjustment) {
4250b57cec5SDimitry Andric   int unsignedExponent;
4260b57cec5SDimitry Andric   bool negative, overflow;
4270b57cec5SDimitry Andric   int exponent = 0;
4280b57cec5SDimitry Andric 
429480093f4SDimitry Andric   if (p == end)
430480093f4SDimitry Andric     return createError("Exponent has no digits");
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric   negative = *p == '-';
4330b57cec5SDimitry Andric   if (*p == '-' || *p == '+') {
4340b57cec5SDimitry Andric     p++;
435480093f4SDimitry Andric     if (p == end)
436480093f4SDimitry Andric       return createError("Exponent has no digits");
4370b57cec5SDimitry Andric   }
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric   unsignedExponent = 0;
4400b57cec5SDimitry Andric   overflow = false;
4410b57cec5SDimitry Andric   for (; p != end; ++p) {
4420b57cec5SDimitry Andric     unsigned int value;
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric     value = decDigitValue(*p);
445480093f4SDimitry Andric     if (value >= 10U)
446480093f4SDimitry Andric       return createError("Invalid character in exponent");
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric     unsignedExponent = unsignedExponent * 10 + value;
4490b57cec5SDimitry Andric     if (unsignedExponent > 32767) {
4500b57cec5SDimitry Andric       overflow = true;
4510b57cec5SDimitry Andric       break;
4520b57cec5SDimitry Andric     }
4530b57cec5SDimitry Andric   }
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   if (exponentAdjustment > 32767 || exponentAdjustment < -32768)
4560b57cec5SDimitry Andric     overflow = true;
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric   if (!overflow) {
4590b57cec5SDimitry Andric     exponent = unsignedExponent;
4600b57cec5SDimitry Andric     if (negative)
4610b57cec5SDimitry Andric       exponent = -exponent;
4620b57cec5SDimitry Andric     exponent += exponentAdjustment;
4630b57cec5SDimitry Andric     if (exponent > 32767 || exponent < -32768)
4640b57cec5SDimitry Andric       overflow = true;
4650b57cec5SDimitry Andric   }
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric   if (overflow)
4680b57cec5SDimitry Andric     exponent = negative ? -32768: 32767;
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric   return exponent;
4710b57cec5SDimitry Andric }
4720b57cec5SDimitry Andric 
473480093f4SDimitry Andric static Expected<StringRef::iterator>
skipLeadingZeroesAndAnyDot(StringRef::iterator begin,StringRef::iterator end,StringRef::iterator * dot)4740b57cec5SDimitry Andric skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end,
475480093f4SDimitry Andric                            StringRef::iterator *dot) {
4760b57cec5SDimitry Andric   StringRef::iterator p = begin;
4770b57cec5SDimitry Andric   *dot = end;
4780b57cec5SDimitry Andric   while (p != end && *p == '0')
4790b57cec5SDimitry Andric     p++;
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric   if (p != end && *p == '.') {
4820b57cec5SDimitry Andric     *dot = p++;
4830b57cec5SDimitry Andric 
484480093f4SDimitry Andric     if (end - begin == 1)
485480093f4SDimitry Andric       return createError("Significand has no digits");
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric     while (p != end && *p == '0')
4880b57cec5SDimitry Andric       p++;
4890b57cec5SDimitry Andric   }
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric   return p;
4920b57cec5SDimitry Andric }
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric /* Given a normal decimal floating point number of the form
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric      dddd.dddd[eE][+-]ddd
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric    where the decimal point and exponent are optional, fill out the
4990b57cec5SDimitry Andric    structure D.  Exponent is appropriate if the significand is
5000b57cec5SDimitry Andric    treated as an integer, and normalizedExponent if the significand
5010b57cec5SDimitry Andric    is taken to have the decimal point after a single leading
5020b57cec5SDimitry Andric    non-zero digit.
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric    If the value is zero, V->firstSigDigit points to a non-digit, and
5050b57cec5SDimitry Andric    the return exponent is zero.
5060b57cec5SDimitry Andric */
5070b57cec5SDimitry Andric struct decimalInfo {
5080b57cec5SDimitry Andric   const char *firstSigDigit;
5090b57cec5SDimitry Andric   const char *lastSigDigit;
5100b57cec5SDimitry Andric   int exponent;
5110b57cec5SDimitry Andric   int normalizedExponent;
5120b57cec5SDimitry Andric };
5130b57cec5SDimitry Andric 
interpretDecimal(StringRef::iterator begin,StringRef::iterator end,decimalInfo * D)514480093f4SDimitry Andric static Error interpretDecimal(StringRef::iterator begin,
515480093f4SDimitry Andric                               StringRef::iterator end, decimalInfo *D) {
5160b57cec5SDimitry Andric   StringRef::iterator dot = end;
517480093f4SDimitry Andric 
518480093f4SDimitry Andric   auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot);
519480093f4SDimitry Andric   if (!PtrOrErr)
520480093f4SDimitry Andric     return PtrOrErr.takeError();
521480093f4SDimitry Andric   StringRef::iterator p = *PtrOrErr;
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric   D->firstSigDigit = p;
5240b57cec5SDimitry Andric   D->exponent = 0;
5250b57cec5SDimitry Andric   D->normalizedExponent = 0;
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric   for (; p != end; ++p) {
5280b57cec5SDimitry Andric     if (*p == '.') {
529480093f4SDimitry Andric       if (dot != end)
530480093f4SDimitry Andric         return createError("String contains multiple dots");
5310b57cec5SDimitry Andric       dot = p++;
5320b57cec5SDimitry Andric       if (p == end)
5330b57cec5SDimitry Andric         break;
5340b57cec5SDimitry Andric     }
5350b57cec5SDimitry Andric     if (decDigitValue(*p) >= 10U)
5360b57cec5SDimitry Andric       break;
5370b57cec5SDimitry Andric   }
5380b57cec5SDimitry Andric 
5390b57cec5SDimitry Andric   if (p != end) {
540480093f4SDimitry Andric     if (*p != 'e' && *p != 'E')
541480093f4SDimitry Andric       return createError("Invalid character in significand");
542480093f4SDimitry Andric     if (p == begin)
543480093f4SDimitry Andric       return createError("Significand has no digits");
544480093f4SDimitry Andric     if (dot != end && p - begin == 1)
545480093f4SDimitry Andric       return createError("Significand has no digits");
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric     /* p points to the first non-digit in the string */
548480093f4SDimitry Andric     auto ExpOrErr = readExponent(p + 1, end);
549480093f4SDimitry Andric     if (!ExpOrErr)
550480093f4SDimitry Andric       return ExpOrErr.takeError();
551480093f4SDimitry Andric     D->exponent = *ExpOrErr;
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric     /* Implied decimal point?  */
5540b57cec5SDimitry Andric     if (dot == end)
5550b57cec5SDimitry Andric       dot = p;
5560b57cec5SDimitry Andric   }
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric   /* If number is all zeroes accept any exponent.  */
5590b57cec5SDimitry Andric   if (p != D->firstSigDigit) {
5600b57cec5SDimitry Andric     /* Drop insignificant trailing zeroes.  */
5610b57cec5SDimitry Andric     if (p != begin) {
5620b57cec5SDimitry Andric       do
5630b57cec5SDimitry Andric         do
5640b57cec5SDimitry Andric           p--;
5650b57cec5SDimitry Andric         while (p != begin && *p == '0');
5660b57cec5SDimitry Andric       while (p != begin && *p == '.');
5670b57cec5SDimitry Andric     }
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric     /* Adjust the exponents for any decimal point.  */
5700b57cec5SDimitry Andric     D->exponent += static_cast<APFloat::ExponentType>((dot - p) - (dot > p));
5710b57cec5SDimitry Andric     D->normalizedExponent = (D->exponent +
5720b57cec5SDimitry Andric               static_cast<APFloat::ExponentType>((p - D->firstSigDigit)
5730b57cec5SDimitry Andric                                       - (dot > D->firstSigDigit && dot < p)));
5740b57cec5SDimitry Andric   }
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   D->lastSigDigit = p;
577480093f4SDimitry Andric   return Error::success();
5780b57cec5SDimitry Andric }
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric /* Return the trailing fraction of a hexadecimal number.
5810b57cec5SDimitry Andric    DIGITVALUE is the first hex digit of the fraction, P points to
5820b57cec5SDimitry Andric    the next digit.  */
583480093f4SDimitry Andric static Expected<lostFraction>
trailingHexadecimalFraction(StringRef::iterator p,StringRef::iterator end,unsigned int digitValue)5840b57cec5SDimitry Andric trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end,
585480093f4SDimitry Andric                             unsigned int digitValue) {
5860b57cec5SDimitry Andric   unsigned int hexDigit;
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric   /* If the first trailing digit isn't 0 or 8 we can work out the
5890b57cec5SDimitry Andric      fraction immediately.  */
5900b57cec5SDimitry Andric   if (digitValue > 8)
5910b57cec5SDimitry Andric     return lfMoreThanHalf;
5920b57cec5SDimitry Andric   else if (digitValue < 8 && digitValue > 0)
5930b57cec5SDimitry Andric     return lfLessThanHalf;
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric   // Otherwise we need to find the first non-zero digit.
5960b57cec5SDimitry Andric   while (p != end && (*p == '0' || *p == '.'))
5970b57cec5SDimitry Andric     p++;
5980b57cec5SDimitry Andric 
599480093f4SDimitry Andric   if (p == end)
600480093f4SDimitry Andric     return createError("Invalid trailing hexadecimal fraction!");
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric   hexDigit = hexDigitValue(*p);
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric   /* If we ran off the end it is exactly zero or one-half, otherwise
6050b57cec5SDimitry Andric      a little more.  */
606fe013be4SDimitry Andric   if (hexDigit == UINT_MAX)
6070b57cec5SDimitry Andric     return digitValue == 0 ? lfExactlyZero: lfExactlyHalf;
6080b57cec5SDimitry Andric   else
6090b57cec5SDimitry Andric     return digitValue == 0 ? lfLessThanHalf: lfMoreThanHalf;
6100b57cec5SDimitry Andric }
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric /* Return the fraction lost were a bignum truncated losing the least
6130b57cec5SDimitry Andric    significant BITS bits.  */
6140b57cec5SDimitry Andric static lostFraction
lostFractionThroughTruncation(const APFloatBase::integerPart * parts,unsigned int partCount,unsigned int bits)6150b57cec5SDimitry Andric lostFractionThroughTruncation(const APFloatBase::integerPart *parts,
6160b57cec5SDimitry Andric                               unsigned int partCount,
6170b57cec5SDimitry Andric                               unsigned int bits)
6180b57cec5SDimitry Andric {
6190b57cec5SDimitry Andric   unsigned int lsb;
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric   lsb = APInt::tcLSB(parts, partCount);
6220b57cec5SDimitry Andric 
623fe013be4SDimitry Andric   /* Note this is guaranteed true if bits == 0, or LSB == UINT_MAX.  */
6240b57cec5SDimitry Andric   if (bits <= lsb)
6250b57cec5SDimitry Andric     return lfExactlyZero;
6260b57cec5SDimitry Andric   if (bits == lsb + 1)
6270b57cec5SDimitry Andric     return lfExactlyHalf;
6280b57cec5SDimitry Andric   if (bits <= partCount * APFloatBase::integerPartWidth &&
6290b57cec5SDimitry Andric       APInt::tcExtractBit(parts, bits - 1))
6300b57cec5SDimitry Andric     return lfMoreThanHalf;
6310b57cec5SDimitry Andric 
6320b57cec5SDimitry Andric   return lfLessThanHalf;
6330b57cec5SDimitry Andric }
6340b57cec5SDimitry Andric 
6350b57cec5SDimitry Andric /* Shift DST right BITS bits noting lost fraction.  */
6360b57cec5SDimitry Andric static lostFraction
shiftRight(APFloatBase::integerPart * dst,unsigned int parts,unsigned int bits)6370b57cec5SDimitry Andric shiftRight(APFloatBase::integerPart *dst, unsigned int parts, unsigned int bits)
6380b57cec5SDimitry Andric {
6390b57cec5SDimitry Andric   lostFraction lost_fraction;
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric   lost_fraction = lostFractionThroughTruncation(dst, parts, bits);
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric   APInt::tcShiftRight(dst, parts, bits);
6440b57cec5SDimitry Andric 
6450b57cec5SDimitry Andric   return lost_fraction;
6460b57cec5SDimitry Andric }
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric /* Combine the effect of two lost fractions.  */
6490b57cec5SDimitry Andric static lostFraction
combineLostFractions(lostFraction moreSignificant,lostFraction lessSignificant)6500b57cec5SDimitry Andric combineLostFractions(lostFraction moreSignificant,
6510b57cec5SDimitry Andric                      lostFraction lessSignificant)
6520b57cec5SDimitry Andric {
6530b57cec5SDimitry Andric   if (lessSignificant != lfExactlyZero) {
6540b57cec5SDimitry Andric     if (moreSignificant == lfExactlyZero)
6550b57cec5SDimitry Andric       moreSignificant = lfLessThanHalf;
6560b57cec5SDimitry Andric     else if (moreSignificant == lfExactlyHalf)
6570b57cec5SDimitry Andric       moreSignificant = lfMoreThanHalf;
6580b57cec5SDimitry Andric   }
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric   return moreSignificant;
6610b57cec5SDimitry Andric }
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric /* The error from the true value, in half-ulps, on multiplying two
6640b57cec5SDimitry Andric    floating point numbers, which differ from the value they
6650b57cec5SDimitry Andric    approximate by at most HUE1 and HUE2 half-ulps, is strictly less
6660b57cec5SDimitry Andric    than the returned value.
6670b57cec5SDimitry Andric 
6680b57cec5SDimitry Andric    See "How to Read Floating Point Numbers Accurately" by William D
6690b57cec5SDimitry Andric    Clinger.  */
6700b57cec5SDimitry Andric static unsigned int
HUerrBound(bool inexactMultiply,unsigned int HUerr1,unsigned int HUerr2)6710b57cec5SDimitry Andric HUerrBound(bool inexactMultiply, unsigned int HUerr1, unsigned int HUerr2)
6720b57cec5SDimitry Andric {
6730b57cec5SDimitry Andric   assert(HUerr1 < 2 || HUerr2 < 2 || (HUerr1 + HUerr2 < 8));
6740b57cec5SDimitry Andric 
6750b57cec5SDimitry Andric   if (HUerr1 + HUerr2 == 0)
6760b57cec5SDimitry Andric     return inexactMultiply * 2;  /* <= inexactMultiply half-ulps.  */
6770b57cec5SDimitry Andric   else
6780b57cec5SDimitry Andric     return inexactMultiply + 2 * (HUerr1 + HUerr2);
6790b57cec5SDimitry Andric }
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric /* The number of ulps from the boundary (zero, or half if ISNEAREST)
6820b57cec5SDimitry Andric    when the least significant BITS are truncated.  BITS cannot be
6830b57cec5SDimitry Andric    zero.  */
6840b57cec5SDimitry Andric static APFloatBase::integerPart
ulpsFromBoundary(const APFloatBase::integerPart * parts,unsigned int bits,bool isNearest)6850b57cec5SDimitry Andric ulpsFromBoundary(const APFloatBase::integerPart *parts, unsigned int bits,
6860b57cec5SDimitry Andric                  bool isNearest) {
6870b57cec5SDimitry Andric   unsigned int count, partBits;
6880b57cec5SDimitry Andric   APFloatBase::integerPart part, boundary;
6890b57cec5SDimitry Andric 
6900b57cec5SDimitry Andric   assert(bits != 0);
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric   bits--;
6930b57cec5SDimitry Andric   count = bits / APFloatBase::integerPartWidth;
6940b57cec5SDimitry Andric   partBits = bits % APFloatBase::integerPartWidth + 1;
6950b57cec5SDimitry Andric 
6960b57cec5SDimitry Andric   part = parts[count] & (~(APFloatBase::integerPart) 0 >> (APFloatBase::integerPartWidth - partBits));
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric   if (isNearest)
6990b57cec5SDimitry Andric     boundary = (APFloatBase::integerPart) 1 << (partBits - 1);
7000b57cec5SDimitry Andric   else
7010b57cec5SDimitry Andric     boundary = 0;
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric   if (count == 0) {
7040b57cec5SDimitry Andric     if (part - boundary <= boundary - part)
7050b57cec5SDimitry Andric       return part - boundary;
7060b57cec5SDimitry Andric     else
7070b57cec5SDimitry Andric       return boundary - part;
7080b57cec5SDimitry Andric   }
7090b57cec5SDimitry Andric 
7100b57cec5SDimitry Andric   if (part == boundary) {
7110b57cec5SDimitry Andric     while (--count)
7120b57cec5SDimitry Andric       if (parts[count])
7130b57cec5SDimitry Andric         return ~(APFloatBase::integerPart) 0; /* A lot.  */
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric     return parts[0];
7160b57cec5SDimitry Andric   } else if (part == boundary - 1) {
7170b57cec5SDimitry Andric     while (--count)
7180b57cec5SDimitry Andric       if (~parts[count])
7190b57cec5SDimitry Andric         return ~(APFloatBase::integerPart) 0; /* A lot.  */
7200b57cec5SDimitry Andric 
7210b57cec5SDimitry Andric     return -parts[0];
7220b57cec5SDimitry Andric   }
7230b57cec5SDimitry Andric 
7240b57cec5SDimitry Andric   return ~(APFloatBase::integerPart) 0; /* A lot.  */
7250b57cec5SDimitry Andric }
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric /* Place pow(5, power) in DST, and return the number of parts used.
7280b57cec5SDimitry Andric    DST must be at least one part larger than size of the answer.  */
7290b57cec5SDimitry Andric static unsigned int
powerOf5(APFloatBase::integerPart * dst,unsigned int power)7300b57cec5SDimitry Andric powerOf5(APFloatBase::integerPart *dst, unsigned int power) {
7310b57cec5SDimitry Andric   static const APFloatBase::integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, 15625, 78125 };
7320b57cec5SDimitry Andric   APFloatBase::integerPart pow5s[maxPowerOfFiveParts * 2 + 5];
7330b57cec5SDimitry Andric   pow5s[0] = 78125 * 5;
7340b57cec5SDimitry Andric 
7350b57cec5SDimitry Andric   unsigned int partsCount[16] = { 1 };
7360b57cec5SDimitry Andric   APFloatBase::integerPart scratch[maxPowerOfFiveParts], *p1, *p2, *pow5;
7370b57cec5SDimitry Andric   unsigned int result;
7380b57cec5SDimitry Andric   assert(power <= maxExponent);
7390b57cec5SDimitry Andric 
7400b57cec5SDimitry Andric   p1 = dst;
7410b57cec5SDimitry Andric   p2 = scratch;
7420b57cec5SDimitry Andric 
7430b57cec5SDimitry Andric   *p1 = firstEightPowers[power & 7];
7440b57cec5SDimitry Andric   power >>= 3;
7450b57cec5SDimitry Andric 
7460b57cec5SDimitry Andric   result = 1;
7470b57cec5SDimitry Andric   pow5 = pow5s;
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric   for (unsigned int n = 0; power; power >>= 1, n++) {
7500b57cec5SDimitry Andric     unsigned int pc;
7510b57cec5SDimitry Andric 
7520b57cec5SDimitry Andric     pc = partsCount[n];
7530b57cec5SDimitry Andric 
7540b57cec5SDimitry Andric     /* Calculate pow(5,pow(2,n+3)) if we haven't yet.  */
7550b57cec5SDimitry Andric     if (pc == 0) {
7560b57cec5SDimitry Andric       pc = partsCount[n - 1];
7570b57cec5SDimitry Andric       APInt::tcFullMultiply(pow5, pow5 - pc, pow5 - pc, pc, pc);
7580b57cec5SDimitry Andric       pc *= 2;
7590b57cec5SDimitry Andric       if (pow5[pc - 1] == 0)
7600b57cec5SDimitry Andric         pc--;
7610b57cec5SDimitry Andric       partsCount[n] = pc;
7620b57cec5SDimitry Andric     }
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric     if (power & 1) {
7650b57cec5SDimitry Andric       APFloatBase::integerPart *tmp;
7660b57cec5SDimitry Andric 
7670b57cec5SDimitry Andric       APInt::tcFullMultiply(p2, p1, pow5, result, pc);
7680b57cec5SDimitry Andric       result += pc;
7690b57cec5SDimitry Andric       if (p2[result - 1] == 0)
7700b57cec5SDimitry Andric         result--;
7710b57cec5SDimitry Andric 
7720b57cec5SDimitry Andric       /* Now result is in p1 with partsCount parts and p2 is scratch
7730b57cec5SDimitry Andric          space.  */
7740b57cec5SDimitry Andric       tmp = p1;
7750b57cec5SDimitry Andric       p1 = p2;
7760b57cec5SDimitry Andric       p2 = tmp;
7770b57cec5SDimitry Andric     }
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric     pow5 += pc;
7800b57cec5SDimitry Andric   }
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric   if (p1 != dst)
7830b57cec5SDimitry Andric     APInt::tcAssign(dst, p1, result);
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric   return result;
7860b57cec5SDimitry Andric }
7870b57cec5SDimitry Andric 
7880b57cec5SDimitry Andric /* Zero at the end to avoid modular arithmetic when adding one; used
7890b57cec5SDimitry Andric    when rounding up during hexadecimal output.  */
7900b57cec5SDimitry Andric static const char hexDigitsLower[] = "0123456789abcdef0";
7910b57cec5SDimitry Andric static const char hexDigitsUpper[] = "0123456789ABCDEF0";
7920b57cec5SDimitry Andric static const char infinityL[] = "infinity";
7930b57cec5SDimitry Andric static const char infinityU[] = "INFINITY";
7940b57cec5SDimitry Andric static const char NaNL[] = "nan";
7950b57cec5SDimitry Andric static const char NaNU[] = "NAN";
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric /* Write out an integerPart in hexadecimal, starting with the most
7980b57cec5SDimitry Andric    significant nibble.  Write out exactly COUNT hexdigits, return
7990b57cec5SDimitry Andric    COUNT.  */
8000b57cec5SDimitry Andric static unsigned int
partAsHex(char * dst,APFloatBase::integerPart part,unsigned int count,const char * hexDigitChars)8010b57cec5SDimitry Andric partAsHex (char *dst, APFloatBase::integerPart part, unsigned int count,
8020b57cec5SDimitry Andric            const char *hexDigitChars)
8030b57cec5SDimitry Andric {
8040b57cec5SDimitry Andric   unsigned int result = count;
8050b57cec5SDimitry Andric 
8060b57cec5SDimitry Andric   assert(count != 0 && count <= APFloatBase::integerPartWidth / 4);
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric   part >>= (APFloatBase::integerPartWidth - 4 * count);
8090b57cec5SDimitry Andric   while (count--) {
8100b57cec5SDimitry Andric     dst[count] = hexDigitChars[part & 0xf];
8110b57cec5SDimitry Andric     part >>= 4;
8120b57cec5SDimitry Andric   }
8130b57cec5SDimitry Andric 
8140b57cec5SDimitry Andric   return result;
8150b57cec5SDimitry Andric }
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric /* Write out an unsigned decimal integer.  */
8180b57cec5SDimitry Andric static char *
writeUnsignedDecimal(char * dst,unsigned int n)8190b57cec5SDimitry Andric writeUnsignedDecimal (char *dst, unsigned int n)
8200b57cec5SDimitry Andric {
8210b57cec5SDimitry Andric   char buff[40], *p;
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric   p = buff;
8240b57cec5SDimitry Andric   do
8250b57cec5SDimitry Andric     *p++ = '0' + n % 10;
8260b57cec5SDimitry Andric   while (n /= 10);
8270b57cec5SDimitry Andric 
8280b57cec5SDimitry Andric   do
8290b57cec5SDimitry Andric     *dst++ = *--p;
8300b57cec5SDimitry Andric   while (p != buff);
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric   return dst;
8330b57cec5SDimitry Andric }
8340b57cec5SDimitry Andric 
8350b57cec5SDimitry Andric /* Write out a signed decimal integer.  */
8360b57cec5SDimitry Andric static char *
writeSignedDecimal(char * dst,int value)8370b57cec5SDimitry Andric writeSignedDecimal (char *dst, int value)
8380b57cec5SDimitry Andric {
8390b57cec5SDimitry Andric   if (value < 0) {
8400b57cec5SDimitry Andric     *dst++ = '-';
8410b57cec5SDimitry Andric     dst = writeUnsignedDecimal(dst, -(unsigned) value);
8420b57cec5SDimitry Andric   } else
8430b57cec5SDimitry Andric     dst = writeUnsignedDecimal(dst, value);
8440b57cec5SDimitry Andric 
8450b57cec5SDimitry Andric   return dst;
8460b57cec5SDimitry Andric }
8470b57cec5SDimitry Andric 
8480b57cec5SDimitry Andric namespace detail {
8490b57cec5SDimitry Andric /* Constructors.  */
initialize(const fltSemantics * ourSemantics)8500b57cec5SDimitry Andric void IEEEFloat::initialize(const fltSemantics *ourSemantics) {
8510b57cec5SDimitry Andric   unsigned int count;
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric   semantics = ourSemantics;
8540b57cec5SDimitry Andric   count = partCount();
8550b57cec5SDimitry Andric   if (count > 1)
8560b57cec5SDimitry Andric     significand.parts = new integerPart[count];
8570b57cec5SDimitry Andric }
8580b57cec5SDimitry Andric 
freeSignificand()8590b57cec5SDimitry Andric void IEEEFloat::freeSignificand() {
8600b57cec5SDimitry Andric   if (needsCleanup())
8610b57cec5SDimitry Andric     delete [] significand.parts;
8620b57cec5SDimitry Andric }
8630b57cec5SDimitry Andric 
assign(const IEEEFloat & rhs)8640b57cec5SDimitry Andric void IEEEFloat::assign(const IEEEFloat &rhs) {
8650b57cec5SDimitry Andric   assert(semantics == rhs.semantics);
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric   sign = rhs.sign;
8680b57cec5SDimitry Andric   category = rhs.category;
8690b57cec5SDimitry Andric   exponent = rhs.exponent;
8700b57cec5SDimitry Andric   if (isFiniteNonZero() || category == fcNaN)
8710b57cec5SDimitry Andric     copySignificand(rhs);
8720b57cec5SDimitry Andric }
8730b57cec5SDimitry Andric 
copySignificand(const IEEEFloat & rhs)8740b57cec5SDimitry Andric void IEEEFloat::copySignificand(const IEEEFloat &rhs) {
8750b57cec5SDimitry Andric   assert(isFiniteNonZero() || category == fcNaN);
8760b57cec5SDimitry Andric   assert(rhs.partCount() >= partCount());
8770b57cec5SDimitry Andric 
8780b57cec5SDimitry Andric   APInt::tcAssign(significandParts(), rhs.significandParts(),
8790b57cec5SDimitry Andric                   partCount());
8800b57cec5SDimitry Andric }
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric /* Make this number a NaN, with an arbitrary but deterministic value
8830b57cec5SDimitry Andric    for the significand.  If double or longer, this is a signalling NaN,
8840b57cec5SDimitry Andric    which may not be ideal.  If float, this is QNaN(0).  */
makeNaN(bool SNaN,bool Negative,const APInt * fill)8850b57cec5SDimitry Andric void IEEEFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) {
8860b57cec5SDimitry Andric   category = fcNaN;
8870b57cec5SDimitry Andric   sign = Negative;
888e8d8bef9SDimitry Andric   exponent = exponentNaN();
8890b57cec5SDimitry Andric 
8900b57cec5SDimitry Andric   integerPart *significand = significandParts();
8910b57cec5SDimitry Andric   unsigned numParts = partCount();
8920b57cec5SDimitry Andric 
893bdd1243dSDimitry Andric   APInt fill_storage;
894bdd1243dSDimitry Andric   if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
895fe013be4SDimitry Andric     // Finite-only types do not distinguish signalling and quiet NaN, so
896fe013be4SDimitry Andric     // make them all signalling.
897bdd1243dSDimitry Andric     SNaN = false;
898fe013be4SDimitry Andric     if (semantics->nanEncoding == fltNanEncoding::NegativeZero) {
899fe013be4SDimitry Andric       sign = true;
900fe013be4SDimitry Andric       fill_storage = APInt::getZero(semantics->precision - 1);
901fe013be4SDimitry Andric     } else {
902bdd1243dSDimitry Andric       fill_storage = APInt::getAllOnes(semantics->precision - 1);
903fe013be4SDimitry Andric     }
904bdd1243dSDimitry Andric     fill = &fill_storage;
905bdd1243dSDimitry Andric   }
906bdd1243dSDimitry Andric 
9070b57cec5SDimitry Andric   // Set the significand bits to the fill.
9080b57cec5SDimitry Andric   if (!fill || fill->getNumWords() < numParts)
9090b57cec5SDimitry Andric     APInt::tcSet(significand, 0, numParts);
9100b57cec5SDimitry Andric   if (fill) {
9110b57cec5SDimitry Andric     APInt::tcAssign(significand, fill->getRawData(),
9120b57cec5SDimitry Andric                     std::min(fill->getNumWords(), numParts));
9130b57cec5SDimitry Andric 
9140b57cec5SDimitry Andric     // Zero out the excess bits of the significand.
9150b57cec5SDimitry Andric     unsigned bitsToPreserve = semantics->precision - 1;
9160b57cec5SDimitry Andric     unsigned part = bitsToPreserve / 64;
9170b57cec5SDimitry Andric     bitsToPreserve %= 64;
9180b57cec5SDimitry Andric     significand[part] &= ((1ULL << bitsToPreserve) - 1);
9190b57cec5SDimitry Andric     for (part++; part != numParts; ++part)
9200b57cec5SDimitry Andric       significand[part] = 0;
9210b57cec5SDimitry Andric   }
9220b57cec5SDimitry Andric 
9230b57cec5SDimitry Andric   unsigned QNaNBit = semantics->precision - 2;
9240b57cec5SDimitry Andric 
9250b57cec5SDimitry Andric   if (SNaN) {
9260b57cec5SDimitry Andric     // We always have to clear the QNaN bit to make it an SNaN.
9270b57cec5SDimitry Andric     APInt::tcClearBit(significand, QNaNBit);
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric     // If there are no bits set in the payload, we have to set
9300b57cec5SDimitry Andric     // *something* to make it a NaN instead of an infinity;
9310b57cec5SDimitry Andric     // conventionally, this is the next bit down from the QNaN bit.
9320b57cec5SDimitry Andric     if (APInt::tcIsZero(significand, numParts))
9330b57cec5SDimitry Andric       APInt::tcSetBit(significand, QNaNBit - 1);
934fe013be4SDimitry Andric   } else if (semantics->nanEncoding == fltNanEncoding::NegativeZero) {
935fe013be4SDimitry Andric     // The only NaN is a quiet NaN, and it has no bits sets in the significand.
936fe013be4SDimitry Andric     // Do nothing.
9370b57cec5SDimitry Andric   } else {
9380b57cec5SDimitry Andric     // We always have to set the QNaN bit to make it a QNaN.
9390b57cec5SDimitry Andric     APInt::tcSetBit(significand, QNaNBit);
9400b57cec5SDimitry Andric   }
9410b57cec5SDimitry Andric 
9420b57cec5SDimitry Andric   // For x87 extended precision, we want to make a NaN, not a
9430b57cec5SDimitry Andric   // pseudo-NaN.  Maybe we should expose the ability to make
9440b57cec5SDimitry Andric   // pseudo-NaNs?
9450b57cec5SDimitry Andric   if (semantics == &semX87DoubleExtended)
9460b57cec5SDimitry Andric     APInt::tcSetBit(significand, QNaNBit + 1);
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric 
operator =(const IEEEFloat & rhs)9490b57cec5SDimitry Andric IEEEFloat &IEEEFloat::operator=(const IEEEFloat &rhs) {
9500b57cec5SDimitry Andric   if (this != &rhs) {
9510b57cec5SDimitry Andric     if (semantics != rhs.semantics) {
9520b57cec5SDimitry Andric       freeSignificand();
9530b57cec5SDimitry Andric       initialize(rhs.semantics);
9540b57cec5SDimitry Andric     }
9550b57cec5SDimitry Andric     assign(rhs);
9560b57cec5SDimitry Andric   }
9570b57cec5SDimitry Andric 
9580b57cec5SDimitry Andric   return *this;
9590b57cec5SDimitry Andric }
9600b57cec5SDimitry Andric 
operator =(IEEEFloat && rhs)9610b57cec5SDimitry Andric IEEEFloat &IEEEFloat::operator=(IEEEFloat &&rhs) {
9620b57cec5SDimitry Andric   freeSignificand();
9630b57cec5SDimitry Andric 
9640b57cec5SDimitry Andric   semantics = rhs.semantics;
9650b57cec5SDimitry Andric   significand = rhs.significand;
9660b57cec5SDimitry Andric   exponent = rhs.exponent;
9670b57cec5SDimitry Andric   category = rhs.category;
9680b57cec5SDimitry Andric   sign = rhs.sign;
9690b57cec5SDimitry Andric 
9700b57cec5SDimitry Andric   rhs.semantics = &semBogus;
9710b57cec5SDimitry Andric   return *this;
9720b57cec5SDimitry Andric }
9730b57cec5SDimitry Andric 
isDenormal() const9740b57cec5SDimitry Andric bool IEEEFloat::isDenormal() const {
9750b57cec5SDimitry Andric   return isFiniteNonZero() && (exponent == semantics->minExponent) &&
9760b57cec5SDimitry Andric          (APInt::tcExtractBit(significandParts(),
9770b57cec5SDimitry Andric                               semantics->precision - 1) == 0);
9780b57cec5SDimitry Andric }
9790b57cec5SDimitry Andric 
isSmallest() const9800b57cec5SDimitry Andric bool IEEEFloat::isSmallest() const {
9810b57cec5SDimitry Andric   // The smallest number by magnitude in our format will be the smallest
9820b57cec5SDimitry Andric   // denormal, i.e. the floating point number with exponent being minimum
9830b57cec5SDimitry Andric   // exponent and significand bitwise equal to 1 (i.e. with MSB equal to 0).
9840b57cec5SDimitry Andric   return isFiniteNonZero() && exponent == semantics->minExponent &&
9850b57cec5SDimitry Andric     significandMSB() == 0;
9860b57cec5SDimitry Andric }
9870b57cec5SDimitry Andric 
isSmallestNormalized() const988bdd1243dSDimitry Andric bool IEEEFloat::isSmallestNormalized() const {
989bdd1243dSDimitry Andric   return getCategory() == fcNormal && exponent == semantics->minExponent &&
990bdd1243dSDimitry Andric          isSignificandAllZerosExceptMSB();
991bdd1243dSDimitry Andric }
992bdd1243dSDimitry Andric 
isSignificandAllOnes() const9930b57cec5SDimitry Andric bool IEEEFloat::isSignificandAllOnes() const {
9940b57cec5SDimitry Andric   // Test if the significand excluding the integral bit is all ones. This allows
9950b57cec5SDimitry Andric   // us to test for binade boundaries.
9960b57cec5SDimitry Andric   const integerPart *Parts = significandParts();
997e8d8bef9SDimitry Andric   const unsigned PartCount = partCountForBits(semantics->precision);
9980b57cec5SDimitry Andric   for (unsigned i = 0; i < PartCount - 1; i++)
9990b57cec5SDimitry Andric     if (~Parts[i])
10000b57cec5SDimitry Andric       return false;
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric   // Set the unused high bits to all ones when we compare.
10030b57cec5SDimitry Andric   const unsigned NumHighBits =
10040b57cec5SDimitry Andric     PartCount*integerPartWidth - semantics->precision + 1;
1005e8d8bef9SDimitry Andric   assert(NumHighBits <= integerPartWidth && NumHighBits > 0 &&
1006e8d8bef9SDimitry Andric          "Can not have more high bits to fill than integerPartWidth");
10070b57cec5SDimitry Andric   const integerPart HighBitFill =
10080b57cec5SDimitry Andric     ~integerPart(0) << (integerPartWidth - NumHighBits);
10090b57cec5SDimitry Andric   if (~(Parts[PartCount - 1] | HighBitFill))
10100b57cec5SDimitry Andric     return false;
10110b57cec5SDimitry Andric 
10120b57cec5SDimitry Andric   return true;
10130b57cec5SDimitry Andric }
10140b57cec5SDimitry Andric 
isSignificandAllOnesExceptLSB() const1015bdd1243dSDimitry Andric bool IEEEFloat::isSignificandAllOnesExceptLSB() const {
1016bdd1243dSDimitry Andric   // Test if the significand excluding the integral bit is all ones except for
1017bdd1243dSDimitry Andric   // the least significant bit.
1018bdd1243dSDimitry Andric   const integerPart *Parts = significandParts();
1019bdd1243dSDimitry Andric 
1020bdd1243dSDimitry Andric   if (Parts[0] & 1)
1021bdd1243dSDimitry Andric     return false;
1022bdd1243dSDimitry Andric 
1023bdd1243dSDimitry Andric   const unsigned PartCount = partCountForBits(semantics->precision);
1024bdd1243dSDimitry Andric   for (unsigned i = 0; i < PartCount - 1; i++) {
1025bdd1243dSDimitry Andric     if (~Parts[i] & ~unsigned{!i})
1026bdd1243dSDimitry Andric       return false;
1027bdd1243dSDimitry Andric   }
1028bdd1243dSDimitry Andric 
1029bdd1243dSDimitry Andric   // Set the unused high bits to all ones when we compare.
1030bdd1243dSDimitry Andric   const unsigned NumHighBits =
1031bdd1243dSDimitry Andric       PartCount * integerPartWidth - semantics->precision + 1;
1032bdd1243dSDimitry Andric   assert(NumHighBits <= integerPartWidth && NumHighBits > 0 &&
1033bdd1243dSDimitry Andric          "Can not have more high bits to fill than integerPartWidth");
1034bdd1243dSDimitry Andric   const integerPart HighBitFill = ~integerPart(0)
1035bdd1243dSDimitry Andric                                   << (integerPartWidth - NumHighBits);
1036bdd1243dSDimitry Andric   if (~(Parts[PartCount - 1] | HighBitFill | 0x1))
1037bdd1243dSDimitry Andric     return false;
1038bdd1243dSDimitry Andric 
1039bdd1243dSDimitry Andric   return true;
1040bdd1243dSDimitry Andric }
1041bdd1243dSDimitry Andric 
isSignificandAllZeros() const10420b57cec5SDimitry Andric bool IEEEFloat::isSignificandAllZeros() const {
10430b57cec5SDimitry Andric   // Test if the significand excluding the integral bit is all zeros. This
10440b57cec5SDimitry Andric   // allows us to test for binade boundaries.
10450b57cec5SDimitry Andric   const integerPart *Parts = significandParts();
1046e8d8bef9SDimitry Andric   const unsigned PartCount = partCountForBits(semantics->precision);
10470b57cec5SDimitry Andric 
10480b57cec5SDimitry Andric   for (unsigned i = 0; i < PartCount - 1; i++)
10490b57cec5SDimitry Andric     if (Parts[i])
10500b57cec5SDimitry Andric       return false;
10510b57cec5SDimitry Andric 
1052e8d8bef9SDimitry Andric   // Compute how many bits are used in the final word.
10530b57cec5SDimitry Andric   const unsigned NumHighBits =
10540b57cec5SDimitry Andric     PartCount*integerPartWidth - semantics->precision + 1;
1055e8d8bef9SDimitry Andric   assert(NumHighBits < integerPartWidth && "Can not have more high bits to "
10560b57cec5SDimitry Andric          "clear than integerPartWidth");
10570b57cec5SDimitry Andric   const integerPart HighBitMask = ~integerPart(0) >> NumHighBits;
10580b57cec5SDimitry Andric 
10590b57cec5SDimitry Andric   if (Parts[PartCount - 1] & HighBitMask)
10600b57cec5SDimitry Andric     return false;
10610b57cec5SDimitry Andric 
10620b57cec5SDimitry Andric   return true;
10630b57cec5SDimitry Andric }
10640b57cec5SDimitry Andric 
isSignificandAllZerosExceptMSB() const1065bdd1243dSDimitry Andric bool IEEEFloat::isSignificandAllZerosExceptMSB() const {
1066bdd1243dSDimitry Andric   const integerPart *Parts = significandParts();
1067bdd1243dSDimitry Andric   const unsigned PartCount = partCountForBits(semantics->precision);
1068bdd1243dSDimitry Andric 
1069bdd1243dSDimitry Andric   for (unsigned i = 0; i < PartCount - 1; i++) {
1070bdd1243dSDimitry Andric     if (Parts[i])
1071bdd1243dSDimitry Andric       return false;
1072bdd1243dSDimitry Andric   }
1073bdd1243dSDimitry Andric 
1074bdd1243dSDimitry Andric   const unsigned NumHighBits =
1075bdd1243dSDimitry Andric       PartCount * integerPartWidth - semantics->precision + 1;
1076bdd1243dSDimitry Andric   return Parts[PartCount - 1] == integerPart(1)
1077bdd1243dSDimitry Andric                                      << (integerPartWidth - NumHighBits);
1078bdd1243dSDimitry Andric }
1079bdd1243dSDimitry Andric 
isLargest() const10800b57cec5SDimitry Andric bool IEEEFloat::isLargest() const {
1081fe013be4SDimitry Andric   if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly &&
1082fe013be4SDimitry Andric       semantics->nanEncoding == fltNanEncoding::AllOnes) {
1083bdd1243dSDimitry Andric     // The largest number by magnitude in our format will be the floating point
1084bdd1243dSDimitry Andric     // number with maximum exponent and with significand that is all ones except
1085bdd1243dSDimitry Andric     // the LSB.
1086bdd1243dSDimitry Andric     return isFiniteNonZero() && exponent == semantics->maxExponent &&
1087bdd1243dSDimitry Andric            isSignificandAllOnesExceptLSB();
1088bdd1243dSDimitry Andric   } else {
10890b57cec5SDimitry Andric     // The largest number by magnitude in our format will be the floating point
10900b57cec5SDimitry Andric     // number with maximum exponent and with significand that is all ones.
1091bdd1243dSDimitry Andric     return isFiniteNonZero() && exponent == semantics->maxExponent &&
1092bdd1243dSDimitry Andric            isSignificandAllOnes();
1093bdd1243dSDimitry Andric   }
10940b57cec5SDimitry Andric }
10950b57cec5SDimitry Andric 
isInteger() const10960b57cec5SDimitry Andric bool IEEEFloat::isInteger() const {
10970b57cec5SDimitry Andric   // This could be made more efficient; I'm going for obviously correct.
10980b57cec5SDimitry Andric   if (!isFinite()) return false;
10990b57cec5SDimitry Andric   IEEEFloat truncated = *this;
11000b57cec5SDimitry Andric   truncated.roundToIntegral(rmTowardZero);
11010b57cec5SDimitry Andric   return compare(truncated) == cmpEqual;
11020b57cec5SDimitry Andric }
11030b57cec5SDimitry Andric 
bitwiseIsEqual(const IEEEFloat & rhs) const11040b57cec5SDimitry Andric bool IEEEFloat::bitwiseIsEqual(const IEEEFloat &rhs) const {
11050b57cec5SDimitry Andric   if (this == &rhs)
11060b57cec5SDimitry Andric     return true;
11070b57cec5SDimitry Andric   if (semantics != rhs.semantics ||
11080b57cec5SDimitry Andric       category != rhs.category ||
11090b57cec5SDimitry Andric       sign != rhs.sign)
11100b57cec5SDimitry Andric     return false;
11110b57cec5SDimitry Andric   if (category==fcZero || category==fcInfinity)
11120b57cec5SDimitry Andric     return true;
11130b57cec5SDimitry Andric 
11140b57cec5SDimitry Andric   if (isFiniteNonZero() && exponent != rhs.exponent)
11150b57cec5SDimitry Andric     return false;
11160b57cec5SDimitry Andric 
11170b57cec5SDimitry Andric   return std::equal(significandParts(), significandParts() + partCount(),
11180b57cec5SDimitry Andric                     rhs.significandParts());
11190b57cec5SDimitry Andric }
11200b57cec5SDimitry Andric 
IEEEFloat(const fltSemantics & ourSemantics,integerPart value)11210b57cec5SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, integerPart value) {
11220b57cec5SDimitry Andric   initialize(&ourSemantics);
11230b57cec5SDimitry Andric   sign = 0;
11240b57cec5SDimitry Andric   category = fcNormal;
11250b57cec5SDimitry Andric   zeroSignificand();
11260b57cec5SDimitry Andric   exponent = ourSemantics.precision - 1;
11270b57cec5SDimitry Andric   significandParts()[0] = value;
11280b57cec5SDimitry Andric   normalize(rmNearestTiesToEven, lfExactlyZero);
11290b57cec5SDimitry Andric }
11300b57cec5SDimitry Andric 
IEEEFloat(const fltSemantics & ourSemantics)11310b57cec5SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics) {
11320b57cec5SDimitry Andric   initialize(&ourSemantics);
1133e8d8bef9SDimitry Andric   makeZero(false);
11340b57cec5SDimitry Andric }
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric // Delegate to the previous constructor, because later copy constructor may
11370b57cec5SDimitry Andric // actually inspects category, which can't be garbage.
IEEEFloat(const fltSemantics & ourSemantics,uninitializedTag tag)11380b57cec5SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, uninitializedTag tag)
11390b57cec5SDimitry Andric     : IEEEFloat(ourSemantics) {}
11400b57cec5SDimitry Andric 
IEEEFloat(const IEEEFloat & rhs)11410b57cec5SDimitry Andric IEEEFloat::IEEEFloat(const IEEEFloat &rhs) {
11420b57cec5SDimitry Andric   initialize(rhs.semantics);
11430b57cec5SDimitry Andric   assign(rhs);
11440b57cec5SDimitry Andric }
11450b57cec5SDimitry Andric 
IEEEFloat(IEEEFloat && rhs)11460b57cec5SDimitry Andric IEEEFloat::IEEEFloat(IEEEFloat &&rhs) : semantics(&semBogus) {
11470b57cec5SDimitry Andric   *this = std::move(rhs);
11480b57cec5SDimitry Andric }
11490b57cec5SDimitry Andric 
~IEEEFloat()11500b57cec5SDimitry Andric IEEEFloat::~IEEEFloat() { freeSignificand(); }
11510b57cec5SDimitry Andric 
partCount() const11520b57cec5SDimitry Andric unsigned int IEEEFloat::partCount() const {
11530b57cec5SDimitry Andric   return partCountForBits(semantics->precision + 1);
11540b57cec5SDimitry Andric }
11550b57cec5SDimitry Andric 
significandParts() const11560b57cec5SDimitry Andric const IEEEFloat::integerPart *IEEEFloat::significandParts() const {
11570b57cec5SDimitry Andric   return const_cast<IEEEFloat *>(this)->significandParts();
11580b57cec5SDimitry Andric }
11590b57cec5SDimitry Andric 
significandParts()11600b57cec5SDimitry Andric IEEEFloat::integerPart *IEEEFloat::significandParts() {
11610b57cec5SDimitry Andric   if (partCount() > 1)
11620b57cec5SDimitry Andric     return significand.parts;
11630b57cec5SDimitry Andric   else
11640b57cec5SDimitry Andric     return &significand.part;
11650b57cec5SDimitry Andric }
11660b57cec5SDimitry Andric 
zeroSignificand()11670b57cec5SDimitry Andric void IEEEFloat::zeroSignificand() {
11680b57cec5SDimitry Andric   APInt::tcSet(significandParts(), 0, partCount());
11690b57cec5SDimitry Andric }
11700b57cec5SDimitry Andric 
11710b57cec5SDimitry Andric /* Increment an fcNormal floating point number's significand.  */
incrementSignificand()11720b57cec5SDimitry Andric void IEEEFloat::incrementSignificand() {
11730b57cec5SDimitry Andric   integerPart carry;
11740b57cec5SDimitry Andric 
11750b57cec5SDimitry Andric   carry = APInt::tcIncrement(significandParts(), partCount());
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric   /* Our callers should never cause us to overflow.  */
11780b57cec5SDimitry Andric   assert(carry == 0);
11790b57cec5SDimitry Andric   (void)carry;
11800b57cec5SDimitry Andric }
11810b57cec5SDimitry Andric 
11820b57cec5SDimitry Andric /* Add the significand of the RHS.  Returns the carry flag.  */
addSignificand(const IEEEFloat & rhs)11830b57cec5SDimitry Andric IEEEFloat::integerPart IEEEFloat::addSignificand(const IEEEFloat &rhs) {
11840b57cec5SDimitry Andric   integerPart *parts;
11850b57cec5SDimitry Andric 
11860b57cec5SDimitry Andric   parts = significandParts();
11870b57cec5SDimitry Andric 
11880b57cec5SDimitry Andric   assert(semantics == rhs.semantics);
11890b57cec5SDimitry Andric   assert(exponent == rhs.exponent);
11900b57cec5SDimitry Andric 
11910b57cec5SDimitry Andric   return APInt::tcAdd(parts, rhs.significandParts(), 0, partCount());
11920b57cec5SDimitry Andric }
11930b57cec5SDimitry Andric 
11940b57cec5SDimitry Andric /* Subtract the significand of the RHS with a borrow flag.  Returns
11950b57cec5SDimitry Andric    the borrow flag.  */
subtractSignificand(const IEEEFloat & rhs,integerPart borrow)11960b57cec5SDimitry Andric IEEEFloat::integerPart IEEEFloat::subtractSignificand(const IEEEFloat &rhs,
11970b57cec5SDimitry Andric                                                       integerPart borrow) {
11980b57cec5SDimitry Andric   integerPart *parts;
11990b57cec5SDimitry Andric 
12000b57cec5SDimitry Andric   parts = significandParts();
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric   assert(semantics == rhs.semantics);
12030b57cec5SDimitry Andric   assert(exponent == rhs.exponent);
12040b57cec5SDimitry Andric 
12050b57cec5SDimitry Andric   return APInt::tcSubtract(parts, rhs.significandParts(), borrow,
12060b57cec5SDimitry Andric                            partCount());
12070b57cec5SDimitry Andric }
12080b57cec5SDimitry Andric 
12090b57cec5SDimitry Andric /* Multiply the significand of the RHS.  If ADDEND is non-NULL, add it
12100b57cec5SDimitry Andric    on to the full-precision result of the multiplication.  Returns the
12110b57cec5SDimitry Andric    lost fraction.  */
multiplySignificand(const IEEEFloat & rhs,IEEEFloat addend)12120b57cec5SDimitry Andric lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs,
1213480093f4SDimitry Andric                                             IEEEFloat addend) {
12140b57cec5SDimitry Andric   unsigned int omsb;        // One, not zero, based MSB.
12150b57cec5SDimitry Andric   unsigned int partsCount, newPartsCount, precision;
12160b57cec5SDimitry Andric   integerPart *lhsSignificand;
12170b57cec5SDimitry Andric   integerPart scratch[4];
12180b57cec5SDimitry Andric   integerPart *fullSignificand;
12190b57cec5SDimitry Andric   lostFraction lost_fraction;
12200b57cec5SDimitry Andric   bool ignored;
12210b57cec5SDimitry Andric 
12220b57cec5SDimitry Andric   assert(semantics == rhs.semantics);
12230b57cec5SDimitry Andric 
12240b57cec5SDimitry Andric   precision = semantics->precision;
12250b57cec5SDimitry Andric 
12260b57cec5SDimitry Andric   // Allocate space for twice as many bits as the original significand, plus one
12270b57cec5SDimitry Andric   // extra bit for the addition to overflow into.
12280b57cec5SDimitry Andric   newPartsCount = partCountForBits(precision * 2 + 1);
12290b57cec5SDimitry Andric 
12300b57cec5SDimitry Andric   if (newPartsCount > 4)
12310b57cec5SDimitry Andric     fullSignificand = new integerPart[newPartsCount];
12320b57cec5SDimitry Andric   else
12330b57cec5SDimitry Andric     fullSignificand = scratch;
12340b57cec5SDimitry Andric 
12350b57cec5SDimitry Andric   lhsSignificand = significandParts();
12360b57cec5SDimitry Andric   partsCount = partCount();
12370b57cec5SDimitry Andric 
12380b57cec5SDimitry Andric   APInt::tcFullMultiply(fullSignificand, lhsSignificand,
12390b57cec5SDimitry Andric                         rhs.significandParts(), partsCount, partsCount);
12400b57cec5SDimitry Andric 
12410b57cec5SDimitry Andric   lost_fraction = lfExactlyZero;
12420b57cec5SDimitry Andric   omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
12430b57cec5SDimitry Andric   exponent += rhs.exponent;
12440b57cec5SDimitry Andric 
12450b57cec5SDimitry Andric   // Assume the operands involved in the multiplication are single-precision
12460b57cec5SDimitry Andric   // FP, and the two multiplicants are:
12470b57cec5SDimitry Andric   //   *this = a23 . a22 ... a0 * 2^e1
12480b57cec5SDimitry Andric   //     rhs = b23 . b22 ... b0 * 2^e2
12490b57cec5SDimitry Andric   // the result of multiplication is:
12500b57cec5SDimitry Andric   //   *this = c48 c47 c46 . c45 ... c0 * 2^(e1+e2)
12510b57cec5SDimitry Andric   // Note that there are three significant bits at the left-hand side of the
12520b57cec5SDimitry Andric   // radix point: two for the multiplication, and an overflow bit for the
12530b57cec5SDimitry Andric   // addition (that will always be zero at this point). Move the radix point
12540b57cec5SDimitry Andric   // toward left by two bits, and adjust exponent accordingly.
12550b57cec5SDimitry Andric   exponent += 2;
12560b57cec5SDimitry Andric 
1257480093f4SDimitry Andric   if (addend.isNonZero()) {
12580b57cec5SDimitry Andric     // The intermediate result of the multiplication has "2 * precision"
12590b57cec5SDimitry Andric     // signicant bit; adjust the addend to be consistent with mul result.
12600b57cec5SDimitry Andric     //
12610b57cec5SDimitry Andric     Significand savedSignificand = significand;
12620b57cec5SDimitry Andric     const fltSemantics *savedSemantics = semantics;
12630b57cec5SDimitry Andric     fltSemantics extendedSemantics;
12640b57cec5SDimitry Andric     opStatus status;
12650b57cec5SDimitry Andric     unsigned int extendedPrecision;
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric     // Normalize our MSB to one below the top bit to allow for overflow.
12680b57cec5SDimitry Andric     extendedPrecision = 2 * precision + 1;
12690b57cec5SDimitry Andric     if (omsb != extendedPrecision - 1) {
12700b57cec5SDimitry Andric       assert(extendedPrecision > omsb);
12710b57cec5SDimitry Andric       APInt::tcShiftLeft(fullSignificand, newPartsCount,
12720b57cec5SDimitry Andric                          (extendedPrecision - 1) - omsb);
12730b57cec5SDimitry Andric       exponent -= (extendedPrecision - 1) - omsb;
12740b57cec5SDimitry Andric     }
12750b57cec5SDimitry Andric 
12760b57cec5SDimitry Andric     /* Create new semantics.  */
12770b57cec5SDimitry Andric     extendedSemantics = *semantics;
12780b57cec5SDimitry Andric     extendedSemantics.precision = extendedPrecision;
12790b57cec5SDimitry Andric 
12800b57cec5SDimitry Andric     if (newPartsCount == 1)
12810b57cec5SDimitry Andric       significand.part = fullSignificand[0];
12820b57cec5SDimitry Andric     else
12830b57cec5SDimitry Andric       significand.parts = fullSignificand;
12840b57cec5SDimitry Andric     semantics = &extendedSemantics;
12850b57cec5SDimitry Andric 
1286480093f4SDimitry Andric     // Make a copy so we can convert it to the extended semantics.
1287480093f4SDimitry Andric     // Note that we cannot convert the addend directly, as the extendedSemantics
1288480093f4SDimitry Andric     // is a local variable (which we take a reference to).
1289480093f4SDimitry Andric     IEEEFloat extendedAddend(addend);
12900b57cec5SDimitry Andric     status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored);
12910b57cec5SDimitry Andric     assert(status == opOK);
12920b57cec5SDimitry Andric     (void)status;
12930b57cec5SDimitry Andric 
12940b57cec5SDimitry Andric     // Shift the significand of the addend right by one bit. This guarantees
12950b57cec5SDimitry Andric     // that the high bit of the significand is zero (same as fullSignificand),
12960b57cec5SDimitry Andric     // so the addition will overflow (if it does overflow at all) into the top bit.
12970b57cec5SDimitry Andric     lost_fraction = extendedAddend.shiftSignificandRight(1);
12980b57cec5SDimitry Andric     assert(lost_fraction == lfExactlyZero &&
12990b57cec5SDimitry Andric            "Lost precision while shifting addend for fused-multiply-add.");
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric     lost_fraction = addOrSubtractSignificand(extendedAddend, false);
13020b57cec5SDimitry Andric 
13030b57cec5SDimitry Andric     /* Restore our state.  */
13040b57cec5SDimitry Andric     if (newPartsCount == 1)
13050b57cec5SDimitry Andric       fullSignificand[0] = significand.part;
13060b57cec5SDimitry Andric     significand = savedSignificand;
13070b57cec5SDimitry Andric     semantics = savedSemantics;
13080b57cec5SDimitry Andric 
13090b57cec5SDimitry Andric     omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
13100b57cec5SDimitry Andric   }
13110b57cec5SDimitry Andric 
13120b57cec5SDimitry Andric   // Convert the result having "2 * precision" significant-bits back to the one
13130b57cec5SDimitry Andric   // having "precision" significant-bits. First, move the radix point from
13140b57cec5SDimitry Andric   // poision "2*precision - 1" to "precision - 1". The exponent need to be
13150b57cec5SDimitry Andric   // adjusted by "2*precision - 1" - "precision - 1" = "precision".
13160b57cec5SDimitry Andric   exponent -= precision + 1;
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric   // In case MSB resides at the left-hand side of radix point, shift the
13190b57cec5SDimitry Andric   // mantissa right by some amount to make sure the MSB reside right before
13200b57cec5SDimitry Andric   // the radix point (i.e. "MSB . rest-significant-bits").
13210b57cec5SDimitry Andric   //
13220b57cec5SDimitry Andric   // Note that the result is not normalized when "omsb < precision". So, the
13230b57cec5SDimitry Andric   // caller needs to call IEEEFloat::normalize() if normalized value is
13240b57cec5SDimitry Andric   // expected.
13250b57cec5SDimitry Andric   if (omsb > precision) {
13260b57cec5SDimitry Andric     unsigned int bits, significantParts;
13270b57cec5SDimitry Andric     lostFraction lf;
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric     bits = omsb - precision;
13300b57cec5SDimitry Andric     significantParts = partCountForBits(omsb);
13310b57cec5SDimitry Andric     lf = shiftRight(fullSignificand, significantParts, bits);
13320b57cec5SDimitry Andric     lost_fraction = combineLostFractions(lf, lost_fraction);
13330b57cec5SDimitry Andric     exponent += bits;
13340b57cec5SDimitry Andric   }
13350b57cec5SDimitry Andric 
13360b57cec5SDimitry Andric   APInt::tcAssign(lhsSignificand, fullSignificand, partsCount);
13370b57cec5SDimitry Andric 
13380b57cec5SDimitry Andric   if (newPartsCount > 4)
13390b57cec5SDimitry Andric     delete [] fullSignificand;
13400b57cec5SDimitry Andric 
13410b57cec5SDimitry Andric   return lost_fraction;
13420b57cec5SDimitry Andric }
13430b57cec5SDimitry Andric 
multiplySignificand(const IEEEFloat & rhs)1344480093f4SDimitry Andric lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs) {
1345480093f4SDimitry Andric   return multiplySignificand(rhs, IEEEFloat(*semantics));
1346480093f4SDimitry Andric }
1347480093f4SDimitry Andric 
13480b57cec5SDimitry Andric /* Multiply the significands of LHS and RHS to DST.  */
divideSignificand(const IEEEFloat & rhs)13490b57cec5SDimitry Andric lostFraction IEEEFloat::divideSignificand(const IEEEFloat &rhs) {
13500b57cec5SDimitry Andric   unsigned int bit, i, partsCount;
13510b57cec5SDimitry Andric   const integerPart *rhsSignificand;
13520b57cec5SDimitry Andric   integerPart *lhsSignificand, *dividend, *divisor;
13530b57cec5SDimitry Andric   integerPart scratch[4];
13540b57cec5SDimitry Andric   lostFraction lost_fraction;
13550b57cec5SDimitry Andric 
13560b57cec5SDimitry Andric   assert(semantics == rhs.semantics);
13570b57cec5SDimitry Andric 
13580b57cec5SDimitry Andric   lhsSignificand = significandParts();
13590b57cec5SDimitry Andric   rhsSignificand = rhs.significandParts();
13600b57cec5SDimitry Andric   partsCount = partCount();
13610b57cec5SDimitry Andric 
13620b57cec5SDimitry Andric   if (partsCount > 2)
13630b57cec5SDimitry Andric     dividend = new integerPart[partsCount * 2];
13640b57cec5SDimitry Andric   else
13650b57cec5SDimitry Andric     dividend = scratch;
13660b57cec5SDimitry Andric 
13670b57cec5SDimitry Andric   divisor = dividend + partsCount;
13680b57cec5SDimitry Andric 
13690b57cec5SDimitry Andric   /* Copy the dividend and divisor as they will be modified in-place.  */
13700b57cec5SDimitry Andric   for (i = 0; i < partsCount; i++) {
13710b57cec5SDimitry Andric     dividend[i] = lhsSignificand[i];
13720b57cec5SDimitry Andric     divisor[i] = rhsSignificand[i];
13730b57cec5SDimitry Andric     lhsSignificand[i] = 0;
13740b57cec5SDimitry Andric   }
13750b57cec5SDimitry Andric 
13760b57cec5SDimitry Andric   exponent -= rhs.exponent;
13770b57cec5SDimitry Andric 
13780b57cec5SDimitry Andric   unsigned int precision = semantics->precision;
13790b57cec5SDimitry Andric 
13800b57cec5SDimitry Andric   /* Normalize the divisor.  */
13810b57cec5SDimitry Andric   bit = precision - APInt::tcMSB(divisor, partsCount) - 1;
13820b57cec5SDimitry Andric   if (bit) {
13830b57cec5SDimitry Andric     exponent += bit;
13840b57cec5SDimitry Andric     APInt::tcShiftLeft(divisor, partsCount, bit);
13850b57cec5SDimitry Andric   }
13860b57cec5SDimitry Andric 
13870b57cec5SDimitry Andric   /* Normalize the dividend.  */
13880b57cec5SDimitry Andric   bit = precision - APInt::tcMSB(dividend, partsCount) - 1;
13890b57cec5SDimitry Andric   if (bit) {
13900b57cec5SDimitry Andric     exponent -= bit;
13910b57cec5SDimitry Andric     APInt::tcShiftLeft(dividend, partsCount, bit);
13920b57cec5SDimitry Andric   }
13930b57cec5SDimitry Andric 
13940b57cec5SDimitry Andric   /* Ensure the dividend >= divisor initially for the loop below.
13950b57cec5SDimitry Andric      Incidentally, this means that the division loop below is
13960b57cec5SDimitry Andric      guaranteed to set the integer bit to one.  */
13970b57cec5SDimitry Andric   if (APInt::tcCompare(dividend, divisor, partsCount) < 0) {
13980b57cec5SDimitry Andric     exponent--;
13990b57cec5SDimitry Andric     APInt::tcShiftLeft(dividend, partsCount, 1);
14000b57cec5SDimitry Andric     assert(APInt::tcCompare(dividend, divisor, partsCount) >= 0);
14010b57cec5SDimitry Andric   }
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric   /* Long division.  */
14040b57cec5SDimitry Andric   for (bit = precision; bit; bit -= 1) {
14050b57cec5SDimitry Andric     if (APInt::tcCompare(dividend, divisor, partsCount) >= 0) {
14060b57cec5SDimitry Andric       APInt::tcSubtract(dividend, divisor, 0, partsCount);
14070b57cec5SDimitry Andric       APInt::tcSetBit(lhsSignificand, bit - 1);
14080b57cec5SDimitry Andric     }
14090b57cec5SDimitry Andric 
14100b57cec5SDimitry Andric     APInt::tcShiftLeft(dividend, partsCount, 1);
14110b57cec5SDimitry Andric   }
14120b57cec5SDimitry Andric 
14130b57cec5SDimitry Andric   /* Figure out the lost fraction.  */
14140b57cec5SDimitry Andric   int cmp = APInt::tcCompare(dividend, divisor, partsCount);
14150b57cec5SDimitry Andric 
14160b57cec5SDimitry Andric   if (cmp > 0)
14170b57cec5SDimitry Andric     lost_fraction = lfMoreThanHalf;
14180b57cec5SDimitry Andric   else if (cmp == 0)
14190b57cec5SDimitry Andric     lost_fraction = lfExactlyHalf;
14200b57cec5SDimitry Andric   else if (APInt::tcIsZero(dividend, partsCount))
14210b57cec5SDimitry Andric     lost_fraction = lfExactlyZero;
14220b57cec5SDimitry Andric   else
14230b57cec5SDimitry Andric     lost_fraction = lfLessThanHalf;
14240b57cec5SDimitry Andric 
14250b57cec5SDimitry Andric   if (partsCount > 2)
14260b57cec5SDimitry Andric     delete [] dividend;
14270b57cec5SDimitry Andric 
14280b57cec5SDimitry Andric   return lost_fraction;
14290b57cec5SDimitry Andric }
14300b57cec5SDimitry Andric 
significandMSB() const14310b57cec5SDimitry Andric unsigned int IEEEFloat::significandMSB() const {
14320b57cec5SDimitry Andric   return APInt::tcMSB(significandParts(), partCount());
14330b57cec5SDimitry Andric }
14340b57cec5SDimitry Andric 
significandLSB() const14350b57cec5SDimitry Andric unsigned int IEEEFloat::significandLSB() const {
14360b57cec5SDimitry Andric   return APInt::tcLSB(significandParts(), partCount());
14370b57cec5SDimitry Andric }
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric /* Note that a zero result is NOT normalized to fcZero.  */
shiftSignificandRight(unsigned int bits)14400b57cec5SDimitry Andric lostFraction IEEEFloat::shiftSignificandRight(unsigned int bits) {
14410b57cec5SDimitry Andric   /* Our exponent should not overflow.  */
14420b57cec5SDimitry Andric   assert((ExponentType) (exponent + bits) >= exponent);
14430b57cec5SDimitry Andric 
14440b57cec5SDimitry Andric   exponent += bits;
14450b57cec5SDimitry Andric 
14460b57cec5SDimitry Andric   return shiftRight(significandParts(), partCount(), bits);
14470b57cec5SDimitry Andric }
14480b57cec5SDimitry Andric 
14490b57cec5SDimitry Andric /* Shift the significand left BITS bits, subtract BITS from its exponent.  */
shiftSignificandLeft(unsigned int bits)14500b57cec5SDimitry Andric void IEEEFloat::shiftSignificandLeft(unsigned int bits) {
14510b57cec5SDimitry Andric   assert(bits < semantics->precision);
14520b57cec5SDimitry Andric 
14530b57cec5SDimitry Andric   if (bits) {
14540b57cec5SDimitry Andric     unsigned int partsCount = partCount();
14550b57cec5SDimitry Andric 
14560b57cec5SDimitry Andric     APInt::tcShiftLeft(significandParts(), partsCount, bits);
14570b57cec5SDimitry Andric     exponent -= bits;
14580b57cec5SDimitry Andric 
14590b57cec5SDimitry Andric     assert(!APInt::tcIsZero(significandParts(), partsCount));
14600b57cec5SDimitry Andric   }
14610b57cec5SDimitry Andric }
14620b57cec5SDimitry Andric 
14630b57cec5SDimitry Andric IEEEFloat::cmpResult
compareAbsoluteValue(const IEEEFloat & rhs) const14640b57cec5SDimitry Andric IEEEFloat::compareAbsoluteValue(const IEEEFloat &rhs) const {
14650b57cec5SDimitry Andric   int compare;
14660b57cec5SDimitry Andric 
14670b57cec5SDimitry Andric   assert(semantics == rhs.semantics);
14680b57cec5SDimitry Andric   assert(isFiniteNonZero());
14690b57cec5SDimitry Andric   assert(rhs.isFiniteNonZero());
14700b57cec5SDimitry Andric 
14710b57cec5SDimitry Andric   compare = exponent - rhs.exponent;
14720b57cec5SDimitry Andric 
14730b57cec5SDimitry Andric   /* If exponents are equal, do an unsigned bignum comparison of the
14740b57cec5SDimitry Andric      significands.  */
14750b57cec5SDimitry Andric   if (compare == 0)
14760b57cec5SDimitry Andric     compare = APInt::tcCompare(significandParts(), rhs.significandParts(),
14770b57cec5SDimitry Andric                                partCount());
14780b57cec5SDimitry Andric 
14790b57cec5SDimitry Andric   if (compare > 0)
14800b57cec5SDimitry Andric     return cmpGreaterThan;
14810b57cec5SDimitry Andric   else if (compare < 0)
14820b57cec5SDimitry Andric     return cmpLessThan;
14830b57cec5SDimitry Andric   else
14840b57cec5SDimitry Andric     return cmpEqual;
14850b57cec5SDimitry Andric }
14860b57cec5SDimitry Andric 
1487349cc55cSDimitry Andric /* Set the least significant BITS bits of a bignum, clear the
1488349cc55cSDimitry Andric    rest.  */
tcSetLeastSignificantBits(APInt::WordType * dst,unsigned parts,unsigned bits)1489349cc55cSDimitry Andric static void tcSetLeastSignificantBits(APInt::WordType *dst, unsigned parts,
1490349cc55cSDimitry Andric                                       unsigned bits) {
1491349cc55cSDimitry Andric   unsigned i = 0;
1492349cc55cSDimitry Andric   while (bits > APInt::APINT_BITS_PER_WORD) {
1493349cc55cSDimitry Andric     dst[i++] = ~(APInt::WordType)0;
1494349cc55cSDimitry Andric     bits -= APInt::APINT_BITS_PER_WORD;
1495349cc55cSDimitry Andric   }
1496349cc55cSDimitry Andric 
1497349cc55cSDimitry Andric   if (bits)
1498349cc55cSDimitry Andric     dst[i++] = ~(APInt::WordType)0 >> (APInt::APINT_BITS_PER_WORD - bits);
1499349cc55cSDimitry Andric 
1500349cc55cSDimitry Andric   while (i < parts)
1501349cc55cSDimitry Andric     dst[i++] = 0;
1502349cc55cSDimitry Andric }
1503349cc55cSDimitry Andric 
15040b57cec5SDimitry Andric /* Handle overflow.  Sign is preserved.  We either become infinity or
15050b57cec5SDimitry Andric    the largest finite number.  */
handleOverflow(roundingMode rounding_mode)15060b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::handleOverflow(roundingMode rounding_mode) {
15070b57cec5SDimitry Andric   /* Infinity?  */
15080b57cec5SDimitry Andric   if (rounding_mode == rmNearestTiesToEven ||
15090b57cec5SDimitry Andric       rounding_mode == rmNearestTiesToAway ||
15100b57cec5SDimitry Andric       (rounding_mode == rmTowardPositive && !sign) ||
15110b57cec5SDimitry Andric       (rounding_mode == rmTowardNegative && sign)) {
1512bdd1243dSDimitry Andric     if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
1513bdd1243dSDimitry Andric       makeNaN(false, sign);
1514bdd1243dSDimitry Andric     else
15150b57cec5SDimitry Andric       category = fcInfinity;
15160b57cec5SDimitry Andric     return (opStatus) (opOverflow | opInexact);
15170b57cec5SDimitry Andric   }
15180b57cec5SDimitry Andric 
15190b57cec5SDimitry Andric   /* Otherwise we become the largest finite number.  */
15200b57cec5SDimitry Andric   category = fcNormal;
15210b57cec5SDimitry Andric   exponent = semantics->maxExponent;
1522349cc55cSDimitry Andric   tcSetLeastSignificantBits(significandParts(), partCount(),
15230b57cec5SDimitry Andric                             semantics->precision);
1524fe013be4SDimitry Andric   if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly &&
1525fe013be4SDimitry Andric       semantics->nanEncoding == fltNanEncoding::AllOnes)
1526bdd1243dSDimitry Andric     APInt::tcClearBit(significandParts(), 0);
15270b57cec5SDimitry Andric 
15280b57cec5SDimitry Andric   return opInexact;
15290b57cec5SDimitry Andric }
15300b57cec5SDimitry Andric 
15310b57cec5SDimitry Andric /* Returns TRUE if, when truncating the current number, with BIT the
15320b57cec5SDimitry Andric    new LSB, with the given lost fraction and rounding mode, the result
15330b57cec5SDimitry Andric    would need to be rounded away from zero (i.e., by increasing the
15340b57cec5SDimitry Andric    signficand).  This routine must work for fcZero of both signs, and
15350b57cec5SDimitry Andric    fcNormal numbers.  */
roundAwayFromZero(roundingMode rounding_mode,lostFraction lost_fraction,unsigned int bit) const15360b57cec5SDimitry Andric bool IEEEFloat::roundAwayFromZero(roundingMode rounding_mode,
15370b57cec5SDimitry Andric                                   lostFraction lost_fraction,
15380b57cec5SDimitry Andric                                   unsigned int bit) const {
15390b57cec5SDimitry Andric   /* NaNs and infinities should not have lost fractions.  */
15400b57cec5SDimitry Andric   assert(isFiniteNonZero() || category == fcZero);
15410b57cec5SDimitry Andric 
15420b57cec5SDimitry Andric   /* Current callers never pass this so we don't handle it.  */
15430b57cec5SDimitry Andric   assert(lost_fraction != lfExactlyZero);
15440b57cec5SDimitry Andric 
15450b57cec5SDimitry Andric   switch (rounding_mode) {
15460b57cec5SDimitry Andric   case rmNearestTiesToAway:
15470b57cec5SDimitry Andric     return lost_fraction == lfExactlyHalf || lost_fraction == lfMoreThanHalf;
15480b57cec5SDimitry Andric 
15490b57cec5SDimitry Andric   case rmNearestTiesToEven:
15500b57cec5SDimitry Andric     if (lost_fraction == lfMoreThanHalf)
15510b57cec5SDimitry Andric       return true;
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric     /* Our zeroes don't have a significand to test.  */
15540b57cec5SDimitry Andric     if (lost_fraction == lfExactlyHalf && category != fcZero)
15550b57cec5SDimitry Andric       return APInt::tcExtractBit(significandParts(), bit);
15560b57cec5SDimitry Andric 
15570b57cec5SDimitry Andric     return false;
15580b57cec5SDimitry Andric 
15590b57cec5SDimitry Andric   case rmTowardZero:
15600b57cec5SDimitry Andric     return false;
15610b57cec5SDimitry Andric 
15620b57cec5SDimitry Andric   case rmTowardPositive:
15630b57cec5SDimitry Andric     return !sign;
15640b57cec5SDimitry Andric 
15650b57cec5SDimitry Andric   case rmTowardNegative:
15660b57cec5SDimitry Andric     return sign;
15675ffd83dbSDimitry Andric 
15685ffd83dbSDimitry Andric   default:
15695ffd83dbSDimitry Andric     break;
15700b57cec5SDimitry Andric   }
15710b57cec5SDimitry Andric   llvm_unreachable("Invalid rounding mode found");
15720b57cec5SDimitry Andric }
15730b57cec5SDimitry Andric 
normalize(roundingMode rounding_mode,lostFraction lost_fraction)15740b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::normalize(roundingMode rounding_mode,
15750b57cec5SDimitry Andric                                          lostFraction lost_fraction) {
15760b57cec5SDimitry Andric   unsigned int omsb;                /* One, not zero, based MSB.  */
15770b57cec5SDimitry Andric   int exponentChange;
15780b57cec5SDimitry Andric 
15790b57cec5SDimitry Andric   if (!isFiniteNonZero())
15800b57cec5SDimitry Andric     return opOK;
15810b57cec5SDimitry Andric 
15820b57cec5SDimitry Andric   /* Before rounding normalize the exponent of fcNormal numbers.  */
15830b57cec5SDimitry Andric   omsb = significandMSB() + 1;
15840b57cec5SDimitry Andric 
15850b57cec5SDimitry Andric   if (omsb) {
15860b57cec5SDimitry Andric     /* OMSB is numbered from 1.  We want to place it in the integer
15870b57cec5SDimitry Andric        bit numbered PRECISION if possible, with a compensating change in
15880b57cec5SDimitry Andric        the exponent.  */
15890b57cec5SDimitry Andric     exponentChange = omsb - semantics->precision;
15900b57cec5SDimitry Andric 
15910b57cec5SDimitry Andric     /* If the resulting exponent is too high, overflow according to
15920b57cec5SDimitry Andric        the rounding mode.  */
15930b57cec5SDimitry Andric     if (exponent + exponentChange > semantics->maxExponent)
15940b57cec5SDimitry Andric       return handleOverflow(rounding_mode);
15950b57cec5SDimitry Andric 
15960b57cec5SDimitry Andric     /* Subnormal numbers have exponent minExponent, and their MSB
15970b57cec5SDimitry Andric        is forced based on that.  */
15980b57cec5SDimitry Andric     if (exponent + exponentChange < semantics->minExponent)
15990b57cec5SDimitry Andric       exponentChange = semantics->minExponent - exponent;
16000b57cec5SDimitry Andric 
16010b57cec5SDimitry Andric     /* Shifting left is easy as we don't lose precision.  */
16020b57cec5SDimitry Andric     if (exponentChange < 0) {
16030b57cec5SDimitry Andric       assert(lost_fraction == lfExactlyZero);
16040b57cec5SDimitry Andric 
16050b57cec5SDimitry Andric       shiftSignificandLeft(-exponentChange);
16060b57cec5SDimitry Andric 
16070b57cec5SDimitry Andric       return opOK;
16080b57cec5SDimitry Andric     }
16090b57cec5SDimitry Andric 
16100b57cec5SDimitry Andric     if (exponentChange > 0) {
16110b57cec5SDimitry Andric       lostFraction lf;
16120b57cec5SDimitry Andric 
16130b57cec5SDimitry Andric       /* Shift right and capture any new lost fraction.  */
16140b57cec5SDimitry Andric       lf = shiftSignificandRight(exponentChange);
16150b57cec5SDimitry Andric 
16160b57cec5SDimitry Andric       lost_fraction = combineLostFractions(lf, lost_fraction);
16170b57cec5SDimitry Andric 
16180b57cec5SDimitry Andric       /* Keep OMSB up-to-date.  */
16190b57cec5SDimitry Andric       if (omsb > (unsigned) exponentChange)
16200b57cec5SDimitry Andric         omsb -= exponentChange;
16210b57cec5SDimitry Andric       else
16220b57cec5SDimitry Andric         omsb = 0;
16230b57cec5SDimitry Andric     }
16240b57cec5SDimitry Andric   }
16250b57cec5SDimitry Andric 
1626fe013be4SDimitry Andric   // The all-ones values is an overflow if NaN is all ones. If NaN is
1627fe013be4SDimitry Andric   // represented by negative zero, then it is a valid finite value.
1628bdd1243dSDimitry Andric   if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly &&
1629fe013be4SDimitry Andric       semantics->nanEncoding == fltNanEncoding::AllOnes &&
1630bdd1243dSDimitry Andric       exponent == semantics->maxExponent && isSignificandAllOnes())
1631bdd1243dSDimitry Andric     return handleOverflow(rounding_mode);
1632bdd1243dSDimitry Andric 
16330b57cec5SDimitry Andric   /* Now round the number according to rounding_mode given the lost
16340b57cec5SDimitry Andric      fraction.  */
16350b57cec5SDimitry Andric 
16360b57cec5SDimitry Andric   /* As specified in IEEE 754, since we do not trap we do not report
16370b57cec5SDimitry Andric      underflow for exact results.  */
16380b57cec5SDimitry Andric   if (lost_fraction == lfExactlyZero) {
16390b57cec5SDimitry Andric     /* Canonicalize zeroes.  */
1640fe013be4SDimitry Andric     if (omsb == 0) {
16410b57cec5SDimitry Andric       category = fcZero;
1642fe013be4SDimitry Andric       if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
1643fe013be4SDimitry Andric         sign = false;
1644fe013be4SDimitry Andric     }
16450b57cec5SDimitry Andric 
16460b57cec5SDimitry Andric     return opOK;
16470b57cec5SDimitry Andric   }
16480b57cec5SDimitry Andric 
16490b57cec5SDimitry Andric   /* Increment the significand if we're rounding away from zero.  */
16500b57cec5SDimitry Andric   if (roundAwayFromZero(rounding_mode, lost_fraction, 0)) {
16510b57cec5SDimitry Andric     if (omsb == 0)
16520b57cec5SDimitry Andric       exponent = semantics->minExponent;
16530b57cec5SDimitry Andric 
16540b57cec5SDimitry Andric     incrementSignificand();
16550b57cec5SDimitry Andric     omsb = significandMSB() + 1;
16560b57cec5SDimitry Andric 
16570b57cec5SDimitry Andric     /* Did the significand increment overflow?  */
16580b57cec5SDimitry Andric     if (omsb == (unsigned) semantics->precision + 1) {
16590b57cec5SDimitry Andric       /* Renormalize by incrementing the exponent and shifting our
16600b57cec5SDimitry Andric          significand right one.  However if we already have the
16610b57cec5SDimitry Andric          maximum exponent we overflow to infinity.  */
1662fe013be4SDimitry Andric       if (exponent == semantics->maxExponent)
1663fe013be4SDimitry Andric         // Invoke overflow handling with a rounding mode that will guarantee
1664fe013be4SDimitry Andric         // that the result gets turned into the correct infinity representation.
1665fe013be4SDimitry Andric         // This is needed instead of just setting the category to infinity to
1666fe013be4SDimitry Andric         // account for 8-bit floating point types that have no inf, only NaN.
1667fe013be4SDimitry Andric         return handleOverflow(sign ? rmTowardNegative : rmTowardPositive);
16680b57cec5SDimitry Andric 
16690b57cec5SDimitry Andric       shiftSignificandRight(1);
16700b57cec5SDimitry Andric 
16710b57cec5SDimitry Andric       return opInexact;
16720b57cec5SDimitry Andric     }
1673bdd1243dSDimitry Andric 
1674fe013be4SDimitry Andric     // The all-ones values is an overflow if NaN is all ones. If NaN is
1675fe013be4SDimitry Andric     // represented by negative zero, then it is a valid finite value.
1676bdd1243dSDimitry Andric     if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly &&
1677fe013be4SDimitry Andric         semantics->nanEncoding == fltNanEncoding::AllOnes &&
1678bdd1243dSDimitry Andric         exponent == semantics->maxExponent && isSignificandAllOnes())
1679bdd1243dSDimitry Andric       return handleOverflow(rounding_mode);
16800b57cec5SDimitry Andric   }
16810b57cec5SDimitry Andric 
16820b57cec5SDimitry Andric   /* The normal case - we were and are not denormal, and any
16830b57cec5SDimitry Andric      significand increment above didn't overflow.  */
16840b57cec5SDimitry Andric   if (omsb == semantics->precision)
16850b57cec5SDimitry Andric     return opInexact;
16860b57cec5SDimitry Andric 
16870b57cec5SDimitry Andric   /* We have a non-zero denormal.  */
16880b57cec5SDimitry Andric   assert(omsb < semantics->precision);
16890b57cec5SDimitry Andric 
16900b57cec5SDimitry Andric   /* Canonicalize zeroes.  */
1691fe013be4SDimitry Andric   if (omsb == 0) {
16920b57cec5SDimitry Andric     category = fcZero;
1693fe013be4SDimitry Andric     if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
1694fe013be4SDimitry Andric       sign = false;
1695fe013be4SDimitry Andric   }
16960b57cec5SDimitry Andric 
16970b57cec5SDimitry Andric   /* The fcZero case is a denormal that underflowed to zero.  */
16980b57cec5SDimitry Andric   return (opStatus) (opUnderflow | opInexact);
16990b57cec5SDimitry Andric }
17000b57cec5SDimitry Andric 
addOrSubtractSpecials(const IEEEFloat & rhs,bool subtract)17010b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::addOrSubtractSpecials(const IEEEFloat &rhs,
17020b57cec5SDimitry Andric                                                      bool subtract) {
17030b57cec5SDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
17040b57cec5SDimitry Andric   default:
17050b57cec5SDimitry Andric     llvm_unreachable(nullptr);
17060b57cec5SDimitry Andric 
17075ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
17085ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
17095ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
17105ffd83dbSDimitry Andric     assign(rhs);
1711bdd1243dSDimitry Andric     [[fallthrough]];
17120b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
17130b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
17140b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
17150b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
17165ffd83dbSDimitry Andric     if (isSignaling()) {
17175ffd83dbSDimitry Andric       makeQuiet();
17185ffd83dbSDimitry Andric       return opInvalidOp;
17195ffd83dbSDimitry Andric     }
17205ffd83dbSDimitry Andric     return rhs.isSignaling() ? opInvalidOp : opOK;
17215ffd83dbSDimitry Andric 
17220b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
17230b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
17240b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
17250b57cec5SDimitry Andric     return opOK;
17260b57cec5SDimitry Andric 
17270b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
17280b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
17290b57cec5SDimitry Andric     category = fcInfinity;
17300b57cec5SDimitry Andric     sign = rhs.sign ^ subtract;
17310b57cec5SDimitry Andric     return opOK;
17320b57cec5SDimitry Andric 
17330b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
17340b57cec5SDimitry Andric     assign(rhs);
17350b57cec5SDimitry Andric     sign = rhs.sign ^ subtract;
17360b57cec5SDimitry Andric     return opOK;
17370b57cec5SDimitry Andric 
17380b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
17390b57cec5SDimitry Andric     /* Sign depends on rounding mode; handled by caller.  */
17400b57cec5SDimitry Andric     return opOK;
17410b57cec5SDimitry Andric 
17420b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
17430b57cec5SDimitry Andric     /* Differently signed infinities can only be validly
17440b57cec5SDimitry Andric        subtracted.  */
17450b57cec5SDimitry Andric     if (((sign ^ rhs.sign)!=0) != subtract) {
17460b57cec5SDimitry Andric       makeNaN();
17470b57cec5SDimitry Andric       return opInvalidOp;
17480b57cec5SDimitry Andric     }
17490b57cec5SDimitry Andric 
17500b57cec5SDimitry Andric     return opOK;
17510b57cec5SDimitry Andric 
17520b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
17530b57cec5SDimitry Andric     return opDivByZero;
17540b57cec5SDimitry Andric   }
17550b57cec5SDimitry Andric }
17560b57cec5SDimitry Andric 
17570b57cec5SDimitry Andric /* Add or subtract two normal numbers.  */
addOrSubtractSignificand(const IEEEFloat & rhs,bool subtract)17580b57cec5SDimitry Andric lostFraction IEEEFloat::addOrSubtractSignificand(const IEEEFloat &rhs,
17590b57cec5SDimitry Andric                                                  bool subtract) {
17600b57cec5SDimitry Andric   integerPart carry;
17610b57cec5SDimitry Andric   lostFraction lost_fraction;
17620b57cec5SDimitry Andric   int bits;
17630b57cec5SDimitry Andric 
17640b57cec5SDimitry Andric   /* Determine if the operation on the absolute values is effectively
17650b57cec5SDimitry Andric      an addition or subtraction.  */
17660b57cec5SDimitry Andric   subtract ^= static_cast<bool>(sign ^ rhs.sign);
17670b57cec5SDimitry Andric 
17680b57cec5SDimitry Andric   /* Are we bigger exponent-wise than the RHS?  */
17690b57cec5SDimitry Andric   bits = exponent - rhs.exponent;
17700b57cec5SDimitry Andric 
17710b57cec5SDimitry Andric   /* Subtraction is more subtle than one might naively expect.  */
17720b57cec5SDimitry Andric   if (subtract) {
17730b57cec5SDimitry Andric     IEEEFloat temp_rhs(rhs);
17740b57cec5SDimitry Andric 
1775480093f4SDimitry Andric     if (bits == 0)
17760b57cec5SDimitry Andric       lost_fraction = lfExactlyZero;
1777480093f4SDimitry Andric     else if (bits > 0) {
17780b57cec5SDimitry Andric       lost_fraction = temp_rhs.shiftSignificandRight(bits - 1);
17790b57cec5SDimitry Andric       shiftSignificandLeft(1);
17800b57cec5SDimitry Andric     } else {
17810b57cec5SDimitry Andric       lost_fraction = shiftSignificandRight(-bits - 1);
17820b57cec5SDimitry Andric       temp_rhs.shiftSignificandLeft(1);
17830b57cec5SDimitry Andric     }
17840b57cec5SDimitry Andric 
1785480093f4SDimitry Andric     // Should we reverse the subtraction.
1786480093f4SDimitry Andric     if (compareAbsoluteValue(temp_rhs) == cmpLessThan) {
17870b57cec5SDimitry Andric       carry = temp_rhs.subtractSignificand
17880b57cec5SDimitry Andric         (*this, lost_fraction != lfExactlyZero);
17890b57cec5SDimitry Andric       copySignificand(temp_rhs);
17900b57cec5SDimitry Andric       sign = !sign;
17910b57cec5SDimitry Andric     } else {
17920b57cec5SDimitry Andric       carry = subtractSignificand
17930b57cec5SDimitry Andric         (temp_rhs, lost_fraction != lfExactlyZero);
17940b57cec5SDimitry Andric     }
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric     /* Invert the lost fraction - it was on the RHS and
17970b57cec5SDimitry Andric        subtracted.  */
17980b57cec5SDimitry Andric     if (lost_fraction == lfLessThanHalf)
17990b57cec5SDimitry Andric       lost_fraction = lfMoreThanHalf;
18000b57cec5SDimitry Andric     else if (lost_fraction == lfMoreThanHalf)
18010b57cec5SDimitry Andric       lost_fraction = lfLessThanHalf;
18020b57cec5SDimitry Andric 
18030b57cec5SDimitry Andric     /* The code above is intended to ensure that no borrow is
18040b57cec5SDimitry Andric        necessary.  */
18050b57cec5SDimitry Andric     assert(!carry);
18060b57cec5SDimitry Andric     (void)carry;
18070b57cec5SDimitry Andric   } else {
18080b57cec5SDimitry Andric     if (bits > 0) {
18090b57cec5SDimitry Andric       IEEEFloat temp_rhs(rhs);
18100b57cec5SDimitry Andric 
18110b57cec5SDimitry Andric       lost_fraction = temp_rhs.shiftSignificandRight(bits);
18120b57cec5SDimitry Andric       carry = addSignificand(temp_rhs);
18130b57cec5SDimitry Andric     } else {
18140b57cec5SDimitry Andric       lost_fraction = shiftSignificandRight(-bits);
18150b57cec5SDimitry Andric       carry = addSignificand(rhs);
18160b57cec5SDimitry Andric     }
18170b57cec5SDimitry Andric 
18180b57cec5SDimitry Andric     /* We have a guard bit; generating a carry cannot happen.  */
18190b57cec5SDimitry Andric     assert(!carry);
18200b57cec5SDimitry Andric     (void)carry;
18210b57cec5SDimitry Andric   }
18220b57cec5SDimitry Andric 
18230b57cec5SDimitry Andric   return lost_fraction;
18240b57cec5SDimitry Andric }
18250b57cec5SDimitry Andric 
multiplySpecials(const IEEEFloat & rhs)18260b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::multiplySpecials(const IEEEFloat &rhs) {
18270b57cec5SDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
18280b57cec5SDimitry Andric   default:
18290b57cec5SDimitry Andric     llvm_unreachable(nullptr);
18300b57cec5SDimitry Andric 
18315ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
18325ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
18335ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
18345ffd83dbSDimitry Andric     assign(rhs);
18355ffd83dbSDimitry Andric     sign = false;
1836bdd1243dSDimitry Andric     [[fallthrough]];
18370b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
18380b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
18390b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
18400b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
18415ffd83dbSDimitry Andric     sign ^= rhs.sign; // restore the original sign
18425ffd83dbSDimitry Andric     if (isSignaling()) {
18435ffd83dbSDimitry Andric       makeQuiet();
18445ffd83dbSDimitry Andric       return opInvalidOp;
18455ffd83dbSDimitry Andric     }
18465ffd83dbSDimitry Andric     return rhs.isSignaling() ? opInvalidOp : opOK;
18470b57cec5SDimitry Andric 
18480b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
18490b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
18500b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
18510b57cec5SDimitry Andric     category = fcInfinity;
18520b57cec5SDimitry Andric     return opOK;
18530b57cec5SDimitry Andric 
18540b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
18550b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
18560b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
18570b57cec5SDimitry Andric     category = fcZero;
18580b57cec5SDimitry Andric     return opOK;
18590b57cec5SDimitry Andric 
18600b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
18610b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
18620b57cec5SDimitry Andric     makeNaN();
18630b57cec5SDimitry Andric     return opInvalidOp;
18640b57cec5SDimitry Andric 
18650b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
18660b57cec5SDimitry Andric     return opOK;
18670b57cec5SDimitry Andric   }
18680b57cec5SDimitry Andric }
18690b57cec5SDimitry Andric 
divideSpecials(const IEEEFloat & rhs)18700b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::divideSpecials(const IEEEFloat &rhs) {
18710b57cec5SDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
18720b57cec5SDimitry Andric   default:
18730b57cec5SDimitry Andric     llvm_unreachable(nullptr);
18740b57cec5SDimitry Andric 
18750b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
18760b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
18770b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
18785ffd83dbSDimitry Andric     assign(rhs);
18795ffd83dbSDimitry Andric     sign = false;
1880bdd1243dSDimitry Andric     [[fallthrough]];
18810b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
18820b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
18830b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
18840b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
18855ffd83dbSDimitry Andric     sign ^= rhs.sign; // restore the original sign
18865ffd83dbSDimitry Andric     if (isSignaling()) {
18875ffd83dbSDimitry Andric       makeQuiet();
18885ffd83dbSDimitry Andric       return opInvalidOp;
18895ffd83dbSDimitry Andric     }
18905ffd83dbSDimitry Andric     return rhs.isSignaling() ? opInvalidOp : opOK;
18915ffd83dbSDimitry Andric 
18920b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
18930b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
18940b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
18950b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
18960b57cec5SDimitry Andric     return opOK;
18970b57cec5SDimitry Andric 
18980b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
18990b57cec5SDimitry Andric     category = fcZero;
19000b57cec5SDimitry Andric     return opOK;
19010b57cec5SDimitry Andric 
19020b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
1903bdd1243dSDimitry Andric     if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
1904bdd1243dSDimitry Andric       makeNaN(false, sign);
1905bdd1243dSDimitry Andric     else
19060b57cec5SDimitry Andric       category = fcInfinity;
19070b57cec5SDimitry Andric     return opDivByZero;
19080b57cec5SDimitry Andric 
19090b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
19100b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
19110b57cec5SDimitry Andric     makeNaN();
19120b57cec5SDimitry Andric     return opInvalidOp;
19130b57cec5SDimitry Andric 
19140b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
19150b57cec5SDimitry Andric     return opOK;
19160b57cec5SDimitry Andric   }
19170b57cec5SDimitry Andric }
19180b57cec5SDimitry Andric 
modSpecials(const IEEEFloat & rhs)19190b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::modSpecials(const IEEEFloat &rhs) {
19200b57cec5SDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
19210b57cec5SDimitry Andric   default:
19220b57cec5SDimitry Andric     llvm_unreachable(nullptr);
19230b57cec5SDimitry Andric 
19245ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
19255ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
19265ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
19275ffd83dbSDimitry Andric     assign(rhs);
1928bdd1243dSDimitry Andric     [[fallthrough]];
19290b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
19300b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
19310b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
19320b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
19335ffd83dbSDimitry Andric     if (isSignaling()) {
19345ffd83dbSDimitry Andric       makeQuiet();
19355ffd83dbSDimitry Andric       return opInvalidOp;
19365ffd83dbSDimitry Andric     }
19375ffd83dbSDimitry Andric     return rhs.isSignaling() ? opInvalidOp : opOK;
19385ffd83dbSDimitry Andric 
19390b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
19400b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
19410b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
19420b57cec5SDimitry Andric     return opOK;
19430b57cec5SDimitry Andric 
19440b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
19450b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
19460b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
19470b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
19480b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
19490b57cec5SDimitry Andric     makeNaN();
19500b57cec5SDimitry Andric     return opInvalidOp;
19510b57cec5SDimitry Andric 
19520b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
19530b57cec5SDimitry Andric     return opOK;
19540b57cec5SDimitry Andric   }
19550b57cec5SDimitry Andric }
19560b57cec5SDimitry Andric 
remainderSpecials(const IEEEFloat & rhs)19575ffd83dbSDimitry Andric IEEEFloat::opStatus IEEEFloat::remainderSpecials(const IEEEFloat &rhs) {
19585ffd83dbSDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
19595ffd83dbSDimitry Andric   default:
19605ffd83dbSDimitry Andric     llvm_unreachable(nullptr);
19615ffd83dbSDimitry Andric 
19625ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
19635ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
19645ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
19655ffd83dbSDimitry Andric     assign(rhs);
1966bdd1243dSDimitry Andric     [[fallthrough]];
19675ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
19685ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
19695ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
19705ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
19715ffd83dbSDimitry Andric     if (isSignaling()) {
19725ffd83dbSDimitry Andric       makeQuiet();
19735ffd83dbSDimitry Andric       return opInvalidOp;
19745ffd83dbSDimitry Andric     }
19755ffd83dbSDimitry Andric     return rhs.isSignaling() ? opInvalidOp : opOK;
19765ffd83dbSDimitry Andric 
19775ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
19785ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
19795ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
19805ffd83dbSDimitry Andric     return opOK;
19815ffd83dbSDimitry Andric 
19825ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
19835ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
19845ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
19855ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
19865ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
19875ffd83dbSDimitry Andric     makeNaN();
19885ffd83dbSDimitry Andric     return opInvalidOp;
19895ffd83dbSDimitry Andric 
19905ffd83dbSDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
19915ffd83dbSDimitry Andric     return opDivByZero; // fake status, indicating this is not a special case
19925ffd83dbSDimitry Andric   }
19935ffd83dbSDimitry Andric }
19945ffd83dbSDimitry Andric 
19950b57cec5SDimitry Andric /* Change sign.  */
changeSign()19960b57cec5SDimitry Andric void IEEEFloat::changeSign() {
1997fe013be4SDimitry Andric   // With NaN-as-negative-zero, neither NaN or negative zero can change
1998fe013be4SDimitry Andric   // their signs.
1999fe013be4SDimitry Andric   if (semantics->nanEncoding == fltNanEncoding::NegativeZero &&
2000fe013be4SDimitry Andric       (isZero() || isNaN()))
2001fe013be4SDimitry Andric     return;
20020b57cec5SDimitry Andric   /* Look mummy, this one's easy.  */
20030b57cec5SDimitry Andric   sign = !sign;
20040b57cec5SDimitry Andric }
20050b57cec5SDimitry Andric 
20060b57cec5SDimitry Andric /* Normalized addition or subtraction.  */
addOrSubtract(const IEEEFloat & rhs,roundingMode rounding_mode,bool subtract)20070b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::addOrSubtract(const IEEEFloat &rhs,
20080b57cec5SDimitry Andric                                              roundingMode rounding_mode,
20090b57cec5SDimitry Andric                                              bool subtract) {
20100b57cec5SDimitry Andric   opStatus fs;
20110b57cec5SDimitry Andric 
20120b57cec5SDimitry Andric   fs = addOrSubtractSpecials(rhs, subtract);
20130b57cec5SDimitry Andric 
20140b57cec5SDimitry Andric   /* This return code means it was not a simple case.  */
20150b57cec5SDimitry Andric   if (fs == opDivByZero) {
20160b57cec5SDimitry Andric     lostFraction lost_fraction;
20170b57cec5SDimitry Andric 
20180b57cec5SDimitry Andric     lost_fraction = addOrSubtractSignificand(rhs, subtract);
20190b57cec5SDimitry Andric     fs = normalize(rounding_mode, lost_fraction);
20200b57cec5SDimitry Andric 
20210b57cec5SDimitry Andric     /* Can only be zero if we lost no fraction.  */
20220b57cec5SDimitry Andric     assert(category != fcZero || lost_fraction == lfExactlyZero);
20230b57cec5SDimitry Andric   }
20240b57cec5SDimitry Andric 
20250b57cec5SDimitry Andric   /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a
20260b57cec5SDimitry Andric      positive zero unless rounding to minus infinity, except that
20270b57cec5SDimitry Andric      adding two like-signed zeroes gives that zero.  */
20280b57cec5SDimitry Andric   if (category == fcZero) {
20290b57cec5SDimitry Andric     if (rhs.category != fcZero || (sign == rhs.sign) == subtract)
20300b57cec5SDimitry Andric       sign = (rounding_mode == rmTowardNegative);
2031fe013be4SDimitry Andric     // NaN-in-negative-zero means zeros need to be normalized to +0.
2032fe013be4SDimitry Andric     if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
2033fe013be4SDimitry Andric       sign = false;
20340b57cec5SDimitry Andric   }
20350b57cec5SDimitry Andric 
20360b57cec5SDimitry Andric   return fs;
20370b57cec5SDimitry Andric }
20380b57cec5SDimitry Andric 
20390b57cec5SDimitry Andric /* Normalized addition.  */
add(const IEEEFloat & rhs,roundingMode rounding_mode)20400b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::add(const IEEEFloat &rhs,
20410b57cec5SDimitry Andric                                    roundingMode rounding_mode) {
20420b57cec5SDimitry Andric   return addOrSubtract(rhs, rounding_mode, false);
20430b57cec5SDimitry Andric }
20440b57cec5SDimitry Andric 
20450b57cec5SDimitry Andric /* Normalized subtraction.  */
subtract(const IEEEFloat & rhs,roundingMode rounding_mode)20460b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::subtract(const IEEEFloat &rhs,
20470b57cec5SDimitry Andric                                         roundingMode rounding_mode) {
20480b57cec5SDimitry Andric   return addOrSubtract(rhs, rounding_mode, true);
20490b57cec5SDimitry Andric }
20500b57cec5SDimitry Andric 
20510b57cec5SDimitry Andric /* Normalized multiply.  */
multiply(const IEEEFloat & rhs,roundingMode rounding_mode)20520b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::multiply(const IEEEFloat &rhs,
20530b57cec5SDimitry Andric                                         roundingMode rounding_mode) {
20540b57cec5SDimitry Andric   opStatus fs;
20550b57cec5SDimitry Andric 
20560b57cec5SDimitry Andric   sign ^= rhs.sign;
20570b57cec5SDimitry Andric   fs = multiplySpecials(rhs);
20580b57cec5SDimitry Andric 
2059fe013be4SDimitry Andric   if (isZero() && semantics->nanEncoding == fltNanEncoding::NegativeZero)
2060fe013be4SDimitry Andric     sign = false;
20610b57cec5SDimitry Andric   if (isFiniteNonZero()) {
2062480093f4SDimitry Andric     lostFraction lost_fraction = multiplySignificand(rhs);
20630b57cec5SDimitry Andric     fs = normalize(rounding_mode, lost_fraction);
20640b57cec5SDimitry Andric     if (lost_fraction != lfExactlyZero)
20650b57cec5SDimitry Andric       fs = (opStatus) (fs | opInexact);
20660b57cec5SDimitry Andric   }
20670b57cec5SDimitry Andric 
20680b57cec5SDimitry Andric   return fs;
20690b57cec5SDimitry Andric }
20700b57cec5SDimitry Andric 
20710b57cec5SDimitry Andric /* Normalized divide.  */
divide(const IEEEFloat & rhs,roundingMode rounding_mode)20720b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::divide(const IEEEFloat &rhs,
20730b57cec5SDimitry Andric                                       roundingMode rounding_mode) {
20740b57cec5SDimitry Andric   opStatus fs;
20750b57cec5SDimitry Andric 
20760b57cec5SDimitry Andric   sign ^= rhs.sign;
20770b57cec5SDimitry Andric   fs = divideSpecials(rhs);
20780b57cec5SDimitry Andric 
2079fe013be4SDimitry Andric   if (isZero() && semantics->nanEncoding == fltNanEncoding::NegativeZero)
2080fe013be4SDimitry Andric     sign = false;
20810b57cec5SDimitry Andric   if (isFiniteNonZero()) {
20820b57cec5SDimitry Andric     lostFraction lost_fraction = divideSignificand(rhs);
20830b57cec5SDimitry Andric     fs = normalize(rounding_mode, lost_fraction);
20840b57cec5SDimitry Andric     if (lost_fraction != lfExactlyZero)
20850b57cec5SDimitry Andric       fs = (opStatus) (fs | opInexact);
20860b57cec5SDimitry Andric   }
20870b57cec5SDimitry Andric 
20880b57cec5SDimitry Andric   return fs;
20890b57cec5SDimitry Andric }
20900b57cec5SDimitry Andric 
20915ffd83dbSDimitry Andric /* Normalized remainder.  */
remainder(const IEEEFloat & rhs)20920b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::remainder(const IEEEFloat &rhs) {
20930b57cec5SDimitry Andric   opStatus fs;
20940b57cec5SDimitry Andric   unsigned int origSign = sign;
20950b57cec5SDimitry Andric 
20965ffd83dbSDimitry Andric   // First handle the special cases.
20975ffd83dbSDimitry Andric   fs = remainderSpecials(rhs);
20985ffd83dbSDimitry Andric   if (fs != opDivByZero)
20990b57cec5SDimitry Andric     return fs;
21000b57cec5SDimitry Andric 
21015ffd83dbSDimitry Andric   fs = opOK;
21025ffd83dbSDimitry Andric 
21035ffd83dbSDimitry Andric   // Make sure the current value is less than twice the denom. If the addition
21045ffd83dbSDimitry Andric   // did not succeed (an overflow has happened), which means that the finite
21055ffd83dbSDimitry Andric   // value we currently posses must be less than twice the denom (as we are
21065ffd83dbSDimitry Andric   // using the same semantics).
21075ffd83dbSDimitry Andric   IEEEFloat P2 = rhs;
21085ffd83dbSDimitry Andric   if (P2.add(rhs, rmNearestTiesToEven) == opOK) {
21095ffd83dbSDimitry Andric     fs = mod(P2);
21105ffd83dbSDimitry Andric     assert(fs == opOK);
21110b57cec5SDimitry Andric   }
21120b57cec5SDimitry Andric 
21135ffd83dbSDimitry Andric   // Lets work with absolute numbers.
21145ffd83dbSDimitry Andric   IEEEFloat P = rhs;
21155ffd83dbSDimitry Andric   P.sign = false;
21165ffd83dbSDimitry Andric   sign = false;
21170b57cec5SDimitry Andric 
21185ffd83dbSDimitry Andric   //
21195ffd83dbSDimitry Andric   // To calculate the remainder we use the following scheme.
21205ffd83dbSDimitry Andric   //
21215ffd83dbSDimitry Andric   // The remainder is defained as follows:
21225ffd83dbSDimitry Andric   //
21235ffd83dbSDimitry Andric   // remainder = numer - rquot * denom = x - r * p
21245ffd83dbSDimitry Andric   //
21255ffd83dbSDimitry Andric   // Where r is the result of: x/p, rounded toward the nearest integral value
21265ffd83dbSDimitry Andric   // (with halfway cases rounded toward the even number).
21275ffd83dbSDimitry Andric   //
21285ffd83dbSDimitry Andric   // Currently, (after x mod 2p):
21295ffd83dbSDimitry Andric   // r is the number of 2p's present inside x, which is inherently, an even
21305ffd83dbSDimitry Andric   // number of p's.
21315ffd83dbSDimitry Andric   //
21325ffd83dbSDimitry Andric   // We may split the remaining calculation into 4 options:
21335ffd83dbSDimitry Andric   // - if x < 0.5p then we round to the nearest number with is 0, and are done.
21345ffd83dbSDimitry Andric   // - if x == 0.5p then we round to the nearest even number which is 0, and we
21355ffd83dbSDimitry Andric   //   are done as well.
21365ffd83dbSDimitry Andric   // - if 0.5p < x < p then we round to nearest number which is 1, and we have
21375ffd83dbSDimitry Andric   //   to subtract 1p at least once.
21385ffd83dbSDimitry Andric   // - if x >= p then we must subtract p at least once, as x must be a
21395ffd83dbSDimitry Andric   //   remainder.
21405ffd83dbSDimitry Andric   //
21415ffd83dbSDimitry Andric   // By now, we were done, or we added 1 to r, which in turn, now an odd number.
21425ffd83dbSDimitry Andric   //
21435ffd83dbSDimitry Andric   // We can now split the remaining calculation to the following 3 options:
21445ffd83dbSDimitry Andric   // - if x < 0.5p then we round to the nearest number with is 0, and are done.
21455ffd83dbSDimitry Andric   // - if x == 0.5p then we round to the nearest even number. As r is odd, we
21465ffd83dbSDimitry Andric   //   must round up to the next even number. so we must subtract p once more.
21475ffd83dbSDimitry Andric   // - if x > 0.5p (and inherently x < p) then we must round r up to the next
21485ffd83dbSDimitry Andric   //   integral, and subtract p once more.
21495ffd83dbSDimitry Andric   //
21500b57cec5SDimitry Andric 
21515ffd83dbSDimitry Andric   // Extend the semantics to prevent an overflow/underflow or inexact result.
21525ffd83dbSDimitry Andric   bool losesInfo;
21535ffd83dbSDimitry Andric   fltSemantics extendedSemantics = *semantics;
21545ffd83dbSDimitry Andric   extendedSemantics.maxExponent++;
21555ffd83dbSDimitry Andric   extendedSemantics.minExponent--;
21565ffd83dbSDimitry Andric   extendedSemantics.precision += 2;
21575ffd83dbSDimitry Andric 
21585ffd83dbSDimitry Andric   IEEEFloat VEx = *this;
21595ffd83dbSDimitry Andric   fs = VEx.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
21605ffd83dbSDimitry Andric   assert(fs == opOK && !losesInfo);
21615ffd83dbSDimitry Andric   IEEEFloat PEx = P;
21625ffd83dbSDimitry Andric   fs = PEx.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
21635ffd83dbSDimitry Andric   assert(fs == opOK && !losesInfo);
21645ffd83dbSDimitry Andric 
21655ffd83dbSDimitry Andric   // It is simpler to work with 2x instead of 0.5p, and we do not need to lose
21665ffd83dbSDimitry Andric   // any fraction.
21675ffd83dbSDimitry Andric   fs = VEx.add(VEx, rmNearestTiesToEven);
21685ffd83dbSDimitry Andric   assert(fs == opOK);
21695ffd83dbSDimitry Andric 
21705ffd83dbSDimitry Andric   if (VEx.compare(PEx) == cmpGreaterThan) {
21715ffd83dbSDimitry Andric     fs = subtract(P, rmNearestTiesToEven);
21725ffd83dbSDimitry Andric     assert(fs == opOK);
21735ffd83dbSDimitry Andric 
21745ffd83dbSDimitry Andric     // Make VEx = this.add(this), but because we have different semantics, we do
21755ffd83dbSDimitry Andric     // not want to `convert` again, so we just subtract PEx twice (which equals
21765ffd83dbSDimitry Andric     // to the desired value).
21775ffd83dbSDimitry Andric     fs = VEx.subtract(PEx, rmNearestTiesToEven);
21785ffd83dbSDimitry Andric     assert(fs == opOK);
21795ffd83dbSDimitry Andric     fs = VEx.subtract(PEx, rmNearestTiesToEven);
21805ffd83dbSDimitry Andric     assert(fs == opOK);
21815ffd83dbSDimitry Andric 
21825ffd83dbSDimitry Andric     cmpResult result = VEx.compare(PEx);
21835ffd83dbSDimitry Andric     if (result == cmpGreaterThan || result == cmpEqual) {
21845ffd83dbSDimitry Andric       fs = subtract(P, rmNearestTiesToEven);
21855ffd83dbSDimitry Andric       assert(fs == opOK);
21865ffd83dbSDimitry Andric     }
21875ffd83dbSDimitry Andric   }
21880b57cec5SDimitry Andric 
2189fe013be4SDimitry Andric   if (isZero()) {
21900b57cec5SDimitry Andric     sign = origSign;    // IEEE754 requires this
2191fe013be4SDimitry Andric     if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
2192fe013be4SDimitry Andric       // But some 8-bit floats only have positive 0.
2193fe013be4SDimitry Andric       sign = false;
2194fe013be4SDimitry Andric   }
2195fe013be4SDimitry Andric 
21965ffd83dbSDimitry Andric   else
21975ffd83dbSDimitry Andric     sign ^= origSign;
21980b57cec5SDimitry Andric   return fs;
21990b57cec5SDimitry Andric }
22000b57cec5SDimitry Andric 
22010b57cec5SDimitry Andric /* Normalized llvm frem (C fmod). */
mod(const IEEEFloat & rhs)22020b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::mod(const IEEEFloat &rhs) {
22030b57cec5SDimitry Andric   opStatus fs;
22040b57cec5SDimitry Andric   fs = modSpecials(rhs);
22050b57cec5SDimitry Andric   unsigned int origSign = sign;
22060b57cec5SDimitry Andric 
22070b57cec5SDimitry Andric   while (isFiniteNonZero() && rhs.isFiniteNonZero() &&
22080b57cec5SDimitry Andric          compareAbsoluteValue(rhs) != cmpLessThan) {
2209bdd1243dSDimitry Andric     int Exp = ilogb(*this) - ilogb(rhs);
2210bdd1243dSDimitry Andric     IEEEFloat V = scalbn(rhs, Exp, rmNearestTiesToEven);
2211bdd1243dSDimitry Andric     // V can overflow to NaN with fltNonfiniteBehavior::NanOnly, so explicitly
2212bdd1243dSDimitry Andric     // check for it.
2213bdd1243dSDimitry Andric     if (V.isNaN() || compareAbsoluteValue(V) == cmpLessThan)
2214bdd1243dSDimitry Andric       V = scalbn(rhs, Exp - 1, rmNearestTiesToEven);
22150b57cec5SDimitry Andric     V.sign = sign;
22160b57cec5SDimitry Andric 
22170b57cec5SDimitry Andric     fs = subtract(V, rmNearestTiesToEven);
22180b57cec5SDimitry Andric     assert(fs==opOK);
22190b57cec5SDimitry Andric   }
2220fe013be4SDimitry Andric   if (isZero()) {
22210b57cec5SDimitry Andric     sign = origSign; // fmod requires this
2222fe013be4SDimitry Andric     if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
2223fe013be4SDimitry Andric       sign = false;
2224fe013be4SDimitry Andric   }
22250b57cec5SDimitry Andric   return fs;
22260b57cec5SDimitry Andric }
22270b57cec5SDimitry Andric 
22280b57cec5SDimitry Andric /* Normalized fused-multiply-add.  */
fusedMultiplyAdd(const IEEEFloat & multiplicand,const IEEEFloat & addend,roundingMode rounding_mode)22290b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::fusedMultiplyAdd(const IEEEFloat &multiplicand,
22300b57cec5SDimitry Andric                                                 const IEEEFloat &addend,
22310b57cec5SDimitry Andric                                                 roundingMode rounding_mode) {
22320b57cec5SDimitry Andric   opStatus fs;
22330b57cec5SDimitry Andric 
22340b57cec5SDimitry Andric   /* Post-multiplication sign, before addition.  */
22350b57cec5SDimitry Andric   sign ^= multiplicand.sign;
22360b57cec5SDimitry Andric 
22370b57cec5SDimitry Andric   /* If and only if all arguments are normal do we need to do an
22380b57cec5SDimitry Andric      extended-precision calculation.  */
22390b57cec5SDimitry Andric   if (isFiniteNonZero() &&
22400b57cec5SDimitry Andric       multiplicand.isFiniteNonZero() &&
22410b57cec5SDimitry Andric       addend.isFinite()) {
22420b57cec5SDimitry Andric     lostFraction lost_fraction;
22430b57cec5SDimitry Andric 
2244480093f4SDimitry Andric     lost_fraction = multiplySignificand(multiplicand, addend);
22450b57cec5SDimitry Andric     fs = normalize(rounding_mode, lost_fraction);
22460b57cec5SDimitry Andric     if (lost_fraction != lfExactlyZero)
22470b57cec5SDimitry Andric       fs = (opStatus) (fs | opInexact);
22480b57cec5SDimitry Andric 
22490b57cec5SDimitry Andric     /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a
22500b57cec5SDimitry Andric        positive zero unless rounding to minus infinity, except that
22510b57cec5SDimitry Andric        adding two like-signed zeroes gives that zero.  */
2252fe013be4SDimitry Andric     if (category == fcZero && !(fs & opUnderflow) && sign != addend.sign) {
22530b57cec5SDimitry Andric       sign = (rounding_mode == rmTowardNegative);
2254fe013be4SDimitry Andric       if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
2255fe013be4SDimitry Andric         sign = false;
2256fe013be4SDimitry Andric     }
22570b57cec5SDimitry Andric   } else {
22580b57cec5SDimitry Andric     fs = multiplySpecials(multiplicand);
22590b57cec5SDimitry Andric 
22600b57cec5SDimitry Andric     /* FS can only be opOK or opInvalidOp.  There is no more work
22610b57cec5SDimitry Andric        to do in the latter case.  The IEEE-754R standard says it is
22620b57cec5SDimitry Andric        implementation-defined in this case whether, if ADDEND is a
22630b57cec5SDimitry Andric        quiet NaN, we raise invalid op; this implementation does so.
22640b57cec5SDimitry Andric 
22650b57cec5SDimitry Andric        If we need to do the addition we can do so with normal
22660b57cec5SDimitry Andric        precision.  */
22670b57cec5SDimitry Andric     if (fs == opOK)
22680b57cec5SDimitry Andric       fs = addOrSubtract(addend, rounding_mode, false);
22690b57cec5SDimitry Andric   }
22700b57cec5SDimitry Andric 
22710b57cec5SDimitry Andric   return fs;
22720b57cec5SDimitry Andric }
22730b57cec5SDimitry Andric 
22745ffd83dbSDimitry Andric /* Rounding-mode correct round to integral value.  */
roundToIntegral(roundingMode rounding_mode)22750b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::roundToIntegral(roundingMode rounding_mode) {
22760b57cec5SDimitry Andric   opStatus fs;
22770b57cec5SDimitry Andric 
22785ffd83dbSDimitry Andric   if (isInfinity())
22795ffd83dbSDimitry Andric     // [IEEE Std 754-2008 6.1]:
22805ffd83dbSDimitry Andric     // The behavior of infinity in floating-point arithmetic is derived from the
22815ffd83dbSDimitry Andric     // limiting cases of real arithmetic with operands of arbitrarily
22825ffd83dbSDimitry Andric     // large magnitude, when such a limit exists.
22835ffd83dbSDimitry Andric     // ...
22845ffd83dbSDimitry Andric     // Operations on infinite operands are usually exact and therefore signal no
22855ffd83dbSDimitry Andric     // exceptions ...
22865ffd83dbSDimitry Andric     return opOK;
22875ffd83dbSDimitry Andric 
22885ffd83dbSDimitry Andric   if (isNaN()) {
22895ffd83dbSDimitry Andric     if (isSignaling()) {
22905ffd83dbSDimitry Andric       // [IEEE Std 754-2008 6.2]:
22915ffd83dbSDimitry Andric       // Under default exception handling, any operation signaling an invalid
22925ffd83dbSDimitry Andric       // operation exception and for which a floating-point result is to be
22935ffd83dbSDimitry Andric       // delivered shall deliver a quiet NaN.
22945ffd83dbSDimitry Andric       makeQuiet();
22955ffd83dbSDimitry Andric       // [IEEE Std 754-2008 6.2]:
22965ffd83dbSDimitry Andric       // Signaling NaNs shall be reserved operands that, under default exception
22975ffd83dbSDimitry Andric       // handling, signal the invalid operation exception(see 7.2) for every
22985ffd83dbSDimitry Andric       // general-computational and signaling-computational operation except for
22995ffd83dbSDimitry Andric       // the conversions described in 5.12.
23005ffd83dbSDimitry Andric       return opInvalidOp;
23015ffd83dbSDimitry Andric     } else {
23025ffd83dbSDimitry Andric       // [IEEE Std 754-2008 6.2]:
23035ffd83dbSDimitry Andric       // For an operation with quiet NaN inputs, other than maximum and minimum
23045ffd83dbSDimitry Andric       // operations, if a floating-point result is to be delivered the result
23055ffd83dbSDimitry Andric       // shall be a quiet NaN which should be one of the input NaNs.
23065ffd83dbSDimitry Andric       // ...
23075ffd83dbSDimitry Andric       // Every general-computational and quiet-computational operation involving
23085ffd83dbSDimitry Andric       // one or more input NaNs, none of them signaling, shall signal no
23095ffd83dbSDimitry Andric       // exception, except fusedMultiplyAdd might signal the invalid operation
23105ffd83dbSDimitry Andric       // exception(see 7.2).
23115ffd83dbSDimitry Andric       return opOK;
23125ffd83dbSDimitry Andric     }
23135ffd83dbSDimitry Andric   }
23145ffd83dbSDimitry Andric 
23155ffd83dbSDimitry Andric   if (isZero()) {
23165ffd83dbSDimitry Andric     // [IEEE Std 754-2008 6.3]:
23175ffd83dbSDimitry Andric     // ... the sign of the result of conversions, the quantize operation, the
23185ffd83dbSDimitry Andric     // roundToIntegral operations, and the roundToIntegralExact(see 5.3.1) is
23195ffd83dbSDimitry Andric     // the sign of the first or only operand.
23205ffd83dbSDimitry Andric     return opOK;
23215ffd83dbSDimitry Andric   }
23225ffd83dbSDimitry Andric 
23230b57cec5SDimitry Andric   // If the exponent is large enough, we know that this value is already
23240b57cec5SDimitry Andric   // integral, and the arithmetic below would potentially cause it to saturate
23250b57cec5SDimitry Andric   // to +/-Inf.  Bail out early instead.
23265ffd83dbSDimitry Andric   if (exponent+1 >= (int)semanticsPrecision(*semantics))
23270b57cec5SDimitry Andric     return opOK;
23280b57cec5SDimitry Andric 
23290b57cec5SDimitry Andric   // The algorithm here is quite simple: we add 2^(p-1), where p is the
23300b57cec5SDimitry Andric   // precision of our format, and then subtract it back off again.  The choice
23310b57cec5SDimitry Andric   // of rounding modes for the addition/subtraction determines the rounding mode
23320b57cec5SDimitry Andric   // for our integral rounding as well.
23330b57cec5SDimitry Andric   // NOTE: When the input value is negative, we do subtraction followed by
23340b57cec5SDimitry Andric   // addition instead.
23350b57cec5SDimitry Andric   APInt IntegerConstant(NextPowerOf2(semanticsPrecision(*semantics)), 1);
23360b57cec5SDimitry Andric   IntegerConstant <<= semanticsPrecision(*semantics)-1;
23370b57cec5SDimitry Andric   IEEEFloat MagicConstant(*semantics);
23380b57cec5SDimitry Andric   fs = MagicConstant.convertFromAPInt(IntegerConstant, false,
23390b57cec5SDimitry Andric                                       rmNearestTiesToEven);
23405ffd83dbSDimitry Andric   assert(fs == opOK);
23410b57cec5SDimitry Andric   MagicConstant.sign = sign;
23420b57cec5SDimitry Andric 
23435ffd83dbSDimitry Andric   // Preserve the input sign so that we can handle the case of zero result
23445ffd83dbSDimitry Andric   // correctly.
23450b57cec5SDimitry Andric   bool inputSign = isNegative();
23460b57cec5SDimitry Andric 
23470b57cec5SDimitry Andric   fs = add(MagicConstant, rounding_mode);
23480b57cec5SDimitry Andric 
23495ffd83dbSDimitry Andric   // Current value and 'MagicConstant' are both integers, so the result of the
23505ffd83dbSDimitry Andric   // subtraction is always exact according to Sterbenz' lemma.
23515ffd83dbSDimitry Andric   subtract(MagicConstant, rounding_mode);
23520b57cec5SDimitry Andric 
23530b57cec5SDimitry Andric   // Restore the input sign.
23540b57cec5SDimitry Andric   if (inputSign != isNegative())
23550b57cec5SDimitry Andric     changeSign();
23560b57cec5SDimitry Andric 
23570b57cec5SDimitry Andric   return fs;
23580b57cec5SDimitry Andric }
23590b57cec5SDimitry Andric 
23600b57cec5SDimitry Andric 
23610b57cec5SDimitry Andric /* Comparison requires normalized numbers.  */
compare(const IEEEFloat & rhs) const23620b57cec5SDimitry Andric IEEEFloat::cmpResult IEEEFloat::compare(const IEEEFloat &rhs) const {
23630b57cec5SDimitry Andric   cmpResult result;
23640b57cec5SDimitry Andric 
23650b57cec5SDimitry Andric   assert(semantics == rhs.semantics);
23660b57cec5SDimitry Andric 
23670b57cec5SDimitry Andric   switch (PackCategoriesIntoKey(category, rhs.category)) {
23680b57cec5SDimitry Andric   default:
23690b57cec5SDimitry Andric     llvm_unreachable(nullptr);
23700b57cec5SDimitry Andric 
23710b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcZero):
23720b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNormal):
23730b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcInfinity):
23740b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNaN, fcNaN):
23750b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNaN):
23760b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNaN):
23770b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNaN):
23780b57cec5SDimitry Andric     return cmpUnordered;
23790b57cec5SDimitry Andric 
23800b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcNormal):
23810b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcZero):
23820b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcZero):
23830b57cec5SDimitry Andric     if (sign)
23840b57cec5SDimitry Andric       return cmpLessThan;
23850b57cec5SDimitry Andric     else
23860b57cec5SDimitry Andric       return cmpGreaterThan;
23870b57cec5SDimitry Andric 
23880b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcInfinity):
23890b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcInfinity):
23900b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcNormal):
23910b57cec5SDimitry Andric     if (rhs.sign)
23920b57cec5SDimitry Andric       return cmpGreaterThan;
23930b57cec5SDimitry Andric     else
23940b57cec5SDimitry Andric       return cmpLessThan;
23950b57cec5SDimitry Andric 
23960b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcInfinity, fcInfinity):
23970b57cec5SDimitry Andric     if (sign == rhs.sign)
23980b57cec5SDimitry Andric       return cmpEqual;
23990b57cec5SDimitry Andric     else if (sign)
24000b57cec5SDimitry Andric       return cmpLessThan;
24010b57cec5SDimitry Andric     else
24020b57cec5SDimitry Andric       return cmpGreaterThan;
24030b57cec5SDimitry Andric 
24040b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcZero, fcZero):
24050b57cec5SDimitry Andric     return cmpEqual;
24060b57cec5SDimitry Andric 
24070b57cec5SDimitry Andric   case PackCategoriesIntoKey(fcNormal, fcNormal):
24080b57cec5SDimitry Andric     break;
24090b57cec5SDimitry Andric   }
24100b57cec5SDimitry Andric 
24110b57cec5SDimitry Andric   /* Two normal numbers.  Do they have the same sign?  */
24120b57cec5SDimitry Andric   if (sign != rhs.sign) {
24130b57cec5SDimitry Andric     if (sign)
24140b57cec5SDimitry Andric       result = cmpLessThan;
24150b57cec5SDimitry Andric     else
24160b57cec5SDimitry Andric       result = cmpGreaterThan;
24170b57cec5SDimitry Andric   } else {
24180b57cec5SDimitry Andric     /* Compare absolute values; invert result if negative.  */
24190b57cec5SDimitry Andric     result = compareAbsoluteValue(rhs);
24200b57cec5SDimitry Andric 
24210b57cec5SDimitry Andric     if (sign) {
24220b57cec5SDimitry Andric       if (result == cmpLessThan)
24230b57cec5SDimitry Andric         result = cmpGreaterThan;
24240b57cec5SDimitry Andric       else if (result == cmpGreaterThan)
24250b57cec5SDimitry Andric         result = cmpLessThan;
24260b57cec5SDimitry Andric     }
24270b57cec5SDimitry Andric   }
24280b57cec5SDimitry Andric 
24290b57cec5SDimitry Andric   return result;
24300b57cec5SDimitry Andric }
24310b57cec5SDimitry Andric 
24320b57cec5SDimitry Andric /// IEEEFloat::convert - convert a value of one floating point type to another.
24330b57cec5SDimitry Andric /// The return value corresponds to the IEEE754 exceptions.  *losesInfo
24340b57cec5SDimitry Andric /// records whether the transformation lost information, i.e. whether
24350b57cec5SDimitry Andric /// converting the result back to the original type will produce the
24360b57cec5SDimitry Andric /// original value (this is almost the same as return value==fsOK, but there
24370b57cec5SDimitry Andric /// are edge cases where this is not so).
24380b57cec5SDimitry Andric 
convert(const fltSemantics & toSemantics,roundingMode rounding_mode,bool * losesInfo)24390b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics,
24400b57cec5SDimitry Andric                                        roundingMode rounding_mode,
24410b57cec5SDimitry Andric                                        bool *losesInfo) {
24420b57cec5SDimitry Andric   lostFraction lostFraction;
24430b57cec5SDimitry Andric   unsigned int newPartCount, oldPartCount;
24440b57cec5SDimitry Andric   opStatus fs;
24450b57cec5SDimitry Andric   int shift;
24460b57cec5SDimitry Andric   const fltSemantics &fromSemantics = *semantics;
2447bdd1243dSDimitry Andric   bool is_signaling = isSignaling();
24480b57cec5SDimitry Andric 
24490b57cec5SDimitry Andric   lostFraction = lfExactlyZero;
24500b57cec5SDimitry Andric   newPartCount = partCountForBits(toSemantics.precision + 1);
24510b57cec5SDimitry Andric   oldPartCount = partCount();
24520b57cec5SDimitry Andric   shift = toSemantics.precision - fromSemantics.precision;
24530b57cec5SDimitry Andric 
24540b57cec5SDimitry Andric   bool X86SpecialNan = false;
24550b57cec5SDimitry Andric   if (&fromSemantics == &semX87DoubleExtended &&
24560b57cec5SDimitry Andric       &toSemantics != &semX87DoubleExtended && category == fcNaN &&
24570b57cec5SDimitry Andric       (!(*significandParts() & 0x8000000000000000ULL) ||
24580b57cec5SDimitry Andric        !(*significandParts() & 0x4000000000000000ULL))) {
24590b57cec5SDimitry Andric     // x86 has some unusual NaNs which cannot be represented in any other
24600b57cec5SDimitry Andric     // format; note them here.
24610b57cec5SDimitry Andric     X86SpecialNan = true;
24620b57cec5SDimitry Andric   }
24630b57cec5SDimitry Andric 
24640b57cec5SDimitry Andric   // If this is a truncation of a denormal number, and the target semantics
24650b57cec5SDimitry Andric   // has larger exponent range than the source semantics (this can happen
24660b57cec5SDimitry Andric   // when truncating from PowerPC double-double to double format), the
24670b57cec5SDimitry Andric   // right shift could lose result mantissa bits.  Adjust exponent instead
24680b57cec5SDimitry Andric   // of performing excessive shift.
246981ad6265SDimitry Andric   // Also do a similar trick in case shifting denormal would produce zero
247081ad6265SDimitry Andric   // significand as this case isn't handled correctly by normalize.
24710b57cec5SDimitry Andric   if (shift < 0 && isFiniteNonZero()) {
247281ad6265SDimitry Andric     int omsb = significandMSB() + 1;
247381ad6265SDimitry Andric     int exponentChange = omsb - fromSemantics.precision;
24740b57cec5SDimitry Andric     if (exponent + exponentChange < toSemantics.minExponent)
24750b57cec5SDimitry Andric       exponentChange = toSemantics.minExponent - exponent;
24760b57cec5SDimitry Andric     if (exponentChange < shift)
24770b57cec5SDimitry Andric       exponentChange = shift;
24780b57cec5SDimitry Andric     if (exponentChange < 0) {
24790b57cec5SDimitry Andric       shift -= exponentChange;
24800b57cec5SDimitry Andric       exponent += exponentChange;
248181ad6265SDimitry Andric     } else if (omsb <= -shift) {
248281ad6265SDimitry Andric       exponentChange = omsb + shift - 1; // leave at least one bit set
248381ad6265SDimitry Andric       shift -= exponentChange;
248481ad6265SDimitry Andric       exponent += exponentChange;
24850b57cec5SDimitry Andric     }
24860b57cec5SDimitry Andric   }
24870b57cec5SDimitry Andric 
24880b57cec5SDimitry Andric   // If this is a truncation, perform the shift before we narrow the storage.
2489bdd1243dSDimitry Andric   if (shift < 0 && (isFiniteNonZero() ||
2490bdd1243dSDimitry Andric                     (category == fcNaN && semantics->nonFiniteBehavior !=
2491bdd1243dSDimitry Andric                                               fltNonfiniteBehavior::NanOnly)))
24920b57cec5SDimitry Andric     lostFraction = shiftRight(significandParts(), oldPartCount, -shift);
24930b57cec5SDimitry Andric 
24940b57cec5SDimitry Andric   // Fix the storage so it can hold to new value.
24950b57cec5SDimitry Andric   if (newPartCount > oldPartCount) {
24960b57cec5SDimitry Andric     // The new type requires more storage; make it available.
24970b57cec5SDimitry Andric     integerPart *newParts;
24980b57cec5SDimitry Andric     newParts = new integerPart[newPartCount];
24990b57cec5SDimitry Andric     APInt::tcSet(newParts, 0, newPartCount);
25000b57cec5SDimitry Andric     if (isFiniteNonZero() || category==fcNaN)
25010b57cec5SDimitry Andric       APInt::tcAssign(newParts, significandParts(), oldPartCount);
25020b57cec5SDimitry Andric     freeSignificand();
25030b57cec5SDimitry Andric     significand.parts = newParts;
25040b57cec5SDimitry Andric   } else if (newPartCount == 1 && oldPartCount != 1) {
25050b57cec5SDimitry Andric     // Switch to built-in storage for a single part.
25060b57cec5SDimitry Andric     integerPart newPart = 0;
25070b57cec5SDimitry Andric     if (isFiniteNonZero() || category==fcNaN)
25080b57cec5SDimitry Andric       newPart = significandParts()[0];
25090b57cec5SDimitry Andric     freeSignificand();
25100b57cec5SDimitry Andric     significand.part = newPart;
25110b57cec5SDimitry Andric   }
25120b57cec5SDimitry Andric 
25130b57cec5SDimitry Andric   // Now that we have the right storage, switch the semantics.
25140b57cec5SDimitry Andric   semantics = &toSemantics;
25150b57cec5SDimitry Andric 
25160b57cec5SDimitry Andric   // If this is an extension, perform the shift now that the storage is
25170b57cec5SDimitry Andric   // available.
25180b57cec5SDimitry Andric   if (shift > 0 && (isFiniteNonZero() || category==fcNaN))
25190b57cec5SDimitry Andric     APInt::tcShiftLeft(significandParts(), newPartCount, shift);
25200b57cec5SDimitry Andric 
25210b57cec5SDimitry Andric   if (isFiniteNonZero()) {
25220b57cec5SDimitry Andric     fs = normalize(rounding_mode, lostFraction);
25230b57cec5SDimitry Andric     *losesInfo = (fs != opOK);
25240b57cec5SDimitry Andric   } else if (category == fcNaN) {
2525bdd1243dSDimitry Andric     if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
2526bdd1243dSDimitry Andric       *losesInfo =
2527bdd1243dSDimitry Andric           fromSemantics.nonFiniteBehavior != fltNonfiniteBehavior::NanOnly;
2528bdd1243dSDimitry Andric       makeNaN(false, sign);
2529bdd1243dSDimitry Andric       return is_signaling ? opInvalidOp : opOK;
2530bdd1243dSDimitry Andric     }
2531bdd1243dSDimitry Andric 
2532fe013be4SDimitry Andric     // If NaN is negative zero, we need to create a new NaN to avoid converting
2533fe013be4SDimitry Andric     // NaN to -Inf.
2534fe013be4SDimitry Andric     if (fromSemantics.nanEncoding == fltNanEncoding::NegativeZero &&
2535fe013be4SDimitry Andric         semantics->nanEncoding != fltNanEncoding::NegativeZero)
2536fe013be4SDimitry Andric       makeNaN(false, false);
2537fe013be4SDimitry Andric 
25380b57cec5SDimitry Andric     *losesInfo = lostFraction != lfExactlyZero || X86SpecialNan;
25390b57cec5SDimitry Andric 
25400b57cec5SDimitry Andric     // For x87 extended precision, we want to make a NaN, not a special NaN if
25410b57cec5SDimitry Andric     // the input wasn't special either.
25420b57cec5SDimitry Andric     if (!X86SpecialNan && semantics == &semX87DoubleExtended)
25430b57cec5SDimitry Andric       APInt::tcSetBit(significandParts(), semantics->precision - 1);
25440b57cec5SDimitry Andric 
2545e8d8bef9SDimitry Andric     // Convert of sNaN creates qNaN and raises an exception (invalid op).
2546e8d8bef9SDimitry Andric     // This also guarantees that a sNaN does not become Inf on a truncation
2547e8d8bef9SDimitry Andric     // that loses all payload bits.
2548bdd1243dSDimitry Andric     if (is_signaling) {
2549e8d8bef9SDimitry Andric       makeQuiet();
2550e8d8bef9SDimitry Andric       fs = opInvalidOp;
2551e8d8bef9SDimitry Andric     } else {
25520b57cec5SDimitry Andric       fs = opOK;
2553e8d8bef9SDimitry Andric     }
2554bdd1243dSDimitry Andric   } else if (category == fcInfinity &&
2555bdd1243dSDimitry Andric              semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
2556bdd1243dSDimitry Andric     makeNaN(false, sign);
2557bdd1243dSDimitry Andric     *losesInfo = true;
2558bdd1243dSDimitry Andric     fs = opInexact;
2559fe013be4SDimitry Andric   } else if (category == fcZero &&
2560fe013be4SDimitry Andric              semantics->nanEncoding == fltNanEncoding::NegativeZero) {
2561fe013be4SDimitry Andric     // Negative zero loses info, but positive zero doesn't.
2562fe013be4SDimitry Andric     *losesInfo =
2563fe013be4SDimitry Andric         fromSemantics.nanEncoding != fltNanEncoding::NegativeZero && sign;
2564fe013be4SDimitry Andric     fs = *losesInfo ? opInexact : opOK;
2565fe013be4SDimitry Andric     // NaN is negative zero means -0 -> +0, which can lose information
2566fe013be4SDimitry Andric     sign = false;
25670b57cec5SDimitry Andric   } else {
25680b57cec5SDimitry Andric     *losesInfo = false;
25690b57cec5SDimitry Andric     fs = opOK;
25700b57cec5SDimitry Andric   }
25710b57cec5SDimitry Andric 
25720b57cec5SDimitry Andric   return fs;
25730b57cec5SDimitry Andric }
25740b57cec5SDimitry Andric 
25750b57cec5SDimitry Andric /* Convert a floating point number to an integer according to the
25760b57cec5SDimitry Andric    rounding mode.  If the rounded integer value is out of range this
25770b57cec5SDimitry Andric    returns an invalid operation exception and the contents of the
25780b57cec5SDimitry Andric    destination parts are unspecified.  If the rounded value is in
25790b57cec5SDimitry Andric    range but the floating point number is not the exact integer, the C
25800b57cec5SDimitry Andric    standard doesn't require an inexact exception to be raised.  IEEE
25810b57cec5SDimitry Andric    854 does require it so we do that.
25820b57cec5SDimitry Andric 
25830b57cec5SDimitry Andric    Note that for conversions to integer type the C standard requires
25840b57cec5SDimitry Andric    round-to-zero to always be used.  */
convertToSignExtendedInteger(MutableArrayRef<integerPart> parts,unsigned int width,bool isSigned,roundingMode rounding_mode,bool * isExact) const25850b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
25860b57cec5SDimitry Andric     MutableArrayRef<integerPart> parts, unsigned int width, bool isSigned,
25870b57cec5SDimitry Andric     roundingMode rounding_mode, bool *isExact) const {
25880b57cec5SDimitry Andric   lostFraction lost_fraction;
25890b57cec5SDimitry Andric   const integerPart *src;
25900b57cec5SDimitry Andric   unsigned int dstPartsCount, truncatedBits;
25910b57cec5SDimitry Andric 
25920b57cec5SDimitry Andric   *isExact = false;
25930b57cec5SDimitry Andric 
25940b57cec5SDimitry Andric   /* Handle the three special cases first.  */
25950b57cec5SDimitry Andric   if (category == fcInfinity || category == fcNaN)
25960b57cec5SDimitry Andric     return opInvalidOp;
25970b57cec5SDimitry Andric 
25980b57cec5SDimitry Andric   dstPartsCount = partCountForBits(width);
25990b57cec5SDimitry Andric   assert(dstPartsCount <= parts.size() && "Integer too big");
26000b57cec5SDimitry Andric 
26010b57cec5SDimitry Andric   if (category == fcZero) {
26020b57cec5SDimitry Andric     APInt::tcSet(parts.data(), 0, dstPartsCount);
26030b57cec5SDimitry Andric     // Negative zero can't be represented as an int.
26040b57cec5SDimitry Andric     *isExact = !sign;
26050b57cec5SDimitry Andric     return opOK;
26060b57cec5SDimitry Andric   }
26070b57cec5SDimitry Andric 
26080b57cec5SDimitry Andric   src = significandParts();
26090b57cec5SDimitry Andric 
26100b57cec5SDimitry Andric   /* Step 1: place our absolute value, with any fraction truncated, in
26110b57cec5SDimitry Andric      the destination.  */
26120b57cec5SDimitry Andric   if (exponent < 0) {
26130b57cec5SDimitry Andric     /* Our absolute value is less than one; truncate everything.  */
26140b57cec5SDimitry Andric     APInt::tcSet(parts.data(), 0, dstPartsCount);
26150b57cec5SDimitry Andric     /* For exponent -1 the integer bit represents .5, look at that.
26160b57cec5SDimitry Andric        For smaller exponents leftmost truncated bit is 0. */
26170b57cec5SDimitry Andric     truncatedBits = semantics->precision -1U - exponent;
26180b57cec5SDimitry Andric   } else {
26190b57cec5SDimitry Andric     /* We want the most significant (exponent + 1) bits; the rest are
26200b57cec5SDimitry Andric        truncated.  */
26210b57cec5SDimitry Andric     unsigned int bits = exponent + 1U;
26220b57cec5SDimitry Andric 
26230b57cec5SDimitry Andric     /* Hopelessly large in magnitude?  */
26240b57cec5SDimitry Andric     if (bits > width)
26250b57cec5SDimitry Andric       return opInvalidOp;
26260b57cec5SDimitry Andric 
26270b57cec5SDimitry Andric     if (bits < semantics->precision) {
26280b57cec5SDimitry Andric       /* We truncate (semantics->precision - bits) bits.  */
26290b57cec5SDimitry Andric       truncatedBits = semantics->precision - bits;
26300b57cec5SDimitry Andric       APInt::tcExtract(parts.data(), dstPartsCount, src, bits, truncatedBits);
26310b57cec5SDimitry Andric     } else {
26320b57cec5SDimitry Andric       /* We want at least as many bits as are available.  */
26330b57cec5SDimitry Andric       APInt::tcExtract(parts.data(), dstPartsCount, src, semantics->precision,
26340b57cec5SDimitry Andric                        0);
26350b57cec5SDimitry Andric       APInt::tcShiftLeft(parts.data(), dstPartsCount,
26360b57cec5SDimitry Andric                          bits - semantics->precision);
26370b57cec5SDimitry Andric       truncatedBits = 0;
26380b57cec5SDimitry Andric     }
26390b57cec5SDimitry Andric   }
26400b57cec5SDimitry Andric 
26410b57cec5SDimitry Andric   /* Step 2: work out any lost fraction, and increment the absolute
26420b57cec5SDimitry Andric      value if we would round away from zero.  */
26430b57cec5SDimitry Andric   if (truncatedBits) {
26440b57cec5SDimitry Andric     lost_fraction = lostFractionThroughTruncation(src, partCount(),
26450b57cec5SDimitry Andric                                                   truncatedBits);
26460b57cec5SDimitry Andric     if (lost_fraction != lfExactlyZero &&
26470b57cec5SDimitry Andric         roundAwayFromZero(rounding_mode, lost_fraction, truncatedBits)) {
26480b57cec5SDimitry Andric       if (APInt::tcIncrement(parts.data(), dstPartsCount))
26490b57cec5SDimitry Andric         return opInvalidOp;     /* Overflow.  */
26500b57cec5SDimitry Andric     }
26510b57cec5SDimitry Andric   } else {
26520b57cec5SDimitry Andric     lost_fraction = lfExactlyZero;
26530b57cec5SDimitry Andric   }
26540b57cec5SDimitry Andric 
26550b57cec5SDimitry Andric   /* Step 3: check if we fit in the destination.  */
26560b57cec5SDimitry Andric   unsigned int omsb = APInt::tcMSB(parts.data(), dstPartsCount) + 1;
26570b57cec5SDimitry Andric 
26580b57cec5SDimitry Andric   if (sign) {
26590b57cec5SDimitry Andric     if (!isSigned) {
26600b57cec5SDimitry Andric       /* Negative numbers cannot be represented as unsigned.  */
26610b57cec5SDimitry Andric       if (omsb != 0)
26620b57cec5SDimitry Andric         return opInvalidOp;
26630b57cec5SDimitry Andric     } else {
26640b57cec5SDimitry Andric       /* It takes omsb bits to represent the unsigned integer value.
26650b57cec5SDimitry Andric          We lose a bit for the sign, but care is needed as the
26660b57cec5SDimitry Andric          maximally negative integer is a special case.  */
26670b57cec5SDimitry Andric       if (omsb == width &&
26680b57cec5SDimitry Andric           APInt::tcLSB(parts.data(), dstPartsCount) + 1 != omsb)
26690b57cec5SDimitry Andric         return opInvalidOp;
26700b57cec5SDimitry Andric 
26710b57cec5SDimitry Andric       /* This case can happen because of rounding.  */
26720b57cec5SDimitry Andric       if (omsb > width)
26730b57cec5SDimitry Andric         return opInvalidOp;
26740b57cec5SDimitry Andric     }
26750b57cec5SDimitry Andric 
26760b57cec5SDimitry Andric     APInt::tcNegate (parts.data(), dstPartsCount);
26770b57cec5SDimitry Andric   } else {
26780b57cec5SDimitry Andric     if (omsb >= width + !isSigned)
26790b57cec5SDimitry Andric       return opInvalidOp;
26800b57cec5SDimitry Andric   }
26810b57cec5SDimitry Andric 
26820b57cec5SDimitry Andric   if (lost_fraction == lfExactlyZero) {
26830b57cec5SDimitry Andric     *isExact = true;
26840b57cec5SDimitry Andric     return opOK;
26850b57cec5SDimitry Andric   } else
26860b57cec5SDimitry Andric     return opInexact;
26870b57cec5SDimitry Andric }
26880b57cec5SDimitry Andric 
26890b57cec5SDimitry Andric /* Same as convertToSignExtendedInteger, except we provide
26900b57cec5SDimitry Andric    deterministic values in case of an invalid operation exception,
26910b57cec5SDimitry Andric    namely zero for NaNs and the minimal or maximal value respectively
26920b57cec5SDimitry Andric    for underflow or overflow.
26930b57cec5SDimitry Andric    The *isExact output tells whether the result is exact, in the sense
26940b57cec5SDimitry Andric    that converting it back to the original floating point type produces
26950b57cec5SDimitry Andric    the original value.  This is almost equivalent to result==opOK,
26960b57cec5SDimitry Andric    except for negative zeroes.
26970b57cec5SDimitry Andric */
26980b57cec5SDimitry Andric IEEEFloat::opStatus
convertToInteger(MutableArrayRef<integerPart> parts,unsigned int width,bool isSigned,roundingMode rounding_mode,bool * isExact) const26990b57cec5SDimitry Andric IEEEFloat::convertToInteger(MutableArrayRef<integerPart> parts,
27000b57cec5SDimitry Andric                             unsigned int width, bool isSigned,
27010b57cec5SDimitry Andric                             roundingMode rounding_mode, bool *isExact) const {
27020b57cec5SDimitry Andric   opStatus fs;
27030b57cec5SDimitry Andric 
27040b57cec5SDimitry Andric   fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode,
27050b57cec5SDimitry Andric                                     isExact);
27060b57cec5SDimitry Andric 
27070b57cec5SDimitry Andric   if (fs == opInvalidOp) {
27080b57cec5SDimitry Andric     unsigned int bits, dstPartsCount;
27090b57cec5SDimitry Andric 
27100b57cec5SDimitry Andric     dstPartsCount = partCountForBits(width);
27110b57cec5SDimitry Andric     assert(dstPartsCount <= parts.size() && "Integer too big");
27120b57cec5SDimitry Andric 
27130b57cec5SDimitry Andric     if (category == fcNaN)
27140b57cec5SDimitry Andric       bits = 0;
27150b57cec5SDimitry Andric     else if (sign)
27160b57cec5SDimitry Andric       bits = isSigned;
27170b57cec5SDimitry Andric     else
27180b57cec5SDimitry Andric       bits = width - isSigned;
27190b57cec5SDimitry Andric 
2720349cc55cSDimitry Andric     tcSetLeastSignificantBits(parts.data(), dstPartsCount, bits);
27210b57cec5SDimitry Andric     if (sign && isSigned)
27220b57cec5SDimitry Andric       APInt::tcShiftLeft(parts.data(), dstPartsCount, width - 1);
27230b57cec5SDimitry Andric   }
27240b57cec5SDimitry Andric 
27250b57cec5SDimitry Andric   return fs;
27260b57cec5SDimitry Andric }
27270b57cec5SDimitry Andric 
27280b57cec5SDimitry Andric /* Convert an unsigned integer SRC to a floating point number,
27290b57cec5SDimitry Andric    rounding according to ROUNDING_MODE.  The sign of the floating
27300b57cec5SDimitry Andric    point number is not modified.  */
convertFromUnsignedParts(const integerPart * src,unsigned int srcCount,roundingMode rounding_mode)27310b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::convertFromUnsignedParts(
27320b57cec5SDimitry Andric     const integerPart *src, unsigned int srcCount, roundingMode rounding_mode) {
27330b57cec5SDimitry Andric   unsigned int omsb, precision, dstCount;
27340b57cec5SDimitry Andric   integerPart *dst;
27350b57cec5SDimitry Andric   lostFraction lost_fraction;
27360b57cec5SDimitry Andric 
27370b57cec5SDimitry Andric   category = fcNormal;
27380b57cec5SDimitry Andric   omsb = APInt::tcMSB(src, srcCount) + 1;
27390b57cec5SDimitry Andric   dst = significandParts();
27400b57cec5SDimitry Andric   dstCount = partCount();
27410b57cec5SDimitry Andric   precision = semantics->precision;
27420b57cec5SDimitry Andric 
27430b57cec5SDimitry Andric   /* We want the most significant PRECISION bits of SRC.  There may not
27440b57cec5SDimitry Andric      be that many; extract what we can.  */
27450b57cec5SDimitry Andric   if (precision <= omsb) {
27460b57cec5SDimitry Andric     exponent = omsb - 1;
27470b57cec5SDimitry Andric     lost_fraction = lostFractionThroughTruncation(src, srcCount,
27480b57cec5SDimitry Andric                                                   omsb - precision);
27490b57cec5SDimitry Andric     APInt::tcExtract(dst, dstCount, src, precision, omsb - precision);
27500b57cec5SDimitry Andric   } else {
27510b57cec5SDimitry Andric     exponent = precision - 1;
27520b57cec5SDimitry Andric     lost_fraction = lfExactlyZero;
27530b57cec5SDimitry Andric     APInt::tcExtract(dst, dstCount, src, omsb, 0);
27540b57cec5SDimitry Andric   }
27550b57cec5SDimitry Andric 
27560b57cec5SDimitry Andric   return normalize(rounding_mode, lost_fraction);
27570b57cec5SDimitry Andric }
27580b57cec5SDimitry Andric 
convertFromAPInt(const APInt & Val,bool isSigned,roundingMode rounding_mode)27590b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::convertFromAPInt(const APInt &Val, bool isSigned,
27600b57cec5SDimitry Andric                                                 roundingMode rounding_mode) {
27610b57cec5SDimitry Andric   unsigned int partCount = Val.getNumWords();
27620b57cec5SDimitry Andric   APInt api = Val;
27630b57cec5SDimitry Andric 
27640b57cec5SDimitry Andric   sign = false;
27650b57cec5SDimitry Andric   if (isSigned && api.isNegative()) {
27660b57cec5SDimitry Andric     sign = true;
27670b57cec5SDimitry Andric     api = -api;
27680b57cec5SDimitry Andric   }
27690b57cec5SDimitry Andric 
27700b57cec5SDimitry Andric   return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
27710b57cec5SDimitry Andric }
27720b57cec5SDimitry Andric 
27730b57cec5SDimitry Andric /* Convert a two's complement integer SRC to a floating point number,
27740b57cec5SDimitry Andric    rounding according to ROUNDING_MODE.  ISSIGNED is true if the
27750b57cec5SDimitry Andric    integer is signed, in which case it must be sign-extended.  */
27760b57cec5SDimitry Andric IEEEFloat::opStatus
convertFromSignExtendedInteger(const integerPart * src,unsigned int srcCount,bool isSigned,roundingMode rounding_mode)27770b57cec5SDimitry Andric IEEEFloat::convertFromSignExtendedInteger(const integerPart *src,
27780b57cec5SDimitry Andric                                           unsigned int srcCount, bool isSigned,
27790b57cec5SDimitry Andric                                           roundingMode rounding_mode) {
27800b57cec5SDimitry Andric   opStatus status;
27810b57cec5SDimitry Andric 
27820b57cec5SDimitry Andric   if (isSigned &&
27830b57cec5SDimitry Andric       APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) {
27840b57cec5SDimitry Andric     integerPart *copy;
27850b57cec5SDimitry Andric 
27860b57cec5SDimitry Andric     /* If we're signed and negative negate a copy.  */
27870b57cec5SDimitry Andric     sign = true;
27880b57cec5SDimitry Andric     copy = new integerPart[srcCount];
27890b57cec5SDimitry Andric     APInt::tcAssign(copy, src, srcCount);
27900b57cec5SDimitry Andric     APInt::tcNegate(copy, srcCount);
27910b57cec5SDimitry Andric     status = convertFromUnsignedParts(copy, srcCount, rounding_mode);
27920b57cec5SDimitry Andric     delete [] copy;
27930b57cec5SDimitry Andric   } else {
27940b57cec5SDimitry Andric     sign = false;
27950b57cec5SDimitry Andric     status = convertFromUnsignedParts(src, srcCount, rounding_mode);
27960b57cec5SDimitry Andric   }
27970b57cec5SDimitry Andric 
27980b57cec5SDimitry Andric   return status;
27990b57cec5SDimitry Andric }
28000b57cec5SDimitry Andric 
28010b57cec5SDimitry Andric /* FIXME: should this just take a const APInt reference?  */
28020b57cec5SDimitry Andric IEEEFloat::opStatus
convertFromZeroExtendedInteger(const integerPart * parts,unsigned int width,bool isSigned,roundingMode rounding_mode)28030b57cec5SDimitry Andric IEEEFloat::convertFromZeroExtendedInteger(const integerPart *parts,
28040b57cec5SDimitry Andric                                           unsigned int width, bool isSigned,
28050b57cec5SDimitry Andric                                           roundingMode rounding_mode) {
28060b57cec5SDimitry Andric   unsigned int partCount = partCountForBits(width);
2807bdd1243dSDimitry Andric   APInt api = APInt(width, ArrayRef(parts, partCount));
28080b57cec5SDimitry Andric 
28090b57cec5SDimitry Andric   sign = false;
28100b57cec5SDimitry Andric   if (isSigned && APInt::tcExtractBit(parts, width - 1)) {
28110b57cec5SDimitry Andric     sign = true;
28120b57cec5SDimitry Andric     api = -api;
28130b57cec5SDimitry Andric   }
28140b57cec5SDimitry Andric 
28150b57cec5SDimitry Andric   return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
28160b57cec5SDimitry Andric }
28170b57cec5SDimitry Andric 
2818480093f4SDimitry Andric Expected<IEEEFloat::opStatus>
convertFromHexadecimalString(StringRef s,roundingMode rounding_mode)28190b57cec5SDimitry Andric IEEEFloat::convertFromHexadecimalString(StringRef s,
28200b57cec5SDimitry Andric                                         roundingMode rounding_mode) {
28210b57cec5SDimitry Andric   lostFraction lost_fraction = lfExactlyZero;
28220b57cec5SDimitry Andric 
28230b57cec5SDimitry Andric   category = fcNormal;
28240b57cec5SDimitry Andric   zeroSignificand();
28250b57cec5SDimitry Andric   exponent = 0;
28260b57cec5SDimitry Andric 
28270b57cec5SDimitry Andric   integerPart *significand = significandParts();
28280b57cec5SDimitry Andric   unsigned partsCount = partCount();
28290b57cec5SDimitry Andric   unsigned bitPos = partsCount * integerPartWidth;
28300b57cec5SDimitry Andric   bool computedTrailingFraction = false;
28310b57cec5SDimitry Andric 
28320b57cec5SDimitry Andric   // Skip leading zeroes and any (hexa)decimal point.
28330b57cec5SDimitry Andric   StringRef::iterator begin = s.begin();
28340b57cec5SDimitry Andric   StringRef::iterator end = s.end();
28350b57cec5SDimitry Andric   StringRef::iterator dot;
2836480093f4SDimitry Andric   auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot);
2837480093f4SDimitry Andric   if (!PtrOrErr)
2838480093f4SDimitry Andric     return PtrOrErr.takeError();
2839480093f4SDimitry Andric   StringRef::iterator p = *PtrOrErr;
28400b57cec5SDimitry Andric   StringRef::iterator firstSignificantDigit = p;
28410b57cec5SDimitry Andric 
28420b57cec5SDimitry Andric   while (p != end) {
28430b57cec5SDimitry Andric     integerPart hex_value;
28440b57cec5SDimitry Andric 
28450b57cec5SDimitry Andric     if (*p == '.') {
2846480093f4SDimitry Andric       if (dot != end)
2847480093f4SDimitry Andric         return createError("String contains multiple dots");
28480b57cec5SDimitry Andric       dot = p++;
28490b57cec5SDimitry Andric       continue;
28500b57cec5SDimitry Andric     }
28510b57cec5SDimitry Andric 
28520b57cec5SDimitry Andric     hex_value = hexDigitValue(*p);
2853fe013be4SDimitry Andric     if (hex_value == UINT_MAX)
28540b57cec5SDimitry Andric       break;
28550b57cec5SDimitry Andric 
28560b57cec5SDimitry Andric     p++;
28570b57cec5SDimitry Andric 
28580b57cec5SDimitry Andric     // Store the number while we have space.
28590b57cec5SDimitry Andric     if (bitPos) {
28600b57cec5SDimitry Andric       bitPos -= 4;
28610b57cec5SDimitry Andric       hex_value <<= bitPos % integerPartWidth;
28620b57cec5SDimitry Andric       significand[bitPos / integerPartWidth] |= hex_value;
28630b57cec5SDimitry Andric     } else if (!computedTrailingFraction) {
2864480093f4SDimitry Andric       auto FractOrErr = trailingHexadecimalFraction(p, end, hex_value);
2865480093f4SDimitry Andric       if (!FractOrErr)
2866480093f4SDimitry Andric         return FractOrErr.takeError();
2867480093f4SDimitry Andric       lost_fraction = *FractOrErr;
28680b57cec5SDimitry Andric       computedTrailingFraction = true;
28690b57cec5SDimitry Andric     }
28700b57cec5SDimitry Andric   }
28710b57cec5SDimitry Andric 
28720b57cec5SDimitry Andric   /* Hex floats require an exponent but not a hexadecimal point.  */
2873480093f4SDimitry Andric   if (p == end)
2874480093f4SDimitry Andric     return createError("Hex strings require an exponent");
2875480093f4SDimitry Andric   if (*p != 'p' && *p != 'P')
2876480093f4SDimitry Andric     return createError("Invalid character in significand");
2877480093f4SDimitry Andric   if (p == begin)
2878480093f4SDimitry Andric     return createError("Significand has no digits");
2879480093f4SDimitry Andric   if (dot != end && p - begin == 1)
2880480093f4SDimitry Andric     return createError("Significand has no digits");
28810b57cec5SDimitry Andric 
28820b57cec5SDimitry Andric   /* Ignore the exponent if we are zero.  */
28830b57cec5SDimitry Andric   if (p != firstSignificantDigit) {
28840b57cec5SDimitry Andric     int expAdjustment;
28850b57cec5SDimitry Andric 
28860b57cec5SDimitry Andric     /* Implicit hexadecimal point?  */
28870b57cec5SDimitry Andric     if (dot == end)
28880b57cec5SDimitry Andric       dot = p;
28890b57cec5SDimitry Andric 
28900b57cec5SDimitry Andric     /* Calculate the exponent adjustment implicit in the number of
28910b57cec5SDimitry Andric        significant digits.  */
28920b57cec5SDimitry Andric     expAdjustment = static_cast<int>(dot - firstSignificantDigit);
28930b57cec5SDimitry Andric     if (expAdjustment < 0)
28940b57cec5SDimitry Andric       expAdjustment++;
28950b57cec5SDimitry Andric     expAdjustment = expAdjustment * 4 - 1;
28960b57cec5SDimitry Andric 
28970b57cec5SDimitry Andric     /* Adjust for writing the significand starting at the most
28980b57cec5SDimitry Andric        significant nibble.  */
28990b57cec5SDimitry Andric     expAdjustment += semantics->precision;
29000b57cec5SDimitry Andric     expAdjustment -= partsCount * integerPartWidth;
29010b57cec5SDimitry Andric 
29020b57cec5SDimitry Andric     /* Adjust for the given exponent.  */
2903480093f4SDimitry Andric     auto ExpOrErr = totalExponent(p + 1, end, expAdjustment);
2904480093f4SDimitry Andric     if (!ExpOrErr)
2905480093f4SDimitry Andric       return ExpOrErr.takeError();
2906480093f4SDimitry Andric     exponent = *ExpOrErr;
29070b57cec5SDimitry Andric   }
29080b57cec5SDimitry Andric 
29090b57cec5SDimitry Andric   return normalize(rounding_mode, lost_fraction);
29100b57cec5SDimitry Andric }
29110b57cec5SDimitry Andric 
29120b57cec5SDimitry Andric IEEEFloat::opStatus
roundSignificandWithExponent(const integerPart * decSigParts,unsigned sigPartCount,int exp,roundingMode rounding_mode)29130b57cec5SDimitry Andric IEEEFloat::roundSignificandWithExponent(const integerPart *decSigParts,
29140b57cec5SDimitry Andric                                         unsigned sigPartCount, int exp,
29150b57cec5SDimitry Andric                                         roundingMode rounding_mode) {
29160b57cec5SDimitry Andric   unsigned int parts, pow5PartCount;
29170b57cec5SDimitry Andric   fltSemantics calcSemantics = { 32767, -32767, 0, 0 };
29180b57cec5SDimitry Andric   integerPart pow5Parts[maxPowerOfFiveParts];
29190b57cec5SDimitry Andric   bool isNearest;
29200b57cec5SDimitry Andric 
29210b57cec5SDimitry Andric   isNearest = (rounding_mode == rmNearestTiesToEven ||
29220b57cec5SDimitry Andric                rounding_mode == rmNearestTiesToAway);
29230b57cec5SDimitry Andric 
29240b57cec5SDimitry Andric   parts = partCountForBits(semantics->precision + 11);
29250b57cec5SDimitry Andric 
29260b57cec5SDimitry Andric   /* Calculate pow(5, abs(exp)).  */
29270b57cec5SDimitry Andric   pow5PartCount = powerOf5(pow5Parts, exp >= 0 ? exp: -exp);
29280b57cec5SDimitry Andric 
29290b57cec5SDimitry Andric   for (;; parts *= 2) {
29300b57cec5SDimitry Andric     opStatus sigStatus, powStatus;
29310b57cec5SDimitry Andric     unsigned int excessPrecision, truncatedBits;
29320b57cec5SDimitry Andric 
29330b57cec5SDimitry Andric     calcSemantics.precision = parts * integerPartWidth - 1;
29340b57cec5SDimitry Andric     excessPrecision = calcSemantics.precision - semantics->precision;
29350b57cec5SDimitry Andric     truncatedBits = excessPrecision;
29360b57cec5SDimitry Andric 
29370b57cec5SDimitry Andric     IEEEFloat decSig(calcSemantics, uninitialized);
29380b57cec5SDimitry Andric     decSig.makeZero(sign);
29390b57cec5SDimitry Andric     IEEEFloat pow5(calcSemantics);
29400b57cec5SDimitry Andric 
29410b57cec5SDimitry Andric     sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount,
29420b57cec5SDimitry Andric                                                 rmNearestTiesToEven);
29430b57cec5SDimitry Andric     powStatus = pow5.convertFromUnsignedParts(pow5Parts, pow5PartCount,
29440b57cec5SDimitry Andric                                               rmNearestTiesToEven);
29450b57cec5SDimitry Andric     /* Add exp, as 10^n = 5^n * 2^n.  */
29460b57cec5SDimitry Andric     decSig.exponent += exp;
29470b57cec5SDimitry Andric 
29480b57cec5SDimitry Andric     lostFraction calcLostFraction;
29490b57cec5SDimitry Andric     integerPart HUerr, HUdistance;
29500b57cec5SDimitry Andric     unsigned int powHUerr;
29510b57cec5SDimitry Andric 
29520b57cec5SDimitry Andric     if (exp >= 0) {
29530b57cec5SDimitry Andric       /* multiplySignificand leaves the precision-th bit set to 1.  */
2954480093f4SDimitry Andric       calcLostFraction = decSig.multiplySignificand(pow5);
29550b57cec5SDimitry Andric       powHUerr = powStatus != opOK;
29560b57cec5SDimitry Andric     } else {
29570b57cec5SDimitry Andric       calcLostFraction = decSig.divideSignificand(pow5);
29580b57cec5SDimitry Andric       /* Denormal numbers have less precision.  */
29590b57cec5SDimitry Andric       if (decSig.exponent < semantics->minExponent) {
29600b57cec5SDimitry Andric         excessPrecision += (semantics->minExponent - decSig.exponent);
29610b57cec5SDimitry Andric         truncatedBits = excessPrecision;
29620b57cec5SDimitry Andric         if (excessPrecision > calcSemantics.precision)
29630b57cec5SDimitry Andric           excessPrecision = calcSemantics.precision;
29640b57cec5SDimitry Andric       }
29650b57cec5SDimitry Andric       /* Extra half-ulp lost in reciprocal of exponent.  */
29660b57cec5SDimitry Andric       powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0:2;
29670b57cec5SDimitry Andric     }
29680b57cec5SDimitry Andric 
29690b57cec5SDimitry Andric     /* Both multiplySignificand and divideSignificand return the
29700b57cec5SDimitry Andric        result with the integer bit set.  */
29710b57cec5SDimitry Andric     assert(APInt::tcExtractBit
29720b57cec5SDimitry Andric            (decSig.significandParts(), calcSemantics.precision - 1) == 1);
29730b57cec5SDimitry Andric 
29740b57cec5SDimitry Andric     HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus != opOK,
29750b57cec5SDimitry Andric                        powHUerr);
29760b57cec5SDimitry Andric     HUdistance = 2 * ulpsFromBoundary(decSig.significandParts(),
29770b57cec5SDimitry Andric                                       excessPrecision, isNearest);
29780b57cec5SDimitry Andric 
29790b57cec5SDimitry Andric     /* Are we guaranteed to round correctly if we truncate?  */
29800b57cec5SDimitry Andric     if (HUdistance >= HUerr) {
29810b57cec5SDimitry Andric       APInt::tcExtract(significandParts(), partCount(), decSig.significandParts(),
29820b57cec5SDimitry Andric                        calcSemantics.precision - excessPrecision,
29830b57cec5SDimitry Andric                        excessPrecision);
29840b57cec5SDimitry Andric       /* Take the exponent of decSig.  If we tcExtract-ed less bits
29850b57cec5SDimitry Andric          above we must adjust our exponent to compensate for the
29860b57cec5SDimitry Andric          implicit right shift.  */
29870b57cec5SDimitry Andric       exponent = (decSig.exponent + semantics->precision
29880b57cec5SDimitry Andric                   - (calcSemantics.precision - excessPrecision));
29890b57cec5SDimitry Andric       calcLostFraction = lostFractionThroughTruncation(decSig.significandParts(),
29900b57cec5SDimitry Andric                                                        decSig.partCount(),
29910b57cec5SDimitry Andric                                                        truncatedBits);
29920b57cec5SDimitry Andric       return normalize(rounding_mode, calcLostFraction);
29930b57cec5SDimitry Andric     }
29940b57cec5SDimitry Andric   }
29950b57cec5SDimitry Andric }
29960b57cec5SDimitry Andric 
2997480093f4SDimitry Andric Expected<IEEEFloat::opStatus>
convertFromDecimalString(StringRef str,roundingMode rounding_mode)29980b57cec5SDimitry Andric IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) {
29990b57cec5SDimitry Andric   decimalInfo D;
30000b57cec5SDimitry Andric   opStatus fs;
30010b57cec5SDimitry Andric 
30020b57cec5SDimitry Andric   /* Scan the text.  */
30030b57cec5SDimitry Andric   StringRef::iterator p = str.begin();
3004480093f4SDimitry Andric   if (Error Err = interpretDecimal(p, str.end(), &D))
3005480093f4SDimitry Andric     return std::move(Err);
30060b57cec5SDimitry Andric 
30070b57cec5SDimitry Andric   /* Handle the quick cases.  First the case of no significant digits,
30080b57cec5SDimitry Andric      i.e. zero, and then exponents that are obviously too large or too
30090b57cec5SDimitry Andric      small.  Writing L for log 10 / log 2, a number d.ddddd*10^exp
30100b57cec5SDimitry Andric      definitely overflows if
30110b57cec5SDimitry Andric 
30120b57cec5SDimitry Andric            (exp - 1) * L >= maxExponent
30130b57cec5SDimitry Andric 
30140b57cec5SDimitry Andric      and definitely underflows to zero where
30150b57cec5SDimitry Andric 
30160b57cec5SDimitry Andric            (exp + 1) * L <= minExponent - precision
30170b57cec5SDimitry Andric 
30180b57cec5SDimitry Andric      With integer arithmetic the tightest bounds for L are
30190b57cec5SDimitry Andric 
30200b57cec5SDimitry Andric            93/28 < L < 196/59            [ numerator <= 256 ]
30210b57cec5SDimitry Andric            42039/12655 < L < 28738/8651  [ numerator <= 65536 ]
30220b57cec5SDimitry Andric   */
30230b57cec5SDimitry Andric 
30240b57cec5SDimitry Andric   // Test if we have a zero number allowing for strings with no null terminators
30250b57cec5SDimitry Andric   // and zero decimals with non-zero exponents.
30260b57cec5SDimitry Andric   //
30270b57cec5SDimitry Andric   // We computed firstSigDigit by ignoring all zeros and dots. Thus if
30280b57cec5SDimitry Andric   // D->firstSigDigit equals str.end(), every digit must be a zero and there can
30290b57cec5SDimitry Andric   // be at most one dot. On the other hand, if we have a zero with a non-zero
30300b57cec5SDimitry Andric   // exponent, then we know that D.firstSigDigit will be non-numeric.
30310b57cec5SDimitry Andric   if (D.firstSigDigit == str.end() || decDigitValue(*D.firstSigDigit) >= 10U) {
30320b57cec5SDimitry Andric     category = fcZero;
30330b57cec5SDimitry Andric     fs = opOK;
3034fe013be4SDimitry Andric     if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
3035fe013be4SDimitry Andric       sign = false;
30360b57cec5SDimitry Andric 
30370b57cec5SDimitry Andric     /* Check whether the normalized exponent is high enough to overflow
30380b57cec5SDimitry Andric        max during the log-rebasing in the max-exponent check below. */
30390b57cec5SDimitry Andric   } else if (D.normalizedExponent - 1 > INT_MAX / 42039) {
30400b57cec5SDimitry Andric     fs = handleOverflow(rounding_mode);
30410b57cec5SDimitry Andric 
30420b57cec5SDimitry Andric   /* If it wasn't, then it also wasn't high enough to overflow max
30430b57cec5SDimitry Andric      during the log-rebasing in the min-exponent check.  Check that it
30440b57cec5SDimitry Andric      won't overflow min in either check, then perform the min-exponent
30450b57cec5SDimitry Andric      check. */
30460b57cec5SDimitry Andric   } else if (D.normalizedExponent - 1 < INT_MIN / 42039 ||
30470b57cec5SDimitry Andric              (D.normalizedExponent + 1) * 28738 <=
30480b57cec5SDimitry Andric                8651 * (semantics->minExponent - (int) semantics->precision)) {
30490b57cec5SDimitry Andric     /* Underflow to zero and round.  */
30500b57cec5SDimitry Andric     category = fcNormal;
30510b57cec5SDimitry Andric     zeroSignificand();
30520b57cec5SDimitry Andric     fs = normalize(rounding_mode, lfLessThanHalf);
30530b57cec5SDimitry Andric 
30540b57cec5SDimitry Andric   /* We can finally safely perform the max-exponent check. */
30550b57cec5SDimitry Andric   } else if ((D.normalizedExponent - 1) * 42039
30560b57cec5SDimitry Andric              >= 12655 * semantics->maxExponent) {
30570b57cec5SDimitry Andric     /* Overflow and round.  */
30580b57cec5SDimitry Andric     fs = handleOverflow(rounding_mode);
30590b57cec5SDimitry Andric   } else {
30600b57cec5SDimitry Andric     integerPart *decSignificand;
30610b57cec5SDimitry Andric     unsigned int partCount;
30620b57cec5SDimitry Andric 
30630b57cec5SDimitry Andric     /* A tight upper bound on number of bits required to hold an
30640b57cec5SDimitry Andric        N-digit decimal integer is N * 196 / 59.  Allocate enough space
30650b57cec5SDimitry Andric        to hold the full significand, and an extra part required by
30660b57cec5SDimitry Andric        tcMultiplyPart.  */
30670b57cec5SDimitry Andric     partCount = static_cast<unsigned int>(D.lastSigDigit - D.firstSigDigit) + 1;
30680b57cec5SDimitry Andric     partCount = partCountForBits(1 + 196 * partCount / 59);
30690b57cec5SDimitry Andric     decSignificand = new integerPart[partCount + 1];
30700b57cec5SDimitry Andric     partCount = 0;
30710b57cec5SDimitry Andric 
30720b57cec5SDimitry Andric     /* Convert to binary efficiently - we do almost all multiplication
30730b57cec5SDimitry Andric        in an integerPart.  When this would overflow do we do a single
30740b57cec5SDimitry Andric        bignum multiplication, and then revert again to multiplication
30750b57cec5SDimitry Andric        in an integerPart.  */
30760b57cec5SDimitry Andric     do {
30770b57cec5SDimitry Andric       integerPart decValue, val, multiplier;
30780b57cec5SDimitry Andric 
30790b57cec5SDimitry Andric       val = 0;
30800b57cec5SDimitry Andric       multiplier = 1;
30810b57cec5SDimitry Andric 
30820b57cec5SDimitry Andric       do {
30830b57cec5SDimitry Andric         if (*p == '.') {
30840b57cec5SDimitry Andric           p++;
30850b57cec5SDimitry Andric           if (p == str.end()) {
30860b57cec5SDimitry Andric             break;
30870b57cec5SDimitry Andric           }
30880b57cec5SDimitry Andric         }
30890b57cec5SDimitry Andric         decValue = decDigitValue(*p++);
3090480093f4SDimitry Andric         if (decValue >= 10U) {
3091480093f4SDimitry Andric           delete[] decSignificand;
3092480093f4SDimitry Andric           return createError("Invalid character in significand");
3093480093f4SDimitry Andric         }
30940b57cec5SDimitry Andric         multiplier *= 10;
30950b57cec5SDimitry Andric         val = val * 10 + decValue;
30960b57cec5SDimitry Andric         /* The maximum number that can be multiplied by ten with any
30970b57cec5SDimitry Andric            digit added without overflowing an integerPart.  */
30980b57cec5SDimitry Andric       } while (p <= D.lastSigDigit && multiplier <= (~ (integerPart) 0 - 9) / 10);
30990b57cec5SDimitry Andric 
31000b57cec5SDimitry Andric       /* Multiply out the current part.  */
31010b57cec5SDimitry Andric       APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val,
31020b57cec5SDimitry Andric                             partCount, partCount + 1, false);
31030b57cec5SDimitry Andric 
31040b57cec5SDimitry Andric       /* If we used another part (likely but not guaranteed), increase
31050b57cec5SDimitry Andric          the count.  */
31060b57cec5SDimitry Andric       if (decSignificand[partCount])
31070b57cec5SDimitry Andric         partCount++;
31080b57cec5SDimitry Andric     } while (p <= D.lastSigDigit);
31090b57cec5SDimitry Andric 
31100b57cec5SDimitry Andric     category = fcNormal;
31110b57cec5SDimitry Andric     fs = roundSignificandWithExponent(decSignificand, partCount,
31120b57cec5SDimitry Andric                                       D.exponent, rounding_mode);
31130b57cec5SDimitry Andric 
31140b57cec5SDimitry Andric     delete [] decSignificand;
31150b57cec5SDimitry Andric   }
31160b57cec5SDimitry Andric 
31170b57cec5SDimitry Andric   return fs;
31180b57cec5SDimitry Andric }
31190b57cec5SDimitry Andric 
convertFromStringSpecials(StringRef str)31200b57cec5SDimitry Andric bool IEEEFloat::convertFromStringSpecials(StringRef str) {
31215ffd83dbSDimitry Andric   const size_t MIN_NAME_SIZE = 3;
31225ffd83dbSDimitry Andric 
31235ffd83dbSDimitry Andric   if (str.size() < MIN_NAME_SIZE)
31245ffd83dbSDimitry Andric     return false;
31255ffd83dbSDimitry Andric 
31260b57cec5SDimitry Andric   if (str.equals("inf") || str.equals("INFINITY") || str.equals("+Inf")) {
31270b57cec5SDimitry Andric     makeInf(false);
31280b57cec5SDimitry Andric     return true;
31290b57cec5SDimitry Andric   }
31300b57cec5SDimitry Andric 
31315ffd83dbSDimitry Andric   bool IsNegative = str.front() == '-';
31325ffd83dbSDimitry Andric   if (IsNegative) {
31335ffd83dbSDimitry Andric     str = str.drop_front();
31345ffd83dbSDimitry Andric     if (str.size() < MIN_NAME_SIZE)
31355ffd83dbSDimitry Andric       return false;
31365ffd83dbSDimitry Andric 
31375ffd83dbSDimitry Andric     if (str.equals("inf") || str.equals("INFINITY") || str.equals("Inf")) {
31380b57cec5SDimitry Andric       makeInf(true);
31390b57cec5SDimitry Andric       return true;
31400b57cec5SDimitry Andric     }
31415ffd83dbSDimitry Andric   }
31420b57cec5SDimitry Andric 
31435ffd83dbSDimitry Andric   // If we have a 's' (or 'S') prefix, then this is a Signaling NaN.
31445ffd83dbSDimitry Andric   bool IsSignaling = str.front() == 's' || str.front() == 'S';
31455ffd83dbSDimitry Andric   if (IsSignaling) {
31465ffd83dbSDimitry Andric     str = str.drop_front();
31475ffd83dbSDimitry Andric     if (str.size() < MIN_NAME_SIZE)
31485ffd83dbSDimitry Andric       return false;
31495ffd83dbSDimitry Andric   }
31505ffd83dbSDimitry Andric 
3151*c9157d92SDimitry Andric   if (str.starts_with("nan") || str.starts_with("NaN")) {
31525ffd83dbSDimitry Andric     str = str.drop_front(3);
31535ffd83dbSDimitry Andric 
31545ffd83dbSDimitry Andric     // A NaN without payload.
31555ffd83dbSDimitry Andric     if (str.empty()) {
31565ffd83dbSDimitry Andric       makeNaN(IsSignaling, IsNegative);
31570b57cec5SDimitry Andric       return true;
31580b57cec5SDimitry Andric     }
31590b57cec5SDimitry Andric 
31605ffd83dbSDimitry Andric     // Allow the payload to be inside parentheses.
31615ffd83dbSDimitry Andric     if (str.front() == '(') {
31625ffd83dbSDimitry Andric       // Parentheses should be balanced (and not empty).
31635ffd83dbSDimitry Andric       if (str.size() <= 2 || str.back() != ')')
31645ffd83dbSDimitry Andric         return false;
31655ffd83dbSDimitry Andric 
31665ffd83dbSDimitry Andric       str = str.slice(1, str.size() - 1);
31675ffd83dbSDimitry Andric     }
31685ffd83dbSDimitry Andric 
31695ffd83dbSDimitry Andric     // Determine the payload number's radix.
31705ffd83dbSDimitry Andric     unsigned Radix = 10;
31715ffd83dbSDimitry Andric     if (str[0] == '0') {
31725ffd83dbSDimitry Andric       if (str.size() > 1 && tolower(str[1]) == 'x') {
31735ffd83dbSDimitry Andric         str = str.drop_front(2);
31745ffd83dbSDimitry Andric         Radix = 16;
31755ffd83dbSDimitry Andric       } else
31765ffd83dbSDimitry Andric         Radix = 8;
31775ffd83dbSDimitry Andric     }
31785ffd83dbSDimitry Andric 
31795ffd83dbSDimitry Andric     // Parse the payload and make the NaN.
31805ffd83dbSDimitry Andric     APInt Payload;
31815ffd83dbSDimitry Andric     if (!str.getAsInteger(Radix, Payload)) {
31825ffd83dbSDimitry Andric       makeNaN(IsSignaling, IsNegative, &Payload);
31830b57cec5SDimitry Andric       return true;
31840b57cec5SDimitry Andric     }
31855ffd83dbSDimitry Andric   }
31860b57cec5SDimitry Andric 
31870b57cec5SDimitry Andric   return false;
31880b57cec5SDimitry Andric }
31890b57cec5SDimitry Andric 
3190480093f4SDimitry Andric Expected<IEEEFloat::opStatus>
convertFromString(StringRef str,roundingMode rounding_mode)3191480093f4SDimitry Andric IEEEFloat::convertFromString(StringRef str, roundingMode rounding_mode) {
3192480093f4SDimitry Andric   if (str.empty())
3193480093f4SDimitry Andric     return createError("Invalid string length");
31940b57cec5SDimitry Andric 
31950b57cec5SDimitry Andric   // Handle special cases.
31960b57cec5SDimitry Andric   if (convertFromStringSpecials(str))
31970b57cec5SDimitry Andric     return opOK;
31980b57cec5SDimitry Andric 
31990b57cec5SDimitry Andric   /* Handle a leading minus sign.  */
32000b57cec5SDimitry Andric   StringRef::iterator p = str.begin();
32010b57cec5SDimitry Andric   size_t slen = str.size();
32020b57cec5SDimitry Andric   sign = *p == '-' ? 1 : 0;
32030b57cec5SDimitry Andric   if (*p == '-' || *p == '+') {
32040b57cec5SDimitry Andric     p++;
32050b57cec5SDimitry Andric     slen--;
3206480093f4SDimitry Andric     if (!slen)
3207480093f4SDimitry Andric       return createError("String has no digits");
32080b57cec5SDimitry Andric   }
32090b57cec5SDimitry Andric 
32100b57cec5SDimitry Andric   if (slen >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
3211480093f4SDimitry Andric     if (slen == 2)
3212480093f4SDimitry Andric       return createError("Invalid string");
32130b57cec5SDimitry Andric     return convertFromHexadecimalString(StringRef(p + 2, slen - 2),
32140b57cec5SDimitry Andric                                         rounding_mode);
32150b57cec5SDimitry Andric   }
32160b57cec5SDimitry Andric 
32170b57cec5SDimitry Andric   return convertFromDecimalString(StringRef(p, slen), rounding_mode);
32180b57cec5SDimitry Andric }
32190b57cec5SDimitry Andric 
32200b57cec5SDimitry Andric /* Write out a hexadecimal representation of the floating point value
32210b57cec5SDimitry Andric    to DST, which must be of sufficient size, in the C99 form
32220b57cec5SDimitry Andric    [-]0xh.hhhhp[+-]d.  Return the number of characters written,
32230b57cec5SDimitry Andric    excluding the terminating NUL.
32240b57cec5SDimitry Andric 
32250b57cec5SDimitry Andric    If UPPERCASE, the output is in upper case, otherwise in lower case.
32260b57cec5SDimitry Andric 
32270b57cec5SDimitry Andric    HEXDIGITS digits appear altogether, rounding the value if
32280b57cec5SDimitry Andric    necessary.  If HEXDIGITS is 0, the minimal precision to display the
32290b57cec5SDimitry Andric    number precisely is used instead.  If nothing would appear after
32300b57cec5SDimitry Andric    the decimal point it is suppressed.
32310b57cec5SDimitry Andric 
32320b57cec5SDimitry Andric    The decimal exponent is always printed and has at least one digit.
32330b57cec5SDimitry Andric    Zero values display an exponent of zero.  Infinities and NaNs
32340b57cec5SDimitry Andric    appear as "infinity" or "nan" respectively.
32350b57cec5SDimitry Andric 
32360b57cec5SDimitry Andric    The above rules are as specified by C99.  There is ambiguity about
32370b57cec5SDimitry Andric    what the leading hexadecimal digit should be.  This implementation
32380b57cec5SDimitry Andric    uses whatever is necessary so that the exponent is displayed as
32390b57cec5SDimitry Andric    stored.  This implies the exponent will fall within the IEEE format
32400b57cec5SDimitry Andric    range, and the leading hexadecimal digit will be 0 (for denormals),
32410b57cec5SDimitry Andric    1 (normal numbers) or 2 (normal numbers rounded-away-from-zero with
32420b57cec5SDimitry Andric    any other digits zero).
32430b57cec5SDimitry Andric */
convertToHexString(char * dst,unsigned int hexDigits,bool upperCase,roundingMode rounding_mode) const32440b57cec5SDimitry Andric unsigned int IEEEFloat::convertToHexString(char *dst, unsigned int hexDigits,
32450b57cec5SDimitry Andric                                            bool upperCase,
32460b57cec5SDimitry Andric                                            roundingMode rounding_mode) const {
32470b57cec5SDimitry Andric   char *p;
32480b57cec5SDimitry Andric 
32490b57cec5SDimitry Andric   p = dst;
32500b57cec5SDimitry Andric   if (sign)
32510b57cec5SDimitry Andric     *dst++ = '-';
32520b57cec5SDimitry Andric 
32530b57cec5SDimitry Andric   switch (category) {
32540b57cec5SDimitry Andric   case fcInfinity:
32550b57cec5SDimitry Andric     memcpy (dst, upperCase ? infinityU: infinityL, sizeof infinityU - 1);
32560b57cec5SDimitry Andric     dst += sizeof infinityL - 1;
32570b57cec5SDimitry Andric     break;
32580b57cec5SDimitry Andric 
32590b57cec5SDimitry Andric   case fcNaN:
32600b57cec5SDimitry Andric     memcpy (dst, upperCase ? NaNU: NaNL, sizeof NaNU - 1);
32610b57cec5SDimitry Andric     dst += sizeof NaNU - 1;
32620b57cec5SDimitry Andric     break;
32630b57cec5SDimitry Andric 
32640b57cec5SDimitry Andric   case fcZero:
32650b57cec5SDimitry Andric     *dst++ = '0';
32660b57cec5SDimitry Andric     *dst++ = upperCase ? 'X': 'x';
32670b57cec5SDimitry Andric     *dst++ = '0';
32680b57cec5SDimitry Andric     if (hexDigits > 1) {
32690b57cec5SDimitry Andric       *dst++ = '.';
32700b57cec5SDimitry Andric       memset (dst, '0', hexDigits - 1);
32710b57cec5SDimitry Andric       dst += hexDigits - 1;
32720b57cec5SDimitry Andric     }
32730b57cec5SDimitry Andric     *dst++ = upperCase ? 'P': 'p';
32740b57cec5SDimitry Andric     *dst++ = '0';
32750b57cec5SDimitry Andric     break;
32760b57cec5SDimitry Andric 
32770b57cec5SDimitry Andric   case fcNormal:
32780b57cec5SDimitry Andric     dst = convertNormalToHexString (dst, hexDigits, upperCase, rounding_mode);
32790b57cec5SDimitry Andric     break;
32800b57cec5SDimitry Andric   }
32810b57cec5SDimitry Andric 
32820b57cec5SDimitry Andric   *dst = 0;
32830b57cec5SDimitry Andric 
32840b57cec5SDimitry Andric   return static_cast<unsigned int>(dst - p);
32850b57cec5SDimitry Andric }
32860b57cec5SDimitry Andric 
32870b57cec5SDimitry Andric /* Does the hard work of outputting the correctly rounded hexadecimal
32880b57cec5SDimitry Andric    form of a normal floating point number with the specified number of
32890b57cec5SDimitry Andric    hexadecimal digits.  If HEXDIGITS is zero the minimum number of
32900b57cec5SDimitry Andric    digits necessary to print the value precisely is output.  */
convertNormalToHexString(char * dst,unsigned int hexDigits,bool upperCase,roundingMode rounding_mode) const32910b57cec5SDimitry Andric char *IEEEFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
32920b57cec5SDimitry Andric                                           bool upperCase,
32930b57cec5SDimitry Andric                                           roundingMode rounding_mode) const {
32940b57cec5SDimitry Andric   unsigned int count, valueBits, shift, partsCount, outputDigits;
32950b57cec5SDimitry Andric   const char *hexDigitChars;
32960b57cec5SDimitry Andric   const integerPart *significand;
32970b57cec5SDimitry Andric   char *p;
32980b57cec5SDimitry Andric   bool roundUp;
32990b57cec5SDimitry Andric 
33000b57cec5SDimitry Andric   *dst++ = '0';
33010b57cec5SDimitry Andric   *dst++ = upperCase ? 'X': 'x';
33020b57cec5SDimitry Andric 
33030b57cec5SDimitry Andric   roundUp = false;
33040b57cec5SDimitry Andric   hexDigitChars = upperCase ? hexDigitsUpper: hexDigitsLower;
33050b57cec5SDimitry Andric 
33060b57cec5SDimitry Andric   significand = significandParts();
33070b57cec5SDimitry Andric   partsCount = partCount();
33080b57cec5SDimitry Andric 
33090b57cec5SDimitry Andric   /* +3 because the first digit only uses the single integer bit, so
33100b57cec5SDimitry Andric      we have 3 virtual zero most-significant-bits.  */
33110b57cec5SDimitry Andric   valueBits = semantics->precision + 3;
33120b57cec5SDimitry Andric   shift = integerPartWidth - valueBits % integerPartWidth;
33130b57cec5SDimitry Andric 
33140b57cec5SDimitry Andric   /* The natural number of digits required ignoring trailing
33150b57cec5SDimitry Andric      insignificant zeroes.  */
33160b57cec5SDimitry Andric   outputDigits = (valueBits - significandLSB () + 3) / 4;
33170b57cec5SDimitry Andric 
33180b57cec5SDimitry Andric   /* hexDigits of zero means use the required number for the
33190b57cec5SDimitry Andric      precision.  Otherwise, see if we are truncating.  If we are,
33200b57cec5SDimitry Andric      find out if we need to round away from zero.  */
33210b57cec5SDimitry Andric   if (hexDigits) {
33220b57cec5SDimitry Andric     if (hexDigits < outputDigits) {
33230b57cec5SDimitry Andric       /* We are dropping non-zero bits, so need to check how to round.
33240b57cec5SDimitry Andric          "bits" is the number of dropped bits.  */
33250b57cec5SDimitry Andric       unsigned int bits;
33260b57cec5SDimitry Andric       lostFraction fraction;
33270b57cec5SDimitry Andric 
33280b57cec5SDimitry Andric       bits = valueBits - hexDigits * 4;
33290b57cec5SDimitry Andric       fraction = lostFractionThroughTruncation (significand, partsCount, bits);
33300b57cec5SDimitry Andric       roundUp = roundAwayFromZero(rounding_mode, fraction, bits);
33310b57cec5SDimitry Andric     }
33320b57cec5SDimitry Andric     outputDigits = hexDigits;
33330b57cec5SDimitry Andric   }
33340b57cec5SDimitry Andric 
33350b57cec5SDimitry Andric   /* Write the digits consecutively, and start writing in the location
33360b57cec5SDimitry Andric      of the hexadecimal point.  We move the most significant digit
33370b57cec5SDimitry Andric      left and add the hexadecimal point later.  */
33380b57cec5SDimitry Andric   p = ++dst;
33390b57cec5SDimitry Andric 
33400b57cec5SDimitry Andric   count = (valueBits + integerPartWidth - 1) / integerPartWidth;
33410b57cec5SDimitry Andric 
33420b57cec5SDimitry Andric   while (outputDigits && count) {
33430b57cec5SDimitry Andric     integerPart part;
33440b57cec5SDimitry Andric 
33450b57cec5SDimitry Andric     /* Put the most significant integerPartWidth bits in "part".  */
33460b57cec5SDimitry Andric     if (--count == partsCount)
33470b57cec5SDimitry Andric       part = 0;  /* An imaginary higher zero part.  */
33480b57cec5SDimitry Andric     else
33490b57cec5SDimitry Andric       part = significand[count] << shift;
33500b57cec5SDimitry Andric 
33510b57cec5SDimitry Andric     if (count && shift)
33520b57cec5SDimitry Andric       part |= significand[count - 1] >> (integerPartWidth - shift);
33530b57cec5SDimitry Andric 
33540b57cec5SDimitry Andric     /* Convert as much of "part" to hexdigits as we can.  */
33550b57cec5SDimitry Andric     unsigned int curDigits = integerPartWidth / 4;
33560b57cec5SDimitry Andric 
33570b57cec5SDimitry Andric     if (curDigits > outputDigits)
33580b57cec5SDimitry Andric       curDigits = outputDigits;
33590b57cec5SDimitry Andric     dst += partAsHex (dst, part, curDigits, hexDigitChars);
33600b57cec5SDimitry Andric     outputDigits -= curDigits;
33610b57cec5SDimitry Andric   }
33620b57cec5SDimitry Andric 
33630b57cec5SDimitry Andric   if (roundUp) {
33640b57cec5SDimitry Andric     char *q = dst;
33650b57cec5SDimitry Andric 
33660b57cec5SDimitry Andric     /* Note that hexDigitChars has a trailing '0'.  */
33670b57cec5SDimitry Andric     do {
33680b57cec5SDimitry Andric       q--;
33690b57cec5SDimitry Andric       *q = hexDigitChars[hexDigitValue (*q) + 1];
33700b57cec5SDimitry Andric     } while (*q == '0');
33710b57cec5SDimitry Andric     assert(q >= p);
33720b57cec5SDimitry Andric   } else {
33730b57cec5SDimitry Andric     /* Add trailing zeroes.  */
33740b57cec5SDimitry Andric     memset (dst, '0', outputDigits);
33750b57cec5SDimitry Andric     dst += outputDigits;
33760b57cec5SDimitry Andric   }
33770b57cec5SDimitry Andric 
33780b57cec5SDimitry Andric   /* Move the most significant digit to before the point, and if there
33790b57cec5SDimitry Andric      is something after the decimal point add it.  This must come
33800b57cec5SDimitry Andric      after rounding above.  */
33810b57cec5SDimitry Andric   p[-1] = p[0];
33820b57cec5SDimitry Andric   if (dst -1 == p)
33830b57cec5SDimitry Andric     dst--;
33840b57cec5SDimitry Andric   else
33850b57cec5SDimitry Andric     p[0] = '.';
33860b57cec5SDimitry Andric 
33870b57cec5SDimitry Andric   /* Finally output the exponent.  */
33880b57cec5SDimitry Andric   *dst++ = upperCase ? 'P': 'p';
33890b57cec5SDimitry Andric 
33900b57cec5SDimitry Andric   return writeSignedDecimal (dst, exponent);
33910b57cec5SDimitry Andric }
33920b57cec5SDimitry Andric 
hash_value(const IEEEFloat & Arg)33930b57cec5SDimitry Andric hash_code hash_value(const IEEEFloat &Arg) {
33940b57cec5SDimitry Andric   if (!Arg.isFiniteNonZero())
33950b57cec5SDimitry Andric     return hash_combine((uint8_t)Arg.category,
33960b57cec5SDimitry Andric                         // NaN has no sign, fix it at zero.
33970b57cec5SDimitry Andric                         Arg.isNaN() ? (uint8_t)0 : (uint8_t)Arg.sign,
33980b57cec5SDimitry Andric                         Arg.semantics->precision);
33990b57cec5SDimitry Andric 
34000b57cec5SDimitry Andric   // Normal floats need their exponent and significand hashed.
34010b57cec5SDimitry Andric   return hash_combine((uint8_t)Arg.category, (uint8_t)Arg.sign,
34020b57cec5SDimitry Andric                       Arg.semantics->precision, Arg.exponent,
34030b57cec5SDimitry Andric                       hash_combine_range(
34040b57cec5SDimitry Andric                         Arg.significandParts(),
34050b57cec5SDimitry Andric                         Arg.significandParts() + Arg.partCount()));
34060b57cec5SDimitry Andric }
34070b57cec5SDimitry Andric 
34080b57cec5SDimitry Andric // Conversion from APFloat to/from host float/double.  It may eventually be
34090b57cec5SDimitry Andric // possible to eliminate these and have everybody deal with APFloats, but that
34100b57cec5SDimitry Andric // will take a while.  This approach will not easily extend to long double.
34110b57cec5SDimitry Andric // Current implementation requires integerPartWidth==64, which is correct at
34120b57cec5SDimitry Andric // the moment but could be made more general.
34130b57cec5SDimitry Andric 
34140b57cec5SDimitry Andric // Denormals have exponent minExponent in APFloat, but minExponent-1 in
34150b57cec5SDimitry Andric // the actual IEEE respresentations.  We compensate for that here.
34160b57cec5SDimitry Andric 
convertF80LongDoubleAPFloatToAPInt() const34170b57cec5SDimitry Andric APInt IEEEFloat::convertF80LongDoubleAPFloatToAPInt() const {
34180b57cec5SDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended);
34190b57cec5SDimitry Andric   assert(partCount()==2);
34200b57cec5SDimitry Andric 
34210b57cec5SDimitry Andric   uint64_t myexponent, mysignificand;
34220b57cec5SDimitry Andric 
34230b57cec5SDimitry Andric   if (isFiniteNonZero()) {
34240b57cec5SDimitry Andric     myexponent = exponent+16383; //bias
34250b57cec5SDimitry Andric     mysignificand = significandParts()[0];
34260b57cec5SDimitry Andric     if (myexponent==1 && !(mysignificand & 0x8000000000000000ULL))
34270b57cec5SDimitry Andric       myexponent = 0;   // denormal
34280b57cec5SDimitry Andric   } else if (category==fcZero) {
34290b57cec5SDimitry Andric     myexponent = 0;
34300b57cec5SDimitry Andric     mysignificand = 0;
34310b57cec5SDimitry Andric   } else if (category==fcInfinity) {
34320b57cec5SDimitry Andric     myexponent = 0x7fff;
34330b57cec5SDimitry Andric     mysignificand = 0x8000000000000000ULL;
34340b57cec5SDimitry Andric   } else {
34350b57cec5SDimitry Andric     assert(category == fcNaN && "Unknown category");
34360b57cec5SDimitry Andric     myexponent = 0x7fff;
34370b57cec5SDimitry Andric     mysignificand = significandParts()[0];
34380b57cec5SDimitry Andric   }
34390b57cec5SDimitry Andric 
34400b57cec5SDimitry Andric   uint64_t words[2];
34410b57cec5SDimitry Andric   words[0] = mysignificand;
34420b57cec5SDimitry Andric   words[1] =  ((uint64_t)(sign & 1) << 15) |
34430b57cec5SDimitry Andric               (myexponent & 0x7fffLL);
34440b57cec5SDimitry Andric   return APInt(80, words);
34450b57cec5SDimitry Andric }
34460b57cec5SDimitry Andric 
convertPPCDoubleDoubleAPFloatToAPInt() const34470b57cec5SDimitry Andric APInt IEEEFloat::convertPPCDoubleDoubleAPFloatToAPInt() const {
34480b57cec5SDimitry Andric   assert(semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy);
34490b57cec5SDimitry Andric   assert(partCount()==2);
34500b57cec5SDimitry Andric 
34510b57cec5SDimitry Andric   uint64_t words[2];
34520b57cec5SDimitry Andric   opStatus fs;
34530b57cec5SDimitry Andric   bool losesInfo;
34540b57cec5SDimitry Andric 
34550b57cec5SDimitry Andric   // Convert number to double.  To avoid spurious underflows, we re-
34560b57cec5SDimitry Andric   // normalize against the "double" minExponent first, and only *then*
34570b57cec5SDimitry Andric   // truncate the mantissa.  The result of that second conversion
34580b57cec5SDimitry Andric   // may be inexact, but should never underflow.
34590b57cec5SDimitry Andric   // Declare fltSemantics before APFloat that uses it (and
34600b57cec5SDimitry Andric   // saves pointer to it) to ensure correct destruction order.
34610b57cec5SDimitry Andric   fltSemantics extendedSemantics = *semantics;
34620b57cec5SDimitry Andric   extendedSemantics.minExponent = semIEEEdouble.minExponent;
34630b57cec5SDimitry Andric   IEEEFloat extended(*this);
34640b57cec5SDimitry Andric   fs = extended.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
34650b57cec5SDimitry Andric   assert(fs == opOK && !losesInfo);
34660b57cec5SDimitry Andric   (void)fs;
34670b57cec5SDimitry Andric 
34680b57cec5SDimitry Andric   IEEEFloat u(extended);
34690b57cec5SDimitry Andric   fs = u.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo);
34700b57cec5SDimitry Andric   assert(fs == opOK || fs == opInexact);
34710b57cec5SDimitry Andric   (void)fs;
34720b57cec5SDimitry Andric   words[0] = *u.convertDoubleAPFloatToAPInt().getRawData();
34730b57cec5SDimitry Andric 
34740b57cec5SDimitry Andric   // If conversion was exact or resulted in a special case, we're done;
34750b57cec5SDimitry Andric   // just set the second double to zero.  Otherwise, re-convert back to
34760b57cec5SDimitry Andric   // the extended format and compute the difference.  This now should
34770b57cec5SDimitry Andric   // convert exactly to double.
34780b57cec5SDimitry Andric   if (u.isFiniteNonZero() && losesInfo) {
34790b57cec5SDimitry Andric     fs = u.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
34800b57cec5SDimitry Andric     assert(fs == opOK && !losesInfo);
34810b57cec5SDimitry Andric     (void)fs;
34820b57cec5SDimitry Andric 
34830b57cec5SDimitry Andric     IEEEFloat v(extended);
34840b57cec5SDimitry Andric     v.subtract(u, rmNearestTiesToEven);
34850b57cec5SDimitry Andric     fs = v.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo);
34860b57cec5SDimitry Andric     assert(fs == opOK && !losesInfo);
34870b57cec5SDimitry Andric     (void)fs;
34880b57cec5SDimitry Andric     words[1] = *v.convertDoubleAPFloatToAPInt().getRawData();
34890b57cec5SDimitry Andric   } else {
34900b57cec5SDimitry Andric     words[1] = 0;
34910b57cec5SDimitry Andric   }
34920b57cec5SDimitry Andric 
34930b57cec5SDimitry Andric   return APInt(128, words);
34940b57cec5SDimitry Andric }
34950b57cec5SDimitry Andric 
3496fe013be4SDimitry Andric template <const fltSemantics &S>
convertIEEEFloatToAPInt() const3497fe013be4SDimitry Andric APInt IEEEFloat::convertIEEEFloatToAPInt() const {
3498fe013be4SDimitry Andric   assert(semantics == &S);
34990b57cec5SDimitry Andric 
3500fe013be4SDimitry Andric   constexpr int bias = -(S.minExponent - 1);
3501fe013be4SDimitry Andric   constexpr unsigned int trailing_significand_bits = S.precision - 1;
3502fe013be4SDimitry Andric   constexpr int integer_bit_part = trailing_significand_bits / integerPartWidth;
3503fe013be4SDimitry Andric   constexpr integerPart integer_bit =
3504fe013be4SDimitry Andric       integerPart{1} << (trailing_significand_bits % integerPartWidth);
3505fe013be4SDimitry Andric   constexpr uint64_t significand_mask = integer_bit - 1;
3506fe013be4SDimitry Andric   constexpr unsigned int exponent_bits =
3507fe013be4SDimitry Andric       S.sizeInBits - 1 - trailing_significand_bits;
3508fe013be4SDimitry Andric   static_assert(exponent_bits < 64);
3509fe013be4SDimitry Andric   constexpr uint64_t exponent_mask = (uint64_t{1} << exponent_bits) - 1;
3510fe013be4SDimitry Andric 
3511fe013be4SDimitry Andric   uint64_t myexponent;
3512fe013be4SDimitry Andric   std::array<integerPart, partCountForBits(trailing_significand_bits)>
3513fe013be4SDimitry Andric       mysignificand;
35140b57cec5SDimitry Andric 
35150b57cec5SDimitry Andric   if (isFiniteNonZero()) {
3516fe013be4SDimitry Andric     myexponent = exponent + bias;
3517fe013be4SDimitry Andric     std::copy_n(significandParts(), mysignificand.size(),
3518fe013be4SDimitry Andric                 mysignificand.begin());
3519fe013be4SDimitry Andric     if (myexponent == 1 &&
3520fe013be4SDimitry Andric         !(significandParts()[integer_bit_part] & integer_bit))
35210b57cec5SDimitry Andric       myexponent = 0; // denormal
35220b57cec5SDimitry Andric   } else if (category == fcZero) {
3523fe013be4SDimitry Andric     myexponent = ::exponentZero(S) + bias;
3524fe013be4SDimitry Andric     mysignificand.fill(0);
35250b57cec5SDimitry Andric   } else if (category == fcInfinity) {
3526fe013be4SDimitry Andric     if (S.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
3527fe013be4SDimitry Andric       llvm_unreachable("semantics don't support inf!");
3528fe013be4SDimitry Andric     }
3529fe013be4SDimitry Andric     myexponent = ::exponentInf(S) + bias;
3530fe013be4SDimitry Andric     mysignificand.fill(0);
35310b57cec5SDimitry Andric   } else {
35320b57cec5SDimitry Andric     assert(category == fcNaN && "Unknown category!");
3533fe013be4SDimitry Andric     myexponent = ::exponentNaN(S) + bias;
3534fe013be4SDimitry Andric     std::copy_n(significandParts(), mysignificand.size(),
3535fe013be4SDimitry Andric                 mysignificand.begin());
3536fe013be4SDimitry Andric   }
3537fe013be4SDimitry Andric   std::array<uint64_t, (S.sizeInBits + 63) / 64> words;
3538fe013be4SDimitry Andric   auto words_iter =
3539fe013be4SDimitry Andric       std::copy_n(mysignificand.begin(), mysignificand.size(), words.begin());
3540fe013be4SDimitry Andric   if constexpr (significand_mask != 0) {
3541fe013be4SDimitry Andric     // Clear the integer bit.
3542fe013be4SDimitry Andric     words[mysignificand.size() - 1] &= significand_mask;
3543fe013be4SDimitry Andric   }
3544fe013be4SDimitry Andric   std::fill(words_iter, words.end(), uint64_t{0});
3545fe013be4SDimitry Andric   constexpr size_t last_word = words.size() - 1;
3546fe013be4SDimitry Andric   uint64_t shifted_sign = static_cast<uint64_t>(sign & 1)
3547fe013be4SDimitry Andric                           << ((S.sizeInBits - 1) % 64);
3548fe013be4SDimitry Andric   words[last_word] |= shifted_sign;
3549fe013be4SDimitry Andric   uint64_t shifted_exponent = (myexponent & exponent_mask)
3550fe013be4SDimitry Andric                               << (trailing_significand_bits % 64);
3551fe013be4SDimitry Andric   words[last_word] |= shifted_exponent;
3552fe013be4SDimitry Andric   if constexpr (last_word == 0) {
3553fe013be4SDimitry Andric     return APInt(S.sizeInBits, words[0]);
3554fe013be4SDimitry Andric   }
3555fe013be4SDimitry Andric   return APInt(S.sizeInBits, words);
35560b57cec5SDimitry Andric }
35570b57cec5SDimitry Andric 
convertQuadrupleAPFloatToAPInt() const3558fe013be4SDimitry Andric APInt IEEEFloat::convertQuadrupleAPFloatToAPInt() const {
3559fe013be4SDimitry Andric   assert(partCount() == 2);
3560fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semIEEEquad>();
35610b57cec5SDimitry Andric }
35620b57cec5SDimitry Andric 
convertDoubleAPFloatToAPInt() const35630b57cec5SDimitry Andric APInt IEEEFloat::convertDoubleAPFloatToAPInt() const {
35640b57cec5SDimitry Andric   assert(partCount()==1);
3565fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semIEEEdouble>();
35660b57cec5SDimitry Andric }
35670b57cec5SDimitry Andric 
convertFloatAPFloatToAPInt() const35680b57cec5SDimitry Andric APInt IEEEFloat::convertFloatAPFloatToAPInt() const {
35690b57cec5SDimitry Andric   assert(partCount()==1);
3570fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semIEEEsingle>();
35710b57cec5SDimitry Andric }
35720b57cec5SDimitry Andric 
convertBFloatAPFloatToAPInt() const35735ffd83dbSDimitry Andric APInt IEEEFloat::convertBFloatAPFloatToAPInt() const {
35745ffd83dbSDimitry Andric   assert(partCount() == 1);
3575fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semBFloat>();
35765ffd83dbSDimitry Andric }
35775ffd83dbSDimitry Andric 
convertHalfAPFloatToAPInt() const35780b57cec5SDimitry Andric APInt IEEEFloat::convertHalfAPFloatToAPInt() const {
35790b57cec5SDimitry Andric   assert(partCount()==1);
3580fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semIEEEhalf>();
35810b57cec5SDimitry Andric }
35820b57cec5SDimitry Andric 
convertFloat8E5M2APFloatToAPInt() const3583bdd1243dSDimitry Andric APInt IEEEFloat::convertFloat8E5M2APFloatToAPInt() const {
3584bdd1243dSDimitry Andric   assert(partCount() == 1);
3585fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semFloat8E5M2>();
3586bdd1243dSDimitry Andric }
3587bdd1243dSDimitry Andric 
convertFloat8E5M2FNUZAPFloatToAPInt() const3588fe013be4SDimitry Andric APInt IEEEFloat::convertFloat8E5M2FNUZAPFloatToAPInt() const {
3589fe013be4SDimitry Andric   assert(partCount() == 1);
3590fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semFloat8E5M2FNUZ>();
3591bdd1243dSDimitry Andric }
3592bdd1243dSDimitry Andric 
convertFloat8E4M3FNAPFloatToAPInt() const3593bdd1243dSDimitry Andric APInt IEEEFloat::convertFloat8E4M3FNAPFloatToAPInt() const {
3594bdd1243dSDimitry Andric   assert(partCount() == 1);
3595fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semFloat8E4M3FN>();
3596bdd1243dSDimitry Andric }
3597bdd1243dSDimitry Andric 
convertFloat8E4M3FNUZAPFloatToAPInt() const3598fe013be4SDimitry Andric APInt IEEEFloat::convertFloat8E4M3FNUZAPFloatToAPInt() const {
3599fe013be4SDimitry Andric   assert(partCount() == 1);
3600fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semFloat8E4M3FNUZ>();
3601fe013be4SDimitry Andric }
3602fe013be4SDimitry Andric 
convertFloat8E4M3B11FNUZAPFloatToAPInt() const3603fe013be4SDimitry Andric APInt IEEEFloat::convertFloat8E4M3B11FNUZAPFloatToAPInt() const {
3604fe013be4SDimitry Andric   assert(partCount() == 1);
3605fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semFloat8E4M3B11FNUZ>();
3606fe013be4SDimitry Andric }
3607fe013be4SDimitry Andric 
convertFloatTF32APFloatToAPInt() const3608fe013be4SDimitry Andric APInt IEEEFloat::convertFloatTF32APFloatToAPInt() const {
3609fe013be4SDimitry Andric   assert(partCount() == 1);
3610fe013be4SDimitry Andric   return convertIEEEFloatToAPInt<semFloatTF32>();
3611bdd1243dSDimitry Andric }
3612bdd1243dSDimitry Andric 
36130b57cec5SDimitry Andric // This function creates an APInt that is just a bit map of the floating
36140b57cec5SDimitry Andric // point constant as it would appear in memory.  It is not a conversion,
36150b57cec5SDimitry Andric // and treating the result as a normal integer is unlikely to be useful.
36160b57cec5SDimitry Andric 
bitcastToAPInt() const36170b57cec5SDimitry Andric APInt IEEEFloat::bitcastToAPInt() const {
36180b57cec5SDimitry Andric   if (semantics == (const llvm::fltSemantics*)&semIEEEhalf)
36190b57cec5SDimitry Andric     return convertHalfAPFloatToAPInt();
36200b57cec5SDimitry Andric 
36215ffd83dbSDimitry Andric   if (semantics == (const llvm::fltSemantics *)&semBFloat)
36225ffd83dbSDimitry Andric     return convertBFloatAPFloatToAPInt();
36235ffd83dbSDimitry Andric 
36240b57cec5SDimitry Andric   if (semantics == (const llvm::fltSemantics*)&semIEEEsingle)
36250b57cec5SDimitry Andric     return convertFloatAPFloatToAPInt();
36260b57cec5SDimitry Andric 
36270b57cec5SDimitry Andric   if (semantics == (const llvm::fltSemantics*)&semIEEEdouble)
36280b57cec5SDimitry Andric     return convertDoubleAPFloatToAPInt();
36290b57cec5SDimitry Andric 
36300b57cec5SDimitry Andric   if (semantics == (const llvm::fltSemantics*)&semIEEEquad)
36310b57cec5SDimitry Andric     return convertQuadrupleAPFloatToAPInt();
36320b57cec5SDimitry Andric 
36330b57cec5SDimitry Andric   if (semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy)
36340b57cec5SDimitry Andric     return convertPPCDoubleDoubleAPFloatToAPInt();
36350b57cec5SDimitry Andric 
3636bdd1243dSDimitry Andric   if (semantics == (const llvm::fltSemantics *)&semFloat8E5M2)
3637bdd1243dSDimitry Andric     return convertFloat8E5M2APFloatToAPInt();
3638bdd1243dSDimitry Andric 
3639fe013be4SDimitry Andric   if (semantics == (const llvm::fltSemantics *)&semFloat8E5M2FNUZ)
3640fe013be4SDimitry Andric     return convertFloat8E5M2FNUZAPFloatToAPInt();
3641fe013be4SDimitry Andric 
3642bdd1243dSDimitry Andric   if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3FN)
3643bdd1243dSDimitry Andric     return convertFloat8E4M3FNAPFloatToAPInt();
3644bdd1243dSDimitry Andric 
3645fe013be4SDimitry Andric   if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3FNUZ)
3646fe013be4SDimitry Andric     return convertFloat8E4M3FNUZAPFloatToAPInt();
3647fe013be4SDimitry Andric 
3648fe013be4SDimitry Andric   if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3B11FNUZ)
3649fe013be4SDimitry Andric     return convertFloat8E4M3B11FNUZAPFloatToAPInt();
3650fe013be4SDimitry Andric 
3651fe013be4SDimitry Andric   if (semantics == (const llvm::fltSemantics *)&semFloatTF32)
3652fe013be4SDimitry Andric     return convertFloatTF32APFloatToAPInt();
3653fe013be4SDimitry Andric 
36540b57cec5SDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended &&
36550b57cec5SDimitry Andric          "unknown format!");
36560b57cec5SDimitry Andric   return convertF80LongDoubleAPFloatToAPInt();
36570b57cec5SDimitry Andric }
36580b57cec5SDimitry Andric 
convertToFloat() const36590b57cec5SDimitry Andric float IEEEFloat::convertToFloat() const {
36600b57cec5SDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semIEEEsingle &&
36610b57cec5SDimitry Andric          "Float semantics are not IEEEsingle");
36620b57cec5SDimitry Andric   APInt api = bitcastToAPInt();
36630b57cec5SDimitry Andric   return api.bitsToFloat();
36640b57cec5SDimitry Andric }
36650b57cec5SDimitry Andric 
convertToDouble() const36660b57cec5SDimitry Andric double IEEEFloat::convertToDouble() const {
36670b57cec5SDimitry Andric   assert(semantics == (const llvm::fltSemantics*)&semIEEEdouble &&
36680b57cec5SDimitry Andric          "Float semantics are not IEEEdouble");
36690b57cec5SDimitry Andric   APInt api = bitcastToAPInt();
36700b57cec5SDimitry Andric   return api.bitsToDouble();
36710b57cec5SDimitry Andric }
36720b57cec5SDimitry Andric 
36730b57cec5SDimitry Andric /// Integer bit is explicit in this format.  Intel hardware (387 and later)
36740b57cec5SDimitry Andric /// does not support these bit patterns:
36750b57cec5SDimitry Andric ///  exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity")
36760b57cec5SDimitry Andric ///  exponent = all 1's, integer bit 0, significand nonzero ("pseudoNaN")
36770b57cec5SDimitry Andric ///  exponent!=0 nor all 1's, integer bit 0 ("unnormal")
36780b57cec5SDimitry Andric ///  exponent = 0, integer bit 1 ("pseudodenormal")
36790b57cec5SDimitry Andric /// At the moment, the first three are treated as NaNs, the last one as Normal.
initFromF80LongDoubleAPInt(const APInt & api)36800b57cec5SDimitry Andric void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) {
36810b57cec5SDimitry Andric   uint64_t i1 = api.getRawData()[0];
36820b57cec5SDimitry Andric   uint64_t i2 = api.getRawData()[1];
36830b57cec5SDimitry Andric   uint64_t myexponent = (i2 & 0x7fff);
36840b57cec5SDimitry Andric   uint64_t mysignificand = i1;
36850b57cec5SDimitry Andric   uint8_t myintegerbit = mysignificand >> 63;
36860b57cec5SDimitry Andric 
36870b57cec5SDimitry Andric   initialize(&semX87DoubleExtended);
36880b57cec5SDimitry Andric   assert(partCount()==2);
36890b57cec5SDimitry Andric 
36900b57cec5SDimitry Andric   sign = static_cast<unsigned int>(i2>>15);
36910b57cec5SDimitry Andric   if (myexponent == 0 && mysignificand == 0) {
3692e8d8bef9SDimitry Andric     makeZero(sign);
36930b57cec5SDimitry Andric   } else if (myexponent==0x7fff && mysignificand==0x8000000000000000ULL) {
3694e8d8bef9SDimitry Andric     makeInf(sign);
36950b57cec5SDimitry Andric   } else if ((myexponent == 0x7fff && mysignificand != 0x8000000000000000ULL) ||
36960b57cec5SDimitry Andric              (myexponent != 0x7fff && myexponent != 0 && myintegerbit == 0)) {
36970b57cec5SDimitry Andric     category = fcNaN;
3698e8d8bef9SDimitry Andric     exponent = exponentNaN();
36990b57cec5SDimitry Andric     significandParts()[0] = mysignificand;
37000b57cec5SDimitry Andric     significandParts()[1] = 0;
37010b57cec5SDimitry Andric   } else {
37020b57cec5SDimitry Andric     category = fcNormal;
37030b57cec5SDimitry Andric     exponent = myexponent - 16383;
37040b57cec5SDimitry Andric     significandParts()[0] = mysignificand;
37050b57cec5SDimitry Andric     significandParts()[1] = 0;
37060b57cec5SDimitry Andric     if (myexponent==0)          // denormal
37070b57cec5SDimitry Andric       exponent = -16382;
37080b57cec5SDimitry Andric   }
37090b57cec5SDimitry Andric }
37100b57cec5SDimitry Andric 
initFromPPCDoubleDoubleAPInt(const APInt & api)37110b57cec5SDimitry Andric void IEEEFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) {
37120b57cec5SDimitry Andric   uint64_t i1 = api.getRawData()[0];
37130b57cec5SDimitry Andric   uint64_t i2 = api.getRawData()[1];
37140b57cec5SDimitry Andric   opStatus fs;
37150b57cec5SDimitry Andric   bool losesInfo;
37160b57cec5SDimitry Andric 
37170b57cec5SDimitry Andric   // Get the first double and convert to our format.
37180b57cec5SDimitry Andric   initFromDoubleAPInt(APInt(64, i1));
37190b57cec5SDimitry Andric   fs = convert(semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo);
37200b57cec5SDimitry Andric   assert(fs == opOK && !losesInfo);
37210b57cec5SDimitry Andric   (void)fs;
37220b57cec5SDimitry Andric 
37230b57cec5SDimitry Andric   // Unless we have a special case, add in second double.
37240b57cec5SDimitry Andric   if (isFiniteNonZero()) {
37250b57cec5SDimitry Andric     IEEEFloat v(semIEEEdouble, APInt(64, i2));
37260b57cec5SDimitry Andric     fs = v.convert(semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo);
37270b57cec5SDimitry Andric     assert(fs == opOK && !losesInfo);
37280b57cec5SDimitry Andric     (void)fs;
37290b57cec5SDimitry Andric 
37300b57cec5SDimitry Andric     add(v, rmNearestTiesToEven);
37310b57cec5SDimitry Andric   }
37320b57cec5SDimitry Andric }
37330b57cec5SDimitry Andric 
3734fe013be4SDimitry Andric template <const fltSemantics &S>
initFromIEEEAPInt(const APInt & api)3735fe013be4SDimitry Andric void IEEEFloat::initFromIEEEAPInt(const APInt &api) {
3736fe013be4SDimitry Andric   assert(api.getBitWidth() == S.sizeInBits);
3737fe013be4SDimitry Andric   constexpr integerPart integer_bit = integerPart{1}
3738fe013be4SDimitry Andric                                       << ((S.precision - 1) % integerPartWidth);
3739fe013be4SDimitry Andric   constexpr uint64_t significand_mask = integer_bit - 1;
3740fe013be4SDimitry Andric   constexpr unsigned int trailing_significand_bits = S.precision - 1;
3741fe013be4SDimitry Andric   constexpr unsigned int stored_significand_parts =
3742fe013be4SDimitry Andric       partCountForBits(trailing_significand_bits);
3743fe013be4SDimitry Andric   constexpr unsigned int exponent_bits =
3744fe013be4SDimitry Andric       S.sizeInBits - 1 - trailing_significand_bits;
3745fe013be4SDimitry Andric   static_assert(exponent_bits < 64);
3746fe013be4SDimitry Andric   constexpr uint64_t exponent_mask = (uint64_t{1} << exponent_bits) - 1;
3747fe013be4SDimitry Andric   constexpr int bias = -(S.minExponent - 1);
37480b57cec5SDimitry Andric 
3749fe013be4SDimitry Andric   // Copy the bits of the significand. We need to clear out the exponent and
3750fe013be4SDimitry Andric   // sign bit in the last word.
3751fe013be4SDimitry Andric   std::array<integerPart, stored_significand_parts> mysignificand;
3752fe013be4SDimitry Andric   std::copy_n(api.getRawData(), mysignificand.size(), mysignificand.begin());
3753fe013be4SDimitry Andric   if constexpr (significand_mask != 0) {
3754fe013be4SDimitry Andric     mysignificand[mysignificand.size() - 1] &= significand_mask;
37550b57cec5SDimitry Andric   }
3756fe013be4SDimitry Andric 
3757fe013be4SDimitry Andric   // We assume the last word holds the sign bit, the exponent, and potentially
3758fe013be4SDimitry Andric   // some of the trailing significand field.
3759fe013be4SDimitry Andric   uint64_t last_word = api.getRawData()[api.getNumWords() - 1];
3760fe013be4SDimitry Andric   uint64_t myexponent =
3761fe013be4SDimitry Andric       (last_word >> (trailing_significand_bits % 64)) & exponent_mask;
3762fe013be4SDimitry Andric 
3763fe013be4SDimitry Andric   initialize(&S);
3764fe013be4SDimitry Andric   assert(partCount() == mysignificand.size());
3765fe013be4SDimitry Andric 
3766fe013be4SDimitry Andric   sign = static_cast<unsigned int>(last_word >> ((S.sizeInBits - 1) % 64));
3767fe013be4SDimitry Andric 
3768fe013be4SDimitry Andric   bool all_zero_significand =
3769fe013be4SDimitry Andric       llvm::all_of(mysignificand, [](integerPart bits) { return bits == 0; });
3770fe013be4SDimitry Andric 
3771fe013be4SDimitry Andric   bool is_zero = myexponent == 0 && all_zero_significand;
3772fe013be4SDimitry Andric 
3773fe013be4SDimitry Andric   if constexpr (S.nonFiniteBehavior == fltNonfiniteBehavior::IEEE754) {
3774fe013be4SDimitry Andric     if (myexponent - bias == ::exponentInf(S) && all_zero_significand) {
3775fe013be4SDimitry Andric       makeInf(sign);
3776fe013be4SDimitry Andric       return;
3777fe013be4SDimitry Andric     }
3778fe013be4SDimitry Andric   }
3779fe013be4SDimitry Andric 
3780fe013be4SDimitry Andric   bool is_nan = false;
3781fe013be4SDimitry Andric 
3782fe013be4SDimitry Andric   if constexpr (S.nanEncoding == fltNanEncoding::IEEE) {
3783fe013be4SDimitry Andric     is_nan = myexponent - bias == ::exponentNaN(S) && !all_zero_significand;
3784fe013be4SDimitry Andric   } else if constexpr (S.nanEncoding == fltNanEncoding::AllOnes) {
3785fe013be4SDimitry Andric     bool all_ones_significand =
3786fe013be4SDimitry Andric         std::all_of(mysignificand.begin(), mysignificand.end() - 1,
3787fe013be4SDimitry Andric                     [](integerPart bits) { return bits == ~integerPart{0}; }) &&
3788fe013be4SDimitry Andric         (!significand_mask ||
3789fe013be4SDimitry Andric          mysignificand[mysignificand.size() - 1] == significand_mask);
3790fe013be4SDimitry Andric     is_nan = myexponent - bias == ::exponentNaN(S) && all_ones_significand;
3791fe013be4SDimitry Andric   } else if constexpr (S.nanEncoding == fltNanEncoding::NegativeZero) {
3792fe013be4SDimitry Andric     is_nan = is_zero && sign;
3793fe013be4SDimitry Andric   }
3794fe013be4SDimitry Andric 
3795fe013be4SDimitry Andric   if (is_nan) {
3796fe013be4SDimitry Andric     category = fcNaN;
3797fe013be4SDimitry Andric     exponent = ::exponentNaN(S);
3798fe013be4SDimitry Andric     std::copy_n(mysignificand.begin(), mysignificand.size(),
3799fe013be4SDimitry Andric                 significandParts());
3800fe013be4SDimitry Andric     return;
3801fe013be4SDimitry Andric   }
3802fe013be4SDimitry Andric 
3803fe013be4SDimitry Andric   if (is_zero) {
3804fe013be4SDimitry Andric     makeZero(sign);
3805fe013be4SDimitry Andric     return;
3806fe013be4SDimitry Andric   }
3807fe013be4SDimitry Andric 
3808fe013be4SDimitry Andric   category = fcNormal;
3809fe013be4SDimitry Andric   exponent = myexponent - bias;
3810fe013be4SDimitry Andric   std::copy_n(mysignificand.begin(), mysignificand.size(), significandParts());
3811fe013be4SDimitry Andric   if (myexponent == 0) // denormal
3812fe013be4SDimitry Andric     exponent = S.minExponent;
3813fe013be4SDimitry Andric   else
3814fe013be4SDimitry Andric     significandParts()[mysignificand.size()-1] |= integer_bit; // integer bit
3815fe013be4SDimitry Andric }
3816fe013be4SDimitry Andric 
initFromQuadrupleAPInt(const APInt & api)3817fe013be4SDimitry Andric void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) {
3818fe013be4SDimitry Andric   initFromIEEEAPInt<semIEEEquad>(api);
38190b57cec5SDimitry Andric }
38200b57cec5SDimitry Andric 
initFromDoubleAPInt(const APInt & api)38210b57cec5SDimitry Andric void IEEEFloat::initFromDoubleAPInt(const APInt &api) {
3822fe013be4SDimitry Andric   initFromIEEEAPInt<semIEEEdouble>(api);
38230b57cec5SDimitry Andric }
38240b57cec5SDimitry Andric 
initFromFloatAPInt(const APInt & api)38250b57cec5SDimitry Andric void IEEEFloat::initFromFloatAPInt(const APInt &api) {
3826fe013be4SDimitry Andric   initFromIEEEAPInt<semIEEEsingle>(api);
38270b57cec5SDimitry Andric }
38280b57cec5SDimitry Andric 
initFromBFloatAPInt(const APInt & api)38295ffd83dbSDimitry Andric void IEEEFloat::initFromBFloatAPInt(const APInt &api) {
3830fe013be4SDimitry Andric   initFromIEEEAPInt<semBFloat>(api);
38315ffd83dbSDimitry Andric }
38325ffd83dbSDimitry Andric 
initFromHalfAPInt(const APInt & api)38330b57cec5SDimitry Andric void IEEEFloat::initFromHalfAPInt(const APInt &api) {
3834fe013be4SDimitry Andric   initFromIEEEAPInt<semIEEEhalf>(api);
38350b57cec5SDimitry Andric }
38360b57cec5SDimitry Andric 
initFromFloat8E5M2APInt(const APInt & api)3837bdd1243dSDimitry Andric void IEEEFloat::initFromFloat8E5M2APInt(const APInt &api) {
3838fe013be4SDimitry Andric   initFromIEEEAPInt<semFloat8E5M2>(api);
3839bdd1243dSDimitry Andric }
3840fe013be4SDimitry Andric 
initFromFloat8E5M2FNUZAPInt(const APInt & api)3841fe013be4SDimitry Andric void IEEEFloat::initFromFloat8E5M2FNUZAPInt(const APInt &api) {
3842fe013be4SDimitry Andric   initFromIEEEAPInt<semFloat8E5M2FNUZ>(api);
3843bdd1243dSDimitry Andric }
3844bdd1243dSDimitry Andric 
initFromFloat8E4M3FNAPInt(const APInt & api)3845bdd1243dSDimitry Andric void IEEEFloat::initFromFloat8E4M3FNAPInt(const APInt &api) {
3846fe013be4SDimitry Andric   initFromIEEEAPInt<semFloat8E4M3FN>(api);
3847bdd1243dSDimitry Andric }
3848fe013be4SDimitry Andric 
initFromFloat8E4M3FNUZAPInt(const APInt & api)3849fe013be4SDimitry Andric void IEEEFloat::initFromFloat8E4M3FNUZAPInt(const APInt &api) {
3850fe013be4SDimitry Andric   initFromIEEEAPInt<semFloat8E4M3FNUZ>(api);
3851fe013be4SDimitry Andric }
3852fe013be4SDimitry Andric 
initFromFloat8E4M3B11FNUZAPInt(const APInt & api)3853fe013be4SDimitry Andric void IEEEFloat::initFromFloat8E4M3B11FNUZAPInt(const APInt &api) {
3854fe013be4SDimitry Andric   initFromIEEEAPInt<semFloat8E4M3B11FNUZ>(api);
3855fe013be4SDimitry Andric }
3856fe013be4SDimitry Andric 
initFromFloatTF32APInt(const APInt & api)3857fe013be4SDimitry Andric void IEEEFloat::initFromFloatTF32APInt(const APInt &api) {
3858fe013be4SDimitry Andric   initFromIEEEAPInt<semFloatTF32>(api);
3859bdd1243dSDimitry Andric }
3860bdd1243dSDimitry Andric 
3861bdd1243dSDimitry Andric /// Treat api as containing the bits of a floating point number.
initFromAPInt(const fltSemantics * Sem,const APInt & api)38620b57cec5SDimitry Andric void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
3863349cc55cSDimitry Andric   assert(api.getBitWidth() == Sem->sizeInBits);
38640b57cec5SDimitry Andric   if (Sem == &semIEEEhalf)
38650b57cec5SDimitry Andric     return initFromHalfAPInt(api);
38665ffd83dbSDimitry Andric   if (Sem == &semBFloat)
38675ffd83dbSDimitry Andric     return initFromBFloatAPInt(api);
38680b57cec5SDimitry Andric   if (Sem == &semIEEEsingle)
38690b57cec5SDimitry Andric     return initFromFloatAPInt(api);
38700b57cec5SDimitry Andric   if (Sem == &semIEEEdouble)
38710b57cec5SDimitry Andric     return initFromDoubleAPInt(api);
38720b57cec5SDimitry Andric   if (Sem == &semX87DoubleExtended)
38730b57cec5SDimitry Andric     return initFromF80LongDoubleAPInt(api);
38740b57cec5SDimitry Andric   if (Sem == &semIEEEquad)
38750b57cec5SDimitry Andric     return initFromQuadrupleAPInt(api);
38760b57cec5SDimitry Andric   if (Sem == &semPPCDoubleDoubleLegacy)
38770b57cec5SDimitry Andric     return initFromPPCDoubleDoubleAPInt(api);
3878bdd1243dSDimitry Andric   if (Sem == &semFloat8E5M2)
3879bdd1243dSDimitry Andric     return initFromFloat8E5M2APInt(api);
3880fe013be4SDimitry Andric   if (Sem == &semFloat8E5M2FNUZ)
3881fe013be4SDimitry Andric     return initFromFloat8E5M2FNUZAPInt(api);
3882bdd1243dSDimitry Andric   if (Sem == &semFloat8E4M3FN)
3883bdd1243dSDimitry Andric     return initFromFloat8E4M3FNAPInt(api);
3884fe013be4SDimitry Andric   if (Sem == &semFloat8E4M3FNUZ)
3885fe013be4SDimitry Andric     return initFromFloat8E4M3FNUZAPInt(api);
3886fe013be4SDimitry Andric   if (Sem == &semFloat8E4M3B11FNUZ)
3887fe013be4SDimitry Andric     return initFromFloat8E4M3B11FNUZAPInt(api);
3888fe013be4SDimitry Andric   if (Sem == &semFloatTF32)
3889fe013be4SDimitry Andric     return initFromFloatTF32APInt(api);
38900b57cec5SDimitry Andric 
38910b57cec5SDimitry Andric   llvm_unreachable(nullptr);
38920b57cec5SDimitry Andric }
38930b57cec5SDimitry Andric 
38940b57cec5SDimitry Andric /// Make this number the largest magnitude normal number in the given
38950b57cec5SDimitry Andric /// semantics.
makeLargest(bool Negative)38960b57cec5SDimitry Andric void IEEEFloat::makeLargest(bool Negative) {
38970b57cec5SDimitry Andric   // We want (in interchange format):
38980b57cec5SDimitry Andric   //   sign = {Negative}
38990b57cec5SDimitry Andric   //   exponent = 1..10
39000b57cec5SDimitry Andric   //   significand = 1..1
39010b57cec5SDimitry Andric   category = fcNormal;
39020b57cec5SDimitry Andric   sign = Negative;
39030b57cec5SDimitry Andric   exponent = semantics->maxExponent;
39040b57cec5SDimitry Andric 
39050b57cec5SDimitry Andric   // Use memset to set all but the highest integerPart to all ones.
39060b57cec5SDimitry Andric   integerPart *significand = significandParts();
39070b57cec5SDimitry Andric   unsigned PartCount = partCount();
39080b57cec5SDimitry Andric   memset(significand, 0xFF, sizeof(integerPart)*(PartCount - 1));
39090b57cec5SDimitry Andric 
39100b57cec5SDimitry Andric   // Set the high integerPart especially setting all unused top bits for
39110b57cec5SDimitry Andric   // internal consistency.
39120b57cec5SDimitry Andric   const unsigned NumUnusedHighBits =
39130b57cec5SDimitry Andric     PartCount*integerPartWidth - semantics->precision;
39140b57cec5SDimitry Andric   significand[PartCount - 1] = (NumUnusedHighBits < integerPartWidth)
39150b57cec5SDimitry Andric                                    ? (~integerPart(0) >> NumUnusedHighBits)
39160b57cec5SDimitry Andric                                    : 0;
3917bdd1243dSDimitry Andric 
3918fe013be4SDimitry Andric   if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly &&
3919fe013be4SDimitry Andric       semantics->nanEncoding == fltNanEncoding::AllOnes)
3920bdd1243dSDimitry Andric     significand[0] &= ~integerPart(1);
39210b57cec5SDimitry Andric }
39220b57cec5SDimitry Andric 
39230b57cec5SDimitry Andric /// Make this number the smallest magnitude denormal number in the given
39240b57cec5SDimitry Andric /// semantics.
makeSmallest(bool Negative)39250b57cec5SDimitry Andric void IEEEFloat::makeSmallest(bool Negative) {
39260b57cec5SDimitry Andric   // We want (in interchange format):
39270b57cec5SDimitry Andric   //   sign = {Negative}
39280b57cec5SDimitry Andric   //   exponent = 0..0
39290b57cec5SDimitry Andric   //   significand = 0..01
39300b57cec5SDimitry Andric   category = fcNormal;
39310b57cec5SDimitry Andric   sign = Negative;
39320b57cec5SDimitry Andric   exponent = semantics->minExponent;
39330b57cec5SDimitry Andric   APInt::tcSet(significandParts(), 1, partCount());
39340b57cec5SDimitry Andric }
39350b57cec5SDimitry Andric 
makeSmallestNormalized(bool Negative)39360b57cec5SDimitry Andric void IEEEFloat::makeSmallestNormalized(bool Negative) {
39370b57cec5SDimitry Andric   // We want (in interchange format):
39380b57cec5SDimitry Andric   //   sign = {Negative}
39390b57cec5SDimitry Andric   //   exponent = 0..0
39400b57cec5SDimitry Andric   //   significand = 10..0
39410b57cec5SDimitry Andric 
39420b57cec5SDimitry Andric   category = fcNormal;
39430b57cec5SDimitry Andric   zeroSignificand();
39440b57cec5SDimitry Andric   sign = Negative;
39450b57cec5SDimitry Andric   exponent = semantics->minExponent;
3946bdd1243dSDimitry Andric   APInt::tcSetBit(significandParts(), semantics->precision - 1);
39470b57cec5SDimitry Andric }
39480b57cec5SDimitry Andric 
IEEEFloat(const fltSemantics & Sem,const APInt & API)39490b57cec5SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &Sem, const APInt &API) {
39500b57cec5SDimitry Andric   initFromAPInt(&Sem, API);
39510b57cec5SDimitry Andric }
39520b57cec5SDimitry Andric 
IEEEFloat(float f)39530b57cec5SDimitry Andric IEEEFloat::IEEEFloat(float f) {
39540b57cec5SDimitry Andric   initFromAPInt(&semIEEEsingle, APInt::floatToBits(f));
39550b57cec5SDimitry Andric }
39560b57cec5SDimitry Andric 
IEEEFloat(double d)39570b57cec5SDimitry Andric IEEEFloat::IEEEFloat(double d) {
39580b57cec5SDimitry Andric   initFromAPInt(&semIEEEdouble, APInt::doubleToBits(d));
39590b57cec5SDimitry Andric }
39600b57cec5SDimitry Andric 
39610b57cec5SDimitry Andric namespace {
append(SmallVectorImpl<char> & Buffer,StringRef Str)39620b57cec5SDimitry Andric   void append(SmallVectorImpl<char> &Buffer, StringRef Str) {
39630b57cec5SDimitry Andric     Buffer.append(Str.begin(), Str.end());
39640b57cec5SDimitry Andric   }
39650b57cec5SDimitry Andric 
39660b57cec5SDimitry Andric   /// Removes data from the given significand until it is no more
39670b57cec5SDimitry Andric   /// precise than is required for the desired precision.
AdjustToPrecision(APInt & significand,int & exp,unsigned FormatPrecision)39680b57cec5SDimitry Andric   void AdjustToPrecision(APInt &significand,
39690b57cec5SDimitry Andric                          int &exp, unsigned FormatPrecision) {
39700b57cec5SDimitry Andric     unsigned bits = significand.getActiveBits();
39710b57cec5SDimitry Andric 
39720b57cec5SDimitry Andric     // 196/59 is a very slight overestimate of lg_2(10).
39730b57cec5SDimitry Andric     unsigned bitsRequired = (FormatPrecision * 196 + 58) / 59;
39740b57cec5SDimitry Andric 
39750b57cec5SDimitry Andric     if (bits <= bitsRequired) return;
39760b57cec5SDimitry Andric 
39770b57cec5SDimitry Andric     unsigned tensRemovable = (bits - bitsRequired) * 59 / 196;
39780b57cec5SDimitry Andric     if (!tensRemovable) return;
39790b57cec5SDimitry Andric 
39800b57cec5SDimitry Andric     exp += tensRemovable;
39810b57cec5SDimitry Andric 
39820b57cec5SDimitry Andric     APInt divisor(significand.getBitWidth(), 1);
39830b57cec5SDimitry Andric     APInt powten(significand.getBitWidth(), 10);
39840b57cec5SDimitry Andric     while (true) {
39850b57cec5SDimitry Andric       if (tensRemovable & 1)
39860b57cec5SDimitry Andric         divisor *= powten;
39870b57cec5SDimitry Andric       tensRemovable >>= 1;
39880b57cec5SDimitry Andric       if (!tensRemovable) break;
39890b57cec5SDimitry Andric       powten *= powten;
39900b57cec5SDimitry Andric     }
39910b57cec5SDimitry Andric 
39920b57cec5SDimitry Andric     significand = significand.udiv(divisor);
39930b57cec5SDimitry Andric 
39940b57cec5SDimitry Andric     // Truncate the significand down to its active bit count.
39950b57cec5SDimitry Andric     significand = significand.trunc(significand.getActiveBits());
39960b57cec5SDimitry Andric   }
39970b57cec5SDimitry Andric 
39980b57cec5SDimitry Andric 
AdjustToPrecision(SmallVectorImpl<char> & buffer,int & exp,unsigned FormatPrecision)39990b57cec5SDimitry Andric   void AdjustToPrecision(SmallVectorImpl<char> &buffer,
40000b57cec5SDimitry Andric                          int &exp, unsigned FormatPrecision) {
40010b57cec5SDimitry Andric     unsigned N = buffer.size();
40020b57cec5SDimitry Andric     if (N <= FormatPrecision) return;
40030b57cec5SDimitry Andric 
40040b57cec5SDimitry Andric     // The most significant figures are the last ones in the buffer.
40050b57cec5SDimitry Andric     unsigned FirstSignificant = N - FormatPrecision;
40060b57cec5SDimitry Andric 
40070b57cec5SDimitry Andric     // Round.
40080b57cec5SDimitry Andric     // FIXME: this probably shouldn't use 'round half up'.
40090b57cec5SDimitry Andric 
40100b57cec5SDimitry Andric     // Rounding down is just a truncation, except we also want to drop
40110b57cec5SDimitry Andric     // trailing zeros from the new result.
40120b57cec5SDimitry Andric     if (buffer[FirstSignificant - 1] < '5') {
40130b57cec5SDimitry Andric       while (FirstSignificant < N && buffer[FirstSignificant] == '0')
40140b57cec5SDimitry Andric         FirstSignificant++;
40150b57cec5SDimitry Andric 
40160b57cec5SDimitry Andric       exp += FirstSignificant;
40170b57cec5SDimitry Andric       buffer.erase(&buffer[0], &buffer[FirstSignificant]);
40180b57cec5SDimitry Andric       return;
40190b57cec5SDimitry Andric     }
40200b57cec5SDimitry Andric 
40210b57cec5SDimitry Andric     // Rounding up requires a decimal add-with-carry.  If we continue
40220b57cec5SDimitry Andric     // the carry, the newly-introduced zeros will just be truncated.
40230b57cec5SDimitry Andric     for (unsigned I = FirstSignificant; I != N; ++I) {
40240b57cec5SDimitry Andric       if (buffer[I] == '9') {
40250b57cec5SDimitry Andric         FirstSignificant++;
40260b57cec5SDimitry Andric       } else {
40270b57cec5SDimitry Andric         buffer[I]++;
40280b57cec5SDimitry Andric         break;
40290b57cec5SDimitry Andric       }
40300b57cec5SDimitry Andric     }
40310b57cec5SDimitry Andric 
40320b57cec5SDimitry Andric     // If we carried through, we have exactly one digit of precision.
40330b57cec5SDimitry Andric     if (FirstSignificant == N) {
40340b57cec5SDimitry Andric       exp += FirstSignificant;
40350b57cec5SDimitry Andric       buffer.clear();
40360b57cec5SDimitry Andric       buffer.push_back('1');
40370b57cec5SDimitry Andric       return;
40380b57cec5SDimitry Andric     }
40390b57cec5SDimitry Andric 
40400b57cec5SDimitry Andric     exp += FirstSignificant;
40410b57cec5SDimitry Andric     buffer.erase(&buffer[0], &buffer[FirstSignificant]);
40420b57cec5SDimitry Andric   }
4043fe6060f1SDimitry Andric } // namespace
40440b57cec5SDimitry Andric 
toString(SmallVectorImpl<char> & Str,unsigned FormatPrecision,unsigned FormatMaxPadding,bool TruncateZero) const40450b57cec5SDimitry Andric void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
40460b57cec5SDimitry Andric                          unsigned FormatMaxPadding, bool TruncateZero) const {
40470b57cec5SDimitry Andric   switch (category) {
40480b57cec5SDimitry Andric   case fcInfinity:
40490b57cec5SDimitry Andric     if (isNegative())
40500b57cec5SDimitry Andric       return append(Str, "-Inf");
40510b57cec5SDimitry Andric     else
40520b57cec5SDimitry Andric       return append(Str, "+Inf");
40530b57cec5SDimitry Andric 
40540b57cec5SDimitry Andric   case fcNaN: return append(Str, "NaN");
40550b57cec5SDimitry Andric 
40560b57cec5SDimitry Andric   case fcZero:
40570b57cec5SDimitry Andric     if (isNegative())
40580b57cec5SDimitry Andric       Str.push_back('-');
40590b57cec5SDimitry Andric 
40600b57cec5SDimitry Andric     if (!FormatMaxPadding) {
40610b57cec5SDimitry Andric       if (TruncateZero)
40620b57cec5SDimitry Andric         append(Str, "0.0E+0");
40630b57cec5SDimitry Andric       else {
40640b57cec5SDimitry Andric         append(Str, "0.0");
40650b57cec5SDimitry Andric         if (FormatPrecision > 1)
40660b57cec5SDimitry Andric           Str.append(FormatPrecision - 1, '0');
40670b57cec5SDimitry Andric         append(Str, "e+00");
40680b57cec5SDimitry Andric       }
40690b57cec5SDimitry Andric     } else
40700b57cec5SDimitry Andric       Str.push_back('0');
40710b57cec5SDimitry Andric     return;
40720b57cec5SDimitry Andric 
40730b57cec5SDimitry Andric   case fcNormal:
40740b57cec5SDimitry Andric     break;
40750b57cec5SDimitry Andric   }
40760b57cec5SDimitry Andric 
40770b57cec5SDimitry Andric   if (isNegative())
40780b57cec5SDimitry Andric     Str.push_back('-');
40790b57cec5SDimitry Andric 
40800b57cec5SDimitry Andric   // Decompose the number into an APInt and an exponent.
40810b57cec5SDimitry Andric   int exp = exponent - ((int) semantics->precision - 1);
4082bdd1243dSDimitry Andric   APInt significand(
4083bdd1243dSDimitry Andric       semantics->precision,
4084bdd1243dSDimitry Andric       ArrayRef(significandParts(), partCountForBits(semantics->precision)));
40850b57cec5SDimitry Andric 
40860b57cec5SDimitry Andric   // Set FormatPrecision if zero.  We want to do this before we
40870b57cec5SDimitry Andric   // truncate trailing zeros, as those are part of the precision.
40880b57cec5SDimitry Andric   if (!FormatPrecision) {
40890b57cec5SDimitry Andric     // We use enough digits so the number can be round-tripped back to an
40900b57cec5SDimitry Andric     // APFloat. The formula comes from "How to Print Floating-Point Numbers
40910b57cec5SDimitry Andric     // Accurately" by Steele and White.
40920b57cec5SDimitry Andric     // FIXME: Using a formula based purely on the precision is conservative;
40930b57cec5SDimitry Andric     // we can print fewer digits depending on the actual value being printed.
40940b57cec5SDimitry Andric 
40950b57cec5SDimitry Andric     // FormatPrecision = 2 + floor(significandBits / lg_2(10))
40960b57cec5SDimitry Andric     FormatPrecision = 2 + semantics->precision * 59 / 196;
40970b57cec5SDimitry Andric   }
40980b57cec5SDimitry Andric 
40990b57cec5SDimitry Andric   // Ignore trailing binary zeros.
4100fe013be4SDimitry Andric   int trailingZeros = significand.countr_zero();
41010b57cec5SDimitry Andric   exp += trailingZeros;
41020b57cec5SDimitry Andric   significand.lshrInPlace(trailingZeros);
41030b57cec5SDimitry Andric 
41040b57cec5SDimitry Andric   // Change the exponent from 2^e to 10^e.
41050b57cec5SDimitry Andric   if (exp == 0) {
41060b57cec5SDimitry Andric     // Nothing to do.
41070b57cec5SDimitry Andric   } else if (exp > 0) {
41080b57cec5SDimitry Andric     // Just shift left.
41090b57cec5SDimitry Andric     significand = significand.zext(semantics->precision + exp);
41100b57cec5SDimitry Andric     significand <<= exp;
41110b57cec5SDimitry Andric     exp = 0;
41120b57cec5SDimitry Andric   } else { /* exp < 0 */
41130b57cec5SDimitry Andric     int texp = -exp;
41140b57cec5SDimitry Andric 
41150b57cec5SDimitry Andric     // We transform this using the identity:
41160b57cec5SDimitry Andric     //   (N)(2^-e) == (N)(5^e)(10^-e)
41170b57cec5SDimitry Andric     // This means we have to multiply N (the significand) by 5^e.
41180b57cec5SDimitry Andric     // To avoid overflow, we have to operate on numbers large
41190b57cec5SDimitry Andric     // enough to store N * 5^e:
41200b57cec5SDimitry Andric     //   log2(N * 5^e) == log2(N) + e * log2(5)
41210b57cec5SDimitry Andric     //                 <= semantics->precision + e * 137 / 59
41220b57cec5SDimitry Andric     //   (log_2(5) ~ 2.321928 < 2.322034 ~ 137/59)
41230b57cec5SDimitry Andric 
41240b57cec5SDimitry Andric     unsigned precision = semantics->precision + (137 * texp + 136) / 59;
41250b57cec5SDimitry Andric 
41260b57cec5SDimitry Andric     // Multiply significand by 5^e.
41270b57cec5SDimitry Andric     //   N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8)
41280b57cec5SDimitry Andric     significand = significand.zext(precision);
41290b57cec5SDimitry Andric     APInt five_to_the_i(precision, 5);
41300b57cec5SDimitry Andric     while (true) {
41310b57cec5SDimitry Andric       if (texp & 1) significand *= five_to_the_i;
41320b57cec5SDimitry Andric 
41330b57cec5SDimitry Andric       texp >>= 1;
41340b57cec5SDimitry Andric       if (!texp) break;
41350b57cec5SDimitry Andric       five_to_the_i *= five_to_the_i;
41360b57cec5SDimitry Andric     }
41370b57cec5SDimitry Andric   }
41380b57cec5SDimitry Andric 
41390b57cec5SDimitry Andric   AdjustToPrecision(significand, exp, FormatPrecision);
41400b57cec5SDimitry Andric 
41410b57cec5SDimitry Andric   SmallVector<char, 256> buffer;
41420b57cec5SDimitry Andric 
41430b57cec5SDimitry Andric   // Fill the buffer.
41440b57cec5SDimitry Andric   unsigned precision = significand.getBitWidth();
4145bdd1243dSDimitry Andric   if (precision < 4) {
4146bdd1243dSDimitry Andric     // We need enough precision to store the value 10.
4147bdd1243dSDimitry Andric     precision = 4;
4148bdd1243dSDimitry Andric     significand = significand.zext(precision);
4149bdd1243dSDimitry Andric   }
41500b57cec5SDimitry Andric   APInt ten(precision, 10);
41510b57cec5SDimitry Andric   APInt digit(precision, 0);
41520b57cec5SDimitry Andric 
41530b57cec5SDimitry Andric   bool inTrail = true;
41540b57cec5SDimitry Andric   while (significand != 0) {
41550b57cec5SDimitry Andric     // digit <- significand % 10
41560b57cec5SDimitry Andric     // significand <- significand / 10
41570b57cec5SDimitry Andric     APInt::udivrem(significand, ten, significand, digit);
41580b57cec5SDimitry Andric 
41590b57cec5SDimitry Andric     unsigned d = digit.getZExtValue();
41600b57cec5SDimitry Andric 
41610b57cec5SDimitry Andric     // Drop trailing zeros.
41620b57cec5SDimitry Andric     if (inTrail && !d) exp++;
41630b57cec5SDimitry Andric     else {
41640b57cec5SDimitry Andric       buffer.push_back((char) ('0' + d));
41650b57cec5SDimitry Andric       inTrail = false;
41660b57cec5SDimitry Andric     }
41670b57cec5SDimitry Andric   }
41680b57cec5SDimitry Andric 
41690b57cec5SDimitry Andric   assert(!buffer.empty() && "no characters in buffer!");
41700b57cec5SDimitry Andric 
41710b57cec5SDimitry Andric   // Drop down to FormatPrecision.
41720b57cec5SDimitry Andric   // TODO: don't do more precise calculations above than are required.
41730b57cec5SDimitry Andric   AdjustToPrecision(buffer, exp, FormatPrecision);
41740b57cec5SDimitry Andric 
41750b57cec5SDimitry Andric   unsigned NDigits = buffer.size();
41760b57cec5SDimitry Andric 
41770b57cec5SDimitry Andric   // Check whether we should use scientific notation.
41780b57cec5SDimitry Andric   bool FormatScientific;
41790b57cec5SDimitry Andric   if (!FormatMaxPadding)
41800b57cec5SDimitry Andric     FormatScientific = true;
41810b57cec5SDimitry Andric   else {
41820b57cec5SDimitry Andric     if (exp >= 0) {
41830b57cec5SDimitry Andric       // 765e3 --> 765000
41840b57cec5SDimitry Andric       //              ^^^
41850b57cec5SDimitry Andric       // But we shouldn't make the number look more precise than it is.
41860b57cec5SDimitry Andric       FormatScientific = ((unsigned) exp > FormatMaxPadding ||
41870b57cec5SDimitry Andric                           NDigits + (unsigned) exp > FormatPrecision);
41880b57cec5SDimitry Andric     } else {
41890b57cec5SDimitry Andric       // Power of the most significant digit.
41900b57cec5SDimitry Andric       int MSD = exp + (int) (NDigits - 1);
41910b57cec5SDimitry Andric       if (MSD >= 0) {
41920b57cec5SDimitry Andric         // 765e-2 == 7.65
41930b57cec5SDimitry Andric         FormatScientific = false;
41940b57cec5SDimitry Andric       } else {
41950b57cec5SDimitry Andric         // 765e-5 == 0.00765
41960b57cec5SDimitry Andric         //           ^ ^^
41970b57cec5SDimitry Andric         FormatScientific = ((unsigned) -MSD) > FormatMaxPadding;
41980b57cec5SDimitry Andric       }
41990b57cec5SDimitry Andric     }
42000b57cec5SDimitry Andric   }
42010b57cec5SDimitry Andric 
42020b57cec5SDimitry Andric   // Scientific formatting is pretty straightforward.
42030b57cec5SDimitry Andric   if (FormatScientific) {
42040b57cec5SDimitry Andric     exp += (NDigits - 1);
42050b57cec5SDimitry Andric 
42060b57cec5SDimitry Andric     Str.push_back(buffer[NDigits-1]);
42070b57cec5SDimitry Andric     Str.push_back('.');
42080b57cec5SDimitry Andric     if (NDigits == 1 && TruncateZero)
42090b57cec5SDimitry Andric       Str.push_back('0');
42100b57cec5SDimitry Andric     else
42110b57cec5SDimitry Andric       for (unsigned I = 1; I != NDigits; ++I)
42120b57cec5SDimitry Andric         Str.push_back(buffer[NDigits-1-I]);
42130b57cec5SDimitry Andric     // Fill with zeros up to FormatPrecision.
42140b57cec5SDimitry Andric     if (!TruncateZero && FormatPrecision > NDigits - 1)
42150b57cec5SDimitry Andric       Str.append(FormatPrecision - NDigits + 1, '0');
42160b57cec5SDimitry Andric     // For !TruncateZero we use lower 'e'.
42170b57cec5SDimitry Andric     Str.push_back(TruncateZero ? 'E' : 'e');
42180b57cec5SDimitry Andric 
42190b57cec5SDimitry Andric     Str.push_back(exp >= 0 ? '+' : '-');
42200b57cec5SDimitry Andric     if (exp < 0) exp = -exp;
42210b57cec5SDimitry Andric     SmallVector<char, 6> expbuf;
42220b57cec5SDimitry Andric     do {
42230b57cec5SDimitry Andric       expbuf.push_back((char) ('0' + (exp % 10)));
42240b57cec5SDimitry Andric       exp /= 10;
42250b57cec5SDimitry Andric     } while (exp);
42260b57cec5SDimitry Andric     // Exponent always at least two digits if we do not truncate zeros.
42270b57cec5SDimitry Andric     if (!TruncateZero && expbuf.size() < 2)
42280b57cec5SDimitry Andric       expbuf.push_back('0');
42290b57cec5SDimitry Andric     for (unsigned I = 0, E = expbuf.size(); I != E; ++I)
42300b57cec5SDimitry Andric       Str.push_back(expbuf[E-1-I]);
42310b57cec5SDimitry Andric     return;
42320b57cec5SDimitry Andric   }
42330b57cec5SDimitry Andric 
42340b57cec5SDimitry Andric   // Non-scientific, positive exponents.
42350b57cec5SDimitry Andric   if (exp >= 0) {
42360b57cec5SDimitry Andric     for (unsigned I = 0; I != NDigits; ++I)
42370b57cec5SDimitry Andric       Str.push_back(buffer[NDigits-1-I]);
42380b57cec5SDimitry Andric     for (unsigned I = 0; I != (unsigned) exp; ++I)
42390b57cec5SDimitry Andric       Str.push_back('0');
42400b57cec5SDimitry Andric     return;
42410b57cec5SDimitry Andric   }
42420b57cec5SDimitry Andric 
42430b57cec5SDimitry Andric   // Non-scientific, negative exponents.
42440b57cec5SDimitry Andric 
42450b57cec5SDimitry Andric   // The number of digits to the left of the decimal point.
42460b57cec5SDimitry Andric   int NWholeDigits = exp + (int) NDigits;
42470b57cec5SDimitry Andric 
42480b57cec5SDimitry Andric   unsigned I = 0;
42490b57cec5SDimitry Andric   if (NWholeDigits > 0) {
42500b57cec5SDimitry Andric     for (; I != (unsigned) NWholeDigits; ++I)
42510b57cec5SDimitry Andric       Str.push_back(buffer[NDigits-I-1]);
42520b57cec5SDimitry Andric     Str.push_back('.');
42530b57cec5SDimitry Andric   } else {
42540b57cec5SDimitry Andric     unsigned NZeros = 1 + (unsigned) -NWholeDigits;
42550b57cec5SDimitry Andric 
42560b57cec5SDimitry Andric     Str.push_back('0');
42570b57cec5SDimitry Andric     Str.push_back('.');
42580b57cec5SDimitry Andric     for (unsigned Z = 1; Z != NZeros; ++Z)
42590b57cec5SDimitry Andric       Str.push_back('0');
42600b57cec5SDimitry Andric   }
42610b57cec5SDimitry Andric 
42620b57cec5SDimitry Andric   for (; I != NDigits; ++I)
42630b57cec5SDimitry Andric     Str.push_back(buffer[NDigits-I-1]);
42640b57cec5SDimitry Andric }
42650b57cec5SDimitry Andric 
getExactInverse(APFloat * inv) const42660b57cec5SDimitry Andric bool IEEEFloat::getExactInverse(APFloat *inv) const {
42670b57cec5SDimitry Andric   // Special floats and denormals have no exact inverse.
42680b57cec5SDimitry Andric   if (!isFiniteNonZero())
42690b57cec5SDimitry Andric     return false;
42700b57cec5SDimitry Andric 
42710b57cec5SDimitry Andric   // Check that the number is a power of two by making sure that only the
42720b57cec5SDimitry Andric   // integer bit is set in the significand.
42730b57cec5SDimitry Andric   if (significandLSB() != semantics->precision - 1)
42740b57cec5SDimitry Andric     return false;
42750b57cec5SDimitry Andric 
42760b57cec5SDimitry Andric   // Get the inverse.
42770b57cec5SDimitry Andric   IEEEFloat reciprocal(*semantics, 1ULL);
42780b57cec5SDimitry Andric   if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
42790b57cec5SDimitry Andric     return false;
42800b57cec5SDimitry Andric 
42810b57cec5SDimitry Andric   // Avoid multiplication with a denormal, it is not safe on all platforms and
42820b57cec5SDimitry Andric   // may be slower than a normal division.
42830b57cec5SDimitry Andric   if (reciprocal.isDenormal())
42840b57cec5SDimitry Andric     return false;
42850b57cec5SDimitry Andric 
42860b57cec5SDimitry Andric   assert(reciprocal.isFiniteNonZero() &&
42870b57cec5SDimitry Andric          reciprocal.significandLSB() == reciprocal.semantics->precision - 1);
42880b57cec5SDimitry Andric 
42890b57cec5SDimitry Andric   if (inv)
42900b57cec5SDimitry Andric     *inv = APFloat(reciprocal, *semantics);
42910b57cec5SDimitry Andric 
42920b57cec5SDimitry Andric   return true;
42930b57cec5SDimitry Andric }
42940b57cec5SDimitry Andric 
getExactLog2Abs() const4295*c9157d92SDimitry Andric int IEEEFloat::getExactLog2Abs() const {
4296*c9157d92SDimitry Andric   if (!isFinite() || isZero())
4297*c9157d92SDimitry Andric     return INT_MIN;
4298*c9157d92SDimitry Andric 
4299*c9157d92SDimitry Andric   const integerPart *Parts = significandParts();
4300*c9157d92SDimitry Andric   const int PartCount = partCountForBits(semantics->precision);
4301*c9157d92SDimitry Andric 
4302*c9157d92SDimitry Andric   int PopCount = 0;
4303*c9157d92SDimitry Andric   for (int i = 0; i < PartCount; ++i) {
4304*c9157d92SDimitry Andric     PopCount += llvm::popcount(Parts[i]);
4305*c9157d92SDimitry Andric     if (PopCount > 1)
4306*c9157d92SDimitry Andric       return INT_MIN;
4307*c9157d92SDimitry Andric   }
4308*c9157d92SDimitry Andric 
4309*c9157d92SDimitry Andric   if (exponent != semantics->minExponent)
4310*c9157d92SDimitry Andric     return exponent;
4311*c9157d92SDimitry Andric 
4312*c9157d92SDimitry Andric   int CountrParts = 0;
4313*c9157d92SDimitry Andric   for (int i = 0; i < PartCount;
4314*c9157d92SDimitry Andric        ++i, CountrParts += APInt::APINT_BITS_PER_WORD) {
4315*c9157d92SDimitry Andric     if (Parts[i] != 0) {
4316*c9157d92SDimitry Andric       return exponent - semantics->precision + CountrParts +
4317*c9157d92SDimitry Andric              llvm::countr_zero(Parts[i]) + 1;
4318*c9157d92SDimitry Andric     }
4319*c9157d92SDimitry Andric   }
4320*c9157d92SDimitry Andric 
4321*c9157d92SDimitry Andric   llvm_unreachable("didn't find the set bit");
4322*c9157d92SDimitry Andric }
4323*c9157d92SDimitry Andric 
isSignaling() const43240b57cec5SDimitry Andric bool IEEEFloat::isSignaling() const {
43250b57cec5SDimitry Andric   if (!isNaN())
43260b57cec5SDimitry Andric     return false;
4327bdd1243dSDimitry Andric   if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
4328bdd1243dSDimitry Andric     return false;
43290b57cec5SDimitry Andric 
43300b57cec5SDimitry Andric   // IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded with the
43310b57cec5SDimitry Andric   // first bit of the trailing significand being 0.
43320b57cec5SDimitry Andric   return !APInt::tcExtractBit(significandParts(), semantics->precision - 2);
43330b57cec5SDimitry Andric }
43340b57cec5SDimitry Andric 
43350b57cec5SDimitry Andric /// IEEE-754R 2008 5.3.1: nextUp/nextDown.
43360b57cec5SDimitry Andric ///
43370b57cec5SDimitry Andric /// *NOTE* since nextDown(x) = -nextUp(-x), we only implement nextUp with
43380b57cec5SDimitry Andric /// appropriate sign switching before/after the computation.
next(bool nextDown)43390b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::next(bool nextDown) {
43400b57cec5SDimitry Andric   // If we are performing nextDown, swap sign so we have -x.
43410b57cec5SDimitry Andric   if (nextDown)
43420b57cec5SDimitry Andric     changeSign();
43430b57cec5SDimitry Andric 
43440b57cec5SDimitry Andric   // Compute nextUp(x)
43450b57cec5SDimitry Andric   opStatus result = opOK;
43460b57cec5SDimitry Andric 
43470b57cec5SDimitry Andric   // Handle each float category separately.
43480b57cec5SDimitry Andric   switch (category) {
43490b57cec5SDimitry Andric   case fcInfinity:
43500b57cec5SDimitry Andric     // nextUp(+inf) = +inf
43510b57cec5SDimitry Andric     if (!isNegative())
43520b57cec5SDimitry Andric       break;
43530b57cec5SDimitry Andric     // nextUp(-inf) = -getLargest()
43540b57cec5SDimitry Andric     makeLargest(true);
43550b57cec5SDimitry Andric     break;
43560b57cec5SDimitry Andric   case fcNaN:
43570b57cec5SDimitry Andric     // IEEE-754R 2008 6.2 Par 2: nextUp(sNaN) = qNaN. Set Invalid flag.
43580b57cec5SDimitry Andric     // IEEE-754R 2008 6.2: nextUp(qNaN) = qNaN. Must be identity so we do not
43590b57cec5SDimitry Andric     //                     change the payload.
43600b57cec5SDimitry Andric     if (isSignaling()) {
43610b57cec5SDimitry Andric       result = opInvalidOp;
43620b57cec5SDimitry Andric       // For consistency, propagate the sign of the sNaN to the qNaN.
43630b57cec5SDimitry Andric       makeNaN(false, isNegative(), nullptr);
43640b57cec5SDimitry Andric     }
43650b57cec5SDimitry Andric     break;
43660b57cec5SDimitry Andric   case fcZero:
43670b57cec5SDimitry Andric     // nextUp(pm 0) = +getSmallest()
43680b57cec5SDimitry Andric     makeSmallest(false);
43690b57cec5SDimitry Andric     break;
43700b57cec5SDimitry Andric   case fcNormal:
43710b57cec5SDimitry Andric     // nextUp(-getSmallest()) = -0
43720b57cec5SDimitry Andric     if (isSmallest() && isNegative()) {
43730b57cec5SDimitry Andric       APInt::tcSet(significandParts(), 0, partCount());
43740b57cec5SDimitry Andric       category = fcZero;
43750b57cec5SDimitry Andric       exponent = 0;
4376fe013be4SDimitry Andric       if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
4377fe013be4SDimitry Andric         sign = false;
43780b57cec5SDimitry Andric       break;
43790b57cec5SDimitry Andric     }
43800b57cec5SDimitry Andric 
43810b57cec5SDimitry Andric     if (isLargest() && !isNegative()) {
4382bdd1243dSDimitry Andric       if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
4383bdd1243dSDimitry Andric         // nextUp(getLargest()) == NAN
4384bdd1243dSDimitry Andric         makeNaN();
4385bdd1243dSDimitry Andric         break;
4386bdd1243dSDimitry Andric       } else {
4387bdd1243dSDimitry Andric         // nextUp(getLargest()) == INFINITY
43880b57cec5SDimitry Andric         APInt::tcSet(significandParts(), 0, partCount());
43890b57cec5SDimitry Andric         category = fcInfinity;
43900b57cec5SDimitry Andric         exponent = semantics->maxExponent + 1;
43910b57cec5SDimitry Andric         break;
43920b57cec5SDimitry Andric       }
4393bdd1243dSDimitry Andric     }
43940b57cec5SDimitry Andric 
43950b57cec5SDimitry Andric     // nextUp(normal) == normal + inc.
43960b57cec5SDimitry Andric     if (isNegative()) {
43970b57cec5SDimitry Andric       // If we are negative, we need to decrement the significand.
43980b57cec5SDimitry Andric 
43990b57cec5SDimitry Andric       // We only cross a binade boundary that requires adjusting the exponent
44000b57cec5SDimitry Andric       // if:
44010b57cec5SDimitry Andric       //   1. exponent != semantics->minExponent. This implies we are not in the
44020b57cec5SDimitry Andric       //   smallest binade or are dealing with denormals.
44030b57cec5SDimitry Andric       //   2. Our significand excluding the integral bit is all zeros.
44040b57cec5SDimitry Andric       bool WillCrossBinadeBoundary =
44050b57cec5SDimitry Andric         exponent != semantics->minExponent && isSignificandAllZeros();
44060b57cec5SDimitry Andric 
44070b57cec5SDimitry Andric       // Decrement the significand.
44080b57cec5SDimitry Andric       //
44090b57cec5SDimitry Andric       // We always do this since:
44100b57cec5SDimitry Andric       //   1. If we are dealing with a non-binade decrement, by definition we
44110b57cec5SDimitry Andric       //   just decrement the significand.
44120b57cec5SDimitry Andric       //   2. If we are dealing with a normal -> normal binade decrement, since
44130b57cec5SDimitry Andric       //   we have an explicit integral bit the fact that all bits but the
44140b57cec5SDimitry Andric       //   integral bit are zero implies that subtracting one will yield a
44150b57cec5SDimitry Andric       //   significand with 0 integral bit and 1 in all other spots. Thus we
44160b57cec5SDimitry Andric       //   must just adjust the exponent and set the integral bit to 1.
44170b57cec5SDimitry Andric       //   3. If we are dealing with a normal -> denormal binade decrement,
44180b57cec5SDimitry Andric       //   since we set the integral bit to 0 when we represent denormals, we
44190b57cec5SDimitry Andric       //   just decrement the significand.
44200b57cec5SDimitry Andric       integerPart *Parts = significandParts();
44210b57cec5SDimitry Andric       APInt::tcDecrement(Parts, partCount());
44220b57cec5SDimitry Andric 
44230b57cec5SDimitry Andric       if (WillCrossBinadeBoundary) {
44240b57cec5SDimitry Andric         // Our result is a normal number. Do the following:
44250b57cec5SDimitry Andric         // 1. Set the integral bit to 1.
44260b57cec5SDimitry Andric         // 2. Decrement the exponent.
44270b57cec5SDimitry Andric         APInt::tcSetBit(Parts, semantics->precision - 1);
44280b57cec5SDimitry Andric         exponent--;
44290b57cec5SDimitry Andric       }
44300b57cec5SDimitry Andric     } else {
44310b57cec5SDimitry Andric       // If we are positive, we need to increment the significand.
44320b57cec5SDimitry Andric 
44330b57cec5SDimitry Andric       // We only cross a binade boundary that requires adjusting the exponent if
44340b57cec5SDimitry Andric       // the input is not a denormal and all of said input's significand bits
44350b57cec5SDimitry Andric       // are set. If all of said conditions are true: clear the significand, set
44360b57cec5SDimitry Andric       // the integral bit to 1, and increment the exponent. If we have a
44370b57cec5SDimitry Andric       // denormal always increment since moving denormals and the numbers in the
44380b57cec5SDimitry Andric       // smallest normal binade have the same exponent in our representation.
44390b57cec5SDimitry Andric       bool WillCrossBinadeBoundary = !isDenormal() && isSignificandAllOnes();
44400b57cec5SDimitry Andric 
44410b57cec5SDimitry Andric       if (WillCrossBinadeBoundary) {
44420b57cec5SDimitry Andric         integerPart *Parts = significandParts();
44430b57cec5SDimitry Andric         APInt::tcSet(Parts, 0, partCount());
44440b57cec5SDimitry Andric         APInt::tcSetBit(Parts, semantics->precision - 1);
44450b57cec5SDimitry Andric         assert(exponent != semantics->maxExponent &&
44460b57cec5SDimitry Andric                "We can not increment an exponent beyond the maxExponent allowed"
44470b57cec5SDimitry Andric                " by the given floating point semantics.");
44480b57cec5SDimitry Andric         exponent++;
44490b57cec5SDimitry Andric       } else {
44500b57cec5SDimitry Andric         incrementSignificand();
44510b57cec5SDimitry Andric       }
44520b57cec5SDimitry Andric     }
44530b57cec5SDimitry Andric     break;
44540b57cec5SDimitry Andric   }
44550b57cec5SDimitry Andric 
44560b57cec5SDimitry Andric   // If we are performing nextDown, swap sign so we have -nextUp(-x)
44570b57cec5SDimitry Andric   if (nextDown)
44580b57cec5SDimitry Andric     changeSign();
44590b57cec5SDimitry Andric 
44600b57cec5SDimitry Andric   return result;
44610b57cec5SDimitry Andric }
44620b57cec5SDimitry Andric 
exponentNaN() const4463e8d8bef9SDimitry Andric APFloatBase::ExponentType IEEEFloat::exponentNaN() const {
4464fe013be4SDimitry Andric   return ::exponentNaN(*semantics);
4465e8d8bef9SDimitry Andric }
4466e8d8bef9SDimitry Andric 
exponentInf() const4467e8d8bef9SDimitry Andric APFloatBase::ExponentType IEEEFloat::exponentInf() const {
4468fe013be4SDimitry Andric   return ::exponentInf(*semantics);
4469e8d8bef9SDimitry Andric }
4470e8d8bef9SDimitry Andric 
exponentZero() const4471e8d8bef9SDimitry Andric APFloatBase::ExponentType IEEEFloat::exponentZero() const {
4472fe013be4SDimitry Andric   return ::exponentZero(*semantics);
4473e8d8bef9SDimitry Andric }
4474e8d8bef9SDimitry Andric 
makeInf(bool Negative)44750b57cec5SDimitry Andric void IEEEFloat::makeInf(bool Negative) {
4476bdd1243dSDimitry Andric   if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
4477bdd1243dSDimitry Andric     // There is no Inf, so make NaN instead.
4478bdd1243dSDimitry Andric     makeNaN(false, Negative);
4479bdd1243dSDimitry Andric     return;
4480bdd1243dSDimitry Andric   }
44810b57cec5SDimitry Andric   category = fcInfinity;
44820b57cec5SDimitry Andric   sign = Negative;
4483e8d8bef9SDimitry Andric   exponent = exponentInf();
44840b57cec5SDimitry Andric   APInt::tcSet(significandParts(), 0, partCount());
44850b57cec5SDimitry Andric }
44860b57cec5SDimitry Andric 
makeZero(bool Negative)44870b57cec5SDimitry Andric void IEEEFloat::makeZero(bool Negative) {
44880b57cec5SDimitry Andric   category = fcZero;
44890b57cec5SDimitry Andric   sign = Negative;
4490fe013be4SDimitry Andric   if (semantics->nanEncoding == fltNanEncoding::NegativeZero) {
4491fe013be4SDimitry Andric     // Merge negative zero to positive because 0b10000...000 is used for NaN
4492fe013be4SDimitry Andric     sign = false;
4493fe013be4SDimitry Andric   }
4494e8d8bef9SDimitry Andric   exponent = exponentZero();
44950b57cec5SDimitry Andric   APInt::tcSet(significandParts(), 0, partCount());
44960b57cec5SDimitry Andric }
44970b57cec5SDimitry Andric 
makeQuiet()44980b57cec5SDimitry Andric void IEEEFloat::makeQuiet() {
44990b57cec5SDimitry Andric   assert(isNaN());
4500bdd1243dSDimitry Andric   if (semantics->nonFiniteBehavior != fltNonfiniteBehavior::NanOnly)
45010b57cec5SDimitry Andric     APInt::tcSetBit(significandParts(), semantics->precision - 2);
45020b57cec5SDimitry Andric }
45030b57cec5SDimitry Andric 
ilogb(const IEEEFloat & Arg)45040b57cec5SDimitry Andric int ilogb(const IEEEFloat &Arg) {
45050b57cec5SDimitry Andric   if (Arg.isNaN())
45060b57cec5SDimitry Andric     return IEEEFloat::IEK_NaN;
45070b57cec5SDimitry Andric   if (Arg.isZero())
45080b57cec5SDimitry Andric     return IEEEFloat::IEK_Zero;
45090b57cec5SDimitry Andric   if (Arg.isInfinity())
45100b57cec5SDimitry Andric     return IEEEFloat::IEK_Inf;
45110b57cec5SDimitry Andric   if (!Arg.isDenormal())
45120b57cec5SDimitry Andric     return Arg.exponent;
45130b57cec5SDimitry Andric 
45140b57cec5SDimitry Andric   IEEEFloat Normalized(Arg);
45150b57cec5SDimitry Andric   int SignificandBits = Arg.getSemantics().precision - 1;
45160b57cec5SDimitry Andric 
45170b57cec5SDimitry Andric   Normalized.exponent += SignificandBits;
45180b57cec5SDimitry Andric   Normalized.normalize(IEEEFloat::rmNearestTiesToEven, lfExactlyZero);
45190b57cec5SDimitry Andric   return Normalized.exponent - SignificandBits;
45200b57cec5SDimitry Andric }
45210b57cec5SDimitry Andric 
scalbn(IEEEFloat X,int Exp,IEEEFloat::roundingMode RoundingMode)45220b57cec5SDimitry Andric IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode RoundingMode) {
45230b57cec5SDimitry Andric   auto MaxExp = X.getSemantics().maxExponent;
45240b57cec5SDimitry Andric   auto MinExp = X.getSemantics().minExponent;
45250b57cec5SDimitry Andric 
45260b57cec5SDimitry Andric   // If Exp is wildly out-of-scale, simply adding it to X.exponent will
45270b57cec5SDimitry Andric   // overflow; clamp it to a safe range before adding, but ensure that the range
45280b57cec5SDimitry Andric   // is large enough that the clamp does not change the result. The range we
45290b57cec5SDimitry Andric   // need to support is the difference between the largest possible exponent and
45300b57cec5SDimitry Andric   // the normalized exponent of half the smallest denormal.
45310b57cec5SDimitry Andric 
45320b57cec5SDimitry Andric   int SignificandBits = X.getSemantics().precision - 1;
45330b57cec5SDimitry Andric   int MaxIncrement = MaxExp - (MinExp - SignificandBits) + 1;
45340b57cec5SDimitry Andric 
45350b57cec5SDimitry Andric   // Clamp to one past the range ends to let normalize handle overlflow.
4536fe013be4SDimitry Andric   X.exponent += std::clamp(Exp, -MaxIncrement - 1, MaxIncrement);
45370b57cec5SDimitry Andric   X.normalize(RoundingMode, lfExactlyZero);
45380b57cec5SDimitry Andric   if (X.isNaN())
45390b57cec5SDimitry Andric     X.makeQuiet();
45400b57cec5SDimitry Andric   return X;
45410b57cec5SDimitry Andric }
45420b57cec5SDimitry Andric 
frexp(const IEEEFloat & Val,int & Exp,IEEEFloat::roundingMode RM)45430b57cec5SDimitry Andric IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM) {
45440b57cec5SDimitry Andric   Exp = ilogb(Val);
45450b57cec5SDimitry Andric 
45460b57cec5SDimitry Andric   // Quiet signalling nans.
45470b57cec5SDimitry Andric   if (Exp == IEEEFloat::IEK_NaN) {
45480b57cec5SDimitry Andric     IEEEFloat Quiet(Val);
45490b57cec5SDimitry Andric     Quiet.makeQuiet();
45500b57cec5SDimitry Andric     return Quiet;
45510b57cec5SDimitry Andric   }
45520b57cec5SDimitry Andric 
45530b57cec5SDimitry Andric   if (Exp == IEEEFloat::IEK_Inf)
45540b57cec5SDimitry Andric     return Val;
45550b57cec5SDimitry Andric 
45560b57cec5SDimitry Andric   // 1 is added because frexp is defined to return a normalized fraction in
45570b57cec5SDimitry Andric   // +/-[0.5, 1.0), rather than the usual +/-[1.0, 2.0).
45580b57cec5SDimitry Andric   Exp = Exp == IEEEFloat::IEK_Zero ? 0 : Exp + 1;
45590b57cec5SDimitry Andric   return scalbn(Val, -Exp, RM);
45600b57cec5SDimitry Andric }
45610b57cec5SDimitry Andric 
DoubleAPFloat(const fltSemantics & S)45620b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S)
45630b57cec5SDimitry Andric     : Semantics(&S),
45640b57cec5SDimitry Andric       Floats(new APFloat[2]{APFloat(semIEEEdouble), APFloat(semIEEEdouble)}) {
45650b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
45660b57cec5SDimitry Andric }
45670b57cec5SDimitry Andric 
DoubleAPFloat(const fltSemantics & S,uninitializedTag)45680b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, uninitializedTag)
45690b57cec5SDimitry Andric     : Semantics(&S),
45700b57cec5SDimitry Andric       Floats(new APFloat[2]{APFloat(semIEEEdouble, uninitialized),
45710b57cec5SDimitry Andric                             APFloat(semIEEEdouble, uninitialized)}) {
45720b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
45730b57cec5SDimitry Andric }
45740b57cec5SDimitry Andric 
DoubleAPFloat(const fltSemantics & S,integerPart I)45750b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, integerPart I)
45760b57cec5SDimitry Andric     : Semantics(&S), Floats(new APFloat[2]{APFloat(semIEEEdouble, I),
45770b57cec5SDimitry Andric                                            APFloat(semIEEEdouble)}) {
45780b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
45790b57cec5SDimitry Andric }
45800b57cec5SDimitry Andric 
DoubleAPFloat(const fltSemantics & S,const APInt & I)45810b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, const APInt &I)
45820b57cec5SDimitry Andric     : Semantics(&S),
45830b57cec5SDimitry Andric       Floats(new APFloat[2]{
45840b57cec5SDimitry Andric           APFloat(semIEEEdouble, APInt(64, I.getRawData()[0])),
45850b57cec5SDimitry Andric           APFloat(semIEEEdouble, APInt(64, I.getRawData()[1]))}) {
45860b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
45870b57cec5SDimitry Andric }
45880b57cec5SDimitry Andric 
DoubleAPFloat(const fltSemantics & S,APFloat && First,APFloat && Second)45890b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, APFloat &&First,
45900b57cec5SDimitry Andric                              APFloat &&Second)
45910b57cec5SDimitry Andric     : Semantics(&S),
45920b57cec5SDimitry Andric       Floats(new APFloat[2]{std::move(First), std::move(Second)}) {
45930b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
45940b57cec5SDimitry Andric   assert(&Floats[0].getSemantics() == &semIEEEdouble);
45950b57cec5SDimitry Andric   assert(&Floats[1].getSemantics() == &semIEEEdouble);
45960b57cec5SDimitry Andric }
45970b57cec5SDimitry Andric 
DoubleAPFloat(const DoubleAPFloat & RHS)45980b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const DoubleAPFloat &RHS)
45990b57cec5SDimitry Andric     : Semantics(RHS.Semantics),
46000b57cec5SDimitry Andric       Floats(RHS.Floats ? new APFloat[2]{APFloat(RHS.Floats[0]),
46010b57cec5SDimitry Andric                                          APFloat(RHS.Floats[1])}
46020b57cec5SDimitry Andric                         : nullptr) {
46030b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
46040b57cec5SDimitry Andric }
46050b57cec5SDimitry Andric 
DoubleAPFloat(DoubleAPFloat && RHS)46060b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(DoubleAPFloat &&RHS)
46070b57cec5SDimitry Andric     : Semantics(RHS.Semantics), Floats(std::move(RHS.Floats)) {
46080b57cec5SDimitry Andric   RHS.Semantics = &semBogus;
46090b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble);
46100b57cec5SDimitry Andric }
46110b57cec5SDimitry Andric 
operator =(const DoubleAPFloat & RHS)46120b57cec5SDimitry Andric DoubleAPFloat &DoubleAPFloat::operator=(const DoubleAPFloat &RHS) {
46130b57cec5SDimitry Andric   if (Semantics == RHS.Semantics && RHS.Floats) {
46140b57cec5SDimitry Andric     Floats[0] = RHS.Floats[0];
46150b57cec5SDimitry Andric     Floats[1] = RHS.Floats[1];
46160b57cec5SDimitry Andric   } else if (this != &RHS) {
46170b57cec5SDimitry Andric     this->~DoubleAPFloat();
46180b57cec5SDimitry Andric     new (this) DoubleAPFloat(RHS);
46190b57cec5SDimitry Andric   }
46200b57cec5SDimitry Andric   return *this;
46210b57cec5SDimitry Andric }
46220b57cec5SDimitry Andric 
46230b57cec5SDimitry Andric // Implement addition, subtraction, multiplication and division based on:
46240b57cec5SDimitry Andric // "Software for Doubled-Precision Floating-Point Computations",
46250b57cec5SDimitry 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)46260b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::addImpl(const APFloat &a, const APFloat &aa,
46270b57cec5SDimitry Andric                                          const APFloat &c, const APFloat &cc,
46280b57cec5SDimitry Andric                                          roundingMode RM) {
46290b57cec5SDimitry Andric   int Status = opOK;
46300b57cec5SDimitry Andric   APFloat z = a;
46310b57cec5SDimitry Andric   Status |= z.add(c, RM);
46320b57cec5SDimitry Andric   if (!z.isFinite()) {
46330b57cec5SDimitry Andric     if (!z.isInfinity()) {
46340b57cec5SDimitry Andric       Floats[0] = std::move(z);
46350b57cec5SDimitry Andric       Floats[1].makeZero(/* Neg = */ false);
46360b57cec5SDimitry Andric       return (opStatus)Status;
46370b57cec5SDimitry Andric     }
46380b57cec5SDimitry Andric     Status = opOK;
46390b57cec5SDimitry Andric     auto AComparedToC = a.compareAbsoluteValue(c);
46400b57cec5SDimitry Andric     z = cc;
46410b57cec5SDimitry Andric     Status |= z.add(aa, RM);
46420b57cec5SDimitry Andric     if (AComparedToC == APFloat::cmpGreaterThan) {
46430b57cec5SDimitry Andric       // z = cc + aa + c + a;
46440b57cec5SDimitry Andric       Status |= z.add(c, RM);
46450b57cec5SDimitry Andric       Status |= z.add(a, RM);
46460b57cec5SDimitry Andric     } else {
46470b57cec5SDimitry Andric       // z = cc + aa + a + c;
46480b57cec5SDimitry Andric       Status |= z.add(a, RM);
46490b57cec5SDimitry Andric       Status |= z.add(c, RM);
46500b57cec5SDimitry Andric     }
46510b57cec5SDimitry Andric     if (!z.isFinite()) {
46520b57cec5SDimitry Andric       Floats[0] = std::move(z);
46530b57cec5SDimitry Andric       Floats[1].makeZero(/* Neg = */ false);
46540b57cec5SDimitry Andric       return (opStatus)Status;
46550b57cec5SDimitry Andric     }
46560b57cec5SDimitry Andric     Floats[0] = z;
46570b57cec5SDimitry Andric     APFloat zz = aa;
46580b57cec5SDimitry Andric     Status |= zz.add(cc, RM);
46590b57cec5SDimitry Andric     if (AComparedToC == APFloat::cmpGreaterThan) {
46600b57cec5SDimitry Andric       // Floats[1] = a - z + c + zz;
46610b57cec5SDimitry Andric       Floats[1] = a;
46620b57cec5SDimitry Andric       Status |= Floats[1].subtract(z, RM);
46630b57cec5SDimitry Andric       Status |= Floats[1].add(c, RM);
46640b57cec5SDimitry Andric       Status |= Floats[1].add(zz, RM);
46650b57cec5SDimitry Andric     } else {
46660b57cec5SDimitry Andric       // Floats[1] = c - z + a + zz;
46670b57cec5SDimitry Andric       Floats[1] = c;
46680b57cec5SDimitry Andric       Status |= Floats[1].subtract(z, RM);
46690b57cec5SDimitry Andric       Status |= Floats[1].add(a, RM);
46700b57cec5SDimitry Andric       Status |= Floats[1].add(zz, RM);
46710b57cec5SDimitry Andric     }
46720b57cec5SDimitry Andric   } else {
46730b57cec5SDimitry Andric     // q = a - z;
46740b57cec5SDimitry Andric     APFloat q = a;
46750b57cec5SDimitry Andric     Status |= q.subtract(z, RM);
46760b57cec5SDimitry Andric 
46770b57cec5SDimitry Andric     // zz = q + c + (a - (q + z)) + aa + cc;
46780b57cec5SDimitry Andric     // Compute a - (q + z) as -((q + z) - a) to avoid temporary copies.
46790b57cec5SDimitry Andric     auto zz = q;
46800b57cec5SDimitry Andric     Status |= zz.add(c, RM);
46810b57cec5SDimitry Andric     Status |= q.add(z, RM);
46820b57cec5SDimitry Andric     Status |= q.subtract(a, RM);
46830b57cec5SDimitry Andric     q.changeSign();
46840b57cec5SDimitry Andric     Status |= zz.add(q, RM);
46850b57cec5SDimitry Andric     Status |= zz.add(aa, RM);
46860b57cec5SDimitry Andric     Status |= zz.add(cc, RM);
46870b57cec5SDimitry Andric     if (zz.isZero() && !zz.isNegative()) {
46880b57cec5SDimitry Andric       Floats[0] = std::move(z);
46890b57cec5SDimitry Andric       Floats[1].makeZero(/* Neg = */ false);
46900b57cec5SDimitry Andric       return opOK;
46910b57cec5SDimitry Andric     }
46920b57cec5SDimitry Andric     Floats[0] = z;
46930b57cec5SDimitry Andric     Status |= Floats[0].add(zz, RM);
46940b57cec5SDimitry Andric     if (!Floats[0].isFinite()) {
46950b57cec5SDimitry Andric       Floats[1].makeZero(/* Neg = */ false);
46960b57cec5SDimitry Andric       return (opStatus)Status;
46970b57cec5SDimitry Andric     }
46980b57cec5SDimitry Andric     Floats[1] = std::move(z);
46990b57cec5SDimitry Andric     Status |= Floats[1].subtract(Floats[0], RM);
47000b57cec5SDimitry Andric     Status |= Floats[1].add(zz, RM);
47010b57cec5SDimitry Andric   }
47020b57cec5SDimitry Andric   return (opStatus)Status;
47030b57cec5SDimitry Andric }
47040b57cec5SDimitry Andric 
addWithSpecial(const DoubleAPFloat & LHS,const DoubleAPFloat & RHS,DoubleAPFloat & Out,roundingMode RM)47050b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::addWithSpecial(const DoubleAPFloat &LHS,
47060b57cec5SDimitry Andric                                                 const DoubleAPFloat &RHS,
47070b57cec5SDimitry Andric                                                 DoubleAPFloat &Out,
47080b57cec5SDimitry Andric                                                 roundingMode RM) {
47090b57cec5SDimitry Andric   if (LHS.getCategory() == fcNaN) {
47100b57cec5SDimitry Andric     Out = LHS;
47110b57cec5SDimitry Andric     return opOK;
47120b57cec5SDimitry Andric   }
47130b57cec5SDimitry Andric   if (RHS.getCategory() == fcNaN) {
47140b57cec5SDimitry Andric     Out = RHS;
47150b57cec5SDimitry Andric     return opOK;
47160b57cec5SDimitry Andric   }
47170b57cec5SDimitry Andric   if (LHS.getCategory() == fcZero) {
47180b57cec5SDimitry Andric     Out = RHS;
47190b57cec5SDimitry Andric     return opOK;
47200b57cec5SDimitry Andric   }
47210b57cec5SDimitry Andric   if (RHS.getCategory() == fcZero) {
47220b57cec5SDimitry Andric     Out = LHS;
47230b57cec5SDimitry Andric     return opOK;
47240b57cec5SDimitry Andric   }
47250b57cec5SDimitry Andric   if (LHS.getCategory() == fcInfinity && RHS.getCategory() == fcInfinity &&
47260b57cec5SDimitry Andric       LHS.isNegative() != RHS.isNegative()) {
47270b57cec5SDimitry Andric     Out.makeNaN(false, Out.isNegative(), nullptr);
47280b57cec5SDimitry Andric     return opInvalidOp;
47290b57cec5SDimitry Andric   }
47300b57cec5SDimitry Andric   if (LHS.getCategory() == fcInfinity) {
47310b57cec5SDimitry Andric     Out = LHS;
47320b57cec5SDimitry Andric     return opOK;
47330b57cec5SDimitry Andric   }
47340b57cec5SDimitry Andric   if (RHS.getCategory() == fcInfinity) {
47350b57cec5SDimitry Andric     Out = RHS;
47360b57cec5SDimitry Andric     return opOK;
47370b57cec5SDimitry Andric   }
47380b57cec5SDimitry Andric   assert(LHS.getCategory() == fcNormal && RHS.getCategory() == fcNormal);
47390b57cec5SDimitry Andric 
47400b57cec5SDimitry Andric   APFloat A(LHS.Floats[0]), AA(LHS.Floats[1]), C(RHS.Floats[0]),
47410b57cec5SDimitry Andric       CC(RHS.Floats[1]);
47420b57cec5SDimitry Andric   assert(&A.getSemantics() == &semIEEEdouble);
47430b57cec5SDimitry Andric   assert(&AA.getSemantics() == &semIEEEdouble);
47440b57cec5SDimitry Andric   assert(&C.getSemantics() == &semIEEEdouble);
47450b57cec5SDimitry Andric   assert(&CC.getSemantics() == &semIEEEdouble);
47460b57cec5SDimitry Andric   assert(&Out.Floats[0].getSemantics() == &semIEEEdouble);
47470b57cec5SDimitry Andric   assert(&Out.Floats[1].getSemantics() == &semIEEEdouble);
47480b57cec5SDimitry Andric   return Out.addImpl(A, AA, C, CC, RM);
47490b57cec5SDimitry Andric }
47500b57cec5SDimitry Andric 
add(const DoubleAPFloat & RHS,roundingMode RM)47510b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::add(const DoubleAPFloat &RHS,
47520b57cec5SDimitry Andric                                      roundingMode RM) {
47530b57cec5SDimitry Andric   return addWithSpecial(*this, RHS, *this, RM);
47540b57cec5SDimitry Andric }
47550b57cec5SDimitry Andric 
subtract(const DoubleAPFloat & RHS,roundingMode RM)47560b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::subtract(const DoubleAPFloat &RHS,
47570b57cec5SDimitry Andric                                           roundingMode RM) {
47580b57cec5SDimitry Andric   changeSign();
47590b57cec5SDimitry Andric   auto Ret = add(RHS, RM);
47600b57cec5SDimitry Andric   changeSign();
47610b57cec5SDimitry Andric   return Ret;
47620b57cec5SDimitry Andric }
47630b57cec5SDimitry Andric 
multiply(const DoubleAPFloat & RHS,APFloat::roundingMode RM)47640b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::multiply(const DoubleAPFloat &RHS,
47650b57cec5SDimitry Andric                                           APFloat::roundingMode RM) {
47660b57cec5SDimitry Andric   const auto &LHS = *this;
47670b57cec5SDimitry Andric   auto &Out = *this;
47680b57cec5SDimitry Andric   /* Interesting observation: For special categories, finding the lowest
47690b57cec5SDimitry Andric      common ancestor of the following layered graph gives the correct
47700b57cec5SDimitry Andric      return category:
47710b57cec5SDimitry Andric 
47720b57cec5SDimitry Andric         NaN
47730b57cec5SDimitry Andric        /   \
47740b57cec5SDimitry Andric      Zero  Inf
47750b57cec5SDimitry Andric        \   /
47760b57cec5SDimitry Andric        Normal
47770b57cec5SDimitry Andric 
47780b57cec5SDimitry Andric      e.g. NaN * NaN = NaN
47790b57cec5SDimitry Andric           Zero * Inf = NaN
47800b57cec5SDimitry Andric           Normal * Zero = Zero
47810b57cec5SDimitry Andric           Normal * Inf = Inf
47820b57cec5SDimitry Andric   */
47830b57cec5SDimitry Andric   if (LHS.getCategory() == fcNaN) {
47840b57cec5SDimitry Andric     Out = LHS;
47850b57cec5SDimitry Andric     return opOK;
47860b57cec5SDimitry Andric   }
47870b57cec5SDimitry Andric   if (RHS.getCategory() == fcNaN) {
47880b57cec5SDimitry Andric     Out = RHS;
47890b57cec5SDimitry Andric     return opOK;
47900b57cec5SDimitry Andric   }
47910b57cec5SDimitry Andric   if ((LHS.getCategory() == fcZero && RHS.getCategory() == fcInfinity) ||
47920b57cec5SDimitry Andric       (LHS.getCategory() == fcInfinity && RHS.getCategory() == fcZero)) {
47930b57cec5SDimitry Andric     Out.makeNaN(false, false, nullptr);
47940b57cec5SDimitry Andric     return opOK;
47950b57cec5SDimitry Andric   }
47960b57cec5SDimitry Andric   if (LHS.getCategory() == fcZero || LHS.getCategory() == fcInfinity) {
47970b57cec5SDimitry Andric     Out = LHS;
47980b57cec5SDimitry Andric     return opOK;
47990b57cec5SDimitry Andric   }
48000b57cec5SDimitry Andric   if (RHS.getCategory() == fcZero || RHS.getCategory() == fcInfinity) {
48010b57cec5SDimitry Andric     Out = RHS;
48020b57cec5SDimitry Andric     return opOK;
48030b57cec5SDimitry Andric   }
48040b57cec5SDimitry Andric   assert(LHS.getCategory() == fcNormal && RHS.getCategory() == fcNormal &&
48050b57cec5SDimitry Andric          "Special cases not handled exhaustively");
48060b57cec5SDimitry Andric 
48070b57cec5SDimitry Andric   int Status = opOK;
48080b57cec5SDimitry Andric   APFloat A = Floats[0], B = Floats[1], C = RHS.Floats[0], D = RHS.Floats[1];
48090b57cec5SDimitry Andric   // t = a * c
48100b57cec5SDimitry Andric   APFloat T = A;
48110b57cec5SDimitry Andric   Status |= T.multiply(C, RM);
48120b57cec5SDimitry Andric   if (!T.isFiniteNonZero()) {
48130b57cec5SDimitry Andric     Floats[0] = T;
48140b57cec5SDimitry Andric     Floats[1].makeZero(/* Neg = */ false);
48150b57cec5SDimitry Andric     return (opStatus)Status;
48160b57cec5SDimitry Andric   }
48170b57cec5SDimitry Andric 
48180b57cec5SDimitry Andric   // tau = fmsub(a, c, t), that is -fmadd(-a, c, t).
48190b57cec5SDimitry Andric   APFloat Tau = A;
48200b57cec5SDimitry Andric   T.changeSign();
48210b57cec5SDimitry Andric   Status |= Tau.fusedMultiplyAdd(C, T, RM);
48220b57cec5SDimitry Andric   T.changeSign();
48230b57cec5SDimitry Andric   {
48240b57cec5SDimitry Andric     // v = a * d
48250b57cec5SDimitry Andric     APFloat V = A;
48260b57cec5SDimitry Andric     Status |= V.multiply(D, RM);
48270b57cec5SDimitry Andric     // w = b * c
48280b57cec5SDimitry Andric     APFloat W = B;
48290b57cec5SDimitry Andric     Status |= W.multiply(C, RM);
48300b57cec5SDimitry Andric     Status |= V.add(W, RM);
48310b57cec5SDimitry Andric     // tau += v + w
48320b57cec5SDimitry Andric     Status |= Tau.add(V, RM);
48330b57cec5SDimitry Andric   }
48340b57cec5SDimitry Andric   // u = t + tau
48350b57cec5SDimitry Andric   APFloat U = T;
48360b57cec5SDimitry Andric   Status |= U.add(Tau, RM);
48370b57cec5SDimitry Andric 
48380b57cec5SDimitry Andric   Floats[0] = U;
48390b57cec5SDimitry Andric   if (!U.isFinite()) {
48400b57cec5SDimitry Andric     Floats[1].makeZero(/* Neg = */ false);
48410b57cec5SDimitry Andric   } else {
48420b57cec5SDimitry Andric     // Floats[1] = (t - u) + tau
48430b57cec5SDimitry Andric     Status |= T.subtract(U, RM);
48440b57cec5SDimitry Andric     Status |= T.add(Tau, RM);
48450b57cec5SDimitry Andric     Floats[1] = T;
48460b57cec5SDimitry Andric   }
48470b57cec5SDimitry Andric   return (opStatus)Status;
48480b57cec5SDimitry Andric }
48490b57cec5SDimitry Andric 
divide(const DoubleAPFloat & RHS,APFloat::roundingMode RM)48500b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::divide(const DoubleAPFloat &RHS,
48510b57cec5SDimitry Andric                                         APFloat::roundingMode RM) {
48520b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
48530b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
48540b57cec5SDimitry Andric   auto Ret =
48550b57cec5SDimitry Andric       Tmp.divide(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()), RM);
48560b57cec5SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
48570b57cec5SDimitry Andric   return Ret;
48580b57cec5SDimitry Andric }
48590b57cec5SDimitry Andric 
remainder(const DoubleAPFloat & RHS)48600b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::remainder(const DoubleAPFloat &RHS) {
48610b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
48620b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
48630b57cec5SDimitry Andric   auto Ret =
48640b57cec5SDimitry Andric       Tmp.remainder(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()));
48650b57cec5SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
48660b57cec5SDimitry Andric   return Ret;
48670b57cec5SDimitry Andric }
48680b57cec5SDimitry Andric 
mod(const DoubleAPFloat & RHS)48690b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::mod(const DoubleAPFloat &RHS) {
48700b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
48710b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
48720b57cec5SDimitry Andric   auto Ret = Tmp.mod(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()));
48730b57cec5SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
48740b57cec5SDimitry Andric   return Ret;
48750b57cec5SDimitry Andric }
48760b57cec5SDimitry Andric 
48770b57cec5SDimitry Andric APFloat::opStatus
fusedMultiplyAdd(const DoubleAPFloat & Multiplicand,const DoubleAPFloat & Addend,APFloat::roundingMode RM)48780b57cec5SDimitry Andric DoubleAPFloat::fusedMultiplyAdd(const DoubleAPFloat &Multiplicand,
48790b57cec5SDimitry Andric                                 const DoubleAPFloat &Addend,
48800b57cec5SDimitry Andric                                 APFloat::roundingMode RM) {
48810b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
48820b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
48830b57cec5SDimitry Andric   auto Ret = Tmp.fusedMultiplyAdd(
48840b57cec5SDimitry Andric       APFloat(semPPCDoubleDoubleLegacy, Multiplicand.bitcastToAPInt()),
48850b57cec5SDimitry Andric       APFloat(semPPCDoubleDoubleLegacy, Addend.bitcastToAPInt()), RM);
48860b57cec5SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
48870b57cec5SDimitry Andric   return Ret;
48880b57cec5SDimitry Andric }
48890b57cec5SDimitry Andric 
roundToIntegral(APFloat::roundingMode RM)48900b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::roundToIntegral(APFloat::roundingMode RM) {
48910b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
48920b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
48930b57cec5SDimitry Andric   auto Ret = Tmp.roundToIntegral(RM);
48940b57cec5SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
48950b57cec5SDimitry Andric   return Ret;
48960b57cec5SDimitry Andric }
48970b57cec5SDimitry Andric 
changeSign()48980b57cec5SDimitry Andric void DoubleAPFloat::changeSign() {
48990b57cec5SDimitry Andric   Floats[0].changeSign();
49000b57cec5SDimitry Andric   Floats[1].changeSign();
49010b57cec5SDimitry Andric }
49020b57cec5SDimitry Andric 
49030b57cec5SDimitry Andric APFloat::cmpResult
compareAbsoluteValue(const DoubleAPFloat & RHS) const49040b57cec5SDimitry Andric DoubleAPFloat::compareAbsoluteValue(const DoubleAPFloat &RHS) const {
49050b57cec5SDimitry Andric   auto Result = Floats[0].compareAbsoluteValue(RHS.Floats[0]);
49060b57cec5SDimitry Andric   if (Result != cmpEqual)
49070b57cec5SDimitry Andric     return Result;
49080b57cec5SDimitry Andric   Result = Floats[1].compareAbsoluteValue(RHS.Floats[1]);
49090b57cec5SDimitry Andric   if (Result == cmpLessThan || Result == cmpGreaterThan) {
49100b57cec5SDimitry Andric     auto Against = Floats[0].isNegative() ^ Floats[1].isNegative();
49110b57cec5SDimitry Andric     auto RHSAgainst = RHS.Floats[0].isNegative() ^ RHS.Floats[1].isNegative();
49120b57cec5SDimitry Andric     if (Against && !RHSAgainst)
49130b57cec5SDimitry Andric       return cmpLessThan;
49140b57cec5SDimitry Andric     if (!Against && RHSAgainst)
49150b57cec5SDimitry Andric       return cmpGreaterThan;
49160b57cec5SDimitry Andric     if (!Against && !RHSAgainst)
49170b57cec5SDimitry Andric       return Result;
49180b57cec5SDimitry Andric     if (Against && RHSAgainst)
49190b57cec5SDimitry Andric       return (cmpResult)(cmpLessThan + cmpGreaterThan - Result);
49200b57cec5SDimitry Andric   }
49210b57cec5SDimitry Andric   return Result;
49220b57cec5SDimitry Andric }
49230b57cec5SDimitry Andric 
getCategory() const49240b57cec5SDimitry Andric APFloat::fltCategory DoubleAPFloat::getCategory() const {
49250b57cec5SDimitry Andric   return Floats[0].getCategory();
49260b57cec5SDimitry Andric }
49270b57cec5SDimitry Andric 
isNegative() const49280b57cec5SDimitry Andric bool DoubleAPFloat::isNegative() const { return Floats[0].isNegative(); }
49290b57cec5SDimitry Andric 
makeInf(bool Neg)49300b57cec5SDimitry Andric void DoubleAPFloat::makeInf(bool Neg) {
49310b57cec5SDimitry Andric   Floats[0].makeInf(Neg);
49320b57cec5SDimitry Andric   Floats[1].makeZero(/* Neg = */ false);
49330b57cec5SDimitry Andric }
49340b57cec5SDimitry Andric 
makeZero(bool Neg)49350b57cec5SDimitry Andric void DoubleAPFloat::makeZero(bool Neg) {
49360b57cec5SDimitry Andric   Floats[0].makeZero(Neg);
49370b57cec5SDimitry Andric   Floats[1].makeZero(/* Neg = */ false);
49380b57cec5SDimitry Andric }
49390b57cec5SDimitry Andric 
makeLargest(bool Neg)49400b57cec5SDimitry Andric void DoubleAPFloat::makeLargest(bool Neg) {
49410b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
49420b57cec5SDimitry Andric   Floats[0] = APFloat(semIEEEdouble, APInt(64, 0x7fefffffffffffffull));
49430b57cec5SDimitry Andric   Floats[1] = APFloat(semIEEEdouble, APInt(64, 0x7c8ffffffffffffeull));
49440b57cec5SDimitry Andric   if (Neg)
49450b57cec5SDimitry Andric     changeSign();
49460b57cec5SDimitry Andric }
49470b57cec5SDimitry Andric 
makeSmallest(bool Neg)49480b57cec5SDimitry Andric void DoubleAPFloat::makeSmallest(bool Neg) {
49490b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
49500b57cec5SDimitry Andric   Floats[0].makeSmallest(Neg);
49510b57cec5SDimitry Andric   Floats[1].makeZero(/* Neg = */ false);
49520b57cec5SDimitry Andric }
49530b57cec5SDimitry Andric 
makeSmallestNormalized(bool Neg)49540b57cec5SDimitry Andric void DoubleAPFloat::makeSmallestNormalized(bool Neg) {
49550b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
49560b57cec5SDimitry Andric   Floats[0] = APFloat(semIEEEdouble, APInt(64, 0x0360000000000000ull));
49570b57cec5SDimitry Andric   if (Neg)
49580b57cec5SDimitry Andric     Floats[0].changeSign();
49590b57cec5SDimitry Andric   Floats[1].makeZero(/* Neg = */ false);
49600b57cec5SDimitry Andric }
49610b57cec5SDimitry Andric 
makeNaN(bool SNaN,bool Neg,const APInt * fill)49620b57cec5SDimitry Andric void DoubleAPFloat::makeNaN(bool SNaN, bool Neg, const APInt *fill) {
49630b57cec5SDimitry Andric   Floats[0].makeNaN(SNaN, Neg, fill);
49640b57cec5SDimitry Andric   Floats[1].makeZero(/* Neg = */ false);
49650b57cec5SDimitry Andric }
49660b57cec5SDimitry Andric 
compare(const DoubleAPFloat & RHS) const49670b57cec5SDimitry Andric APFloat::cmpResult DoubleAPFloat::compare(const DoubleAPFloat &RHS) const {
49680b57cec5SDimitry Andric   auto Result = Floats[0].compare(RHS.Floats[0]);
49690b57cec5SDimitry Andric   // |Float[0]| > |Float[1]|
49700b57cec5SDimitry Andric   if (Result == APFloat::cmpEqual)
49710b57cec5SDimitry Andric     return Floats[1].compare(RHS.Floats[1]);
49720b57cec5SDimitry Andric   return Result;
49730b57cec5SDimitry Andric }
49740b57cec5SDimitry Andric 
bitwiseIsEqual(const DoubleAPFloat & RHS) const49750b57cec5SDimitry Andric bool DoubleAPFloat::bitwiseIsEqual(const DoubleAPFloat &RHS) const {
49760b57cec5SDimitry Andric   return Floats[0].bitwiseIsEqual(RHS.Floats[0]) &&
49770b57cec5SDimitry Andric          Floats[1].bitwiseIsEqual(RHS.Floats[1]);
49780b57cec5SDimitry Andric }
49790b57cec5SDimitry Andric 
hash_value(const DoubleAPFloat & Arg)49800b57cec5SDimitry Andric hash_code hash_value(const DoubleAPFloat &Arg) {
49810b57cec5SDimitry Andric   if (Arg.Floats)
49820b57cec5SDimitry Andric     return hash_combine(hash_value(Arg.Floats[0]), hash_value(Arg.Floats[1]));
49830b57cec5SDimitry Andric   return hash_combine(Arg.Semantics);
49840b57cec5SDimitry Andric }
49850b57cec5SDimitry Andric 
bitcastToAPInt() const49860b57cec5SDimitry Andric APInt DoubleAPFloat::bitcastToAPInt() const {
49870b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
49880b57cec5SDimitry Andric   uint64_t Data[] = {
49890b57cec5SDimitry Andric       Floats[0].bitcastToAPInt().getRawData()[0],
49900b57cec5SDimitry Andric       Floats[1].bitcastToAPInt().getRawData()[0],
49910b57cec5SDimitry Andric   };
49920b57cec5SDimitry Andric   return APInt(128, 2, Data);
49930b57cec5SDimitry Andric }
49940b57cec5SDimitry Andric 
convertFromString(StringRef S,roundingMode RM)4995480093f4SDimitry Andric Expected<APFloat::opStatus> DoubleAPFloat::convertFromString(StringRef S,
49960b57cec5SDimitry Andric                                                              roundingMode RM) {
49970b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
49980b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy);
49990b57cec5SDimitry Andric   auto Ret = Tmp.convertFromString(S, RM);
50000b57cec5SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
50010b57cec5SDimitry Andric   return Ret;
50020b57cec5SDimitry Andric }
50030b57cec5SDimitry Andric 
next(bool nextDown)50040b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::next(bool nextDown) {
50050b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
50060b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
50070b57cec5SDimitry Andric   auto Ret = Tmp.next(nextDown);
50080b57cec5SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
50090b57cec5SDimitry Andric   return Ret;
50100b57cec5SDimitry Andric }
50110b57cec5SDimitry Andric 
50120b57cec5SDimitry Andric APFloat::opStatus
convertToInteger(MutableArrayRef<integerPart> Input,unsigned int Width,bool IsSigned,roundingMode RM,bool * IsExact) const50130b57cec5SDimitry Andric DoubleAPFloat::convertToInteger(MutableArrayRef<integerPart> Input,
50140b57cec5SDimitry Andric                                 unsigned int Width, bool IsSigned,
50150b57cec5SDimitry Andric                                 roundingMode RM, bool *IsExact) const {
50160b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
50170b57cec5SDimitry Andric   return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
50180b57cec5SDimitry Andric       .convertToInteger(Input, Width, IsSigned, RM, IsExact);
50190b57cec5SDimitry Andric }
50200b57cec5SDimitry Andric 
convertFromAPInt(const APInt & Input,bool IsSigned,roundingMode RM)50210b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::convertFromAPInt(const APInt &Input,
50220b57cec5SDimitry Andric                                                   bool IsSigned,
50230b57cec5SDimitry Andric                                                   roundingMode RM) {
50240b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
50250b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy);
50260b57cec5SDimitry Andric   auto Ret = Tmp.convertFromAPInt(Input, IsSigned, RM);
50270b57cec5SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
50280b57cec5SDimitry Andric   return Ret;
50290b57cec5SDimitry Andric }
50300b57cec5SDimitry Andric 
50310b57cec5SDimitry Andric APFloat::opStatus
convertFromSignExtendedInteger(const integerPart * Input,unsigned int InputSize,bool IsSigned,roundingMode RM)50320b57cec5SDimitry Andric DoubleAPFloat::convertFromSignExtendedInteger(const integerPart *Input,
50330b57cec5SDimitry Andric                                               unsigned int InputSize,
50340b57cec5SDimitry Andric                                               bool IsSigned, roundingMode RM) {
50350b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
50360b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy);
50370b57cec5SDimitry Andric   auto Ret = Tmp.convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM);
50380b57cec5SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
50390b57cec5SDimitry Andric   return Ret;
50400b57cec5SDimitry Andric }
50410b57cec5SDimitry Andric 
50420b57cec5SDimitry Andric APFloat::opStatus
convertFromZeroExtendedInteger(const integerPart * Input,unsigned int InputSize,bool IsSigned,roundingMode RM)50430b57cec5SDimitry Andric DoubleAPFloat::convertFromZeroExtendedInteger(const integerPart *Input,
50440b57cec5SDimitry Andric                                               unsigned int InputSize,
50450b57cec5SDimitry Andric                                               bool IsSigned, roundingMode RM) {
50460b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
50470b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy);
50480b57cec5SDimitry Andric   auto Ret = Tmp.convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM);
50490b57cec5SDimitry Andric   *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
50500b57cec5SDimitry Andric   return Ret;
50510b57cec5SDimitry Andric }
50520b57cec5SDimitry Andric 
convertToHexString(char * DST,unsigned int HexDigits,bool UpperCase,roundingMode RM) const50530b57cec5SDimitry Andric unsigned int DoubleAPFloat::convertToHexString(char *DST,
50540b57cec5SDimitry Andric                                                unsigned int HexDigits,
50550b57cec5SDimitry Andric                                                bool UpperCase,
50560b57cec5SDimitry Andric                                                roundingMode RM) const {
50570b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
50580b57cec5SDimitry Andric   return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
50590b57cec5SDimitry Andric       .convertToHexString(DST, HexDigits, UpperCase, RM);
50600b57cec5SDimitry Andric }
50610b57cec5SDimitry Andric 
isDenormal() const50620b57cec5SDimitry Andric bool DoubleAPFloat::isDenormal() const {
50630b57cec5SDimitry Andric   return getCategory() == fcNormal &&
50640b57cec5SDimitry Andric          (Floats[0].isDenormal() || Floats[1].isDenormal() ||
50650b57cec5SDimitry Andric           // (double)(Hi + Lo) == Hi defines a normal number.
50665ffd83dbSDimitry Andric           Floats[0] != Floats[0] + Floats[1]);
50670b57cec5SDimitry Andric }
50680b57cec5SDimitry Andric 
isSmallest() const50690b57cec5SDimitry Andric bool DoubleAPFloat::isSmallest() const {
50700b57cec5SDimitry Andric   if (getCategory() != fcNormal)
50710b57cec5SDimitry Andric     return false;
50720b57cec5SDimitry Andric   DoubleAPFloat Tmp(*this);
50730b57cec5SDimitry Andric   Tmp.makeSmallest(this->isNegative());
50740b57cec5SDimitry Andric   return Tmp.compare(*this) == cmpEqual;
50750b57cec5SDimitry Andric }
50760b57cec5SDimitry Andric 
isSmallestNormalized() const5077bdd1243dSDimitry Andric bool DoubleAPFloat::isSmallestNormalized() const {
5078bdd1243dSDimitry Andric   if (getCategory() != fcNormal)
5079bdd1243dSDimitry Andric     return false;
5080bdd1243dSDimitry Andric 
5081bdd1243dSDimitry Andric   DoubleAPFloat Tmp(*this);
5082bdd1243dSDimitry Andric   Tmp.makeSmallestNormalized(this->isNegative());
5083bdd1243dSDimitry Andric   return Tmp.compare(*this) == cmpEqual;
5084bdd1243dSDimitry Andric }
5085bdd1243dSDimitry Andric 
isLargest() const50860b57cec5SDimitry Andric bool DoubleAPFloat::isLargest() const {
50870b57cec5SDimitry Andric   if (getCategory() != fcNormal)
50880b57cec5SDimitry Andric     return false;
50890b57cec5SDimitry Andric   DoubleAPFloat Tmp(*this);
50900b57cec5SDimitry Andric   Tmp.makeLargest(this->isNegative());
50910b57cec5SDimitry Andric   return Tmp.compare(*this) == cmpEqual;
50920b57cec5SDimitry Andric }
50930b57cec5SDimitry Andric 
isInteger() const50940b57cec5SDimitry Andric bool DoubleAPFloat::isInteger() const {
50950b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
50960b57cec5SDimitry Andric   return Floats[0].isInteger() && Floats[1].isInteger();
50970b57cec5SDimitry Andric }
50980b57cec5SDimitry Andric 
toString(SmallVectorImpl<char> & Str,unsigned FormatPrecision,unsigned FormatMaxPadding,bool TruncateZero) const50990b57cec5SDimitry Andric void DoubleAPFloat::toString(SmallVectorImpl<char> &Str,
51000b57cec5SDimitry Andric                              unsigned FormatPrecision,
51010b57cec5SDimitry Andric                              unsigned FormatMaxPadding,
51020b57cec5SDimitry Andric                              bool TruncateZero) const {
51030b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
51040b57cec5SDimitry Andric   APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
51050b57cec5SDimitry Andric       .toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero);
51060b57cec5SDimitry Andric }
51070b57cec5SDimitry Andric 
getExactInverse(APFloat * inv) const51080b57cec5SDimitry Andric bool DoubleAPFloat::getExactInverse(APFloat *inv) const {
51090b57cec5SDimitry Andric   assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
51100b57cec5SDimitry Andric   APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
51110b57cec5SDimitry Andric   if (!inv)
51120b57cec5SDimitry Andric     return Tmp.getExactInverse(nullptr);
51130b57cec5SDimitry Andric   APFloat Inv(semPPCDoubleDoubleLegacy);
51140b57cec5SDimitry Andric   auto Ret = Tmp.getExactInverse(&Inv);
51150b57cec5SDimitry Andric   *inv = APFloat(semPPCDoubleDouble, Inv.bitcastToAPInt());
51160b57cec5SDimitry Andric   return Ret;
51170b57cec5SDimitry Andric }
51180b57cec5SDimitry Andric 
getExactLog2() const5119*c9157d92SDimitry Andric int DoubleAPFloat::getExactLog2() const {
5120*c9157d92SDimitry Andric   // TODO: Implement me
5121*c9157d92SDimitry Andric   return INT_MIN;
5122*c9157d92SDimitry Andric }
5123*c9157d92SDimitry Andric 
getExactLog2Abs() const5124*c9157d92SDimitry Andric int DoubleAPFloat::getExactLog2Abs() const {
5125*c9157d92SDimitry Andric   // TODO: Implement me
5126*c9157d92SDimitry Andric   return INT_MIN;
5127*c9157d92SDimitry Andric }
5128*c9157d92SDimitry Andric 
scalbn(const DoubleAPFloat & Arg,int Exp,APFloat::roundingMode RM)5129fe6060f1SDimitry Andric DoubleAPFloat scalbn(const DoubleAPFloat &Arg, int Exp,
5130fe6060f1SDimitry Andric                      APFloat::roundingMode RM) {
51310b57cec5SDimitry Andric   assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
51320b57cec5SDimitry Andric   return DoubleAPFloat(semPPCDoubleDouble, scalbn(Arg.Floats[0], Exp, RM),
51330b57cec5SDimitry Andric                        scalbn(Arg.Floats[1], Exp, RM));
51340b57cec5SDimitry Andric }
51350b57cec5SDimitry Andric 
frexp(const DoubleAPFloat & Arg,int & Exp,APFloat::roundingMode RM)51360b57cec5SDimitry Andric DoubleAPFloat frexp(const DoubleAPFloat &Arg, int &Exp,
51370b57cec5SDimitry Andric                     APFloat::roundingMode RM) {
51380b57cec5SDimitry Andric   assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
51390b57cec5SDimitry Andric   APFloat First = frexp(Arg.Floats[0], Exp, RM);
51400b57cec5SDimitry Andric   APFloat Second = Arg.Floats[1];
51410b57cec5SDimitry Andric   if (Arg.getCategory() == APFloat::fcNormal)
51420b57cec5SDimitry Andric     Second = scalbn(Second, -Exp, RM);
51430b57cec5SDimitry Andric   return DoubleAPFloat(semPPCDoubleDouble, std::move(First), std::move(Second));
51440b57cec5SDimitry Andric }
51450b57cec5SDimitry Andric 
5146fe6060f1SDimitry Andric } // namespace detail
51470b57cec5SDimitry Andric 
Storage(IEEEFloat F,const fltSemantics & Semantics)51480b57cec5SDimitry Andric APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) {
51490b57cec5SDimitry Andric   if (usesLayout<IEEEFloat>(Semantics)) {
51500b57cec5SDimitry Andric     new (&IEEE) IEEEFloat(std::move(F));
51510b57cec5SDimitry Andric     return;
51520b57cec5SDimitry Andric   }
51530b57cec5SDimitry Andric   if (usesLayout<DoubleAPFloat>(Semantics)) {
51540b57cec5SDimitry Andric     const fltSemantics& S = F.getSemantics();
51550b57cec5SDimitry Andric     new (&Double)
51560b57cec5SDimitry Andric         DoubleAPFloat(Semantics, APFloat(std::move(F), S),
51570b57cec5SDimitry Andric                       APFloat(semIEEEdouble));
51580b57cec5SDimitry Andric     return;
51590b57cec5SDimitry Andric   }
51600b57cec5SDimitry Andric   llvm_unreachable("Unexpected semantics");
51610b57cec5SDimitry Andric }
51620b57cec5SDimitry Andric 
convertFromString(StringRef Str,roundingMode RM)5163480093f4SDimitry Andric Expected<APFloat::opStatus> APFloat::convertFromString(StringRef Str,
5164480093f4SDimitry Andric                                                        roundingMode RM) {
51650b57cec5SDimitry Andric   APFLOAT_DISPATCH_ON_SEMANTICS(convertFromString(Str, RM));
51660b57cec5SDimitry Andric }
51670b57cec5SDimitry Andric 
hash_value(const APFloat & Arg)51680b57cec5SDimitry Andric hash_code hash_value(const APFloat &Arg) {
51690b57cec5SDimitry Andric   if (APFloat::usesLayout<detail::IEEEFloat>(Arg.getSemantics()))
51700b57cec5SDimitry Andric     return hash_value(Arg.U.IEEE);
51710b57cec5SDimitry Andric   if (APFloat::usesLayout<detail::DoubleAPFloat>(Arg.getSemantics()))
51720b57cec5SDimitry Andric     return hash_value(Arg.U.Double);
51730b57cec5SDimitry Andric   llvm_unreachable("Unexpected semantics");
51740b57cec5SDimitry Andric }
51750b57cec5SDimitry Andric 
APFloat(const fltSemantics & Semantics,StringRef S)51760b57cec5SDimitry Andric APFloat::APFloat(const fltSemantics &Semantics, StringRef S)
51770b57cec5SDimitry Andric     : APFloat(Semantics) {
5178480093f4SDimitry Andric   auto StatusOrErr = convertFromString(S, rmNearestTiesToEven);
5179480093f4SDimitry Andric   assert(StatusOrErr && "Invalid floating point representation");
5180480093f4SDimitry Andric   consumeError(StatusOrErr.takeError());
51810b57cec5SDimitry Andric }
51820b57cec5SDimitry Andric 
classify() const5183fe013be4SDimitry Andric FPClassTest APFloat::classify() const {
5184fe013be4SDimitry Andric   if (isZero())
5185fe013be4SDimitry Andric     return isNegative() ? fcNegZero : fcPosZero;
5186fe013be4SDimitry Andric   if (isNormal())
5187fe013be4SDimitry Andric     return isNegative() ? fcNegNormal : fcPosNormal;
5188fe013be4SDimitry Andric   if (isDenormal())
5189fe013be4SDimitry Andric     return isNegative() ? fcNegSubnormal : fcPosSubnormal;
5190fe013be4SDimitry Andric   if (isInfinity())
5191fe013be4SDimitry Andric     return isNegative() ? fcNegInf : fcPosInf;
5192fe013be4SDimitry Andric   assert(isNaN() && "Other class of FP constant");
5193fe013be4SDimitry Andric   return isSignaling() ? fcSNan : fcQNan;
5194fe013be4SDimitry Andric }
5195fe013be4SDimitry Andric 
convert(const fltSemantics & ToSemantics,roundingMode RM,bool * losesInfo)51960b57cec5SDimitry Andric APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics,
51970b57cec5SDimitry Andric                                    roundingMode RM, bool *losesInfo) {
51980b57cec5SDimitry Andric   if (&getSemantics() == &ToSemantics) {
51990b57cec5SDimitry Andric     *losesInfo = false;
52000b57cec5SDimitry Andric     return opOK;
52010b57cec5SDimitry Andric   }
52020b57cec5SDimitry Andric   if (usesLayout<IEEEFloat>(getSemantics()) &&
52030b57cec5SDimitry Andric       usesLayout<IEEEFloat>(ToSemantics))
52040b57cec5SDimitry Andric     return U.IEEE.convert(ToSemantics, RM, losesInfo);
52050b57cec5SDimitry Andric   if (usesLayout<IEEEFloat>(getSemantics()) &&
52060b57cec5SDimitry Andric       usesLayout<DoubleAPFloat>(ToSemantics)) {
52070b57cec5SDimitry Andric     assert(&ToSemantics == &semPPCDoubleDouble);
52080b57cec5SDimitry Andric     auto Ret = U.IEEE.convert(semPPCDoubleDoubleLegacy, RM, losesInfo);
52090b57cec5SDimitry Andric     *this = APFloat(ToSemantics, U.IEEE.bitcastToAPInt());
52100b57cec5SDimitry Andric     return Ret;
52110b57cec5SDimitry Andric   }
52120b57cec5SDimitry Andric   if (usesLayout<DoubleAPFloat>(getSemantics()) &&
52130b57cec5SDimitry Andric       usesLayout<IEEEFloat>(ToSemantics)) {
52140b57cec5SDimitry Andric     auto Ret = getIEEE().convert(ToSemantics, RM, losesInfo);
52150b57cec5SDimitry Andric     *this = APFloat(std::move(getIEEE()), ToSemantics);
52160b57cec5SDimitry Andric     return Ret;
52170b57cec5SDimitry Andric   }
52180b57cec5SDimitry Andric   llvm_unreachable("Unexpected semantics");
52190b57cec5SDimitry Andric }
52200b57cec5SDimitry Andric 
getAllOnesValue(const fltSemantics & Semantics)5221349cc55cSDimitry Andric APFloat APFloat::getAllOnesValue(const fltSemantics &Semantics) {
5222349cc55cSDimitry Andric   return APFloat(Semantics, APInt::getAllOnes(Semantics.sizeInBits));
52230b57cec5SDimitry Andric }
52240b57cec5SDimitry Andric 
print(raw_ostream & OS) const52250b57cec5SDimitry Andric void APFloat::print(raw_ostream &OS) const {
52260b57cec5SDimitry Andric   SmallVector<char, 16> Buffer;
52270b57cec5SDimitry Andric   toString(Buffer);
52280b57cec5SDimitry Andric   OS << Buffer << "\n";
52290b57cec5SDimitry Andric }
52300b57cec5SDimitry Andric 
52310b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const52320b57cec5SDimitry Andric LLVM_DUMP_METHOD void APFloat::dump() const { print(dbgs()); }
52330b57cec5SDimitry Andric #endif
52340b57cec5SDimitry Andric 
Profile(FoldingSetNodeID & NID) const52350b57cec5SDimitry Andric void APFloat::Profile(FoldingSetNodeID &NID) const {
52360b57cec5SDimitry Andric   NID.Add(bitcastToAPInt());
52370b57cec5SDimitry Andric }
52380b57cec5SDimitry Andric 
52390b57cec5SDimitry Andric /* Same as convertToInteger(integerPart*, ...), except the result is returned in
52400b57cec5SDimitry Andric    an APSInt, whose initial bit-width and signed-ness are used to determine the
52410b57cec5SDimitry Andric    precision of the conversion.
52420b57cec5SDimitry Andric  */
convertToInteger(APSInt & result,roundingMode rounding_mode,bool * isExact) const52430b57cec5SDimitry Andric APFloat::opStatus APFloat::convertToInteger(APSInt &result,
52440b57cec5SDimitry Andric                                             roundingMode rounding_mode,
52450b57cec5SDimitry Andric                                             bool *isExact) const {
52460b57cec5SDimitry Andric   unsigned bitWidth = result.getBitWidth();
52470b57cec5SDimitry Andric   SmallVector<uint64_t, 4> parts(result.getNumWords());
52480b57cec5SDimitry Andric   opStatus status = convertToInteger(parts, bitWidth, result.isSigned(),
52490b57cec5SDimitry Andric                                      rounding_mode, isExact);
52500b57cec5SDimitry Andric   // Keeps the original signed-ness.
52510b57cec5SDimitry Andric   result = APInt(bitWidth, parts);
52520b57cec5SDimitry Andric   return status;
52530b57cec5SDimitry Andric }
52540b57cec5SDimitry Andric 
convertToDouble() const5255fe6060f1SDimitry Andric double APFloat::convertToDouble() const {
5256fe6060f1SDimitry Andric   if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEdouble)
5257fe6060f1SDimitry Andric     return getIEEE().convertToDouble();
5258fe6060f1SDimitry Andric   assert(getSemantics().isRepresentableBy(semIEEEdouble) &&
5259fe6060f1SDimitry Andric          "Float semantics is not representable by IEEEdouble");
5260fe6060f1SDimitry Andric   APFloat Temp = *this;
5261fe6060f1SDimitry Andric   bool LosesInfo;
5262fe6060f1SDimitry Andric   opStatus St = Temp.convert(semIEEEdouble, rmNearestTiesToEven, &LosesInfo);
5263fe6060f1SDimitry Andric   assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision");
5264fe6060f1SDimitry Andric   (void)St;
5265fe6060f1SDimitry Andric   return Temp.getIEEE().convertToDouble();
5266fe6060f1SDimitry Andric }
5267fe6060f1SDimitry Andric 
convertToFloat() const5268fe6060f1SDimitry Andric float APFloat::convertToFloat() const {
5269fe6060f1SDimitry Andric   if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle)
5270fe6060f1SDimitry Andric     return getIEEE().convertToFloat();
5271fe6060f1SDimitry Andric   assert(getSemantics().isRepresentableBy(semIEEEsingle) &&
5272fe6060f1SDimitry Andric          "Float semantics is not representable by IEEEsingle");
5273fe6060f1SDimitry Andric   APFloat Temp = *this;
5274fe6060f1SDimitry Andric   bool LosesInfo;
5275fe6060f1SDimitry Andric   opStatus St = Temp.convert(semIEEEsingle, rmNearestTiesToEven, &LosesInfo);
5276fe6060f1SDimitry Andric   assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision");
5277fe6060f1SDimitry Andric   (void)St;
5278fe6060f1SDimitry Andric   return Temp.getIEEE().convertToFloat();
5279fe6060f1SDimitry Andric }
5280fe6060f1SDimitry Andric 
5281e8d8bef9SDimitry Andric } // namespace llvm
52820b57cec5SDimitry Andric 
52830b57cec5SDimitry Andric #undef APFLOAT_DISPATCH_ON_SEMANTICS
5284