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