1009b1c42SEd Schouten //===-- APFloat.cpp - Implement APFloat class -----------------------------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // This file implements a class to represent arbitrary precision floating
10009b1c42SEd Schouten // point values and provide a variety of arithmetic operations on them.
11009b1c42SEd Schouten //
12009b1c42SEd Schouten //===----------------------------------------------------------------------===//
13009b1c42SEd Schouten
14009b1c42SEd Schouten #include "llvm/ADT/APFloat.h"
15411bd29eSDimitry Andric #include "llvm/ADT/APSInt.h"
1601095a5dSDimitry Andric #include "llvm/ADT/ArrayRef.h"
177fa27ce4SDimitry Andric #include "llvm/ADT/FloatingPointMode.h"
18009b1c42SEd Schouten #include "llvm/ADT/FoldingSet.h"
1963faed5bSDimitry Andric #include "llvm/ADT/Hashing.h"
207fa27ce4SDimitry Andric #include "llvm/ADT/STLExtras.h"
214a16efa3SDimitry Andric #include "llvm/ADT/StringExtras.h"
2263faed5bSDimitry Andric #include "llvm/ADT/StringRef.h"
23eb11fae6SDimitry Andric #include "llvm/Config/llvm-config.h"
24b915e9e0SDimitry Andric #include "llvm/Support/Debug.h"
25706b4fc4SDimitry Andric #include "llvm/Support/Error.h"
26009b1c42SEd Schouten #include "llvm/Support/MathExtras.h"
27b915e9e0SDimitry Andric #include "llvm/Support/raw_ostream.h"
28009b1c42SEd Schouten #include <cstring>
294a16efa3SDimitry Andric #include <limits.h>
30009b1c42SEd Schouten
3171d5a254SDimitry Andric #define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \
3271d5a254SDimitry Andric do { \
3371d5a254SDimitry Andric if (usesLayout<IEEEFloat>(getSemantics())) \
3471d5a254SDimitry Andric return U.IEEE.METHOD_CALL; \
3571d5a254SDimitry Andric if (usesLayout<DoubleAPFloat>(getSemantics())) \
3671d5a254SDimitry Andric return U.Double.METHOD_CALL; \
3771d5a254SDimitry Andric llvm_unreachable("Unexpected semantics"); \
3871d5a254SDimitry Andric } while (false)
3971d5a254SDimitry Andric
40009b1c42SEd Schouten using namespace llvm;
41009b1c42SEd Schouten
42f8af5cf6SDimitry Andric /// A macro used to combine two fcCategory enums into one key which can be used
43f8af5cf6SDimitry Andric /// in a switch statement to classify how the interaction of two APFloat's
44f8af5cf6SDimitry Andric /// categories affects an operation.
45f8af5cf6SDimitry Andric ///
46f8af5cf6SDimitry Andric /// TODO: If clang source code is ever allowed to use constexpr in its own
47f8af5cf6SDimitry Andric /// codebase, change this into a static inline function.
48f8af5cf6SDimitry Andric #define PackCategoriesIntoKey(_lhs, _rhs) ((_lhs) * 4 + (_rhs))
49009b1c42SEd Schouten
50009b1c42SEd Schouten /* Assumed in hexadecimal significand parsing, and conversion to
51009b1c42SEd Schouten hexadecimal strings. */
5208bbd35aSDimitry Andric static_assert(APFloatBase::integerPartWidth % 4 == 0, "Part width must be divisible by 4!");
53009b1c42SEd Schouten
54009b1c42SEd Schouten namespace llvm {
55e3b55780SDimitry Andric
56e3b55780SDimitry Andric // How the nonfinite values Inf and NaN are represented.
57e3b55780SDimitry Andric enum class fltNonfiniteBehavior {
58e3b55780SDimitry Andric // Represents standard IEEE 754 behavior. A value is nonfinite if the
59e3b55780SDimitry Andric // exponent field is all 1s. In such cases, a value is Inf if the
60e3b55780SDimitry Andric // significand bits are all zero, and NaN otherwise
61e3b55780SDimitry Andric IEEE754,
62e3b55780SDimitry Andric
637fa27ce4SDimitry Andric // This behavior is present in the Float8ExMyFN* types (Float8E4M3FN,
647fa27ce4SDimitry Andric // Float8E5M2FNUZ, Float8E4M3FNUZ, and Float8E4M3B11FNUZ). There is no
657fa27ce4SDimitry Andric // representation for Inf, and operations that would ordinarily produce Inf
667fa27ce4SDimitry Andric // produce NaN instead.
677fa27ce4SDimitry Andric // The details of the NaN representation(s) in this form are determined by the
687fa27ce4SDimitry Andric // `fltNanEncoding` enum. We treat all NaNs as quiet, as the available
697fa27ce4SDimitry Andric // encodings do not distinguish between signalling and quiet NaN.
707fa27ce4SDimitry Andric NanOnly,
71ac9a064cSDimitry Andric
72ac9a064cSDimitry Andric // This behavior is present in Float6E3M2FN, Float6E2M3FN, and
73ac9a064cSDimitry Andric // Float4E2M1FN types, which do not support Inf or NaN values.
74ac9a064cSDimitry Andric FiniteOnly,
757fa27ce4SDimitry Andric };
767fa27ce4SDimitry Andric
777fa27ce4SDimitry Andric // How NaN values are represented. This is curently only used in combination
787fa27ce4SDimitry Andric // with fltNonfiniteBehavior::NanOnly, and using a variant other than IEEE
797fa27ce4SDimitry Andric // while having IEEE non-finite behavior is liable to lead to unexpected
807fa27ce4SDimitry Andric // results.
817fa27ce4SDimitry Andric enum class fltNanEncoding {
827fa27ce4SDimitry Andric // Represents the standard IEEE behavior where a value is NaN if its
837fa27ce4SDimitry Andric // exponent is all 1s and the significand is non-zero.
847fa27ce4SDimitry Andric IEEE,
857fa27ce4SDimitry Andric
86ac9a064cSDimitry Andric // Represents the behavior in the Float8E4M3FN floating point type where NaN
87ac9a064cSDimitry Andric // is represented by having the exponent and mantissa set to all 1s.
88e3b55780SDimitry Andric // This behavior matches the FP8 E4M3 type described in
89e3b55780SDimitry Andric // https://arxiv.org/abs/2209.05433. We treat both signed and unsigned NaNs
90e3b55780SDimitry Andric // as non-signalling, although the paper does not state whether the NaN
91e3b55780SDimitry Andric // values are signalling or not.
927fa27ce4SDimitry Andric AllOnes,
937fa27ce4SDimitry Andric
947fa27ce4SDimitry Andric // Represents the behavior in Float8E{5,4}E{2,3}FNUZ floating point types
957fa27ce4SDimitry Andric // where NaN is represented by a sign bit of 1 and all 0s in the exponent
967fa27ce4SDimitry Andric // and mantissa (i.e. the negative zero encoding in a IEEE float). Since
977fa27ce4SDimitry Andric // there is only one NaN value, it is treated as quiet NaN. This matches the
987fa27ce4SDimitry Andric // behavior described in https://arxiv.org/abs/2206.02915 .
997fa27ce4SDimitry Andric NegativeZero,
100e3b55780SDimitry Andric };
101e3b55780SDimitry Andric
102009b1c42SEd Schouten /* Represents floating point arithmetic semantics. */
103009b1c42SEd Schouten struct fltSemantics {
104009b1c42SEd Schouten /* The largest E such that 2^E is representable; this matches the
105009b1c42SEd Schouten definition of IEEE 754. */
106b915e9e0SDimitry Andric APFloatBase::ExponentType maxExponent;
107009b1c42SEd Schouten
108009b1c42SEd Schouten /* The smallest E such that 2^E is a normalized number; this
109009b1c42SEd Schouten matches the definition of IEEE 754. */
110b915e9e0SDimitry Andric APFloatBase::ExponentType minExponent;
111009b1c42SEd Schouten
112009b1c42SEd Schouten /* Number of bits in the significand. This includes the integer
113009b1c42SEd Schouten bit. */
114009b1c42SEd Schouten unsigned int precision;
115ee8648bdSDimitry Andric
116ee8648bdSDimitry Andric /* Number of bits actually used in the semantics. */
117ee8648bdSDimitry Andric unsigned int sizeInBits;
118344a3780SDimitry Andric
119e3b55780SDimitry Andric fltNonfiniteBehavior nonFiniteBehavior = fltNonfiniteBehavior::IEEE754;
120e3b55780SDimitry Andric
1217fa27ce4SDimitry Andric fltNanEncoding nanEncoding = fltNanEncoding::IEEE;
122344a3780SDimitry Andric // Returns true if any number described by this semantics can be precisely
123e3b55780SDimitry Andric // represented by the specified semantics. Does not take into account
124e3b55780SDimitry Andric // the value of fltNonfiniteBehavior.
isRepresentableByllvm::fltSemantics125344a3780SDimitry Andric bool isRepresentableBy(const fltSemantics &S) const {
126344a3780SDimitry Andric return maxExponent <= S.maxExponent && minExponent >= S.minExponent &&
127344a3780SDimitry Andric precision <= S.precision;
128344a3780SDimitry Andric }
129009b1c42SEd Schouten };
130009b1c42SEd Schouten
1317fa27ce4SDimitry Andric static constexpr fltSemantics semIEEEhalf = {15, -14, 11, 16};
1327fa27ce4SDimitry Andric static constexpr fltSemantics semBFloat = {127, -126, 8, 16};
1337fa27ce4SDimitry Andric static constexpr fltSemantics semIEEEsingle = {127, -126, 24, 32};
1347fa27ce4SDimitry Andric static constexpr fltSemantics semIEEEdouble = {1023, -1022, 53, 64};
1357fa27ce4SDimitry Andric static constexpr fltSemantics semIEEEquad = {16383, -16382, 113, 128};
1367fa27ce4SDimitry Andric static constexpr fltSemantics semFloat8E5M2 = {15, -14, 3, 8};
1377fa27ce4SDimitry Andric static constexpr fltSemantics semFloat8E5M2FNUZ = {
1387fa27ce4SDimitry Andric 15, -15, 3, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero};
139ac9a064cSDimitry Andric static constexpr fltSemantics semFloat8E4M3 = {7, -6, 4, 8};
1407fa27ce4SDimitry Andric static constexpr fltSemantics semFloat8E4M3FN = {
1417fa27ce4SDimitry Andric 8, -6, 4, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::AllOnes};
1427fa27ce4SDimitry Andric static constexpr fltSemantics semFloat8E4M3FNUZ = {
1437fa27ce4SDimitry Andric 7, -7, 4, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero};
1447fa27ce4SDimitry Andric static constexpr fltSemantics semFloat8E4M3B11FNUZ = {
1457fa27ce4SDimitry Andric 4, -10, 4, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero};
1467fa27ce4SDimitry Andric static constexpr fltSemantics semFloatTF32 = {127, -126, 11, 19};
147ac9a064cSDimitry Andric static constexpr fltSemantics semFloat6E3M2FN = {
148ac9a064cSDimitry Andric 4, -2, 3, 6, fltNonfiniteBehavior::FiniteOnly};
149ac9a064cSDimitry Andric static constexpr fltSemantics semFloat6E2M3FN = {
150ac9a064cSDimitry Andric 2, 0, 4, 6, fltNonfiniteBehavior::FiniteOnly};
151ac9a064cSDimitry Andric static constexpr fltSemantics semFloat4E2M1FN = {
152ac9a064cSDimitry Andric 2, 0, 2, 4, fltNonfiniteBehavior::FiniteOnly};
1537fa27ce4SDimitry Andric static constexpr fltSemantics semX87DoubleExtended = {16383, -16382, 64, 80};
1547fa27ce4SDimitry Andric static constexpr fltSemantics semBogus = {0, 0, 0, 0};
155009b1c42SEd Schouten
15671d5a254SDimitry Andric /* The IBM double-double semantics. Such a number consists of a pair of IEEE
15771d5a254SDimitry Andric 64-bit doubles (Hi, Lo), where |Hi| > |Lo|, and if normal,
15871d5a254SDimitry Andric (double)(Hi + Lo) == Hi. The numeric value it's modeling is Hi + Lo.
15971d5a254SDimitry Andric Therefore it has two 53-bit mantissa parts that aren't necessarily adjacent
16071d5a254SDimitry Andric to each other, and two 11-bit exponents.
161c82ad72fSDimitry Andric
162c82ad72fSDimitry Andric Note: we need to make the value different from semBogus as otherwise
163c82ad72fSDimitry Andric an unsafe optimization may collapse both values to a single address,
164c82ad72fSDimitry Andric and we heavily rely on them having distinct addresses. */
1657fa27ce4SDimitry Andric static constexpr fltSemantics semPPCDoubleDouble = {-1, 0, 0, 128};
166b915e9e0SDimitry Andric
16771d5a254SDimitry Andric /* These are legacy semantics for the fallback, inaccrurate implementation of
16871d5a254SDimitry Andric IBM double-double, if the accurate semPPCDoubleDouble doesn't handle the
16971d5a254SDimitry Andric operation. It's equivalent to having an IEEE number with consecutive 106
17071d5a254SDimitry Andric bits of mantissa and 11 bits of exponent.
171b915e9e0SDimitry Andric
17271d5a254SDimitry Andric It's not equivalent to IBM double-double. For example, a legit IBM
17371d5a254SDimitry Andric double-double, 1 + epsilon:
17471d5a254SDimitry Andric
17571d5a254SDimitry Andric 1 + epsilon = 1 + (1 >> 1076)
17671d5a254SDimitry Andric
17771d5a254SDimitry Andric is not representable by a consecutive 106 bits of mantissa.
17871d5a254SDimitry Andric
17971d5a254SDimitry Andric Currently, these semantics are used in the following way:
18071d5a254SDimitry Andric
18171d5a254SDimitry Andric semPPCDoubleDouble -> (IEEEdouble, IEEEdouble) ->
18271d5a254SDimitry Andric (64-bit APInt, 64-bit APInt) -> (128-bit APInt) ->
18371d5a254SDimitry Andric semPPCDoubleDoubleLegacy -> IEEE operations
18471d5a254SDimitry Andric
18571d5a254SDimitry Andric We use bitcastToAPInt() to get the bit representation (in APInt) of the
18671d5a254SDimitry Andric underlying IEEEdouble, then use the APInt constructor to construct the
18771d5a254SDimitry Andric legacy IEEE float.
18871d5a254SDimitry Andric
18971d5a254SDimitry Andric TODO: Implement all operations in semPPCDoubleDouble, and delete these
19071d5a254SDimitry Andric semantics. */
1917fa27ce4SDimitry Andric static constexpr fltSemantics semPPCDoubleDoubleLegacy = {1023, -1022 + 53,
19271d5a254SDimitry Andric 53 + 53, 128};
193b915e9e0SDimitry Andric
EnumToSemantics(Semantics S)194e6d15924SDimitry Andric const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) {
195e6d15924SDimitry Andric switch (S) {
196e6d15924SDimitry Andric case S_IEEEhalf:
197e6d15924SDimitry Andric return IEEEhalf();
198cfca06d7SDimitry Andric case S_BFloat:
199cfca06d7SDimitry Andric return BFloat();
200e6d15924SDimitry Andric case S_IEEEsingle:
201e6d15924SDimitry Andric return IEEEsingle();
202e6d15924SDimitry Andric case S_IEEEdouble:
203e6d15924SDimitry Andric return IEEEdouble();
204e6d15924SDimitry Andric case S_IEEEquad:
205e6d15924SDimitry Andric return IEEEquad();
206e6d15924SDimitry Andric case S_PPCDoubleDouble:
207e6d15924SDimitry Andric return PPCDoubleDouble();
208e3b55780SDimitry Andric case S_Float8E5M2:
209e3b55780SDimitry Andric return Float8E5M2();
2107fa27ce4SDimitry Andric case S_Float8E5M2FNUZ:
2117fa27ce4SDimitry Andric return Float8E5M2FNUZ();
212ac9a064cSDimitry Andric case S_Float8E4M3:
213ac9a064cSDimitry Andric return Float8E4M3();
214e3b55780SDimitry Andric case S_Float8E4M3FN:
215e3b55780SDimitry Andric return Float8E4M3FN();
2167fa27ce4SDimitry Andric case S_Float8E4M3FNUZ:
2177fa27ce4SDimitry Andric return Float8E4M3FNUZ();
2187fa27ce4SDimitry Andric case S_Float8E4M3B11FNUZ:
2197fa27ce4SDimitry Andric return Float8E4M3B11FNUZ();
2207fa27ce4SDimitry Andric case S_FloatTF32:
2217fa27ce4SDimitry Andric return FloatTF32();
222ac9a064cSDimitry Andric case S_Float6E3M2FN:
223ac9a064cSDimitry Andric return Float6E3M2FN();
224ac9a064cSDimitry Andric case S_Float6E2M3FN:
225ac9a064cSDimitry Andric return Float6E2M3FN();
226ac9a064cSDimitry Andric case S_Float4E2M1FN:
227ac9a064cSDimitry Andric return Float4E2M1FN();
228e3b55780SDimitry Andric case S_x87DoubleExtended:
229e3b55780SDimitry Andric return x87DoubleExtended();
230e6d15924SDimitry Andric }
231e6d15924SDimitry Andric llvm_unreachable("Unrecognised floating semantics");
232e6d15924SDimitry Andric }
233e6d15924SDimitry Andric
234e6d15924SDimitry Andric APFloatBase::Semantics
SemanticsToEnum(const llvm::fltSemantics & Sem)235e6d15924SDimitry Andric APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) {
236e6d15924SDimitry Andric if (&Sem == &llvm::APFloat::IEEEhalf())
237e6d15924SDimitry Andric return S_IEEEhalf;
238cfca06d7SDimitry Andric else if (&Sem == &llvm::APFloat::BFloat())
239cfca06d7SDimitry Andric return S_BFloat;
240e6d15924SDimitry Andric else if (&Sem == &llvm::APFloat::IEEEsingle())
241e6d15924SDimitry Andric return S_IEEEsingle;
242e6d15924SDimitry Andric else if (&Sem == &llvm::APFloat::IEEEdouble())
243e6d15924SDimitry Andric return S_IEEEdouble;
244e6d15924SDimitry Andric else if (&Sem == &llvm::APFloat::IEEEquad())
245e6d15924SDimitry Andric return S_IEEEquad;
246e6d15924SDimitry Andric else if (&Sem == &llvm::APFloat::PPCDoubleDouble())
247e6d15924SDimitry Andric return S_PPCDoubleDouble;
248e3b55780SDimitry Andric else if (&Sem == &llvm::APFloat::Float8E5M2())
249e3b55780SDimitry Andric return S_Float8E5M2;
2507fa27ce4SDimitry Andric else if (&Sem == &llvm::APFloat::Float8E5M2FNUZ())
2517fa27ce4SDimitry Andric return S_Float8E5M2FNUZ;
252ac9a064cSDimitry Andric else if (&Sem == &llvm::APFloat::Float8E4M3())
253ac9a064cSDimitry Andric return S_Float8E4M3;
254e3b55780SDimitry Andric else if (&Sem == &llvm::APFloat::Float8E4M3FN())
255e3b55780SDimitry Andric return S_Float8E4M3FN;
2567fa27ce4SDimitry Andric else if (&Sem == &llvm::APFloat::Float8E4M3FNUZ())
2577fa27ce4SDimitry Andric return S_Float8E4M3FNUZ;
2587fa27ce4SDimitry Andric else if (&Sem == &llvm::APFloat::Float8E4M3B11FNUZ())
2597fa27ce4SDimitry Andric return S_Float8E4M3B11FNUZ;
2607fa27ce4SDimitry Andric else if (&Sem == &llvm::APFloat::FloatTF32())
2617fa27ce4SDimitry Andric return S_FloatTF32;
262ac9a064cSDimitry Andric else if (&Sem == &llvm::APFloat::Float6E3M2FN())
263ac9a064cSDimitry Andric return S_Float6E3M2FN;
264ac9a064cSDimitry Andric else if (&Sem == &llvm::APFloat::Float6E2M3FN())
265ac9a064cSDimitry Andric return S_Float6E2M3FN;
266ac9a064cSDimitry Andric else if (&Sem == &llvm::APFloat::Float4E2M1FN())
267ac9a064cSDimitry Andric return S_Float4E2M1FN;
268e3b55780SDimitry Andric else if (&Sem == &llvm::APFloat::x87DoubleExtended())
269e3b55780SDimitry Andric return S_x87DoubleExtended;
270e6d15924SDimitry Andric else
271e6d15924SDimitry Andric llvm_unreachable("Unknown floating semantics");
272e6d15924SDimitry Andric }
273e6d15924SDimitry Andric
IEEEhalf()2747fa27ce4SDimitry Andric const fltSemantics &APFloatBase::IEEEhalf() { return semIEEEhalf; }
BFloat()2757fa27ce4SDimitry Andric const fltSemantics &APFloatBase::BFloat() { return semBFloat; }
IEEEsingle()2767fa27ce4SDimitry Andric const fltSemantics &APFloatBase::IEEEsingle() { return semIEEEsingle; }
IEEEdouble()2777fa27ce4SDimitry Andric const fltSemantics &APFloatBase::IEEEdouble() { return semIEEEdouble; }
IEEEquad()278e3b55780SDimitry Andric const fltSemantics &APFloatBase::IEEEquad() { return semIEEEquad; }
PPCDoubleDouble()279b915e9e0SDimitry Andric const fltSemantics &APFloatBase::PPCDoubleDouble() {
280b915e9e0SDimitry Andric return semPPCDoubleDouble;
281b915e9e0SDimitry Andric }
Float8E5M2()282e3b55780SDimitry Andric const fltSemantics &APFloatBase::Float8E5M2() { return semFloat8E5M2; }
Float8E5M2FNUZ()2837fa27ce4SDimitry Andric const fltSemantics &APFloatBase::Float8E5M2FNUZ() { return semFloat8E5M2FNUZ; }
Float8E4M3()284ac9a064cSDimitry Andric const fltSemantics &APFloatBase::Float8E4M3() { return semFloat8E4M3; }
Float8E4M3FN()285e3b55780SDimitry Andric const fltSemantics &APFloatBase::Float8E4M3FN() { return semFloat8E4M3FN; }
Float8E4M3FNUZ()2867fa27ce4SDimitry Andric const fltSemantics &APFloatBase::Float8E4M3FNUZ() { return semFloat8E4M3FNUZ; }
Float8E4M3B11FNUZ()2877fa27ce4SDimitry Andric const fltSemantics &APFloatBase::Float8E4M3B11FNUZ() {
2887fa27ce4SDimitry Andric return semFloat8E4M3B11FNUZ;
2897fa27ce4SDimitry Andric }
FloatTF32()2907fa27ce4SDimitry Andric const fltSemantics &APFloatBase::FloatTF32() { return semFloatTF32; }
Float6E3M2FN()291ac9a064cSDimitry Andric const fltSemantics &APFloatBase::Float6E3M2FN() { return semFloat6E3M2FN; }
Float6E2M3FN()292ac9a064cSDimitry Andric const fltSemantics &APFloatBase::Float6E2M3FN() { return semFloat6E2M3FN; }
Float4E2M1FN()293ac9a064cSDimitry Andric const fltSemantics &APFloatBase::Float4E2M1FN() { return semFloat4E2M1FN; }
x87DoubleExtended()294e3b55780SDimitry Andric const fltSemantics &APFloatBase::x87DoubleExtended() {
295e3b55780SDimitry Andric return semX87DoubleExtended;
296e3b55780SDimitry Andric }
Bogus()297e3b55780SDimitry Andric const fltSemantics &APFloatBase::Bogus() { return semBogus; }
298009b1c42SEd Schouten
299cfca06d7SDimitry Andric constexpr RoundingMode APFloatBase::rmNearestTiesToEven;
300cfca06d7SDimitry Andric constexpr RoundingMode APFloatBase::rmTowardPositive;
301cfca06d7SDimitry Andric constexpr RoundingMode APFloatBase::rmTowardNegative;
302cfca06d7SDimitry Andric constexpr RoundingMode APFloatBase::rmTowardZero;
303cfca06d7SDimitry Andric constexpr RoundingMode APFloatBase::rmNearestTiesToAway;
304cfca06d7SDimitry Andric
305009b1c42SEd Schouten /* A tight upper bound on number of parts required to hold the value
306009b1c42SEd Schouten pow(5, power) is
307009b1c42SEd Schouten
308009b1c42SEd Schouten power * 815 / (351 * integerPartWidth) + 1
309009b1c42SEd Schouten
310009b1c42SEd Schouten However, whilst the result may require only this many parts,
311009b1c42SEd Schouten because we are multiplying two values to get it, the
312009b1c42SEd Schouten multiplication may require an extra part with the excess part
313009b1c42SEd Schouten being zero (consider the trivial case of 1 * 1, tcFullMultiply
314009b1c42SEd Schouten requires two parts to hold the single-part result). So we add an
315009b1c42SEd Schouten extra one to guarantee enough space whilst multiplying. */
316009b1c42SEd Schouten const unsigned int maxExponent = 16383;
317009b1c42SEd Schouten const unsigned int maxPrecision = 113;
318009b1c42SEd Schouten const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1;
3197fa27ce4SDimitry Andric const unsigned int maxPowerOfFiveParts =
3207fa27ce4SDimitry Andric 2 +
3217fa27ce4SDimitry Andric ((maxPowerOfFiveExponent * 815) / (351 * APFloatBase::integerPartWidth));
322b915e9e0SDimitry Andric
semanticsPrecision(const fltSemantics & semantics)323b915e9e0SDimitry Andric unsigned int APFloatBase::semanticsPrecision(const fltSemantics &semantics) {
324b915e9e0SDimitry Andric return semantics.precision;
325b915e9e0SDimitry Andric }
326b915e9e0SDimitry Andric APFloatBase::ExponentType
semanticsMaxExponent(const fltSemantics & semantics)327b915e9e0SDimitry Andric APFloatBase::semanticsMaxExponent(const fltSemantics &semantics) {
328b915e9e0SDimitry Andric return semantics.maxExponent;
329b915e9e0SDimitry Andric }
330b915e9e0SDimitry Andric APFloatBase::ExponentType
semanticsMinExponent(const fltSemantics & semantics)331b915e9e0SDimitry Andric APFloatBase::semanticsMinExponent(const fltSemantics &semantics) {
332b915e9e0SDimitry Andric return semantics.minExponent;
333b915e9e0SDimitry Andric }
semanticsSizeInBits(const fltSemantics & semantics)334b915e9e0SDimitry Andric unsigned int APFloatBase::semanticsSizeInBits(const fltSemantics &semantics) {
335b915e9e0SDimitry Andric return semantics.sizeInBits;
336b915e9e0SDimitry Andric }
semanticsIntSizeInBits(const fltSemantics & semantics,bool isSigned)3377fa27ce4SDimitry Andric unsigned int APFloatBase::semanticsIntSizeInBits(const fltSemantics &semantics,
3387fa27ce4SDimitry Andric bool isSigned) {
3397fa27ce4SDimitry Andric // The max FP value is pow(2, MaxExponent) * (1 + MaxFraction), so we need
3407fa27ce4SDimitry Andric // at least one more bit than the MaxExponent to hold the max FP value.
3417fa27ce4SDimitry Andric unsigned int MinBitWidth = semanticsMaxExponent(semantics) + 1;
3427fa27ce4SDimitry Andric // Extra sign bit needed.
3437fa27ce4SDimitry Andric if (isSigned)
3447fa27ce4SDimitry Andric ++MinBitWidth;
3457fa27ce4SDimitry Andric return MinBitWidth;
3467fa27ce4SDimitry Andric }
3477fa27ce4SDimitry Andric
isRepresentableAsNormalIn(const fltSemantics & Src,const fltSemantics & Dst)3487fa27ce4SDimitry Andric bool APFloatBase::isRepresentableAsNormalIn(const fltSemantics &Src,
3497fa27ce4SDimitry Andric const fltSemantics &Dst) {
3507fa27ce4SDimitry Andric // Exponent range must be larger.
3517fa27ce4SDimitry Andric if (Src.maxExponent >= Dst.maxExponent || Src.minExponent <= Dst.minExponent)
3527fa27ce4SDimitry Andric return false;
3537fa27ce4SDimitry Andric
3547fa27ce4SDimitry Andric // If the mantissa is long enough, the result value could still be denormal
3557fa27ce4SDimitry Andric // with a larger exponent range.
3567fa27ce4SDimitry Andric //
3577fa27ce4SDimitry Andric // FIXME: This condition is probably not accurate but also shouldn't be a
3587fa27ce4SDimitry Andric // practical concern with existing types.
3597fa27ce4SDimitry Andric return Dst.precision >= Src.precision;
3607fa27ce4SDimitry Andric }
361b915e9e0SDimitry Andric
getSizeInBits(const fltSemantics & Sem)362b915e9e0SDimitry Andric unsigned APFloatBase::getSizeInBits(const fltSemantics &Sem) {
363b915e9e0SDimitry Andric return Sem.sizeInBits;
3641a82d4c0SDimitry Andric }
365009b1c42SEd Schouten
3667fa27ce4SDimitry Andric static constexpr APFloatBase::ExponentType
exponentZero(const fltSemantics & semantics)3677fa27ce4SDimitry Andric exponentZero(const fltSemantics &semantics) {
3687fa27ce4SDimitry Andric return semantics.minExponent - 1;
3697fa27ce4SDimitry Andric }
3707fa27ce4SDimitry Andric
3717fa27ce4SDimitry Andric static constexpr APFloatBase::ExponentType
exponentInf(const fltSemantics & semantics)3727fa27ce4SDimitry Andric exponentInf(const fltSemantics &semantics) {
3737fa27ce4SDimitry Andric return semantics.maxExponent + 1;
3747fa27ce4SDimitry Andric }
3757fa27ce4SDimitry Andric
3767fa27ce4SDimitry Andric static constexpr APFloatBase::ExponentType
exponentNaN(const fltSemantics & semantics)3777fa27ce4SDimitry Andric exponentNaN(const fltSemantics &semantics) {
3787fa27ce4SDimitry Andric if (semantics.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
3797fa27ce4SDimitry Andric if (semantics.nanEncoding == fltNanEncoding::NegativeZero)
3807fa27ce4SDimitry Andric return exponentZero(semantics);
3817fa27ce4SDimitry Andric return semantics.maxExponent;
3827fa27ce4SDimitry Andric }
3837fa27ce4SDimitry Andric return semantics.maxExponent + 1;
3847fa27ce4SDimitry Andric }
3857fa27ce4SDimitry Andric
386009b1c42SEd Schouten /* A bunch of private, handy routines. */
387009b1c42SEd Schouten
createError(const Twine & Err)388706b4fc4SDimitry Andric static inline Error createError(const Twine &Err) {
389706b4fc4SDimitry Andric return make_error<StringError>(Err, inconvertibleErrorCode());
390706b4fc4SDimitry Andric }
391706b4fc4SDimitry Andric
partCountForBits(unsigned int bits)3927fa27ce4SDimitry Andric static constexpr inline unsigned int partCountForBits(unsigned int bits) {
39308bbd35aSDimitry Andric return ((bits) + APFloatBase::integerPartWidth - 1) / APFloatBase::integerPartWidth;
394009b1c42SEd Schouten }
395009b1c42SEd Schouten
396009b1c42SEd Schouten /* Returns 0U-9U. Return values >= 10U are not digits. */
397009b1c42SEd Schouten static inline unsigned int
decDigitValue(unsigned int c)398009b1c42SEd Schouten decDigitValue(unsigned int c)
399009b1c42SEd Schouten {
400009b1c42SEd Schouten return c - '0';
401009b1c42SEd Schouten }
402009b1c42SEd Schouten
403009b1c42SEd Schouten /* Return the value of a decimal exponent of the form
404009b1c42SEd Schouten [+-]ddddddd.
405009b1c42SEd Schouten
406009b1c42SEd Schouten If the exponent overflows, returns a large exponent with the
407009b1c42SEd Schouten appropriate sign. */
readExponent(StringRef::iterator begin,StringRef::iterator end)408706b4fc4SDimitry Andric static Expected<int> readExponent(StringRef::iterator begin,
409706b4fc4SDimitry Andric StringRef::iterator end) {
410009b1c42SEd Schouten bool isNegative;
411009b1c42SEd Schouten unsigned int absExponent;
412009b1c42SEd Schouten const unsigned int overlargeExponent = 24000; /* FIXME. */
41359850d08SRoman Divacky StringRef::iterator p = begin;
41459850d08SRoman Divacky
415e6d15924SDimitry Andric // Treat no exponent as 0 to match binutils
416e6d15924SDimitry Andric if (p == end || ((*p == '-' || *p == '+') && (p + 1) == end)) {
417e6d15924SDimitry Andric return 0;
418e6d15924SDimitry Andric }
419009b1c42SEd Schouten
420009b1c42SEd Schouten isNegative = (*p == '-');
42159850d08SRoman Divacky if (*p == '-' || *p == '+') {
422009b1c42SEd Schouten p++;
423706b4fc4SDimitry Andric if (p == end)
424706b4fc4SDimitry Andric return createError("Exponent has no digits");
42559850d08SRoman Divacky }
426009b1c42SEd Schouten
427009b1c42SEd Schouten absExponent = decDigitValue(*p++);
428706b4fc4SDimitry Andric if (absExponent >= 10U)
429706b4fc4SDimitry Andric return createError("Invalid character in exponent");
430009b1c42SEd Schouten
43159850d08SRoman Divacky for (; p != end; ++p) {
432009b1c42SEd Schouten unsigned int value;
433009b1c42SEd Schouten
434009b1c42SEd Schouten value = decDigitValue(*p);
435706b4fc4SDimitry Andric if (value >= 10U)
436706b4fc4SDimitry Andric return createError("Invalid character in exponent");
437009b1c42SEd Schouten
438706b4fc4SDimitry Andric absExponent = absExponent * 10U + value;
439009b1c42SEd Schouten if (absExponent >= overlargeExponent) {
440009b1c42SEd Schouten absExponent = overlargeExponent;
441009b1c42SEd Schouten break;
442009b1c42SEd Schouten }
443009b1c42SEd Schouten }
444009b1c42SEd Schouten
445009b1c42SEd Schouten if (isNegative)
446009b1c42SEd Schouten return -(int) absExponent;
447009b1c42SEd Schouten else
448009b1c42SEd Schouten return (int) absExponent;
449009b1c42SEd Schouten }
450009b1c42SEd Schouten
451009b1c42SEd Schouten /* This is ugly and needs cleaning up, but I don't immediately see
452009b1c42SEd Schouten how whilst remaining safe. */
totalExponent(StringRef::iterator p,StringRef::iterator end,int exponentAdjustment)453706b4fc4SDimitry Andric static Expected<int> totalExponent(StringRef::iterator p,
454706b4fc4SDimitry Andric StringRef::iterator end,
455706b4fc4SDimitry Andric int exponentAdjustment) {
456009b1c42SEd Schouten int unsignedExponent;
457009b1c42SEd Schouten bool negative, overflow;
458cf099d11SDimitry Andric int exponent = 0;
459009b1c42SEd Schouten
460706b4fc4SDimitry Andric if (p == end)
461706b4fc4SDimitry Andric return createError("Exponent has no digits");
46259850d08SRoman Divacky
463009b1c42SEd Schouten negative = *p == '-';
46459850d08SRoman Divacky if (*p == '-' || *p == '+') {
465009b1c42SEd Schouten p++;
466706b4fc4SDimitry Andric if (p == end)
467706b4fc4SDimitry Andric return createError("Exponent has no digits");
46859850d08SRoman Divacky }
469009b1c42SEd Schouten
470009b1c42SEd Schouten unsignedExponent = 0;
471009b1c42SEd Schouten overflow = false;
47259850d08SRoman Divacky for (; p != end; ++p) {
473009b1c42SEd Schouten unsigned int value;
474009b1c42SEd Schouten
475009b1c42SEd Schouten value = decDigitValue(*p);
476706b4fc4SDimitry Andric if (value >= 10U)
477706b4fc4SDimitry Andric return createError("Invalid character in exponent");
478009b1c42SEd Schouten
479009b1c42SEd Schouten unsignedExponent = unsignedExponent * 10 + value;
480522600a2SDimitry Andric if (unsignedExponent > 32767) {
481009b1c42SEd Schouten overflow = true;
482522600a2SDimitry Andric break;
483522600a2SDimitry Andric }
484009b1c42SEd Schouten }
485009b1c42SEd Schouten
486cf099d11SDimitry Andric if (exponentAdjustment > 32767 || exponentAdjustment < -32768)
487009b1c42SEd Schouten overflow = true;
488009b1c42SEd Schouten
489009b1c42SEd Schouten if (!overflow) {
490009b1c42SEd Schouten exponent = unsignedExponent;
491009b1c42SEd Schouten if (negative)
492009b1c42SEd Schouten exponent = -exponent;
493009b1c42SEd Schouten exponent += exponentAdjustment;
494cf099d11SDimitry Andric if (exponent > 32767 || exponent < -32768)
495009b1c42SEd Schouten overflow = true;
496009b1c42SEd Schouten }
497009b1c42SEd Schouten
498009b1c42SEd Schouten if (overflow)
499cf099d11SDimitry Andric exponent = negative ? -32768: 32767;
500009b1c42SEd Schouten
501009b1c42SEd Schouten return exponent;
502009b1c42SEd Schouten }
503009b1c42SEd Schouten
504706b4fc4SDimitry Andric static Expected<StringRef::iterator>
skipLeadingZeroesAndAnyDot(StringRef::iterator begin,StringRef::iterator end,StringRef::iterator * dot)50559850d08SRoman Divacky skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end,
506706b4fc4SDimitry Andric StringRef::iterator *dot) {
50759850d08SRoman Divacky StringRef::iterator p = begin;
50859850d08SRoman Divacky *dot = end;
50967c32a98SDimitry Andric while (p != end && *p == '0')
510009b1c42SEd Schouten p++;
511009b1c42SEd Schouten
51267c32a98SDimitry Andric if (p != end && *p == '.') {
513009b1c42SEd Schouten *dot = p++;
51459850d08SRoman Divacky
515706b4fc4SDimitry Andric if (end - begin == 1)
516706b4fc4SDimitry Andric return createError("Significand has no digits");
51759850d08SRoman Divacky
51867c32a98SDimitry Andric while (p != end && *p == '0')
519009b1c42SEd Schouten p++;
520009b1c42SEd Schouten }
521009b1c42SEd Schouten
522009b1c42SEd Schouten return p;
523009b1c42SEd Schouten }
524009b1c42SEd Schouten
525009b1c42SEd Schouten /* Given a normal decimal floating point number of the form
526009b1c42SEd Schouten
527009b1c42SEd Schouten dddd.dddd[eE][+-]ddd
528009b1c42SEd Schouten
529009b1c42SEd Schouten where the decimal point and exponent are optional, fill out the
530009b1c42SEd Schouten structure D. Exponent is appropriate if the significand is
531009b1c42SEd Schouten treated as an integer, and normalizedExponent if the significand
532009b1c42SEd Schouten is taken to have the decimal point after a single leading
533009b1c42SEd Schouten non-zero digit.
534009b1c42SEd Schouten
535009b1c42SEd Schouten If the value is zero, V->firstSigDigit points to a non-digit, and
536009b1c42SEd Schouten the return exponent is zero.
537009b1c42SEd Schouten */
538009b1c42SEd Schouten struct decimalInfo {
539009b1c42SEd Schouten const char *firstSigDigit;
540009b1c42SEd Schouten const char *lastSigDigit;
541009b1c42SEd Schouten int exponent;
542009b1c42SEd Schouten int normalizedExponent;
543009b1c42SEd Schouten };
544009b1c42SEd Schouten
interpretDecimal(StringRef::iterator begin,StringRef::iterator end,decimalInfo * D)545706b4fc4SDimitry Andric static Error interpretDecimal(StringRef::iterator begin,
546706b4fc4SDimitry Andric StringRef::iterator end, decimalInfo *D) {
54759850d08SRoman Divacky StringRef::iterator dot = end;
548706b4fc4SDimitry Andric
549706b4fc4SDimitry Andric auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot);
550706b4fc4SDimitry Andric if (!PtrOrErr)
551706b4fc4SDimitry Andric return PtrOrErr.takeError();
552706b4fc4SDimitry Andric StringRef::iterator p = *PtrOrErr;
553009b1c42SEd Schouten
554009b1c42SEd Schouten D->firstSigDigit = p;
555009b1c42SEd Schouten D->exponent = 0;
556009b1c42SEd Schouten D->normalizedExponent = 0;
557009b1c42SEd Schouten
55859850d08SRoman Divacky for (; p != end; ++p) {
559009b1c42SEd Schouten if (*p == '.') {
560706b4fc4SDimitry Andric if (dot != end)
561706b4fc4SDimitry Andric return createError("String contains multiple dots");
562009b1c42SEd Schouten dot = p++;
56359850d08SRoman Divacky if (p == end)
56459850d08SRoman Divacky break;
565009b1c42SEd Schouten }
566009b1c42SEd Schouten if (decDigitValue(*p) >= 10U)
567009b1c42SEd Schouten break;
568009b1c42SEd Schouten }
569009b1c42SEd Schouten
57059850d08SRoman Divacky if (p != end) {
571706b4fc4SDimitry Andric if (*p != 'e' && *p != 'E')
572706b4fc4SDimitry Andric return createError("Invalid character in significand");
573706b4fc4SDimitry Andric if (p == begin)
574706b4fc4SDimitry Andric return createError("Significand has no digits");
575706b4fc4SDimitry Andric if (dot != end && p - begin == 1)
576706b4fc4SDimitry Andric return createError("Significand has no digits");
57759850d08SRoman Divacky
57859850d08SRoman Divacky /* p points to the first non-digit in the string */
579706b4fc4SDimitry Andric auto ExpOrErr = readExponent(p + 1, end);
580706b4fc4SDimitry Andric if (!ExpOrErr)
581706b4fc4SDimitry Andric return ExpOrErr.takeError();
582706b4fc4SDimitry Andric D->exponent = *ExpOrErr;
583009b1c42SEd Schouten
584009b1c42SEd Schouten /* Implied decimal point? */
58559850d08SRoman Divacky if (dot == end)
586009b1c42SEd Schouten dot = p;
58759850d08SRoman Divacky }
588009b1c42SEd Schouten
58959850d08SRoman Divacky /* If number is all zeroes accept any exponent. */
59059850d08SRoman Divacky if (p != D->firstSigDigit) {
591009b1c42SEd Schouten /* Drop insignificant trailing zeroes. */
59259850d08SRoman Divacky if (p != begin) {
593009b1c42SEd Schouten do
594009b1c42SEd Schouten do
595009b1c42SEd Schouten p--;
59659850d08SRoman Divacky while (p != begin && *p == '0');
59759850d08SRoman Divacky while (p != begin && *p == '.');
59859850d08SRoman Divacky }
599009b1c42SEd Schouten
600009b1c42SEd Schouten /* Adjust the exponents for any decimal point. */
601f8af5cf6SDimitry Andric D->exponent += static_cast<APFloat::ExponentType>((dot - p) - (dot > p));
602009b1c42SEd Schouten D->normalizedExponent = (D->exponent +
603f8af5cf6SDimitry Andric static_cast<APFloat::ExponentType>((p - D->firstSigDigit)
604009b1c42SEd Schouten - (dot > D->firstSigDigit && dot < p)));
605009b1c42SEd Schouten }
606009b1c42SEd Schouten
607009b1c42SEd Schouten D->lastSigDigit = p;
608706b4fc4SDimitry Andric return Error::success();
609009b1c42SEd Schouten }
610009b1c42SEd Schouten
611009b1c42SEd Schouten /* Return the trailing fraction of a hexadecimal number.
612009b1c42SEd Schouten DIGITVALUE is the first hex digit of the fraction, P points to
613009b1c42SEd Schouten the next digit. */
614706b4fc4SDimitry Andric static Expected<lostFraction>
trailingHexadecimalFraction(StringRef::iterator p,StringRef::iterator end,unsigned int digitValue)61559850d08SRoman Divacky trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end,
616706b4fc4SDimitry Andric unsigned int digitValue) {
617009b1c42SEd Schouten unsigned int hexDigit;
618009b1c42SEd Schouten
619009b1c42SEd Schouten /* If the first trailing digit isn't 0 or 8 we can work out the
620009b1c42SEd Schouten fraction immediately. */
621009b1c42SEd Schouten if (digitValue > 8)
622009b1c42SEd Schouten return lfMoreThanHalf;
623009b1c42SEd Schouten else if (digitValue < 8 && digitValue > 0)
624009b1c42SEd Schouten return lfLessThanHalf;
625009b1c42SEd Schouten
626f8af5cf6SDimitry Andric // Otherwise we need to find the first non-zero digit.
627f8af5cf6SDimitry Andric while (p != end && (*p == '0' || *p == '.'))
628009b1c42SEd Schouten p++;
629009b1c42SEd Schouten
630706b4fc4SDimitry Andric if (p == end)
631706b4fc4SDimitry Andric return createError("Invalid trailing hexadecimal fraction!");
63259850d08SRoman Divacky
633009b1c42SEd Schouten hexDigit = hexDigitValue(*p);
634009b1c42SEd Schouten
635009b1c42SEd Schouten /* If we ran off the end it is exactly zero or one-half, otherwise
636009b1c42SEd Schouten a little more. */
6377fa27ce4SDimitry Andric if (hexDigit == UINT_MAX)
638009b1c42SEd Schouten return digitValue == 0 ? lfExactlyZero: lfExactlyHalf;
639009b1c42SEd Schouten else
640009b1c42SEd Schouten return digitValue == 0 ? lfLessThanHalf: lfMoreThanHalf;
641009b1c42SEd Schouten }
642009b1c42SEd Schouten
643009b1c42SEd Schouten /* Return the fraction lost were a bignum truncated losing the least
644009b1c42SEd Schouten significant BITS bits. */
645009b1c42SEd Schouten static lostFraction
lostFractionThroughTruncation(const APFloatBase::integerPart * parts,unsigned int partCount,unsigned int bits)64608bbd35aSDimitry Andric lostFractionThroughTruncation(const APFloatBase::integerPart *parts,
647009b1c42SEd Schouten unsigned int partCount,
648009b1c42SEd Schouten unsigned int bits)
649009b1c42SEd Schouten {
650009b1c42SEd Schouten unsigned int lsb;
651009b1c42SEd Schouten
652009b1c42SEd Schouten lsb = APInt::tcLSB(parts, partCount);
653009b1c42SEd Schouten
6547fa27ce4SDimitry Andric /* Note this is guaranteed true if bits == 0, or LSB == UINT_MAX. */
655009b1c42SEd Schouten if (bits <= lsb)
656009b1c42SEd Schouten return lfExactlyZero;
657009b1c42SEd Schouten if (bits == lsb + 1)
658009b1c42SEd Schouten return lfExactlyHalf;
65908bbd35aSDimitry Andric if (bits <= partCount * APFloatBase::integerPartWidth &&
660104bd817SRoman Divacky APInt::tcExtractBit(parts, bits - 1))
661009b1c42SEd Schouten return lfMoreThanHalf;
662009b1c42SEd Schouten
663009b1c42SEd Schouten return lfLessThanHalf;
664009b1c42SEd Schouten }
665009b1c42SEd Schouten
666009b1c42SEd Schouten /* Shift DST right BITS bits noting lost fraction. */
667009b1c42SEd Schouten static lostFraction
shiftRight(APFloatBase::integerPart * dst,unsigned int parts,unsigned int bits)66808bbd35aSDimitry Andric shiftRight(APFloatBase::integerPart *dst, unsigned int parts, unsigned int bits)
669009b1c42SEd Schouten {
670009b1c42SEd Schouten lostFraction lost_fraction;
671009b1c42SEd Schouten
672009b1c42SEd Schouten lost_fraction = lostFractionThroughTruncation(dst, parts, bits);
673009b1c42SEd Schouten
674009b1c42SEd Schouten APInt::tcShiftRight(dst, parts, bits);
675009b1c42SEd Schouten
676009b1c42SEd Schouten return lost_fraction;
677009b1c42SEd Schouten }
678009b1c42SEd Schouten
679009b1c42SEd Schouten /* Combine the effect of two lost fractions. */
680009b1c42SEd Schouten static lostFraction
combineLostFractions(lostFraction moreSignificant,lostFraction lessSignificant)681009b1c42SEd Schouten combineLostFractions(lostFraction moreSignificant,
682009b1c42SEd Schouten lostFraction lessSignificant)
683009b1c42SEd Schouten {
684009b1c42SEd Schouten if (lessSignificant != lfExactlyZero) {
685009b1c42SEd Schouten if (moreSignificant == lfExactlyZero)
686009b1c42SEd Schouten moreSignificant = lfLessThanHalf;
687009b1c42SEd Schouten else if (moreSignificant == lfExactlyHalf)
688009b1c42SEd Schouten moreSignificant = lfMoreThanHalf;
689009b1c42SEd Schouten }
690009b1c42SEd Schouten
691009b1c42SEd Schouten return moreSignificant;
692009b1c42SEd Schouten }
693009b1c42SEd Schouten
694009b1c42SEd Schouten /* The error from the true value, in half-ulps, on multiplying two
695009b1c42SEd Schouten floating point numbers, which differ from the value they
696009b1c42SEd Schouten approximate by at most HUE1 and HUE2 half-ulps, is strictly less
697009b1c42SEd Schouten than the returned value.
698009b1c42SEd Schouten
699009b1c42SEd Schouten See "How to Read Floating Point Numbers Accurately" by William D
700009b1c42SEd Schouten Clinger. */
701009b1c42SEd Schouten static unsigned int
HUerrBound(bool inexactMultiply,unsigned int HUerr1,unsigned int HUerr2)702009b1c42SEd Schouten HUerrBound(bool inexactMultiply, unsigned int HUerr1, unsigned int HUerr2)
703009b1c42SEd Schouten {
704009b1c42SEd Schouten assert(HUerr1 < 2 || HUerr2 < 2 || (HUerr1 + HUerr2 < 8));
705009b1c42SEd Schouten
706009b1c42SEd Schouten if (HUerr1 + HUerr2 == 0)
707009b1c42SEd Schouten return inexactMultiply * 2; /* <= inexactMultiply half-ulps. */
708009b1c42SEd Schouten else
709009b1c42SEd Schouten return inexactMultiply + 2 * (HUerr1 + HUerr2);
710009b1c42SEd Schouten }
711009b1c42SEd Schouten
712009b1c42SEd Schouten /* The number of ulps from the boundary (zero, or half if ISNEAREST)
713009b1c42SEd Schouten when the least significant BITS are truncated. BITS cannot be
714009b1c42SEd Schouten zero. */
71508bbd35aSDimitry Andric static APFloatBase::integerPart
ulpsFromBoundary(const APFloatBase::integerPart * parts,unsigned int bits,bool isNearest)71608bbd35aSDimitry Andric ulpsFromBoundary(const APFloatBase::integerPart *parts, unsigned int bits,
71708bbd35aSDimitry Andric bool isNearest) {
718009b1c42SEd Schouten unsigned int count, partBits;
71908bbd35aSDimitry Andric APFloatBase::integerPart part, boundary;
720009b1c42SEd Schouten
721009b1c42SEd Schouten assert(bits != 0);
722009b1c42SEd Schouten
723009b1c42SEd Schouten bits--;
72408bbd35aSDimitry Andric count = bits / APFloatBase::integerPartWidth;
72508bbd35aSDimitry Andric partBits = bits % APFloatBase::integerPartWidth + 1;
726009b1c42SEd Schouten
72708bbd35aSDimitry Andric part = parts[count] & (~(APFloatBase::integerPart) 0 >> (APFloatBase::integerPartWidth - partBits));
728009b1c42SEd Schouten
729009b1c42SEd Schouten if (isNearest)
73008bbd35aSDimitry Andric boundary = (APFloatBase::integerPart) 1 << (partBits - 1);
731009b1c42SEd Schouten else
732009b1c42SEd Schouten boundary = 0;
733009b1c42SEd Schouten
734009b1c42SEd Schouten if (count == 0) {
735009b1c42SEd Schouten if (part - boundary <= boundary - part)
736009b1c42SEd Schouten return part - boundary;
737009b1c42SEd Schouten else
738009b1c42SEd Schouten return boundary - part;
739009b1c42SEd Schouten }
740009b1c42SEd Schouten
741009b1c42SEd Schouten if (part == boundary) {
742009b1c42SEd Schouten while (--count)
743009b1c42SEd Schouten if (parts[count])
74408bbd35aSDimitry Andric return ~(APFloatBase::integerPart) 0; /* A lot. */
745009b1c42SEd Schouten
746009b1c42SEd Schouten return parts[0];
747009b1c42SEd Schouten } else if (part == boundary - 1) {
748009b1c42SEd Schouten while (--count)
749009b1c42SEd Schouten if (~parts[count])
75008bbd35aSDimitry Andric return ~(APFloatBase::integerPart) 0; /* A lot. */
751009b1c42SEd Schouten
752009b1c42SEd Schouten return -parts[0];
753009b1c42SEd Schouten }
754009b1c42SEd Schouten
75508bbd35aSDimitry Andric return ~(APFloatBase::integerPart) 0; /* A lot. */
756009b1c42SEd Schouten }
757009b1c42SEd Schouten
758009b1c42SEd Schouten /* Place pow(5, power) in DST, and return the number of parts used.
759009b1c42SEd Schouten DST must be at least one part larger than size of the answer. */
760009b1c42SEd Schouten static unsigned int
powerOf5(APFloatBase::integerPart * dst,unsigned int power)76108bbd35aSDimitry Andric powerOf5(APFloatBase::integerPart *dst, unsigned int power) {
76208bbd35aSDimitry Andric static const APFloatBase::integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, 15625, 78125 };
76308bbd35aSDimitry Andric APFloatBase::integerPart pow5s[maxPowerOfFiveParts * 2 + 5];
764009b1c42SEd Schouten pow5s[0] = 78125 * 5;
765009b1c42SEd Schouten
766ac9a064cSDimitry Andric unsigned int partsCount = 1;
76708bbd35aSDimitry Andric APFloatBase::integerPart scratch[maxPowerOfFiveParts], *p1, *p2, *pow5;
768009b1c42SEd Schouten unsigned int result;
769009b1c42SEd Schouten assert(power <= maxExponent);
770009b1c42SEd Schouten
771009b1c42SEd Schouten p1 = dst;
772009b1c42SEd Schouten p2 = scratch;
773009b1c42SEd Schouten
774009b1c42SEd Schouten *p1 = firstEightPowers[power & 7];
775009b1c42SEd Schouten power >>= 3;
776009b1c42SEd Schouten
777009b1c42SEd Schouten result = 1;
778009b1c42SEd Schouten pow5 = pow5s;
779009b1c42SEd Schouten
780009b1c42SEd Schouten for (unsigned int n = 0; power; power >>= 1, n++) {
781009b1c42SEd Schouten /* Calculate pow(5,pow(2,n+3)) if we haven't yet. */
782ac9a064cSDimitry Andric if (n != 0) {
783ac9a064cSDimitry Andric APInt::tcFullMultiply(pow5, pow5 - partsCount, pow5 - partsCount,
784ac9a064cSDimitry Andric partsCount, partsCount);
785ac9a064cSDimitry Andric partsCount *= 2;
786ac9a064cSDimitry Andric if (pow5[partsCount - 1] == 0)
787ac9a064cSDimitry Andric partsCount--;
788009b1c42SEd Schouten }
789009b1c42SEd Schouten
790009b1c42SEd Schouten if (power & 1) {
79108bbd35aSDimitry Andric APFloatBase::integerPart *tmp;
792009b1c42SEd Schouten
793ac9a064cSDimitry Andric APInt::tcFullMultiply(p2, p1, pow5, result, partsCount);
794ac9a064cSDimitry Andric result += partsCount;
795009b1c42SEd Schouten if (p2[result - 1] == 0)
796009b1c42SEd Schouten result--;
797009b1c42SEd Schouten
798009b1c42SEd Schouten /* Now result is in p1 with partsCount parts and p2 is scratch
799009b1c42SEd Schouten space. */
80001095a5dSDimitry Andric tmp = p1;
80101095a5dSDimitry Andric p1 = p2;
80201095a5dSDimitry Andric p2 = tmp;
803009b1c42SEd Schouten }
804009b1c42SEd Schouten
805ac9a064cSDimitry Andric pow5 += partsCount;
806009b1c42SEd Schouten }
807009b1c42SEd Schouten
808009b1c42SEd Schouten if (p1 != dst)
809009b1c42SEd Schouten APInt::tcAssign(dst, p1, result);
810009b1c42SEd Schouten
811009b1c42SEd Schouten return result;
812009b1c42SEd Schouten }
813009b1c42SEd Schouten
814009b1c42SEd Schouten /* Zero at the end to avoid modular arithmetic when adding one; used
815009b1c42SEd Schouten when rounding up during hexadecimal output. */
816009b1c42SEd Schouten static const char hexDigitsLower[] = "0123456789abcdef0";
817009b1c42SEd Schouten static const char hexDigitsUpper[] = "0123456789ABCDEF0";
818009b1c42SEd Schouten static const char infinityL[] = "infinity";
819009b1c42SEd Schouten static const char infinityU[] = "INFINITY";
820009b1c42SEd Schouten static const char NaNL[] = "nan";
821009b1c42SEd Schouten static const char NaNU[] = "NAN";
822009b1c42SEd Schouten
823009b1c42SEd Schouten /* Write out an integerPart in hexadecimal, starting with the most
824009b1c42SEd Schouten significant nibble. Write out exactly COUNT hexdigits, return
825009b1c42SEd Schouten COUNT. */
826009b1c42SEd Schouten static unsigned int
partAsHex(char * dst,APFloatBase::integerPart part,unsigned int count,const char * hexDigitChars)82708bbd35aSDimitry Andric partAsHex (char *dst, APFloatBase::integerPart part, unsigned int count,
828009b1c42SEd Schouten const char *hexDigitChars)
829009b1c42SEd Schouten {
830009b1c42SEd Schouten unsigned int result = count;
831009b1c42SEd Schouten
83208bbd35aSDimitry Andric assert(count != 0 && count <= APFloatBase::integerPartWidth / 4);
833009b1c42SEd Schouten
83408bbd35aSDimitry Andric part >>= (APFloatBase::integerPartWidth - 4 * count);
835009b1c42SEd Schouten while (count--) {
836009b1c42SEd Schouten dst[count] = hexDigitChars[part & 0xf];
837009b1c42SEd Schouten part >>= 4;
838009b1c42SEd Schouten }
839009b1c42SEd Schouten
840009b1c42SEd Schouten return result;
841009b1c42SEd Schouten }
842009b1c42SEd Schouten
843009b1c42SEd Schouten /* Write out an unsigned decimal integer. */
844009b1c42SEd Schouten static char *
writeUnsignedDecimal(char * dst,unsigned int n)845009b1c42SEd Schouten writeUnsignedDecimal (char *dst, unsigned int n)
846009b1c42SEd Schouten {
847009b1c42SEd Schouten char buff[40], *p;
848009b1c42SEd Schouten
849009b1c42SEd Schouten p = buff;
850009b1c42SEd Schouten do
851009b1c42SEd Schouten *p++ = '0' + n % 10;
852009b1c42SEd Schouten while (n /= 10);
853009b1c42SEd Schouten
854009b1c42SEd Schouten do
855009b1c42SEd Schouten *dst++ = *--p;
856009b1c42SEd Schouten while (p != buff);
857009b1c42SEd Schouten
858009b1c42SEd Schouten return dst;
859009b1c42SEd Schouten }
860009b1c42SEd Schouten
861009b1c42SEd Schouten /* Write out a signed decimal integer. */
862009b1c42SEd Schouten static char *
writeSignedDecimal(char * dst,int value)863009b1c42SEd Schouten writeSignedDecimal (char *dst, int value)
864009b1c42SEd Schouten {
865009b1c42SEd Schouten if (value < 0) {
866009b1c42SEd Schouten *dst++ = '-';
867009b1c42SEd Schouten dst = writeUnsignedDecimal(dst, -(unsigned) value);
868009b1c42SEd Schouten } else
869009b1c42SEd Schouten dst = writeUnsignedDecimal(dst, value);
870009b1c42SEd Schouten
871009b1c42SEd Schouten return dst;
872009b1c42SEd Schouten }
873009b1c42SEd Schouten
874b915e9e0SDimitry Andric namespace detail {
875009b1c42SEd Schouten /* Constructors. */
initialize(const fltSemantics * ourSemantics)876b915e9e0SDimitry Andric void IEEEFloat::initialize(const fltSemantics *ourSemantics) {
877009b1c42SEd Schouten unsigned int count;
878009b1c42SEd Schouten
879009b1c42SEd Schouten semantics = ourSemantics;
880009b1c42SEd Schouten count = partCount();
881009b1c42SEd Schouten if (count > 1)
882009b1c42SEd Schouten significand.parts = new integerPart[count];
883009b1c42SEd Schouten }
884009b1c42SEd Schouten
freeSignificand()885b915e9e0SDimitry Andric void IEEEFloat::freeSignificand() {
886f8af5cf6SDimitry Andric if (needsCleanup())
887009b1c42SEd Schouten delete [] significand.parts;
888009b1c42SEd Schouten }
889009b1c42SEd Schouten
assign(const IEEEFloat & rhs)890b915e9e0SDimitry Andric void IEEEFloat::assign(const IEEEFloat &rhs) {
891009b1c42SEd Schouten assert(semantics == rhs.semantics);
892009b1c42SEd Schouten
893009b1c42SEd Schouten sign = rhs.sign;
894009b1c42SEd Schouten category = rhs.category;
895009b1c42SEd Schouten exponent = rhs.exponent;
896f8af5cf6SDimitry Andric if (isFiniteNonZero() || category == fcNaN)
897009b1c42SEd Schouten copySignificand(rhs);
898009b1c42SEd Schouten }
899009b1c42SEd Schouten
copySignificand(const IEEEFloat & rhs)900b915e9e0SDimitry Andric void IEEEFloat::copySignificand(const IEEEFloat &rhs) {
901f8af5cf6SDimitry Andric assert(isFiniteNonZero() || category == fcNaN);
902009b1c42SEd Schouten assert(rhs.partCount() >= partCount());
903009b1c42SEd Schouten
904009b1c42SEd Schouten APInt::tcAssign(significandParts(), rhs.significandParts(),
905009b1c42SEd Schouten partCount());
906009b1c42SEd Schouten }
907009b1c42SEd Schouten
908009b1c42SEd Schouten /* Make this number a NaN, with an arbitrary but deterministic value
909009b1c42SEd Schouten for the significand. If double or longer, this is a signalling NaN,
910009b1c42SEd Schouten which may not be ideal. If float, this is QNaN(0). */
makeNaN(bool SNaN,bool Negative,const APInt * fill)911b915e9e0SDimitry Andric void IEEEFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) {
912ac9a064cSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
913ac9a064cSDimitry Andric llvm_unreachable("This floating point format does not support NaN");
914ac9a064cSDimitry Andric
915009b1c42SEd Schouten category = fcNaN;
91667a71b31SRoman Divacky sign = Negative;
917b60736ecSDimitry Andric exponent = exponentNaN();
91867a71b31SRoman Divacky
91967a71b31SRoman Divacky integerPart *significand = significandParts();
92067a71b31SRoman Divacky unsigned numParts = partCount();
92167a71b31SRoman Divacky
922e3b55780SDimitry Andric APInt fill_storage;
923e3b55780SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
9247fa27ce4SDimitry Andric // Finite-only types do not distinguish signalling and quiet NaN, so
9257fa27ce4SDimitry Andric // make them all signalling.
926e3b55780SDimitry Andric SNaN = false;
9277fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) {
9287fa27ce4SDimitry Andric sign = true;
9297fa27ce4SDimitry Andric fill_storage = APInt::getZero(semantics->precision - 1);
9307fa27ce4SDimitry Andric } else {
931e3b55780SDimitry Andric fill_storage = APInt::getAllOnes(semantics->precision - 1);
9327fa27ce4SDimitry Andric }
933e3b55780SDimitry Andric fill = &fill_storage;
934e3b55780SDimitry Andric }
935e3b55780SDimitry Andric
93667a71b31SRoman Divacky // Set the significand bits to the fill.
93767a71b31SRoman Divacky if (!fill || fill->getNumWords() < numParts)
93867a71b31SRoman Divacky APInt::tcSet(significand, 0, numParts);
93967a71b31SRoman Divacky if (fill) {
94067a71b31SRoman Divacky APInt::tcAssign(significand, fill->getRawData(),
94167a71b31SRoman Divacky std::min(fill->getNumWords(), numParts));
94267a71b31SRoman Divacky
94367a71b31SRoman Divacky // Zero out the excess bits of the significand.
94467a71b31SRoman Divacky unsigned bitsToPreserve = semantics->precision - 1;
94567a71b31SRoman Divacky unsigned part = bitsToPreserve / 64;
94667a71b31SRoman Divacky bitsToPreserve %= 64;
94767a71b31SRoman Divacky significand[part] &= ((1ULL << bitsToPreserve) - 1);
94867a71b31SRoman Divacky for (part++; part != numParts; ++part)
94967a71b31SRoman Divacky significand[part] = 0;
95067a71b31SRoman Divacky }
95167a71b31SRoman Divacky
95267a71b31SRoman Divacky unsigned QNaNBit = semantics->precision - 2;
95367a71b31SRoman Divacky
95467a71b31SRoman Divacky if (SNaN) {
95567a71b31SRoman Divacky // We always have to clear the QNaN bit to make it an SNaN.
95667a71b31SRoman Divacky APInt::tcClearBit(significand, QNaNBit);
95767a71b31SRoman Divacky
95867a71b31SRoman Divacky // If there are no bits set in the payload, we have to set
95967a71b31SRoman Divacky // *something* to make it a NaN instead of an infinity;
96067a71b31SRoman Divacky // conventionally, this is the next bit down from the QNaN bit.
96167a71b31SRoman Divacky if (APInt::tcIsZero(significand, numParts))
96267a71b31SRoman Divacky APInt::tcSetBit(significand, QNaNBit - 1);
9637fa27ce4SDimitry Andric } else if (semantics->nanEncoding == fltNanEncoding::NegativeZero) {
9647fa27ce4SDimitry Andric // The only NaN is a quiet NaN, and it has no bits sets in the significand.
9657fa27ce4SDimitry Andric // Do nothing.
96667a71b31SRoman Divacky } else {
96767a71b31SRoman Divacky // We always have to set the QNaN bit to make it a QNaN.
96867a71b31SRoman Divacky APInt::tcSetBit(significand, QNaNBit);
96967a71b31SRoman Divacky }
97067a71b31SRoman Divacky
97167a71b31SRoman Divacky // For x87 extended precision, we want to make a NaN, not a
97267a71b31SRoman Divacky // pseudo-NaN. Maybe we should expose the ability to make
97367a71b31SRoman Divacky // pseudo-NaNs?
974b915e9e0SDimitry Andric if (semantics == &semX87DoubleExtended)
97567a71b31SRoman Divacky APInt::tcSetBit(significand, QNaNBit + 1);
97667a71b31SRoman Divacky }
97767a71b31SRoman Divacky
operator =(const IEEEFloat & rhs)978b915e9e0SDimitry Andric IEEEFloat &IEEEFloat::operator=(const IEEEFloat &rhs) {
979009b1c42SEd Schouten if (this != &rhs) {
980009b1c42SEd Schouten if (semantics != rhs.semantics) {
981009b1c42SEd Schouten freeSignificand();
982009b1c42SEd Schouten initialize(rhs.semantics);
983009b1c42SEd Schouten }
984009b1c42SEd Schouten assign(rhs);
985009b1c42SEd Schouten }
986009b1c42SEd Schouten
987009b1c42SEd Schouten return *this;
988009b1c42SEd Schouten }
989009b1c42SEd Schouten
operator =(IEEEFloat && rhs)990b915e9e0SDimitry Andric IEEEFloat &IEEEFloat::operator=(IEEEFloat &&rhs) {
9915ca98fd9SDimitry Andric freeSignificand();
9925ca98fd9SDimitry Andric
9935ca98fd9SDimitry Andric semantics = rhs.semantics;
9945ca98fd9SDimitry Andric significand = rhs.significand;
9955ca98fd9SDimitry Andric exponent = rhs.exponent;
9965ca98fd9SDimitry Andric category = rhs.category;
9975ca98fd9SDimitry Andric sign = rhs.sign;
9985ca98fd9SDimitry Andric
999b915e9e0SDimitry Andric rhs.semantics = &semBogus;
10005ca98fd9SDimitry Andric return *this;
10015ca98fd9SDimitry Andric }
10025ca98fd9SDimitry Andric
isDenormal() const1003b915e9e0SDimitry Andric bool IEEEFloat::isDenormal() const {
1004f8af5cf6SDimitry Andric return isFiniteNonZero() && (exponent == semantics->minExponent) &&
10054a16efa3SDimitry Andric (APInt::tcExtractBit(significandParts(),
10064a16efa3SDimitry Andric semantics->precision - 1) == 0);
10074a16efa3SDimitry Andric }
10084a16efa3SDimitry Andric
isSmallest() const1009b915e9e0SDimitry Andric bool IEEEFloat::isSmallest() const {
1010f8af5cf6SDimitry Andric // The smallest number by magnitude in our format will be the smallest
1011f8af5cf6SDimitry Andric // denormal, i.e. the floating point number with exponent being minimum
1012f8af5cf6SDimitry Andric // exponent and significand bitwise equal to 1 (i.e. with MSB equal to 0).
1013f8af5cf6SDimitry Andric return isFiniteNonZero() && exponent == semantics->minExponent &&
1014f8af5cf6SDimitry Andric significandMSB() == 0;
1015f8af5cf6SDimitry Andric }
1016f8af5cf6SDimitry Andric
isSmallestNormalized() const1017e3b55780SDimitry Andric bool IEEEFloat::isSmallestNormalized() const {
1018e3b55780SDimitry Andric return getCategory() == fcNormal && exponent == semantics->minExponent &&
1019e3b55780SDimitry Andric isSignificandAllZerosExceptMSB();
1020e3b55780SDimitry Andric }
1021e3b55780SDimitry Andric
isSignificandAllOnes() const1022b915e9e0SDimitry Andric bool IEEEFloat::isSignificandAllOnes() const {
1023f8af5cf6SDimitry Andric // Test if the significand excluding the integral bit is all ones. This allows
1024f8af5cf6SDimitry Andric // us to test for binade boundaries.
1025f8af5cf6SDimitry Andric const integerPart *Parts = significandParts();
1026b60736ecSDimitry Andric const unsigned PartCount = partCountForBits(semantics->precision);
1027f8af5cf6SDimitry Andric for (unsigned i = 0; i < PartCount - 1; i++)
1028f8af5cf6SDimitry Andric if (~Parts[i])
1029f8af5cf6SDimitry Andric return false;
1030f8af5cf6SDimitry Andric
1031f8af5cf6SDimitry Andric // Set the unused high bits to all ones when we compare.
1032f8af5cf6SDimitry Andric const unsigned NumHighBits =
1033f8af5cf6SDimitry Andric PartCount*integerPartWidth - semantics->precision + 1;
1034b60736ecSDimitry Andric assert(NumHighBits <= integerPartWidth && NumHighBits > 0 &&
1035b60736ecSDimitry Andric "Can not have more high bits to fill than integerPartWidth");
1036f8af5cf6SDimitry Andric const integerPart HighBitFill =
1037f8af5cf6SDimitry Andric ~integerPart(0) << (integerPartWidth - NumHighBits);
1038f8af5cf6SDimitry Andric if (~(Parts[PartCount - 1] | HighBitFill))
1039f8af5cf6SDimitry Andric return false;
1040f8af5cf6SDimitry Andric
1041f8af5cf6SDimitry Andric return true;
1042f8af5cf6SDimitry Andric }
1043f8af5cf6SDimitry Andric
isSignificandAllOnesExceptLSB() const1044e3b55780SDimitry Andric bool IEEEFloat::isSignificandAllOnesExceptLSB() const {
1045e3b55780SDimitry Andric // Test if the significand excluding the integral bit is all ones except for
1046e3b55780SDimitry Andric // the least significant bit.
1047e3b55780SDimitry Andric const integerPart *Parts = significandParts();
1048e3b55780SDimitry Andric
1049e3b55780SDimitry Andric if (Parts[0] & 1)
1050e3b55780SDimitry Andric return false;
1051e3b55780SDimitry Andric
1052e3b55780SDimitry Andric const unsigned PartCount = partCountForBits(semantics->precision);
1053e3b55780SDimitry Andric for (unsigned i = 0; i < PartCount - 1; i++) {
1054e3b55780SDimitry Andric if (~Parts[i] & ~unsigned{!i})
1055e3b55780SDimitry Andric return false;
1056e3b55780SDimitry Andric }
1057e3b55780SDimitry Andric
1058e3b55780SDimitry Andric // Set the unused high bits to all ones when we compare.
1059e3b55780SDimitry Andric const unsigned NumHighBits =
1060e3b55780SDimitry Andric PartCount * integerPartWidth - semantics->precision + 1;
1061e3b55780SDimitry Andric assert(NumHighBits <= integerPartWidth && NumHighBits > 0 &&
1062e3b55780SDimitry Andric "Can not have more high bits to fill than integerPartWidth");
1063e3b55780SDimitry Andric const integerPart HighBitFill = ~integerPart(0)
1064e3b55780SDimitry Andric << (integerPartWidth - NumHighBits);
1065e3b55780SDimitry Andric if (~(Parts[PartCount - 1] | HighBitFill | 0x1))
1066e3b55780SDimitry Andric return false;
1067e3b55780SDimitry Andric
1068e3b55780SDimitry Andric return true;
1069e3b55780SDimitry Andric }
1070e3b55780SDimitry Andric
isSignificandAllZeros() const1071b915e9e0SDimitry Andric bool IEEEFloat::isSignificandAllZeros() const {
1072f8af5cf6SDimitry Andric // Test if the significand excluding the integral bit is all zeros. This
1073f8af5cf6SDimitry Andric // allows us to test for binade boundaries.
1074f8af5cf6SDimitry Andric const integerPart *Parts = significandParts();
1075b60736ecSDimitry Andric const unsigned PartCount = partCountForBits(semantics->precision);
1076f8af5cf6SDimitry Andric
1077f8af5cf6SDimitry Andric for (unsigned i = 0; i < PartCount - 1; i++)
1078f8af5cf6SDimitry Andric if (Parts[i])
1079f8af5cf6SDimitry Andric return false;
1080f8af5cf6SDimitry Andric
1081b60736ecSDimitry Andric // Compute how many bits are used in the final word.
1082f8af5cf6SDimitry Andric const unsigned NumHighBits =
1083f8af5cf6SDimitry Andric PartCount*integerPartWidth - semantics->precision + 1;
1084b60736ecSDimitry Andric assert(NumHighBits < integerPartWidth && "Can not have more high bits to "
1085f8af5cf6SDimitry Andric "clear than integerPartWidth");
1086f8af5cf6SDimitry Andric const integerPart HighBitMask = ~integerPart(0) >> NumHighBits;
1087f8af5cf6SDimitry Andric
1088f8af5cf6SDimitry Andric if (Parts[PartCount - 1] & HighBitMask)
1089f8af5cf6SDimitry Andric return false;
1090f8af5cf6SDimitry Andric
1091f8af5cf6SDimitry Andric return true;
1092f8af5cf6SDimitry Andric }
1093f8af5cf6SDimitry Andric
isSignificandAllZerosExceptMSB() const1094e3b55780SDimitry Andric bool IEEEFloat::isSignificandAllZerosExceptMSB() const {
1095e3b55780SDimitry Andric const integerPart *Parts = significandParts();
1096e3b55780SDimitry Andric const unsigned PartCount = partCountForBits(semantics->precision);
1097e3b55780SDimitry Andric
1098e3b55780SDimitry Andric for (unsigned i = 0; i < PartCount - 1; i++) {
1099e3b55780SDimitry Andric if (Parts[i])
1100e3b55780SDimitry Andric return false;
1101e3b55780SDimitry Andric }
1102e3b55780SDimitry Andric
1103e3b55780SDimitry Andric const unsigned NumHighBits =
1104e3b55780SDimitry Andric PartCount * integerPartWidth - semantics->precision + 1;
1105e3b55780SDimitry Andric return Parts[PartCount - 1] == integerPart(1)
1106e3b55780SDimitry Andric << (integerPartWidth - NumHighBits);
1107e3b55780SDimitry Andric }
1108e3b55780SDimitry Andric
isLargest() const1109b915e9e0SDimitry Andric bool IEEEFloat::isLargest() const {
11107fa27ce4SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly &&
11117fa27ce4SDimitry Andric semantics->nanEncoding == fltNanEncoding::AllOnes) {
1112e3b55780SDimitry Andric // The largest number by magnitude in our format will be the floating point
1113e3b55780SDimitry Andric // number with maximum exponent and with significand that is all ones except
1114e3b55780SDimitry Andric // the LSB.
1115e3b55780SDimitry Andric return isFiniteNonZero() && exponent == semantics->maxExponent &&
1116e3b55780SDimitry Andric isSignificandAllOnesExceptLSB();
1117e3b55780SDimitry Andric } else {
1118f8af5cf6SDimitry Andric // The largest number by magnitude in our format will be the floating point
1119f8af5cf6SDimitry Andric // number with maximum exponent and with significand that is all ones.
1120e3b55780SDimitry Andric return isFiniteNonZero() && exponent == semantics->maxExponent &&
1121e3b55780SDimitry Andric isSignificandAllOnes();
1122e3b55780SDimitry Andric }
1123f8af5cf6SDimitry Andric }
1124f8af5cf6SDimitry Andric
isInteger() const1125b915e9e0SDimitry Andric bool IEEEFloat::isInteger() const {
1126dd58ef01SDimitry Andric // This could be made more efficient; I'm going for obviously correct.
1127dd58ef01SDimitry Andric if (!isFinite()) return false;
1128b915e9e0SDimitry Andric IEEEFloat truncated = *this;
1129dd58ef01SDimitry Andric truncated.roundToIntegral(rmTowardZero);
1130dd58ef01SDimitry Andric return compare(truncated) == cmpEqual;
1131dd58ef01SDimitry Andric }
1132dd58ef01SDimitry Andric
bitwiseIsEqual(const IEEEFloat & rhs) const1133b915e9e0SDimitry Andric bool IEEEFloat::bitwiseIsEqual(const IEEEFloat &rhs) const {
1134009b1c42SEd Schouten if (this == &rhs)
1135009b1c42SEd Schouten return true;
1136009b1c42SEd Schouten if (semantics != rhs.semantics ||
1137009b1c42SEd Schouten category != rhs.category ||
1138009b1c42SEd Schouten sign != rhs.sign)
1139009b1c42SEd Schouten return false;
1140009b1c42SEd Schouten if (category==fcZero || category==fcInfinity)
1141009b1c42SEd Schouten return true;
1142dd58ef01SDimitry Andric
1143dd58ef01SDimitry Andric if (isFiniteNonZero() && exponent != rhs.exponent)
1144009b1c42SEd Schouten return false;
1145dd58ef01SDimitry Andric
1146dd58ef01SDimitry Andric return std::equal(significandParts(), significandParts() + partCount(),
1147dd58ef01SDimitry Andric rhs.significandParts());
1148009b1c42SEd Schouten }
1149009b1c42SEd Schouten
IEEEFloat(const fltSemantics & ourSemantics,integerPart value)1150b915e9e0SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, integerPart value) {
1151009b1c42SEd Schouten initialize(&ourSemantics);
1152009b1c42SEd Schouten sign = 0;
1153f8af5cf6SDimitry Andric category = fcNormal;
1154009b1c42SEd Schouten zeroSignificand();
1155009b1c42SEd Schouten exponent = ourSemantics.precision - 1;
1156009b1c42SEd Schouten significandParts()[0] = value;
1157009b1c42SEd Schouten normalize(rmNearestTiesToEven, lfExactlyZero);
1158009b1c42SEd Schouten }
1159009b1c42SEd Schouten
IEEEFloat(const fltSemantics & ourSemantics)1160b915e9e0SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics) {
116159850d08SRoman Divacky initialize(&ourSemantics);
1162b60736ecSDimitry Andric makeZero(false);
116359850d08SRoman Divacky }
116459850d08SRoman Divacky
1165b915e9e0SDimitry Andric // Delegate to the previous constructor, because later copy constructor may
1166b915e9e0SDimitry Andric // actually inspects category, which can't be garbage.
IEEEFloat(const fltSemantics & ourSemantics,uninitializedTag tag)1167b915e9e0SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, uninitializedTag tag)
1168b915e9e0SDimitry Andric : IEEEFloat(ourSemantics) {}
116959850d08SRoman Divacky
IEEEFloat(const IEEEFloat & rhs)1170b915e9e0SDimitry Andric IEEEFloat::IEEEFloat(const IEEEFloat &rhs) {
1171009b1c42SEd Schouten initialize(rhs.semantics);
1172009b1c42SEd Schouten assign(rhs);
1173009b1c42SEd Schouten }
1174009b1c42SEd Schouten
IEEEFloat(IEEEFloat && rhs)1175b915e9e0SDimitry Andric IEEEFloat::IEEEFloat(IEEEFloat &&rhs) : semantics(&semBogus) {
11765ca98fd9SDimitry Andric *this = std::move(rhs);
11775ca98fd9SDimitry Andric }
11785ca98fd9SDimitry Andric
~IEEEFloat()1179b915e9e0SDimitry Andric IEEEFloat::~IEEEFloat() { freeSignificand(); }
1180009b1c42SEd Schouten
partCount() const1181b915e9e0SDimitry Andric unsigned int IEEEFloat::partCount() const {
1182009b1c42SEd Schouten return partCountForBits(semantics->precision + 1);
1183009b1c42SEd Schouten }
1184009b1c42SEd Schouten
significandParts() const118508bbd35aSDimitry Andric const IEEEFloat::integerPart *IEEEFloat::significandParts() const {
1186b915e9e0SDimitry Andric return const_cast<IEEEFloat *>(this)->significandParts();
1187dd58ef01SDimitry Andric }
1188009b1c42SEd Schouten
significandParts()118908bbd35aSDimitry Andric IEEEFloat::integerPart *IEEEFloat::significandParts() {
1190009b1c42SEd Schouten if (partCount() > 1)
1191009b1c42SEd Schouten return significand.parts;
1192009b1c42SEd Schouten else
1193009b1c42SEd Schouten return &significand.part;
1194009b1c42SEd Schouten }
1195009b1c42SEd Schouten
zeroSignificand()1196b915e9e0SDimitry Andric void IEEEFloat::zeroSignificand() {
1197009b1c42SEd Schouten APInt::tcSet(significandParts(), 0, partCount());
1198009b1c42SEd Schouten }
1199009b1c42SEd Schouten
1200009b1c42SEd Schouten /* Increment an fcNormal floating point number's significand. */
incrementSignificand()1201b915e9e0SDimitry Andric void IEEEFloat::incrementSignificand() {
1202009b1c42SEd Schouten integerPart carry;
1203009b1c42SEd Schouten
1204009b1c42SEd Schouten carry = APInt::tcIncrement(significandParts(), partCount());
1205009b1c42SEd Schouten
1206009b1c42SEd Schouten /* Our callers should never cause us to overflow. */
1207009b1c42SEd Schouten assert(carry == 0);
120830815c53SDimitry Andric (void)carry;
1209009b1c42SEd Schouten }
1210009b1c42SEd Schouten
1211009b1c42SEd Schouten /* Add the significand of the RHS. Returns the carry flag. */
addSignificand(const IEEEFloat & rhs)121208bbd35aSDimitry Andric IEEEFloat::integerPart IEEEFloat::addSignificand(const IEEEFloat &rhs) {
1213009b1c42SEd Schouten integerPart *parts;
1214009b1c42SEd Schouten
1215009b1c42SEd Schouten parts = significandParts();
1216009b1c42SEd Schouten
1217009b1c42SEd Schouten assert(semantics == rhs.semantics);
1218009b1c42SEd Schouten assert(exponent == rhs.exponent);
1219009b1c42SEd Schouten
1220009b1c42SEd Schouten return APInt::tcAdd(parts, rhs.significandParts(), 0, partCount());
1221009b1c42SEd Schouten }
1222009b1c42SEd Schouten
1223009b1c42SEd Schouten /* Subtract the significand of the RHS with a borrow flag. Returns
1224009b1c42SEd Schouten the borrow flag. */
subtractSignificand(const IEEEFloat & rhs,integerPart borrow)122508bbd35aSDimitry Andric IEEEFloat::integerPart IEEEFloat::subtractSignificand(const IEEEFloat &rhs,
1226b915e9e0SDimitry Andric integerPart borrow) {
1227009b1c42SEd Schouten integerPart *parts;
1228009b1c42SEd Schouten
1229009b1c42SEd Schouten parts = significandParts();
1230009b1c42SEd Schouten
1231009b1c42SEd Schouten assert(semantics == rhs.semantics);
1232009b1c42SEd Schouten assert(exponent == rhs.exponent);
1233009b1c42SEd Schouten
1234009b1c42SEd Schouten return APInt::tcSubtract(parts, rhs.significandParts(), borrow,
1235009b1c42SEd Schouten partCount());
1236009b1c42SEd Schouten }
1237009b1c42SEd Schouten
1238009b1c42SEd Schouten /* Multiply the significand of the RHS. If ADDEND is non-NULL, add it
1239009b1c42SEd Schouten on to the full-precision result of the multiplication. Returns the
1240009b1c42SEd Schouten lost fraction. */
multiplySignificand(const IEEEFloat & rhs,IEEEFloat addend)1241b915e9e0SDimitry Andric lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs,
1242706b4fc4SDimitry Andric IEEEFloat addend) {
1243009b1c42SEd Schouten unsigned int omsb; // One, not zero, based MSB.
1244009b1c42SEd Schouten unsigned int partsCount, newPartsCount, precision;
1245009b1c42SEd Schouten integerPart *lhsSignificand;
1246009b1c42SEd Schouten integerPart scratch[4];
1247009b1c42SEd Schouten integerPart *fullSignificand;
1248009b1c42SEd Schouten lostFraction lost_fraction;
1249009b1c42SEd Schouten bool ignored;
1250009b1c42SEd Schouten
1251009b1c42SEd Schouten assert(semantics == rhs.semantics);
1252009b1c42SEd Schouten
1253009b1c42SEd Schouten precision = semantics->precision;
125467c32a98SDimitry Andric
125567c32a98SDimitry Andric // Allocate space for twice as many bits as the original significand, plus one
125667c32a98SDimitry Andric // extra bit for the addition to overflow into.
125767c32a98SDimitry Andric newPartsCount = partCountForBits(precision * 2 + 1);
1258009b1c42SEd Schouten
1259009b1c42SEd Schouten if (newPartsCount > 4)
1260009b1c42SEd Schouten fullSignificand = new integerPart[newPartsCount];
1261009b1c42SEd Schouten else
1262009b1c42SEd Schouten fullSignificand = scratch;
1263009b1c42SEd Schouten
1264009b1c42SEd Schouten lhsSignificand = significandParts();
1265009b1c42SEd Schouten partsCount = partCount();
1266009b1c42SEd Schouten
1267009b1c42SEd Schouten APInt::tcFullMultiply(fullSignificand, lhsSignificand,
1268009b1c42SEd Schouten rhs.significandParts(), partsCount, partsCount);
1269009b1c42SEd Schouten
1270009b1c42SEd Schouten lost_fraction = lfExactlyZero;
1271009b1c42SEd Schouten omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
1272009b1c42SEd Schouten exponent += rhs.exponent;
1273009b1c42SEd Schouten
1274f8af5cf6SDimitry Andric // Assume the operands involved in the multiplication are single-precision
1275f8af5cf6SDimitry Andric // FP, and the two multiplicants are:
1276f8af5cf6SDimitry Andric // *this = a23 . a22 ... a0 * 2^e1
1277f8af5cf6SDimitry Andric // rhs = b23 . b22 ... b0 * 2^e2
1278f8af5cf6SDimitry Andric // the result of multiplication is:
127967c32a98SDimitry Andric // *this = c48 c47 c46 . c45 ... c0 * 2^(e1+e2)
128067c32a98SDimitry Andric // Note that there are three significant bits at the left-hand side of the
128167c32a98SDimitry Andric // radix point: two for the multiplication, and an overflow bit for the
128267c32a98SDimitry Andric // addition (that will always be zero at this point). Move the radix point
128367c32a98SDimitry Andric // toward left by two bits, and adjust exponent accordingly.
128467c32a98SDimitry Andric exponent += 2;
1285f8af5cf6SDimitry Andric
1286706b4fc4SDimitry Andric if (addend.isNonZero()) {
1287f8af5cf6SDimitry Andric // The intermediate result of the multiplication has "2 * precision"
1288f8af5cf6SDimitry Andric // signicant bit; adjust the addend to be consistent with mul result.
1289f8af5cf6SDimitry Andric //
1290009b1c42SEd Schouten Significand savedSignificand = significand;
1291009b1c42SEd Schouten const fltSemantics *savedSemantics = semantics;
1292009b1c42SEd Schouten fltSemantics extendedSemantics;
1293009b1c42SEd Schouten opStatus status;
1294009b1c42SEd Schouten unsigned int extendedPrecision;
1295009b1c42SEd Schouten
129667c32a98SDimitry Andric // Normalize our MSB to one below the top bit to allow for overflow.
129767c32a98SDimitry Andric extendedPrecision = 2 * precision + 1;
129867c32a98SDimitry Andric if (omsb != extendedPrecision - 1) {
1299f8af5cf6SDimitry Andric assert(extendedPrecision > omsb);
1300009b1c42SEd Schouten APInt::tcShiftLeft(fullSignificand, newPartsCount,
130167c32a98SDimitry Andric (extendedPrecision - 1) - omsb);
130267c32a98SDimitry Andric exponent -= (extendedPrecision - 1) - omsb;
1303009b1c42SEd Schouten }
1304009b1c42SEd Schouten
1305009b1c42SEd Schouten /* Create new semantics. */
1306009b1c42SEd Schouten extendedSemantics = *semantics;
1307009b1c42SEd Schouten extendedSemantics.precision = extendedPrecision;
1308009b1c42SEd Schouten
1309009b1c42SEd Schouten if (newPartsCount == 1)
1310009b1c42SEd Schouten significand.part = fullSignificand[0];
1311009b1c42SEd Schouten else
1312009b1c42SEd Schouten significand.parts = fullSignificand;
1313009b1c42SEd Schouten semantics = &extendedSemantics;
1314009b1c42SEd Schouten
1315706b4fc4SDimitry Andric // Make a copy so we can convert it to the extended semantics.
1316706b4fc4SDimitry Andric // Note that we cannot convert the addend directly, as the extendedSemantics
1317706b4fc4SDimitry Andric // is a local variable (which we take a reference to).
1318706b4fc4SDimitry Andric IEEEFloat extendedAddend(addend);
1319009b1c42SEd Schouten status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored);
1320009b1c42SEd Schouten assert(status == opOK);
132130815c53SDimitry Andric (void)status;
132267c32a98SDimitry Andric
132367c32a98SDimitry Andric // Shift the significand of the addend right by one bit. This guarantees
132467c32a98SDimitry Andric // that the high bit of the significand is zero (same as fullSignificand),
132567c32a98SDimitry Andric // so the addition will overflow (if it does overflow at all) into the top bit.
132667c32a98SDimitry Andric lost_fraction = extendedAddend.shiftSignificandRight(1);
132767c32a98SDimitry Andric assert(lost_fraction == lfExactlyZero &&
132867c32a98SDimitry Andric "Lost precision while shifting addend for fused-multiply-add.");
132967c32a98SDimitry Andric
1330009b1c42SEd Schouten lost_fraction = addOrSubtractSignificand(extendedAddend, false);
1331009b1c42SEd Schouten
1332009b1c42SEd Schouten /* Restore our state. */
1333009b1c42SEd Schouten if (newPartsCount == 1)
1334009b1c42SEd Schouten fullSignificand[0] = significand.part;
1335009b1c42SEd Schouten significand = savedSignificand;
1336009b1c42SEd Schouten semantics = savedSemantics;
1337009b1c42SEd Schouten
1338009b1c42SEd Schouten omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
1339009b1c42SEd Schouten }
1340009b1c42SEd Schouten
1341f8af5cf6SDimitry Andric // Convert the result having "2 * precision" significant-bits back to the one
1342f8af5cf6SDimitry Andric // having "precision" significant-bits. First, move the radix point from
1343f8af5cf6SDimitry Andric // poision "2*precision - 1" to "precision - 1". The exponent need to be
1344f8af5cf6SDimitry Andric // adjusted by "2*precision - 1" - "precision - 1" = "precision".
134567c32a98SDimitry Andric exponent -= precision + 1;
1346009b1c42SEd Schouten
1347f8af5cf6SDimitry Andric // In case MSB resides at the left-hand side of radix point, shift the
1348f8af5cf6SDimitry Andric // mantissa right by some amount to make sure the MSB reside right before
1349f8af5cf6SDimitry Andric // the radix point (i.e. "MSB . rest-significant-bits").
1350f8af5cf6SDimitry Andric //
1351f8af5cf6SDimitry Andric // Note that the result is not normalized when "omsb < precision". So, the
1352b915e9e0SDimitry Andric // caller needs to call IEEEFloat::normalize() if normalized value is
1353b915e9e0SDimitry Andric // expected.
1354009b1c42SEd Schouten if (omsb > precision) {
1355009b1c42SEd Schouten unsigned int bits, significantParts;
1356009b1c42SEd Schouten lostFraction lf;
1357009b1c42SEd Schouten
1358009b1c42SEd Schouten bits = omsb - precision;
1359009b1c42SEd Schouten significantParts = partCountForBits(omsb);
1360009b1c42SEd Schouten lf = shiftRight(fullSignificand, significantParts, bits);
1361009b1c42SEd Schouten lost_fraction = combineLostFractions(lf, lost_fraction);
1362009b1c42SEd Schouten exponent += bits;
1363009b1c42SEd Schouten }
1364009b1c42SEd Schouten
1365009b1c42SEd Schouten APInt::tcAssign(lhsSignificand, fullSignificand, partsCount);
1366009b1c42SEd Schouten
1367009b1c42SEd Schouten if (newPartsCount > 4)
1368009b1c42SEd Schouten delete [] fullSignificand;
1369009b1c42SEd Schouten
1370009b1c42SEd Schouten return lost_fraction;
1371009b1c42SEd Schouten }
1372009b1c42SEd Schouten
multiplySignificand(const IEEEFloat & rhs)1373706b4fc4SDimitry Andric lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs) {
1374706b4fc4SDimitry Andric return multiplySignificand(rhs, IEEEFloat(*semantics));
1375706b4fc4SDimitry Andric }
1376706b4fc4SDimitry Andric
1377009b1c42SEd Schouten /* Multiply the significands of LHS and RHS to DST. */
divideSignificand(const IEEEFloat & rhs)1378b915e9e0SDimitry Andric lostFraction IEEEFloat::divideSignificand(const IEEEFloat &rhs) {
1379009b1c42SEd Schouten unsigned int bit, i, partsCount;
1380009b1c42SEd Schouten const integerPart *rhsSignificand;
1381009b1c42SEd Schouten integerPart *lhsSignificand, *dividend, *divisor;
1382009b1c42SEd Schouten integerPart scratch[4];
1383009b1c42SEd Schouten lostFraction lost_fraction;
1384009b1c42SEd Schouten
1385009b1c42SEd Schouten assert(semantics == rhs.semantics);
1386009b1c42SEd Schouten
1387009b1c42SEd Schouten lhsSignificand = significandParts();
1388009b1c42SEd Schouten rhsSignificand = rhs.significandParts();
1389009b1c42SEd Schouten partsCount = partCount();
1390009b1c42SEd Schouten
1391009b1c42SEd Schouten if (partsCount > 2)
1392009b1c42SEd Schouten dividend = new integerPart[partsCount * 2];
1393009b1c42SEd Schouten else
1394009b1c42SEd Schouten dividend = scratch;
1395009b1c42SEd Schouten
1396009b1c42SEd Schouten divisor = dividend + partsCount;
1397009b1c42SEd Schouten
1398009b1c42SEd Schouten /* Copy the dividend and divisor as they will be modified in-place. */
1399009b1c42SEd Schouten for (i = 0; i < partsCount; i++) {
1400009b1c42SEd Schouten dividend[i] = lhsSignificand[i];
1401009b1c42SEd Schouten divisor[i] = rhsSignificand[i];
1402009b1c42SEd Schouten lhsSignificand[i] = 0;
1403009b1c42SEd Schouten }
1404009b1c42SEd Schouten
1405009b1c42SEd Schouten exponent -= rhs.exponent;
1406009b1c42SEd Schouten
1407009b1c42SEd Schouten unsigned int precision = semantics->precision;
1408009b1c42SEd Schouten
1409009b1c42SEd Schouten /* Normalize the divisor. */
1410009b1c42SEd Schouten bit = precision - APInt::tcMSB(divisor, partsCount) - 1;
1411009b1c42SEd Schouten if (bit) {
1412009b1c42SEd Schouten exponent += bit;
1413009b1c42SEd Schouten APInt::tcShiftLeft(divisor, partsCount, bit);
1414009b1c42SEd Schouten }
1415009b1c42SEd Schouten
1416009b1c42SEd Schouten /* Normalize the dividend. */
1417009b1c42SEd Schouten bit = precision - APInt::tcMSB(dividend, partsCount) - 1;
1418009b1c42SEd Schouten if (bit) {
1419009b1c42SEd Schouten exponent -= bit;
1420009b1c42SEd Schouten APInt::tcShiftLeft(dividend, partsCount, bit);
1421009b1c42SEd Schouten }
1422009b1c42SEd Schouten
1423009b1c42SEd Schouten /* Ensure the dividend >= divisor initially for the loop below.
1424009b1c42SEd Schouten Incidentally, this means that the division loop below is
1425009b1c42SEd Schouten guaranteed to set the integer bit to one. */
1426009b1c42SEd Schouten if (APInt::tcCompare(dividend, divisor, partsCount) < 0) {
1427009b1c42SEd Schouten exponent--;
1428009b1c42SEd Schouten APInt::tcShiftLeft(dividend, partsCount, 1);
1429009b1c42SEd Schouten assert(APInt::tcCompare(dividend, divisor, partsCount) >= 0);
1430009b1c42SEd Schouten }
1431009b1c42SEd Schouten
1432009b1c42SEd Schouten /* Long division. */
1433009b1c42SEd Schouten for (bit = precision; bit; bit -= 1) {
1434009b1c42SEd Schouten if (APInt::tcCompare(dividend, divisor, partsCount) >= 0) {
1435009b1c42SEd Schouten APInt::tcSubtract(dividend, divisor, 0, partsCount);
1436009b1c42SEd Schouten APInt::tcSetBit(lhsSignificand, bit - 1);
1437009b1c42SEd Schouten }
1438009b1c42SEd Schouten
1439009b1c42SEd Schouten APInt::tcShiftLeft(dividend, partsCount, 1);
1440009b1c42SEd Schouten }
1441009b1c42SEd Schouten
1442009b1c42SEd Schouten /* Figure out the lost fraction. */
1443009b1c42SEd Schouten int cmp = APInt::tcCompare(dividend, divisor, partsCount);
1444009b1c42SEd Schouten
1445009b1c42SEd Schouten if (cmp > 0)
1446009b1c42SEd Schouten lost_fraction = lfMoreThanHalf;
1447009b1c42SEd Schouten else if (cmp == 0)
1448009b1c42SEd Schouten lost_fraction = lfExactlyHalf;
1449009b1c42SEd Schouten else if (APInt::tcIsZero(dividend, partsCount))
1450009b1c42SEd Schouten lost_fraction = lfExactlyZero;
1451009b1c42SEd Schouten else
1452009b1c42SEd Schouten lost_fraction = lfLessThanHalf;
1453009b1c42SEd Schouten
1454009b1c42SEd Schouten if (partsCount > 2)
1455009b1c42SEd Schouten delete [] dividend;
1456009b1c42SEd Schouten
1457009b1c42SEd Schouten return lost_fraction;
1458009b1c42SEd Schouten }
1459009b1c42SEd Schouten
significandMSB() const1460b915e9e0SDimitry Andric unsigned int IEEEFloat::significandMSB() const {
1461009b1c42SEd Schouten return APInt::tcMSB(significandParts(), partCount());
1462009b1c42SEd Schouten }
1463009b1c42SEd Schouten
significandLSB() const1464b915e9e0SDimitry Andric unsigned int IEEEFloat::significandLSB() const {
1465009b1c42SEd Schouten return APInt::tcLSB(significandParts(), partCount());
1466009b1c42SEd Schouten }
1467009b1c42SEd Schouten
1468009b1c42SEd Schouten /* Note that a zero result is NOT normalized to fcZero. */
shiftSignificandRight(unsigned int bits)1469b915e9e0SDimitry Andric lostFraction IEEEFloat::shiftSignificandRight(unsigned int bits) {
1470009b1c42SEd Schouten /* Our exponent should not overflow. */
1471f8af5cf6SDimitry Andric assert((ExponentType) (exponent + bits) >= exponent);
1472009b1c42SEd Schouten
1473009b1c42SEd Schouten exponent += bits;
1474009b1c42SEd Schouten
1475009b1c42SEd Schouten return shiftRight(significandParts(), partCount(), bits);
1476009b1c42SEd Schouten }
1477009b1c42SEd Schouten
1478009b1c42SEd Schouten /* Shift the significand left BITS bits, subtract BITS from its exponent. */
shiftSignificandLeft(unsigned int bits)1479b915e9e0SDimitry Andric void IEEEFloat::shiftSignificandLeft(unsigned int bits) {
1480009b1c42SEd Schouten assert(bits < semantics->precision);
1481009b1c42SEd Schouten
1482009b1c42SEd Schouten if (bits) {
1483009b1c42SEd Schouten unsigned int partsCount = partCount();
1484009b1c42SEd Schouten
1485009b1c42SEd Schouten APInt::tcShiftLeft(significandParts(), partsCount, bits);
1486009b1c42SEd Schouten exponent -= bits;
1487009b1c42SEd Schouten
1488009b1c42SEd Schouten assert(!APInt::tcIsZero(significandParts(), partsCount));
1489009b1c42SEd Schouten }
1490009b1c42SEd Schouten }
1491009b1c42SEd Schouten
1492b915e9e0SDimitry Andric IEEEFloat::cmpResult
compareAbsoluteValue(const IEEEFloat & rhs) const1493b915e9e0SDimitry Andric IEEEFloat::compareAbsoluteValue(const IEEEFloat &rhs) const {
1494009b1c42SEd Schouten int compare;
1495009b1c42SEd Schouten
1496009b1c42SEd Schouten assert(semantics == rhs.semantics);
1497f8af5cf6SDimitry Andric assert(isFiniteNonZero());
1498f8af5cf6SDimitry Andric assert(rhs.isFiniteNonZero());
1499009b1c42SEd Schouten
1500009b1c42SEd Schouten compare = exponent - rhs.exponent;
1501009b1c42SEd Schouten
1502009b1c42SEd Schouten /* If exponents are equal, do an unsigned bignum comparison of the
1503009b1c42SEd Schouten significands. */
1504009b1c42SEd Schouten if (compare == 0)
1505009b1c42SEd Schouten compare = APInt::tcCompare(significandParts(), rhs.significandParts(),
1506009b1c42SEd Schouten partCount());
1507009b1c42SEd Schouten
1508009b1c42SEd Schouten if (compare > 0)
1509009b1c42SEd Schouten return cmpGreaterThan;
1510009b1c42SEd Schouten else if (compare < 0)
1511009b1c42SEd Schouten return cmpLessThan;
1512009b1c42SEd Schouten else
1513009b1c42SEd Schouten return cmpEqual;
1514009b1c42SEd Schouten }
1515009b1c42SEd Schouten
1516c0981da4SDimitry Andric /* Set the least significant BITS bits of a bignum, clear the
1517c0981da4SDimitry Andric rest. */
tcSetLeastSignificantBits(APInt::WordType * dst,unsigned parts,unsigned bits)1518c0981da4SDimitry Andric static void tcSetLeastSignificantBits(APInt::WordType *dst, unsigned parts,
1519c0981da4SDimitry Andric unsigned bits) {
1520c0981da4SDimitry Andric unsigned i = 0;
1521c0981da4SDimitry Andric while (bits > APInt::APINT_BITS_PER_WORD) {
1522c0981da4SDimitry Andric dst[i++] = ~(APInt::WordType)0;
1523c0981da4SDimitry Andric bits -= APInt::APINT_BITS_PER_WORD;
1524c0981da4SDimitry Andric }
1525c0981da4SDimitry Andric
1526c0981da4SDimitry Andric if (bits)
1527c0981da4SDimitry Andric dst[i++] = ~(APInt::WordType)0 >> (APInt::APINT_BITS_PER_WORD - bits);
1528c0981da4SDimitry Andric
1529c0981da4SDimitry Andric while (i < parts)
1530c0981da4SDimitry Andric dst[i++] = 0;
1531c0981da4SDimitry Andric }
1532c0981da4SDimitry Andric
1533009b1c42SEd Schouten /* Handle overflow. Sign is preserved. We either become infinity or
1534009b1c42SEd Schouten the largest finite number. */
handleOverflow(roundingMode rounding_mode)1535b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::handleOverflow(roundingMode rounding_mode) {
1536ac9a064cSDimitry Andric if (semantics->nonFiniteBehavior != fltNonfiniteBehavior::FiniteOnly) {
1537009b1c42SEd Schouten /* Infinity? */
1538104bd817SRoman Divacky if (rounding_mode == rmNearestTiesToEven ||
1539104bd817SRoman Divacky rounding_mode == rmNearestTiesToAway ||
1540104bd817SRoman Divacky (rounding_mode == rmTowardPositive && !sign) ||
1541104bd817SRoman Divacky (rounding_mode == rmTowardNegative && sign)) {
1542e3b55780SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
1543e3b55780SDimitry Andric makeNaN(false, sign);
1544e3b55780SDimitry Andric else
1545009b1c42SEd Schouten category = fcInfinity;
1546ac9a064cSDimitry Andric return static_cast<opStatus>(opOverflow | opInexact);
1547ac9a064cSDimitry Andric }
1548009b1c42SEd Schouten }
1549009b1c42SEd Schouten
1550009b1c42SEd Schouten /* Otherwise we become the largest finite number. */
1551009b1c42SEd Schouten category = fcNormal;
1552009b1c42SEd Schouten exponent = semantics->maxExponent;
1553c0981da4SDimitry Andric tcSetLeastSignificantBits(significandParts(), partCount(),
1554009b1c42SEd Schouten semantics->precision);
15557fa27ce4SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly &&
15567fa27ce4SDimitry Andric semantics->nanEncoding == fltNanEncoding::AllOnes)
1557e3b55780SDimitry Andric APInt::tcClearBit(significandParts(), 0);
1558009b1c42SEd Schouten
1559009b1c42SEd Schouten return opInexact;
1560009b1c42SEd Schouten }
1561009b1c42SEd Schouten
1562009b1c42SEd Schouten /* Returns TRUE if, when truncating the current number, with BIT the
1563009b1c42SEd Schouten new LSB, with the given lost fraction and rounding mode, the result
1564009b1c42SEd Schouten would need to be rounded away from zero (i.e., by increasing the
1565009b1c42SEd Schouten signficand). This routine must work for fcZero of both signs, and
1566009b1c42SEd Schouten fcNormal numbers. */
roundAwayFromZero(roundingMode rounding_mode,lostFraction lost_fraction,unsigned int bit) const1567b915e9e0SDimitry Andric bool IEEEFloat::roundAwayFromZero(roundingMode rounding_mode,
1568009b1c42SEd Schouten lostFraction lost_fraction,
1569b915e9e0SDimitry Andric unsigned int bit) const {
1570009b1c42SEd Schouten /* NaNs and infinities should not have lost fractions. */
1571f8af5cf6SDimitry Andric assert(isFiniteNonZero() || category == fcZero);
1572009b1c42SEd Schouten
1573009b1c42SEd Schouten /* Current callers never pass this so we don't handle it. */
1574009b1c42SEd Schouten assert(lost_fraction != lfExactlyZero);
1575009b1c42SEd Schouten
1576009b1c42SEd Schouten switch (rounding_mode) {
1577009b1c42SEd Schouten case rmNearestTiesToAway:
1578009b1c42SEd Schouten return lost_fraction == lfExactlyHalf || lost_fraction == lfMoreThanHalf;
1579009b1c42SEd Schouten
1580009b1c42SEd Schouten case rmNearestTiesToEven:
1581009b1c42SEd Schouten if (lost_fraction == lfMoreThanHalf)
1582009b1c42SEd Schouten return true;
1583009b1c42SEd Schouten
1584009b1c42SEd Schouten /* Our zeroes don't have a significand to test. */
1585009b1c42SEd Schouten if (lost_fraction == lfExactlyHalf && category != fcZero)
1586009b1c42SEd Schouten return APInt::tcExtractBit(significandParts(), bit);
1587009b1c42SEd Schouten
1588009b1c42SEd Schouten return false;
1589009b1c42SEd Schouten
1590009b1c42SEd Schouten case rmTowardZero:
1591009b1c42SEd Schouten return false;
1592009b1c42SEd Schouten
1593009b1c42SEd Schouten case rmTowardPositive:
15945a5ac124SDimitry Andric return !sign;
1595009b1c42SEd Schouten
1596009b1c42SEd Schouten case rmTowardNegative:
15975a5ac124SDimitry Andric return sign;
1598cfca06d7SDimitry Andric
1599cfca06d7SDimitry Andric default:
1600cfca06d7SDimitry Andric break;
1601009b1c42SEd Schouten }
160263faed5bSDimitry Andric llvm_unreachable("Invalid rounding mode found");
1603009b1c42SEd Schouten }
1604009b1c42SEd Schouten
normalize(roundingMode rounding_mode,lostFraction lost_fraction)1605b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::normalize(roundingMode rounding_mode,
1606b915e9e0SDimitry Andric lostFraction lost_fraction) {
1607009b1c42SEd Schouten unsigned int omsb; /* One, not zero, based MSB. */
1608009b1c42SEd Schouten int exponentChange;
1609009b1c42SEd Schouten
1610f8af5cf6SDimitry Andric if (!isFiniteNonZero())
1611009b1c42SEd Schouten return opOK;
1612009b1c42SEd Schouten
1613009b1c42SEd Schouten /* Before rounding normalize the exponent of fcNormal numbers. */
1614009b1c42SEd Schouten omsb = significandMSB() + 1;
1615009b1c42SEd Schouten
1616009b1c42SEd Schouten if (omsb) {
1617009b1c42SEd Schouten /* OMSB is numbered from 1. We want to place it in the integer
161830815c53SDimitry Andric bit numbered PRECISION if possible, with a compensating change in
1619009b1c42SEd Schouten the exponent. */
1620009b1c42SEd Schouten exponentChange = omsb - semantics->precision;
1621009b1c42SEd Schouten
1622009b1c42SEd Schouten /* If the resulting exponent is too high, overflow according to
1623009b1c42SEd Schouten the rounding mode. */
1624009b1c42SEd Schouten if (exponent + exponentChange > semantics->maxExponent)
1625009b1c42SEd Schouten return handleOverflow(rounding_mode);
1626009b1c42SEd Schouten
1627009b1c42SEd Schouten /* Subnormal numbers have exponent minExponent, and their MSB
1628009b1c42SEd Schouten is forced based on that. */
1629009b1c42SEd Schouten if (exponent + exponentChange < semantics->minExponent)
1630009b1c42SEd Schouten exponentChange = semantics->minExponent - exponent;
1631009b1c42SEd Schouten
1632009b1c42SEd Schouten /* Shifting left is easy as we don't lose precision. */
1633009b1c42SEd Schouten if (exponentChange < 0) {
1634009b1c42SEd Schouten assert(lost_fraction == lfExactlyZero);
1635009b1c42SEd Schouten
1636009b1c42SEd Schouten shiftSignificandLeft(-exponentChange);
1637009b1c42SEd Schouten
1638009b1c42SEd Schouten return opOK;
1639009b1c42SEd Schouten }
1640009b1c42SEd Schouten
1641009b1c42SEd Schouten if (exponentChange > 0) {
1642009b1c42SEd Schouten lostFraction lf;
1643009b1c42SEd Schouten
1644009b1c42SEd Schouten /* Shift right and capture any new lost fraction. */
1645009b1c42SEd Schouten lf = shiftSignificandRight(exponentChange);
1646009b1c42SEd Schouten
1647009b1c42SEd Schouten lost_fraction = combineLostFractions(lf, lost_fraction);
1648009b1c42SEd Schouten
1649009b1c42SEd Schouten /* Keep OMSB up-to-date. */
1650009b1c42SEd Schouten if (omsb > (unsigned) exponentChange)
1651009b1c42SEd Schouten omsb -= exponentChange;
1652009b1c42SEd Schouten else
1653009b1c42SEd Schouten omsb = 0;
1654009b1c42SEd Schouten }
1655009b1c42SEd Schouten }
1656009b1c42SEd Schouten
16577fa27ce4SDimitry Andric // The all-ones values is an overflow if NaN is all ones. If NaN is
16587fa27ce4SDimitry Andric // represented by negative zero, then it is a valid finite value.
1659e3b55780SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly &&
16607fa27ce4SDimitry Andric semantics->nanEncoding == fltNanEncoding::AllOnes &&
1661e3b55780SDimitry Andric exponent == semantics->maxExponent && isSignificandAllOnes())
1662e3b55780SDimitry Andric return handleOverflow(rounding_mode);
1663e3b55780SDimitry Andric
1664009b1c42SEd Schouten /* Now round the number according to rounding_mode given the lost
1665009b1c42SEd Schouten fraction. */
1666009b1c42SEd Schouten
1667009b1c42SEd Schouten /* As specified in IEEE 754, since we do not trap we do not report
1668009b1c42SEd Schouten underflow for exact results. */
1669009b1c42SEd Schouten if (lost_fraction == lfExactlyZero) {
1670009b1c42SEd Schouten /* Canonicalize zeroes. */
16717fa27ce4SDimitry Andric if (omsb == 0) {
1672009b1c42SEd Schouten category = fcZero;
16737fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
16747fa27ce4SDimitry Andric sign = false;
16757fa27ce4SDimitry Andric }
1676009b1c42SEd Schouten
1677009b1c42SEd Schouten return opOK;
1678009b1c42SEd Schouten }
1679009b1c42SEd Schouten
1680009b1c42SEd Schouten /* Increment the significand if we're rounding away from zero. */
1681009b1c42SEd Schouten if (roundAwayFromZero(rounding_mode, lost_fraction, 0)) {
1682009b1c42SEd Schouten if (omsb == 0)
1683009b1c42SEd Schouten exponent = semantics->minExponent;
1684009b1c42SEd Schouten
1685009b1c42SEd Schouten incrementSignificand();
1686009b1c42SEd Schouten omsb = significandMSB() + 1;
1687009b1c42SEd Schouten
1688009b1c42SEd Schouten /* Did the significand increment overflow? */
1689009b1c42SEd Schouten if (omsb == (unsigned) semantics->precision + 1) {
1690009b1c42SEd Schouten /* Renormalize by incrementing the exponent and shifting our
1691009b1c42SEd Schouten significand right one. However if we already have the
1692009b1c42SEd Schouten maximum exponent we overflow to infinity. */
16937fa27ce4SDimitry Andric if (exponent == semantics->maxExponent)
16947fa27ce4SDimitry Andric // Invoke overflow handling with a rounding mode that will guarantee
16957fa27ce4SDimitry Andric // that the result gets turned into the correct infinity representation.
16967fa27ce4SDimitry Andric // This is needed instead of just setting the category to infinity to
16977fa27ce4SDimitry Andric // account for 8-bit floating point types that have no inf, only NaN.
16987fa27ce4SDimitry Andric return handleOverflow(sign ? rmTowardNegative : rmTowardPositive);
1699009b1c42SEd Schouten
1700009b1c42SEd Schouten shiftSignificandRight(1);
1701009b1c42SEd Schouten
1702009b1c42SEd Schouten return opInexact;
1703009b1c42SEd Schouten }
1704e3b55780SDimitry Andric
17057fa27ce4SDimitry Andric // The all-ones values is an overflow if NaN is all ones. If NaN is
17067fa27ce4SDimitry Andric // represented by negative zero, then it is a valid finite value.
1707e3b55780SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly &&
17087fa27ce4SDimitry Andric semantics->nanEncoding == fltNanEncoding::AllOnes &&
1709e3b55780SDimitry Andric exponent == semantics->maxExponent && isSignificandAllOnes())
1710e3b55780SDimitry Andric return handleOverflow(rounding_mode);
1711009b1c42SEd Schouten }
1712009b1c42SEd Schouten
1713009b1c42SEd Schouten /* The normal case - we were and are not denormal, and any
1714009b1c42SEd Schouten significand increment above didn't overflow. */
1715009b1c42SEd Schouten if (omsb == semantics->precision)
1716009b1c42SEd Schouten return opInexact;
1717009b1c42SEd Schouten
1718009b1c42SEd Schouten /* We have a non-zero denormal. */
1719009b1c42SEd Schouten assert(omsb < semantics->precision);
1720009b1c42SEd Schouten
1721009b1c42SEd Schouten /* Canonicalize zeroes. */
17227fa27ce4SDimitry Andric if (omsb == 0) {
1723009b1c42SEd Schouten category = fcZero;
17247fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
17257fa27ce4SDimitry Andric sign = false;
17267fa27ce4SDimitry Andric }
1727009b1c42SEd Schouten
1728009b1c42SEd Schouten /* The fcZero case is a denormal that underflowed to zero. */
1729009b1c42SEd Schouten return (opStatus) (opUnderflow | opInexact);
1730009b1c42SEd Schouten }
1731009b1c42SEd Schouten
addOrSubtractSpecials(const IEEEFloat & rhs,bool subtract)1732b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::addOrSubtractSpecials(const IEEEFloat &rhs,
1733b915e9e0SDimitry Andric bool subtract) {
1734f8af5cf6SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) {
1735009b1c42SEd Schouten default:
17365ca98fd9SDimitry Andric llvm_unreachable(nullptr);
1737009b1c42SEd Schouten
1738cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN):
1739cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN):
1740cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN):
1741cfca06d7SDimitry Andric assign(rhs);
1742e3b55780SDimitry Andric [[fallthrough]];
1743f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero):
1744f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal):
1745f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity):
1746f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN):
1747cfca06d7SDimitry Andric if (isSignaling()) {
1748cfca06d7SDimitry Andric makeQuiet();
1749cfca06d7SDimitry Andric return opInvalidOp;
1750cfca06d7SDimitry Andric }
1751cfca06d7SDimitry Andric return rhs.isSignaling() ? opInvalidOp : opOK;
1752cfca06d7SDimitry Andric
1753f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero):
1754f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal):
1755f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero):
1756009b1c42SEd Schouten return opOK;
1757009b1c42SEd Schouten
1758f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity):
1759f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity):
1760009b1c42SEd Schouten category = fcInfinity;
1761009b1c42SEd Schouten sign = rhs.sign ^ subtract;
1762009b1c42SEd Schouten return opOK;
1763009b1c42SEd Schouten
1764f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal):
1765009b1c42SEd Schouten assign(rhs);
1766009b1c42SEd Schouten sign = rhs.sign ^ subtract;
1767009b1c42SEd Schouten return opOK;
1768009b1c42SEd Schouten
1769f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero):
1770009b1c42SEd Schouten /* Sign depends on rounding mode; handled by caller. */
1771009b1c42SEd Schouten return opOK;
1772009b1c42SEd Schouten
1773f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity):
1774009b1c42SEd Schouten /* Differently signed infinities can only be validly
1775009b1c42SEd Schouten subtracted. */
1776009b1c42SEd Schouten if (((sign ^ rhs.sign)!=0) != subtract) {
1777009b1c42SEd Schouten makeNaN();
1778009b1c42SEd Schouten return opInvalidOp;
1779009b1c42SEd Schouten }
1780009b1c42SEd Schouten
1781009b1c42SEd Schouten return opOK;
1782009b1c42SEd Schouten
1783f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal):
1784009b1c42SEd Schouten return opDivByZero;
1785009b1c42SEd Schouten }
1786009b1c42SEd Schouten }
1787009b1c42SEd Schouten
1788009b1c42SEd Schouten /* Add or subtract two normal numbers. */
addOrSubtractSignificand(const IEEEFloat & rhs,bool subtract)1789b915e9e0SDimitry Andric lostFraction IEEEFloat::addOrSubtractSignificand(const IEEEFloat &rhs,
1790b915e9e0SDimitry Andric bool subtract) {
1791009b1c42SEd Schouten integerPart carry;
1792009b1c42SEd Schouten lostFraction lost_fraction;
1793009b1c42SEd Schouten int bits;
1794009b1c42SEd Schouten
1795009b1c42SEd Schouten /* Determine if the operation on the absolute values is effectively
1796009b1c42SEd Schouten an addition or subtraction. */
17975a5ac124SDimitry Andric subtract ^= static_cast<bool>(sign ^ rhs.sign);
1798009b1c42SEd Schouten
1799009b1c42SEd Schouten /* Are we bigger exponent-wise than the RHS? */
1800009b1c42SEd Schouten bits = exponent - rhs.exponent;
1801009b1c42SEd Schouten
1802009b1c42SEd Schouten /* Subtraction is more subtle than one might naively expect. */
1803009b1c42SEd Schouten if (subtract) {
1804b915e9e0SDimitry Andric IEEEFloat temp_rhs(rhs);
1805009b1c42SEd Schouten
1806706b4fc4SDimitry Andric if (bits == 0)
1807009b1c42SEd Schouten lost_fraction = lfExactlyZero;
1808706b4fc4SDimitry Andric else if (bits > 0) {
1809009b1c42SEd Schouten lost_fraction = temp_rhs.shiftSignificandRight(bits - 1);
1810009b1c42SEd Schouten shiftSignificandLeft(1);
1811009b1c42SEd Schouten } else {
1812009b1c42SEd Schouten lost_fraction = shiftSignificandRight(-bits - 1);
1813009b1c42SEd Schouten temp_rhs.shiftSignificandLeft(1);
1814009b1c42SEd Schouten }
1815009b1c42SEd Schouten
1816706b4fc4SDimitry Andric // Should we reverse the subtraction.
1817706b4fc4SDimitry Andric if (compareAbsoluteValue(temp_rhs) == cmpLessThan) {
1818009b1c42SEd Schouten carry = temp_rhs.subtractSignificand
1819009b1c42SEd Schouten (*this, lost_fraction != lfExactlyZero);
1820009b1c42SEd Schouten copySignificand(temp_rhs);
1821009b1c42SEd Schouten sign = !sign;
1822009b1c42SEd Schouten } else {
1823009b1c42SEd Schouten carry = subtractSignificand
1824009b1c42SEd Schouten (temp_rhs, lost_fraction != lfExactlyZero);
1825009b1c42SEd Schouten }
1826009b1c42SEd Schouten
1827009b1c42SEd Schouten /* Invert the lost fraction - it was on the RHS and
1828009b1c42SEd Schouten subtracted. */
1829009b1c42SEd Schouten if (lost_fraction == lfLessThanHalf)
1830009b1c42SEd Schouten lost_fraction = lfMoreThanHalf;
1831009b1c42SEd Schouten else if (lost_fraction == lfMoreThanHalf)
1832009b1c42SEd Schouten lost_fraction = lfLessThanHalf;
1833009b1c42SEd Schouten
1834009b1c42SEd Schouten /* The code above is intended to ensure that no borrow is
1835009b1c42SEd Schouten necessary. */
1836009b1c42SEd Schouten assert(!carry);
183730815c53SDimitry Andric (void)carry;
1838009b1c42SEd Schouten } else {
1839009b1c42SEd Schouten if (bits > 0) {
1840b915e9e0SDimitry Andric IEEEFloat temp_rhs(rhs);
1841009b1c42SEd Schouten
1842009b1c42SEd Schouten lost_fraction = temp_rhs.shiftSignificandRight(bits);
1843009b1c42SEd Schouten carry = addSignificand(temp_rhs);
1844009b1c42SEd Schouten } else {
1845009b1c42SEd Schouten lost_fraction = shiftSignificandRight(-bits);
1846009b1c42SEd Schouten carry = addSignificand(rhs);
1847009b1c42SEd Schouten }
1848009b1c42SEd Schouten
1849009b1c42SEd Schouten /* We have a guard bit; generating a carry cannot happen. */
1850009b1c42SEd Schouten assert(!carry);
185130815c53SDimitry Andric (void)carry;
1852009b1c42SEd Schouten }
1853009b1c42SEd Schouten
1854009b1c42SEd Schouten return lost_fraction;
1855009b1c42SEd Schouten }
1856009b1c42SEd Schouten
multiplySpecials(const IEEEFloat & rhs)1857b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::multiplySpecials(const IEEEFloat &rhs) {
1858f8af5cf6SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) {
1859009b1c42SEd Schouten default:
18605ca98fd9SDimitry Andric llvm_unreachable(nullptr);
1861009b1c42SEd Schouten
1862cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN):
1863cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN):
1864cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN):
1865cfca06d7SDimitry Andric assign(rhs);
1866cfca06d7SDimitry Andric sign = false;
1867e3b55780SDimitry Andric [[fallthrough]];
1868f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero):
1869f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal):
1870f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity):
1871f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN):
1872cfca06d7SDimitry Andric sign ^= rhs.sign; // restore the original sign
1873cfca06d7SDimitry Andric if (isSignaling()) {
1874cfca06d7SDimitry Andric makeQuiet();
1875cfca06d7SDimitry Andric return opInvalidOp;
1876cfca06d7SDimitry Andric }
1877cfca06d7SDimitry Andric return rhs.isSignaling() ? opInvalidOp : opOK;
1878009b1c42SEd Schouten
1879f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity):
1880f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal):
1881f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity):
1882009b1c42SEd Schouten category = fcInfinity;
1883009b1c42SEd Schouten return opOK;
1884009b1c42SEd Schouten
1885f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal):
1886f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero):
1887f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero):
1888009b1c42SEd Schouten category = fcZero;
1889009b1c42SEd Schouten return opOK;
1890009b1c42SEd Schouten
1891f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity):
1892f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero):
1893009b1c42SEd Schouten makeNaN();
1894009b1c42SEd Schouten return opInvalidOp;
1895009b1c42SEd Schouten
1896f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal):
1897009b1c42SEd Schouten return opOK;
1898009b1c42SEd Schouten }
1899009b1c42SEd Schouten }
1900009b1c42SEd Schouten
divideSpecials(const IEEEFloat & rhs)1901b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::divideSpecials(const IEEEFloat &rhs) {
1902f8af5cf6SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) {
1903009b1c42SEd Schouten default:
19045ca98fd9SDimitry Andric llvm_unreachable(nullptr);
1905009b1c42SEd Schouten
1906f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN):
1907f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN):
1908f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN):
1909cfca06d7SDimitry Andric assign(rhs);
1910cfca06d7SDimitry Andric sign = false;
1911e3b55780SDimitry Andric [[fallthrough]];
1912f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero):
1913f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal):
1914f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity):
1915f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN):
1916cfca06d7SDimitry Andric sign ^= rhs.sign; // restore the original sign
1917cfca06d7SDimitry Andric if (isSignaling()) {
1918cfca06d7SDimitry Andric makeQuiet();
1919cfca06d7SDimitry Andric return opInvalidOp;
1920cfca06d7SDimitry Andric }
1921cfca06d7SDimitry Andric return rhs.isSignaling() ? opInvalidOp : opOK;
1922cfca06d7SDimitry Andric
1923f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero):
1924f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal):
1925f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity):
1926f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal):
1927009b1c42SEd Schouten return opOK;
1928009b1c42SEd Schouten
1929f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity):
1930009b1c42SEd Schouten category = fcZero;
1931009b1c42SEd Schouten return opOK;
1932009b1c42SEd Schouten
1933f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero):
1934e3b55780SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
1935e3b55780SDimitry Andric makeNaN(false, sign);
1936e3b55780SDimitry Andric else
1937009b1c42SEd Schouten category = fcInfinity;
1938009b1c42SEd Schouten return opDivByZero;
1939009b1c42SEd Schouten
1940f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity):
1941f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero):
1942009b1c42SEd Schouten makeNaN();
1943009b1c42SEd Schouten return opInvalidOp;
1944009b1c42SEd Schouten
1945f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal):
1946009b1c42SEd Schouten return opOK;
1947009b1c42SEd Schouten }
1948009b1c42SEd Schouten }
1949009b1c42SEd Schouten
modSpecials(const IEEEFloat & rhs)1950b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::modSpecials(const IEEEFloat &rhs) {
1951f8af5cf6SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) {
1952009b1c42SEd Schouten default:
19535ca98fd9SDimitry Andric llvm_unreachable(nullptr);
1954009b1c42SEd Schouten
1955cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN):
1956cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN):
1957cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN):
1958cfca06d7SDimitry Andric assign(rhs);
1959e3b55780SDimitry Andric [[fallthrough]];
1960f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero):
1961f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal):
1962f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity):
1963f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN):
1964cfca06d7SDimitry Andric if (isSignaling()) {
1965cfca06d7SDimitry Andric makeQuiet();
1966cfca06d7SDimitry Andric return opInvalidOp;
1967cfca06d7SDimitry Andric }
1968cfca06d7SDimitry Andric return rhs.isSignaling() ? opInvalidOp : opOK;
1969cfca06d7SDimitry Andric
1970f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity):
1971f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal):
1972f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity):
1973009b1c42SEd Schouten return opOK;
1974009b1c42SEd Schouten
1975f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero):
1976f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero):
1977f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal):
1978f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity):
1979f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero):
1980009b1c42SEd Schouten makeNaN();
1981009b1c42SEd Schouten return opInvalidOp;
1982009b1c42SEd Schouten
1983f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal):
1984009b1c42SEd Schouten return opOK;
1985009b1c42SEd Schouten }
1986009b1c42SEd Schouten }
1987009b1c42SEd Schouten
remainderSpecials(const IEEEFloat & rhs)1988cfca06d7SDimitry Andric IEEEFloat::opStatus IEEEFloat::remainderSpecials(const IEEEFloat &rhs) {
1989cfca06d7SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) {
1990cfca06d7SDimitry Andric default:
1991cfca06d7SDimitry Andric llvm_unreachable(nullptr);
1992cfca06d7SDimitry Andric
1993cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN):
1994cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN):
1995cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN):
1996cfca06d7SDimitry Andric assign(rhs);
1997e3b55780SDimitry Andric [[fallthrough]];
1998cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero):
1999cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal):
2000cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity):
2001cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN):
2002cfca06d7SDimitry Andric if (isSignaling()) {
2003cfca06d7SDimitry Andric makeQuiet();
2004cfca06d7SDimitry Andric return opInvalidOp;
2005cfca06d7SDimitry Andric }
2006cfca06d7SDimitry Andric return rhs.isSignaling() ? opInvalidOp : opOK;
2007cfca06d7SDimitry Andric
2008cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity):
2009cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal):
2010cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity):
2011cfca06d7SDimitry Andric return opOK;
2012cfca06d7SDimitry Andric
2013cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero):
2014cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero):
2015cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal):
2016cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity):
2017cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero):
2018cfca06d7SDimitry Andric makeNaN();
2019cfca06d7SDimitry Andric return opInvalidOp;
2020cfca06d7SDimitry Andric
2021cfca06d7SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal):
2022cfca06d7SDimitry Andric return opDivByZero; // fake status, indicating this is not a special case
2023cfca06d7SDimitry Andric }
2024cfca06d7SDimitry Andric }
2025cfca06d7SDimitry Andric
2026009b1c42SEd Schouten /* Change sign. */
changeSign()2027b915e9e0SDimitry Andric void IEEEFloat::changeSign() {
20287fa27ce4SDimitry Andric // With NaN-as-negative-zero, neither NaN or negative zero can change
20297fa27ce4SDimitry Andric // their signs.
20307fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero &&
20317fa27ce4SDimitry Andric (isZero() || isNaN()))
20327fa27ce4SDimitry Andric return;
2033009b1c42SEd Schouten /* Look mummy, this one's easy. */
2034009b1c42SEd Schouten sign = !sign;
2035009b1c42SEd Schouten }
2036009b1c42SEd Schouten
2037009b1c42SEd Schouten /* Normalized addition or subtraction. */
addOrSubtract(const IEEEFloat & rhs,roundingMode rounding_mode,bool subtract)2038b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::addOrSubtract(const IEEEFloat &rhs,
2039b915e9e0SDimitry Andric roundingMode rounding_mode,
2040b915e9e0SDimitry Andric bool subtract) {
2041009b1c42SEd Schouten opStatus fs;
2042009b1c42SEd Schouten
2043009b1c42SEd Schouten fs = addOrSubtractSpecials(rhs, subtract);
2044009b1c42SEd Schouten
2045009b1c42SEd Schouten /* This return code means it was not a simple case. */
2046009b1c42SEd Schouten if (fs == opDivByZero) {
2047009b1c42SEd Schouten lostFraction lost_fraction;
2048009b1c42SEd Schouten
2049009b1c42SEd Schouten lost_fraction = addOrSubtractSignificand(rhs, subtract);
2050009b1c42SEd Schouten fs = normalize(rounding_mode, lost_fraction);
2051009b1c42SEd Schouten
2052009b1c42SEd Schouten /* Can only be zero if we lost no fraction. */
2053009b1c42SEd Schouten assert(category != fcZero || lost_fraction == lfExactlyZero);
2054009b1c42SEd Schouten }
2055009b1c42SEd Schouten
2056009b1c42SEd Schouten /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a
2057009b1c42SEd Schouten positive zero unless rounding to minus infinity, except that
2058009b1c42SEd Schouten adding two like-signed zeroes gives that zero. */
2059009b1c42SEd Schouten if (category == fcZero) {
2060009b1c42SEd Schouten if (rhs.category != fcZero || (sign == rhs.sign) == subtract)
2061009b1c42SEd Schouten sign = (rounding_mode == rmTowardNegative);
20627fa27ce4SDimitry Andric // NaN-in-negative-zero means zeros need to be normalized to +0.
20637fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
20647fa27ce4SDimitry Andric sign = false;
2065009b1c42SEd Schouten }
2066009b1c42SEd Schouten
2067009b1c42SEd Schouten return fs;
2068009b1c42SEd Schouten }
2069009b1c42SEd Schouten
2070009b1c42SEd Schouten /* Normalized addition. */
add(const IEEEFloat & rhs,roundingMode rounding_mode)2071b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::add(const IEEEFloat &rhs,
2072b915e9e0SDimitry Andric roundingMode rounding_mode) {
2073009b1c42SEd Schouten return addOrSubtract(rhs, rounding_mode, false);
2074009b1c42SEd Schouten }
2075009b1c42SEd Schouten
2076009b1c42SEd Schouten /* Normalized subtraction. */
subtract(const IEEEFloat & rhs,roundingMode rounding_mode)2077b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::subtract(const IEEEFloat &rhs,
2078b915e9e0SDimitry Andric roundingMode rounding_mode) {
2079009b1c42SEd Schouten return addOrSubtract(rhs, rounding_mode, true);
2080009b1c42SEd Schouten }
2081009b1c42SEd Schouten
2082009b1c42SEd Schouten /* Normalized multiply. */
multiply(const IEEEFloat & rhs,roundingMode rounding_mode)2083b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::multiply(const IEEEFloat &rhs,
2084b915e9e0SDimitry Andric roundingMode rounding_mode) {
2085009b1c42SEd Schouten opStatus fs;
2086009b1c42SEd Schouten
2087009b1c42SEd Schouten sign ^= rhs.sign;
2088009b1c42SEd Schouten fs = multiplySpecials(rhs);
2089009b1c42SEd Schouten
20907fa27ce4SDimitry Andric if (isZero() && semantics->nanEncoding == fltNanEncoding::NegativeZero)
20917fa27ce4SDimitry Andric sign = false;
2092f8af5cf6SDimitry Andric if (isFiniteNonZero()) {
2093706b4fc4SDimitry Andric lostFraction lost_fraction = multiplySignificand(rhs);
2094009b1c42SEd Schouten fs = normalize(rounding_mode, lost_fraction);
2095009b1c42SEd Schouten if (lost_fraction != lfExactlyZero)
2096009b1c42SEd Schouten fs = (opStatus) (fs | opInexact);
2097009b1c42SEd Schouten }
2098009b1c42SEd Schouten
2099009b1c42SEd Schouten return fs;
2100009b1c42SEd Schouten }
2101009b1c42SEd Schouten
2102009b1c42SEd Schouten /* Normalized divide. */
divide(const IEEEFloat & rhs,roundingMode rounding_mode)2103b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::divide(const IEEEFloat &rhs,
2104b915e9e0SDimitry Andric roundingMode rounding_mode) {
2105009b1c42SEd Schouten opStatus fs;
2106009b1c42SEd Schouten
2107009b1c42SEd Schouten sign ^= rhs.sign;
2108009b1c42SEd Schouten fs = divideSpecials(rhs);
2109009b1c42SEd Schouten
21107fa27ce4SDimitry Andric if (isZero() && semantics->nanEncoding == fltNanEncoding::NegativeZero)
21117fa27ce4SDimitry Andric sign = false;
2112f8af5cf6SDimitry Andric if (isFiniteNonZero()) {
2113009b1c42SEd Schouten lostFraction lost_fraction = divideSignificand(rhs);
2114009b1c42SEd Schouten fs = normalize(rounding_mode, lost_fraction);
2115009b1c42SEd Schouten if (lost_fraction != lfExactlyZero)
2116009b1c42SEd Schouten fs = (opStatus) (fs | opInexact);
2117009b1c42SEd Schouten }
2118009b1c42SEd Schouten
2119009b1c42SEd Schouten return fs;
2120009b1c42SEd Schouten }
2121009b1c42SEd Schouten
2122cfca06d7SDimitry Andric /* Normalized remainder. */
remainder(const IEEEFloat & rhs)2123b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::remainder(const IEEEFloat &rhs) {
2124009b1c42SEd Schouten opStatus fs;
2125009b1c42SEd Schouten unsigned int origSign = sign;
2126009b1c42SEd Schouten
2127cfca06d7SDimitry Andric // First handle the special cases.
2128cfca06d7SDimitry Andric fs = remainderSpecials(rhs);
2129cfca06d7SDimitry Andric if (fs != opDivByZero)
2130009b1c42SEd Schouten return fs;
2131009b1c42SEd Schouten
2132cfca06d7SDimitry Andric fs = opOK;
2133cfca06d7SDimitry Andric
2134cfca06d7SDimitry Andric // Make sure the current value is less than twice the denom. If the addition
2135cfca06d7SDimitry Andric // did not succeed (an overflow has happened), which means that the finite
2136cfca06d7SDimitry Andric // value we currently posses must be less than twice the denom (as we are
2137cfca06d7SDimitry Andric // using the same semantics).
2138cfca06d7SDimitry Andric IEEEFloat P2 = rhs;
2139cfca06d7SDimitry Andric if (P2.add(rhs, rmNearestTiesToEven) == opOK) {
2140cfca06d7SDimitry Andric fs = mod(P2);
2141cfca06d7SDimitry Andric assert(fs == opOK);
2142b915e9e0SDimitry Andric }
2143009b1c42SEd Schouten
2144cfca06d7SDimitry Andric // Lets work with absolute numbers.
2145cfca06d7SDimitry Andric IEEEFloat P = rhs;
2146cfca06d7SDimitry Andric P.sign = false;
2147cfca06d7SDimitry Andric sign = false;
2148009b1c42SEd Schouten
2149cfca06d7SDimitry Andric //
2150cfca06d7SDimitry Andric // To calculate the remainder we use the following scheme.
2151cfca06d7SDimitry Andric //
2152cfca06d7SDimitry Andric // The remainder is defained as follows:
2153cfca06d7SDimitry Andric //
2154cfca06d7SDimitry Andric // remainder = numer - rquot * denom = x - r * p
2155cfca06d7SDimitry Andric //
2156cfca06d7SDimitry Andric // Where r is the result of: x/p, rounded toward the nearest integral value
2157cfca06d7SDimitry Andric // (with halfway cases rounded toward the even number).
2158cfca06d7SDimitry Andric //
2159cfca06d7SDimitry Andric // Currently, (after x mod 2p):
2160cfca06d7SDimitry Andric // r is the number of 2p's present inside x, which is inherently, an even
2161cfca06d7SDimitry Andric // number of p's.
2162cfca06d7SDimitry Andric //
2163cfca06d7SDimitry Andric // We may split the remaining calculation into 4 options:
2164cfca06d7SDimitry Andric // - if x < 0.5p then we round to the nearest number with is 0, and are done.
2165cfca06d7SDimitry Andric // - if x == 0.5p then we round to the nearest even number which is 0, and we
2166cfca06d7SDimitry Andric // are done as well.
2167cfca06d7SDimitry Andric // - if 0.5p < x < p then we round to nearest number which is 1, and we have
2168cfca06d7SDimitry Andric // to subtract 1p at least once.
2169cfca06d7SDimitry Andric // - if x >= p then we must subtract p at least once, as x must be a
2170cfca06d7SDimitry Andric // remainder.
2171cfca06d7SDimitry Andric //
2172cfca06d7SDimitry Andric // By now, we were done, or we added 1 to r, which in turn, now an odd number.
2173cfca06d7SDimitry Andric //
2174cfca06d7SDimitry Andric // We can now split the remaining calculation to the following 3 options:
2175cfca06d7SDimitry Andric // - if x < 0.5p then we round to the nearest number with is 0, and are done.
2176cfca06d7SDimitry Andric // - if x == 0.5p then we round to the nearest even number. As r is odd, we
2177cfca06d7SDimitry Andric // must round up to the next even number. so we must subtract p once more.
2178cfca06d7SDimitry Andric // - if x > 0.5p (and inherently x < p) then we must round r up to the next
2179cfca06d7SDimitry Andric // integral, and subtract p once more.
2180cfca06d7SDimitry Andric //
2181009b1c42SEd Schouten
2182cfca06d7SDimitry Andric // Extend the semantics to prevent an overflow/underflow or inexact result.
2183cfca06d7SDimitry Andric bool losesInfo;
2184cfca06d7SDimitry Andric fltSemantics extendedSemantics = *semantics;
2185cfca06d7SDimitry Andric extendedSemantics.maxExponent++;
2186cfca06d7SDimitry Andric extendedSemantics.minExponent--;
2187cfca06d7SDimitry Andric extendedSemantics.precision += 2;
2188cfca06d7SDimitry Andric
2189cfca06d7SDimitry Andric IEEEFloat VEx = *this;
2190cfca06d7SDimitry Andric fs = VEx.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
2191cfca06d7SDimitry Andric assert(fs == opOK && !losesInfo);
2192cfca06d7SDimitry Andric IEEEFloat PEx = P;
2193cfca06d7SDimitry Andric fs = PEx.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
2194cfca06d7SDimitry Andric assert(fs == opOK && !losesInfo);
2195cfca06d7SDimitry Andric
2196cfca06d7SDimitry Andric // It is simpler to work with 2x instead of 0.5p, and we do not need to lose
2197cfca06d7SDimitry Andric // any fraction.
2198cfca06d7SDimitry Andric fs = VEx.add(VEx, rmNearestTiesToEven);
2199cfca06d7SDimitry Andric assert(fs == opOK);
2200cfca06d7SDimitry Andric
2201cfca06d7SDimitry Andric if (VEx.compare(PEx) == cmpGreaterThan) {
2202cfca06d7SDimitry Andric fs = subtract(P, rmNearestTiesToEven);
2203cfca06d7SDimitry Andric assert(fs == opOK);
2204cfca06d7SDimitry Andric
2205cfca06d7SDimitry Andric // Make VEx = this.add(this), but because we have different semantics, we do
2206cfca06d7SDimitry Andric // not want to `convert` again, so we just subtract PEx twice (which equals
2207cfca06d7SDimitry Andric // to the desired value).
2208cfca06d7SDimitry Andric fs = VEx.subtract(PEx, rmNearestTiesToEven);
2209cfca06d7SDimitry Andric assert(fs == opOK);
2210cfca06d7SDimitry Andric fs = VEx.subtract(PEx, rmNearestTiesToEven);
2211cfca06d7SDimitry Andric assert(fs == opOK);
2212cfca06d7SDimitry Andric
2213cfca06d7SDimitry Andric cmpResult result = VEx.compare(PEx);
2214cfca06d7SDimitry Andric if (result == cmpGreaterThan || result == cmpEqual) {
2215cfca06d7SDimitry Andric fs = subtract(P, rmNearestTiesToEven);
2216cfca06d7SDimitry Andric assert(fs == opOK);
2217cfca06d7SDimitry Andric }
2218cfca06d7SDimitry Andric }
2219009b1c42SEd Schouten
22207fa27ce4SDimitry Andric if (isZero()) {
2221009b1c42SEd Schouten sign = origSign; // IEEE754 requires this
22227fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
22237fa27ce4SDimitry Andric // But some 8-bit floats only have positive 0.
22247fa27ce4SDimitry Andric sign = false;
22257fa27ce4SDimitry Andric }
22267fa27ce4SDimitry Andric
2227cfca06d7SDimitry Andric else
2228cfca06d7SDimitry Andric sign ^= origSign;
2229009b1c42SEd Schouten return fs;
2230009b1c42SEd Schouten }
2231009b1c42SEd Schouten
223271d5a254SDimitry Andric /* Normalized llvm frem (C fmod). */
mod(const IEEEFloat & rhs)2233b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::mod(const IEEEFloat &rhs) {
2234009b1c42SEd Schouten opStatus fs;
2235009b1c42SEd Schouten fs = modSpecials(rhs);
2236044eb2f6SDimitry Andric unsigned int origSign = sign;
2237009b1c42SEd Schouten
223871d5a254SDimitry Andric while (isFiniteNonZero() && rhs.isFiniteNonZero() &&
223971d5a254SDimitry Andric compareAbsoluteValue(rhs) != cmpLessThan) {
2240e3b55780SDimitry Andric int Exp = ilogb(*this) - ilogb(rhs);
2241e3b55780SDimitry Andric IEEEFloat V = scalbn(rhs, Exp, rmNearestTiesToEven);
2242e3b55780SDimitry Andric // V can overflow to NaN with fltNonfiniteBehavior::NanOnly, so explicitly
2243e3b55780SDimitry Andric // check for it.
2244e3b55780SDimitry Andric if (V.isNaN() || compareAbsoluteValue(V) == cmpLessThan)
2245e3b55780SDimitry Andric V = scalbn(rhs, Exp - 1, rmNearestTiesToEven);
224671d5a254SDimitry Andric V.sign = sign;
2247009b1c42SEd Schouten
2248dd58ef01SDimitry Andric fs = subtract(V, rmNearestTiesToEven);
224971d5a254SDimitry Andric assert(fs==opOK);
2250009b1c42SEd Schouten }
22517fa27ce4SDimitry Andric if (isZero()) {
2252044eb2f6SDimitry Andric sign = origSign; // fmod requires this
22537fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
22547fa27ce4SDimitry Andric sign = false;
22557fa27ce4SDimitry Andric }
2256009b1c42SEd Schouten return fs;
2257009b1c42SEd Schouten }
2258009b1c42SEd Schouten
2259009b1c42SEd Schouten /* Normalized fused-multiply-add. */
fusedMultiplyAdd(const IEEEFloat & multiplicand,const IEEEFloat & addend,roundingMode rounding_mode)2260b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::fusedMultiplyAdd(const IEEEFloat &multiplicand,
2261b915e9e0SDimitry Andric const IEEEFloat &addend,
2262b915e9e0SDimitry Andric roundingMode rounding_mode) {
2263009b1c42SEd Schouten opStatus fs;
2264009b1c42SEd Schouten
2265009b1c42SEd Schouten /* Post-multiplication sign, before addition. */
2266009b1c42SEd Schouten sign ^= multiplicand.sign;
2267009b1c42SEd Schouten
2268009b1c42SEd Schouten /* If and only if all arguments are normal do we need to do an
2269009b1c42SEd Schouten extended-precision calculation. */
2270f8af5cf6SDimitry Andric if (isFiniteNonZero() &&
2271f8af5cf6SDimitry Andric multiplicand.isFiniteNonZero() &&
227267c32a98SDimitry Andric addend.isFinite()) {
2273009b1c42SEd Schouten lostFraction lost_fraction;
2274009b1c42SEd Schouten
2275706b4fc4SDimitry Andric lost_fraction = multiplySignificand(multiplicand, addend);
2276009b1c42SEd Schouten fs = normalize(rounding_mode, lost_fraction);
2277009b1c42SEd Schouten if (lost_fraction != lfExactlyZero)
2278009b1c42SEd Schouten fs = (opStatus) (fs | opInexact);
2279009b1c42SEd Schouten
2280009b1c42SEd Schouten /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a
2281009b1c42SEd Schouten positive zero unless rounding to minus infinity, except that
2282009b1c42SEd Schouten adding two like-signed zeroes gives that zero. */
22837fa27ce4SDimitry Andric if (category == fcZero && !(fs & opUnderflow) && sign != addend.sign) {
2284009b1c42SEd Schouten sign = (rounding_mode == rmTowardNegative);
22857fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
22867fa27ce4SDimitry Andric sign = false;
22877fa27ce4SDimitry Andric }
2288009b1c42SEd Schouten } else {
2289009b1c42SEd Schouten fs = multiplySpecials(multiplicand);
2290009b1c42SEd Schouten
2291009b1c42SEd Schouten /* FS can only be opOK or opInvalidOp. There is no more work
2292009b1c42SEd Schouten to do in the latter case. The IEEE-754R standard says it is
2293009b1c42SEd Schouten implementation-defined in this case whether, if ADDEND is a
2294009b1c42SEd Schouten quiet NaN, we raise invalid op; this implementation does so.
2295009b1c42SEd Schouten
2296009b1c42SEd Schouten If we need to do the addition we can do so with normal
2297009b1c42SEd Schouten precision. */
2298009b1c42SEd Schouten if (fs == opOK)
2299009b1c42SEd Schouten fs = addOrSubtract(addend, rounding_mode, false);
2300009b1c42SEd Schouten }
2301009b1c42SEd Schouten
2302009b1c42SEd Schouten return fs;
2303009b1c42SEd Schouten }
2304009b1c42SEd Schouten
2305cfca06d7SDimitry Andric /* Rounding-mode correct round to integral value. */
roundToIntegral(roundingMode rounding_mode)2306b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::roundToIntegral(roundingMode rounding_mode) {
230758b69754SDimitry Andric opStatus fs;
230858b69754SDimitry Andric
2309cfca06d7SDimitry Andric if (isInfinity())
2310cfca06d7SDimitry Andric // [IEEE Std 754-2008 6.1]:
2311cfca06d7SDimitry Andric // The behavior of infinity in floating-point arithmetic is derived from the
2312cfca06d7SDimitry Andric // limiting cases of real arithmetic with operands of arbitrarily
2313cfca06d7SDimitry Andric // large magnitude, when such a limit exists.
2314cfca06d7SDimitry Andric // ...
2315cfca06d7SDimitry Andric // Operations on infinite operands are usually exact and therefore signal no
2316cfca06d7SDimitry Andric // exceptions ...
2317cfca06d7SDimitry Andric return opOK;
2318cfca06d7SDimitry Andric
2319cfca06d7SDimitry Andric if (isNaN()) {
2320cfca06d7SDimitry Andric if (isSignaling()) {
2321cfca06d7SDimitry Andric // [IEEE Std 754-2008 6.2]:
2322cfca06d7SDimitry Andric // Under default exception handling, any operation signaling an invalid
2323cfca06d7SDimitry Andric // operation exception and for which a floating-point result is to be
2324cfca06d7SDimitry Andric // delivered shall deliver a quiet NaN.
2325cfca06d7SDimitry Andric makeQuiet();
2326cfca06d7SDimitry Andric // [IEEE Std 754-2008 6.2]:
2327cfca06d7SDimitry Andric // Signaling NaNs shall be reserved operands that, under default exception
2328cfca06d7SDimitry Andric // handling, signal the invalid operation exception(see 7.2) for every
2329cfca06d7SDimitry Andric // general-computational and signaling-computational operation except for
2330cfca06d7SDimitry Andric // the conversions described in 5.12.
2331cfca06d7SDimitry Andric return opInvalidOp;
2332cfca06d7SDimitry Andric } else {
2333cfca06d7SDimitry Andric // [IEEE Std 754-2008 6.2]:
2334cfca06d7SDimitry Andric // For an operation with quiet NaN inputs, other than maximum and minimum
2335cfca06d7SDimitry Andric // operations, if a floating-point result is to be delivered the result
2336cfca06d7SDimitry Andric // shall be a quiet NaN which should be one of the input NaNs.
2337cfca06d7SDimitry Andric // ...
2338cfca06d7SDimitry Andric // Every general-computational and quiet-computational operation involving
2339cfca06d7SDimitry Andric // one or more input NaNs, none of them signaling, shall signal no
2340cfca06d7SDimitry Andric // exception, except fusedMultiplyAdd might signal the invalid operation
2341cfca06d7SDimitry Andric // exception(see 7.2).
2342cfca06d7SDimitry Andric return opOK;
2343cfca06d7SDimitry Andric }
2344cfca06d7SDimitry Andric }
2345cfca06d7SDimitry Andric
2346cfca06d7SDimitry Andric if (isZero()) {
2347cfca06d7SDimitry Andric // [IEEE Std 754-2008 6.3]:
2348cfca06d7SDimitry Andric // ... the sign of the result of conversions, the quantize operation, the
2349cfca06d7SDimitry Andric // roundToIntegral operations, and the roundToIntegralExact(see 5.3.1) is
2350cfca06d7SDimitry Andric // the sign of the first or only operand.
2351cfca06d7SDimitry Andric return opOK;
2352cfca06d7SDimitry Andric }
2353cfca06d7SDimitry Andric
2354902a7b52SDimitry Andric // If the exponent is large enough, we know that this value is already
2355902a7b52SDimitry Andric // integral, and the arithmetic below would potentially cause it to saturate
2356902a7b52SDimitry Andric // to +/-Inf. Bail out early instead.
2357cfca06d7SDimitry Andric if (exponent+1 >= (int)semanticsPrecision(*semantics))
2358902a7b52SDimitry Andric return opOK;
2359902a7b52SDimitry Andric
236058b69754SDimitry Andric // The algorithm here is quite simple: we add 2^(p-1), where p is the
236158b69754SDimitry Andric // precision of our format, and then subtract it back off again. The choice
236258b69754SDimitry Andric // of rounding modes for the addition/subtraction determines the rounding mode
236358b69754SDimitry Andric // for our integral rounding as well.
2364902a7b52SDimitry Andric // NOTE: When the input value is negative, we do subtraction followed by
2365902a7b52SDimitry Andric // addition instead.
2366902a7b52SDimitry Andric APInt IntegerConstant(NextPowerOf2(semanticsPrecision(*semantics)), 1);
2367902a7b52SDimitry Andric IntegerConstant <<= semanticsPrecision(*semantics)-1;
2368b915e9e0SDimitry Andric IEEEFloat MagicConstant(*semantics);
236958b69754SDimitry Andric fs = MagicConstant.convertFromAPInt(IntegerConstant, false,
237058b69754SDimitry Andric rmNearestTiesToEven);
2371cfca06d7SDimitry Andric assert(fs == opOK);
237271d5a254SDimitry Andric MagicConstant.sign = sign;
2373902a7b52SDimitry Andric
2374cfca06d7SDimitry Andric // Preserve the input sign so that we can handle the case of zero result
2375cfca06d7SDimitry Andric // correctly.
2376902a7b52SDimitry Andric bool inputSign = isNegative();
2377902a7b52SDimitry Andric
237858b69754SDimitry Andric fs = add(MagicConstant, rounding_mode);
237958b69754SDimitry Andric
2380cfca06d7SDimitry Andric // Current value and 'MagicConstant' are both integers, so the result of the
2381cfca06d7SDimitry Andric // subtraction is always exact according to Sterbenz' lemma.
2382cfca06d7SDimitry Andric subtract(MagicConstant, rounding_mode);
2383902a7b52SDimitry Andric
2384902a7b52SDimitry Andric // Restore the input sign.
2385902a7b52SDimitry Andric if (inputSign != isNegative())
2386902a7b52SDimitry Andric changeSign();
2387902a7b52SDimitry Andric
238858b69754SDimitry Andric return fs;
238958b69754SDimitry Andric }
239058b69754SDimitry Andric
239158b69754SDimitry Andric
2392009b1c42SEd Schouten /* Comparison requires normalized numbers. */
compare(const IEEEFloat & rhs) const2393b915e9e0SDimitry Andric IEEEFloat::cmpResult IEEEFloat::compare(const IEEEFloat &rhs) const {
2394009b1c42SEd Schouten cmpResult result;
2395009b1c42SEd Schouten
2396009b1c42SEd Schouten assert(semantics == rhs.semantics);
2397009b1c42SEd Schouten
2398f8af5cf6SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) {
2399009b1c42SEd Schouten default:
24005ca98fd9SDimitry Andric llvm_unreachable(nullptr);
2401009b1c42SEd Schouten
2402f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero):
2403f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal):
2404f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity):
2405f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN):
2406f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN):
2407f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN):
2408f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN):
2409009b1c42SEd Schouten return cmpUnordered;
2410009b1c42SEd Schouten
2411f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal):
2412f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero):
2413f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero):
2414009b1c42SEd Schouten if (sign)
2415009b1c42SEd Schouten return cmpLessThan;
2416009b1c42SEd Schouten else
2417009b1c42SEd Schouten return cmpGreaterThan;
2418009b1c42SEd Schouten
2419f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity):
2420f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity):
2421f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal):
2422009b1c42SEd Schouten if (rhs.sign)
2423009b1c42SEd Schouten return cmpGreaterThan;
2424009b1c42SEd Schouten else
2425009b1c42SEd Schouten return cmpLessThan;
2426009b1c42SEd Schouten
2427f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity):
2428009b1c42SEd Schouten if (sign == rhs.sign)
2429009b1c42SEd Schouten return cmpEqual;
2430009b1c42SEd Schouten else if (sign)
2431009b1c42SEd Schouten return cmpLessThan;
2432009b1c42SEd Schouten else
2433009b1c42SEd Schouten return cmpGreaterThan;
2434009b1c42SEd Schouten
2435f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero):
2436009b1c42SEd Schouten return cmpEqual;
2437009b1c42SEd Schouten
2438f8af5cf6SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal):
2439009b1c42SEd Schouten break;
2440009b1c42SEd Schouten }
2441009b1c42SEd Schouten
2442009b1c42SEd Schouten /* Two normal numbers. Do they have the same sign? */
2443009b1c42SEd Schouten if (sign != rhs.sign) {
2444009b1c42SEd Schouten if (sign)
2445009b1c42SEd Schouten result = cmpLessThan;
2446009b1c42SEd Schouten else
2447009b1c42SEd Schouten result = cmpGreaterThan;
2448009b1c42SEd Schouten } else {
2449009b1c42SEd Schouten /* Compare absolute values; invert result if negative. */
2450009b1c42SEd Schouten result = compareAbsoluteValue(rhs);
2451009b1c42SEd Schouten
2452009b1c42SEd Schouten if (sign) {
2453009b1c42SEd Schouten if (result == cmpLessThan)
2454009b1c42SEd Schouten result = cmpGreaterThan;
2455009b1c42SEd Schouten else if (result == cmpGreaterThan)
2456009b1c42SEd Schouten result = cmpLessThan;
2457009b1c42SEd Schouten }
2458009b1c42SEd Schouten }
2459009b1c42SEd Schouten
2460009b1c42SEd Schouten return result;
2461009b1c42SEd Schouten }
2462009b1c42SEd Schouten
2463b915e9e0SDimitry Andric /// IEEEFloat::convert - convert a value of one floating point type to another.
2464009b1c42SEd Schouten /// The return value corresponds to the IEEE754 exceptions. *losesInfo
2465009b1c42SEd Schouten /// records whether the transformation lost information, i.e. whether
2466009b1c42SEd Schouten /// converting the result back to the original type will produce the
2467009b1c42SEd Schouten /// original value (this is almost the same as return value==fsOK, but there
2468009b1c42SEd Schouten /// are edge cases where this is not so).
2469009b1c42SEd Schouten
convert(const fltSemantics & toSemantics,roundingMode rounding_mode,bool * losesInfo)2470b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics,
2471b915e9e0SDimitry Andric roundingMode rounding_mode,
2472b915e9e0SDimitry Andric bool *losesInfo) {
2473009b1c42SEd Schouten lostFraction lostFraction;
2474009b1c42SEd Schouten unsigned int newPartCount, oldPartCount;
2475009b1c42SEd Schouten opStatus fs;
247663faed5bSDimitry Andric int shift;
247763faed5bSDimitry Andric const fltSemantics &fromSemantics = *semantics;
2478e3b55780SDimitry Andric bool is_signaling = isSignaling();
2479009b1c42SEd Schouten
2480009b1c42SEd Schouten lostFraction = lfExactlyZero;
2481009b1c42SEd Schouten newPartCount = partCountForBits(toSemantics.precision + 1);
2482009b1c42SEd Schouten oldPartCount = partCount();
248363faed5bSDimitry Andric shift = toSemantics.precision - fromSemantics.precision;
2484009b1c42SEd Schouten
248563faed5bSDimitry Andric bool X86SpecialNan = false;
2486b915e9e0SDimitry Andric if (&fromSemantics == &semX87DoubleExtended &&
2487b915e9e0SDimitry Andric &toSemantics != &semX87DoubleExtended && category == fcNaN &&
248863faed5bSDimitry Andric (!(*significandParts() & 0x8000000000000000ULL) ||
248963faed5bSDimitry Andric !(*significandParts() & 0x4000000000000000ULL))) {
249063faed5bSDimitry Andric // x86 has some unusual NaNs which cannot be represented in any other
249163faed5bSDimitry Andric // format; note them here.
249263faed5bSDimitry Andric X86SpecialNan = true;
249363faed5bSDimitry Andric }
249463faed5bSDimitry Andric
2495f8af5cf6SDimitry Andric // If this is a truncation of a denormal number, and the target semantics
2496f8af5cf6SDimitry Andric // has larger exponent range than the source semantics (this can happen
2497f8af5cf6SDimitry Andric // when truncating from PowerPC double-double to double format), the
2498f8af5cf6SDimitry Andric // right shift could lose result mantissa bits. Adjust exponent instead
2499f8af5cf6SDimitry Andric // of performing excessive shift.
2500145449b1SDimitry Andric // Also do a similar trick in case shifting denormal would produce zero
2501145449b1SDimitry Andric // significand as this case isn't handled correctly by normalize.
2502f8af5cf6SDimitry Andric if (shift < 0 && isFiniteNonZero()) {
2503145449b1SDimitry Andric int omsb = significandMSB() + 1;
2504145449b1SDimitry Andric int exponentChange = omsb - fromSemantics.precision;
2505f8af5cf6SDimitry Andric if (exponent + exponentChange < toSemantics.minExponent)
2506f8af5cf6SDimitry Andric exponentChange = toSemantics.minExponent - exponent;
2507f8af5cf6SDimitry Andric if (exponentChange < shift)
2508f8af5cf6SDimitry Andric exponentChange = shift;
2509f8af5cf6SDimitry Andric if (exponentChange < 0) {
2510f8af5cf6SDimitry Andric shift -= exponentChange;
2511f8af5cf6SDimitry Andric exponent += exponentChange;
2512145449b1SDimitry Andric } else if (omsb <= -shift) {
2513145449b1SDimitry Andric exponentChange = omsb + shift - 1; // leave at least one bit set
2514145449b1SDimitry Andric shift -= exponentChange;
2515145449b1SDimitry Andric exponent += exponentChange;
2516f8af5cf6SDimitry Andric }
2517f8af5cf6SDimitry Andric }
2518f8af5cf6SDimitry Andric
251963faed5bSDimitry Andric // If this is a truncation, perform the shift before we narrow the storage.
2520e3b55780SDimitry Andric if (shift < 0 && (isFiniteNonZero() ||
2521e3b55780SDimitry Andric (category == fcNaN && semantics->nonFiniteBehavior !=
2522e3b55780SDimitry Andric fltNonfiniteBehavior::NanOnly)))
252363faed5bSDimitry Andric lostFraction = shiftRight(significandParts(), oldPartCount, -shift);
252463faed5bSDimitry Andric
252563faed5bSDimitry Andric // Fix the storage so it can hold to new value.
2526009b1c42SEd Schouten if (newPartCount > oldPartCount) {
252763faed5bSDimitry Andric // The new type requires more storage; make it available.
2528009b1c42SEd Schouten integerPart *newParts;
2529009b1c42SEd Schouten newParts = new integerPart[newPartCount];
2530009b1c42SEd Schouten APInt::tcSet(newParts, 0, newPartCount);
2531f8af5cf6SDimitry Andric if (isFiniteNonZero() || category==fcNaN)
2532009b1c42SEd Schouten APInt::tcAssign(newParts, significandParts(), oldPartCount);
2533009b1c42SEd Schouten freeSignificand();
2534009b1c42SEd Schouten significand.parts = newParts;
253563faed5bSDimitry Andric } else if (newPartCount == 1 && oldPartCount != 1) {
253663faed5bSDimitry Andric // Switch to built-in storage for a single part.
2537009b1c42SEd Schouten integerPart newPart = 0;
2538f8af5cf6SDimitry Andric if (isFiniteNonZero() || category==fcNaN)
2539009b1c42SEd Schouten newPart = significandParts()[0];
2540009b1c42SEd Schouten freeSignificand();
2541009b1c42SEd Schouten significand.part = newPart;
2542009b1c42SEd Schouten }
254363faed5bSDimitry Andric
254463faed5bSDimitry Andric // Now that we have the right storage, switch the semantics.
254563faed5bSDimitry Andric semantics = &toSemantics;
254663faed5bSDimitry Andric
254763faed5bSDimitry Andric // If this is an extension, perform the shift now that the storage is
254863faed5bSDimitry Andric // available.
2549f8af5cf6SDimitry Andric if (shift > 0 && (isFiniteNonZero() || category==fcNaN))
255063faed5bSDimitry Andric APInt::tcShiftLeft(significandParts(), newPartCount, shift);
2551009b1c42SEd Schouten
2552f8af5cf6SDimitry Andric if (isFiniteNonZero()) {
2553009b1c42SEd Schouten fs = normalize(rounding_mode, lostFraction);
2554009b1c42SEd Schouten *losesInfo = (fs != opOK);
2555009b1c42SEd Schouten } else if (category == fcNaN) {
2556e3b55780SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
2557e3b55780SDimitry Andric *losesInfo =
2558e3b55780SDimitry Andric fromSemantics.nonFiniteBehavior != fltNonfiniteBehavior::NanOnly;
2559e3b55780SDimitry Andric makeNaN(false, sign);
2560e3b55780SDimitry Andric return is_signaling ? opInvalidOp : opOK;
2561e3b55780SDimitry Andric }
2562e3b55780SDimitry Andric
25637fa27ce4SDimitry Andric // If NaN is negative zero, we need to create a new NaN to avoid converting
25647fa27ce4SDimitry Andric // NaN to -Inf.
25657fa27ce4SDimitry Andric if (fromSemantics.nanEncoding == fltNanEncoding::NegativeZero &&
25667fa27ce4SDimitry Andric semantics->nanEncoding != fltNanEncoding::NegativeZero)
25677fa27ce4SDimitry Andric makeNaN(false, false);
25687fa27ce4SDimitry Andric
256963faed5bSDimitry Andric *losesInfo = lostFraction != lfExactlyZero || X86SpecialNan;
25704a16efa3SDimitry Andric
25714a16efa3SDimitry Andric // For x87 extended precision, we want to make a NaN, not a special NaN if
25724a16efa3SDimitry Andric // the input wasn't special either.
2573b915e9e0SDimitry Andric if (!X86SpecialNan && semantics == &semX87DoubleExtended)
25744a16efa3SDimitry Andric APInt::tcSetBit(significandParts(), semantics->precision - 1);
25754a16efa3SDimitry Andric
2576b60736ecSDimitry Andric // Convert of sNaN creates qNaN and raises an exception (invalid op).
2577b60736ecSDimitry Andric // This also guarantees that a sNaN does not become Inf on a truncation
2578b60736ecSDimitry Andric // that loses all payload bits.
2579e3b55780SDimitry Andric if (is_signaling) {
2580b60736ecSDimitry Andric makeQuiet();
2581b60736ecSDimitry Andric fs = opInvalidOp;
2582b60736ecSDimitry Andric } else {
2583009b1c42SEd Schouten fs = opOK;
2584b60736ecSDimitry Andric }
2585e3b55780SDimitry Andric } else if (category == fcInfinity &&
2586e3b55780SDimitry Andric semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
2587e3b55780SDimitry Andric makeNaN(false, sign);
2588e3b55780SDimitry Andric *losesInfo = true;
2589e3b55780SDimitry Andric fs = opInexact;
25907fa27ce4SDimitry Andric } else if (category == fcZero &&
25917fa27ce4SDimitry Andric semantics->nanEncoding == fltNanEncoding::NegativeZero) {
25927fa27ce4SDimitry Andric // Negative zero loses info, but positive zero doesn't.
25937fa27ce4SDimitry Andric *losesInfo =
25947fa27ce4SDimitry Andric fromSemantics.nanEncoding != fltNanEncoding::NegativeZero && sign;
25957fa27ce4SDimitry Andric fs = *losesInfo ? opInexact : opOK;
25967fa27ce4SDimitry Andric // NaN is negative zero means -0 -> +0, which can lose information
25977fa27ce4SDimitry Andric sign = false;
2598009b1c42SEd Schouten } else {
2599009b1c42SEd Schouten *losesInfo = false;
260063faed5bSDimitry Andric fs = opOK;
2601009b1c42SEd Schouten }
2602009b1c42SEd Schouten
2603009b1c42SEd Schouten return fs;
2604009b1c42SEd Schouten }
2605009b1c42SEd Schouten
2606009b1c42SEd Schouten /* Convert a floating point number to an integer according to the
2607009b1c42SEd Schouten rounding mode. If the rounded integer value is out of range this
2608009b1c42SEd Schouten returns an invalid operation exception and the contents of the
2609009b1c42SEd Schouten destination parts are unspecified. If the rounded value is in
2610009b1c42SEd Schouten range but the floating point number is not the exact integer, the C
2611009b1c42SEd Schouten standard doesn't require an inexact exception to be raised. IEEE
2612009b1c42SEd Schouten 854 does require it so we do that.
2613009b1c42SEd Schouten
2614009b1c42SEd Schouten Note that for conversions to integer type the C standard requires
2615009b1c42SEd Schouten round-to-zero to always be used. */
convertToSignExtendedInteger(MutableArrayRef<integerPart> parts,unsigned int width,bool isSigned,roundingMode rounding_mode,bool * isExact) const2616b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
261771d5a254SDimitry Andric MutableArrayRef<integerPart> parts, unsigned int width, bool isSigned,
2618b915e9e0SDimitry Andric roundingMode rounding_mode, bool *isExact) const {
2619009b1c42SEd Schouten lostFraction lost_fraction;
2620009b1c42SEd Schouten const integerPart *src;
2621009b1c42SEd Schouten unsigned int dstPartsCount, truncatedBits;
2622009b1c42SEd Schouten
2623009b1c42SEd Schouten *isExact = false;
2624009b1c42SEd Schouten
2625009b1c42SEd Schouten /* Handle the three special cases first. */
2626009b1c42SEd Schouten if (category == fcInfinity || category == fcNaN)
2627009b1c42SEd Schouten return opInvalidOp;
2628009b1c42SEd Schouten
2629009b1c42SEd Schouten dstPartsCount = partCountForBits(width);
263071d5a254SDimitry Andric assert(dstPartsCount <= parts.size() && "Integer too big");
2631009b1c42SEd Schouten
2632009b1c42SEd Schouten if (category == fcZero) {
263371d5a254SDimitry Andric APInt::tcSet(parts.data(), 0, dstPartsCount);
2634009b1c42SEd Schouten // Negative zero can't be represented as an int.
2635009b1c42SEd Schouten *isExact = !sign;
2636009b1c42SEd Schouten return opOK;
2637009b1c42SEd Schouten }
2638009b1c42SEd Schouten
2639009b1c42SEd Schouten src = significandParts();
2640009b1c42SEd Schouten
2641009b1c42SEd Schouten /* Step 1: place our absolute value, with any fraction truncated, in
2642009b1c42SEd Schouten the destination. */
2643009b1c42SEd Schouten if (exponent < 0) {
2644009b1c42SEd Schouten /* Our absolute value is less than one; truncate everything. */
264571d5a254SDimitry Andric APInt::tcSet(parts.data(), 0, dstPartsCount);
2646009b1c42SEd Schouten /* For exponent -1 the integer bit represents .5, look at that.
2647009b1c42SEd Schouten For smaller exponents leftmost truncated bit is 0. */
2648009b1c42SEd Schouten truncatedBits = semantics->precision -1U - exponent;
2649009b1c42SEd Schouten } else {
2650009b1c42SEd Schouten /* We want the most significant (exponent + 1) bits; the rest are
2651009b1c42SEd Schouten truncated. */
2652009b1c42SEd Schouten unsigned int bits = exponent + 1U;
2653009b1c42SEd Schouten
2654009b1c42SEd Schouten /* Hopelessly large in magnitude? */
2655009b1c42SEd Schouten if (bits > width)
2656009b1c42SEd Schouten return opInvalidOp;
2657009b1c42SEd Schouten
2658009b1c42SEd Schouten if (bits < semantics->precision) {
2659009b1c42SEd Schouten /* We truncate (semantics->precision - bits) bits. */
2660009b1c42SEd Schouten truncatedBits = semantics->precision - bits;
266171d5a254SDimitry Andric APInt::tcExtract(parts.data(), dstPartsCount, src, bits, truncatedBits);
2662009b1c42SEd Schouten } else {
2663009b1c42SEd Schouten /* We want at least as many bits as are available. */
266471d5a254SDimitry Andric APInt::tcExtract(parts.data(), dstPartsCount, src, semantics->precision,
266571d5a254SDimitry Andric 0);
266671d5a254SDimitry Andric APInt::tcShiftLeft(parts.data(), dstPartsCount,
266771d5a254SDimitry Andric bits - semantics->precision);
2668009b1c42SEd Schouten truncatedBits = 0;
2669009b1c42SEd Schouten }
2670009b1c42SEd Schouten }
2671009b1c42SEd Schouten
2672009b1c42SEd Schouten /* Step 2: work out any lost fraction, and increment the absolute
2673009b1c42SEd Schouten value if we would round away from zero. */
2674009b1c42SEd Schouten if (truncatedBits) {
2675009b1c42SEd Schouten lost_fraction = lostFractionThroughTruncation(src, partCount(),
2676009b1c42SEd Schouten truncatedBits);
2677104bd817SRoman Divacky if (lost_fraction != lfExactlyZero &&
2678104bd817SRoman Divacky roundAwayFromZero(rounding_mode, lost_fraction, truncatedBits)) {
267971d5a254SDimitry Andric if (APInt::tcIncrement(parts.data(), dstPartsCount))
2680009b1c42SEd Schouten return opInvalidOp; /* Overflow. */
2681009b1c42SEd Schouten }
2682009b1c42SEd Schouten } else {
2683009b1c42SEd Schouten lost_fraction = lfExactlyZero;
2684009b1c42SEd Schouten }
2685009b1c42SEd Schouten
2686009b1c42SEd Schouten /* Step 3: check if we fit in the destination. */
268771d5a254SDimitry Andric unsigned int omsb = APInt::tcMSB(parts.data(), dstPartsCount) + 1;
2688009b1c42SEd Schouten
2689009b1c42SEd Schouten if (sign) {
2690009b1c42SEd Schouten if (!isSigned) {
2691009b1c42SEd Schouten /* Negative numbers cannot be represented as unsigned. */
2692009b1c42SEd Schouten if (omsb != 0)
2693009b1c42SEd Schouten return opInvalidOp;
2694009b1c42SEd Schouten } else {
2695009b1c42SEd Schouten /* It takes omsb bits to represent the unsigned integer value.
2696009b1c42SEd Schouten We lose a bit for the sign, but care is needed as the
2697009b1c42SEd Schouten maximally negative integer is a special case. */
269871d5a254SDimitry Andric if (omsb == width &&
269971d5a254SDimitry Andric APInt::tcLSB(parts.data(), dstPartsCount) + 1 != omsb)
2700009b1c42SEd Schouten return opInvalidOp;
2701009b1c42SEd Schouten
2702009b1c42SEd Schouten /* This case can happen because of rounding. */
2703009b1c42SEd Schouten if (omsb > width)
2704009b1c42SEd Schouten return opInvalidOp;
2705009b1c42SEd Schouten }
2706009b1c42SEd Schouten
270771d5a254SDimitry Andric APInt::tcNegate (parts.data(), dstPartsCount);
2708009b1c42SEd Schouten } else {
2709009b1c42SEd Schouten if (omsb >= width + !isSigned)
2710009b1c42SEd Schouten return opInvalidOp;
2711009b1c42SEd Schouten }
2712009b1c42SEd Schouten
2713009b1c42SEd Schouten if (lost_fraction == lfExactlyZero) {
2714009b1c42SEd Schouten *isExact = true;
2715009b1c42SEd Schouten return opOK;
2716009b1c42SEd Schouten } else
2717009b1c42SEd Schouten return opInexact;
2718009b1c42SEd Schouten }
2719009b1c42SEd Schouten
2720009b1c42SEd Schouten /* Same as convertToSignExtendedInteger, except we provide
2721009b1c42SEd Schouten deterministic values in case of an invalid operation exception,
2722009b1c42SEd Schouten namely zero for NaNs and the minimal or maximal value respectively
2723009b1c42SEd Schouten for underflow or overflow.
2724009b1c42SEd Schouten The *isExact output tells whether the result is exact, in the sense
2725009b1c42SEd Schouten that converting it back to the original floating point type produces
2726009b1c42SEd Schouten the original value. This is almost equivalent to result==opOK,
2727009b1c42SEd Schouten except for negative zeroes.
2728009b1c42SEd Schouten */
272971d5a254SDimitry Andric IEEEFloat::opStatus
convertToInteger(MutableArrayRef<integerPart> parts,unsigned int width,bool isSigned,roundingMode rounding_mode,bool * isExact) const273071d5a254SDimitry Andric IEEEFloat::convertToInteger(MutableArrayRef<integerPart> parts,
273171d5a254SDimitry Andric unsigned int width, bool isSigned,
273271d5a254SDimitry Andric roundingMode rounding_mode, bool *isExact) const {
2733009b1c42SEd Schouten opStatus fs;
2734009b1c42SEd Schouten
2735009b1c42SEd Schouten fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode,
2736009b1c42SEd Schouten isExact);
2737009b1c42SEd Schouten
2738009b1c42SEd Schouten if (fs == opInvalidOp) {
2739009b1c42SEd Schouten unsigned int bits, dstPartsCount;
2740009b1c42SEd Schouten
2741009b1c42SEd Schouten dstPartsCount = partCountForBits(width);
274271d5a254SDimitry Andric assert(dstPartsCount <= parts.size() && "Integer too big");
2743009b1c42SEd Schouten
2744009b1c42SEd Schouten if (category == fcNaN)
2745009b1c42SEd Schouten bits = 0;
2746009b1c42SEd Schouten else if (sign)
2747009b1c42SEd Schouten bits = isSigned;
2748009b1c42SEd Schouten else
2749009b1c42SEd Schouten bits = width - isSigned;
2750009b1c42SEd Schouten
2751c0981da4SDimitry Andric tcSetLeastSignificantBits(parts.data(), dstPartsCount, bits);
2752009b1c42SEd Schouten if (sign && isSigned)
275371d5a254SDimitry Andric APInt::tcShiftLeft(parts.data(), dstPartsCount, width - 1);
2754009b1c42SEd Schouten }
2755009b1c42SEd Schouten
2756009b1c42SEd Schouten return fs;
2757009b1c42SEd Schouten }
2758009b1c42SEd Schouten
2759009b1c42SEd Schouten /* Convert an unsigned integer SRC to a floating point number,
2760009b1c42SEd Schouten rounding according to ROUNDING_MODE. The sign of the floating
2761009b1c42SEd Schouten point number is not modified. */
convertFromUnsignedParts(const integerPart * src,unsigned int srcCount,roundingMode rounding_mode)2762b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::convertFromUnsignedParts(
2763b915e9e0SDimitry Andric const integerPart *src, unsigned int srcCount, roundingMode rounding_mode) {
2764009b1c42SEd Schouten unsigned int omsb, precision, dstCount;
2765009b1c42SEd Schouten integerPart *dst;
2766009b1c42SEd Schouten lostFraction lost_fraction;
2767009b1c42SEd Schouten
2768009b1c42SEd Schouten category = fcNormal;
2769009b1c42SEd Schouten omsb = APInt::tcMSB(src, srcCount) + 1;
2770009b1c42SEd Schouten dst = significandParts();
2771009b1c42SEd Schouten dstCount = partCount();
2772009b1c42SEd Schouten precision = semantics->precision;
2773009b1c42SEd Schouten
277430815c53SDimitry Andric /* We want the most significant PRECISION bits of SRC. There may not
2775009b1c42SEd Schouten be that many; extract what we can. */
2776009b1c42SEd Schouten if (precision <= omsb) {
2777009b1c42SEd Schouten exponent = omsb - 1;
2778009b1c42SEd Schouten lost_fraction = lostFractionThroughTruncation(src, srcCount,
2779009b1c42SEd Schouten omsb - precision);
2780009b1c42SEd Schouten APInt::tcExtract(dst, dstCount, src, precision, omsb - precision);
2781009b1c42SEd Schouten } else {
2782009b1c42SEd Schouten exponent = precision - 1;
2783009b1c42SEd Schouten lost_fraction = lfExactlyZero;
2784009b1c42SEd Schouten APInt::tcExtract(dst, dstCount, src, omsb, 0);
2785009b1c42SEd Schouten }
2786009b1c42SEd Schouten
2787009b1c42SEd Schouten return normalize(rounding_mode, lost_fraction);
2788009b1c42SEd Schouten }
2789009b1c42SEd Schouten
convertFromAPInt(const APInt & Val,bool isSigned,roundingMode rounding_mode)2790b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::convertFromAPInt(const APInt &Val, bool isSigned,
2791b915e9e0SDimitry Andric roundingMode rounding_mode) {
2792009b1c42SEd Schouten unsigned int partCount = Val.getNumWords();
2793009b1c42SEd Schouten APInt api = Val;
2794009b1c42SEd Schouten
2795009b1c42SEd Schouten sign = false;
2796009b1c42SEd Schouten if (isSigned && api.isNegative()) {
2797009b1c42SEd Schouten sign = true;
2798009b1c42SEd Schouten api = -api;
2799009b1c42SEd Schouten }
2800009b1c42SEd Schouten
2801009b1c42SEd Schouten return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
2802009b1c42SEd Schouten }
2803009b1c42SEd Schouten
2804009b1c42SEd Schouten /* Convert a two's complement integer SRC to a floating point number,
2805009b1c42SEd Schouten rounding according to ROUNDING_MODE. ISSIGNED is true if the
2806009b1c42SEd Schouten integer is signed, in which case it must be sign-extended. */
2807b915e9e0SDimitry Andric IEEEFloat::opStatus
convertFromSignExtendedInteger(const integerPart * src,unsigned int srcCount,bool isSigned,roundingMode rounding_mode)2808b915e9e0SDimitry Andric IEEEFloat::convertFromSignExtendedInteger(const integerPart *src,
2809b915e9e0SDimitry Andric unsigned int srcCount, bool isSigned,
2810b915e9e0SDimitry Andric roundingMode rounding_mode) {
2811009b1c42SEd Schouten opStatus status;
2812009b1c42SEd Schouten
2813104bd817SRoman Divacky if (isSigned &&
2814104bd817SRoman Divacky APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) {
2815009b1c42SEd Schouten integerPart *copy;
2816009b1c42SEd Schouten
2817009b1c42SEd Schouten /* If we're signed and negative negate a copy. */
2818009b1c42SEd Schouten sign = true;
2819009b1c42SEd Schouten copy = new integerPart[srcCount];
2820009b1c42SEd Schouten APInt::tcAssign(copy, src, srcCount);
2821009b1c42SEd Schouten APInt::tcNegate(copy, srcCount);
2822009b1c42SEd Schouten status = convertFromUnsignedParts(copy, srcCount, rounding_mode);
2823009b1c42SEd Schouten delete [] copy;
2824009b1c42SEd Schouten } else {
2825009b1c42SEd Schouten sign = false;
2826009b1c42SEd Schouten status = convertFromUnsignedParts(src, srcCount, rounding_mode);
2827009b1c42SEd Schouten }
2828009b1c42SEd Schouten
2829009b1c42SEd Schouten return status;
2830009b1c42SEd Schouten }
2831009b1c42SEd Schouten
2832009b1c42SEd Schouten /* FIXME: should this just take a const APInt reference? */
2833b915e9e0SDimitry Andric IEEEFloat::opStatus
convertFromZeroExtendedInteger(const integerPart * parts,unsigned int width,bool isSigned,roundingMode rounding_mode)2834b915e9e0SDimitry Andric IEEEFloat::convertFromZeroExtendedInteger(const integerPart *parts,
2835009b1c42SEd Schouten unsigned int width, bool isSigned,
2836b915e9e0SDimitry Andric roundingMode rounding_mode) {
2837009b1c42SEd Schouten unsigned int partCount = partCountForBits(width);
2838e3b55780SDimitry Andric APInt api = APInt(width, ArrayRef(parts, partCount));
2839009b1c42SEd Schouten
2840009b1c42SEd Schouten sign = false;
2841009b1c42SEd Schouten if (isSigned && APInt::tcExtractBit(parts, width - 1)) {
2842009b1c42SEd Schouten sign = true;
2843009b1c42SEd Schouten api = -api;
2844009b1c42SEd Schouten }
2845009b1c42SEd Schouten
2846009b1c42SEd Schouten return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
2847009b1c42SEd Schouten }
2848009b1c42SEd Schouten
2849706b4fc4SDimitry Andric Expected<IEEEFloat::opStatus>
convertFromHexadecimalString(StringRef s,roundingMode rounding_mode)2850b915e9e0SDimitry Andric IEEEFloat::convertFromHexadecimalString(StringRef s,
2851b915e9e0SDimitry Andric roundingMode rounding_mode) {
285259850d08SRoman Divacky lostFraction lost_fraction = lfExactlyZero;
2853009b1c42SEd Schouten
2854f8af5cf6SDimitry Andric category = fcNormal;
2855009b1c42SEd Schouten zeroSignificand();
2856009b1c42SEd Schouten exponent = 0;
2857009b1c42SEd Schouten
2858f8af5cf6SDimitry Andric integerPart *significand = significandParts();
2859f8af5cf6SDimitry Andric unsigned partsCount = partCount();
2860f8af5cf6SDimitry Andric unsigned bitPos = partsCount * integerPartWidth;
2861f8af5cf6SDimitry Andric bool computedTrailingFraction = false;
2862009b1c42SEd Schouten
2863f8af5cf6SDimitry Andric // Skip leading zeroes and any (hexa)decimal point.
286459850d08SRoman Divacky StringRef::iterator begin = s.begin();
286559850d08SRoman Divacky StringRef::iterator end = s.end();
2866f8af5cf6SDimitry Andric StringRef::iterator dot;
2867706b4fc4SDimitry Andric auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot);
2868706b4fc4SDimitry Andric if (!PtrOrErr)
2869706b4fc4SDimitry Andric return PtrOrErr.takeError();
2870706b4fc4SDimitry Andric StringRef::iterator p = *PtrOrErr;
2871f8af5cf6SDimitry Andric StringRef::iterator firstSignificantDigit = p;
2872009b1c42SEd Schouten
2873f8af5cf6SDimitry Andric while (p != end) {
2874009b1c42SEd Schouten integerPart hex_value;
2875009b1c42SEd Schouten
2876009b1c42SEd Schouten if (*p == '.') {
2877706b4fc4SDimitry Andric if (dot != end)
2878706b4fc4SDimitry Andric return createError("String contains multiple dots");
2879009b1c42SEd Schouten dot = p++;
2880f8af5cf6SDimitry Andric continue;
2881009b1c42SEd Schouten }
2882009b1c42SEd Schouten
2883009b1c42SEd Schouten hex_value = hexDigitValue(*p);
28847fa27ce4SDimitry Andric if (hex_value == UINT_MAX)
2885009b1c42SEd Schouten break;
2886009b1c42SEd Schouten
2887009b1c42SEd Schouten p++;
2888009b1c42SEd Schouten
2889f8af5cf6SDimitry Andric // Store the number while we have space.
2890009b1c42SEd Schouten if (bitPos) {
2891009b1c42SEd Schouten bitPos -= 4;
2892009b1c42SEd Schouten hex_value <<= bitPos % integerPartWidth;
2893009b1c42SEd Schouten significand[bitPos / integerPartWidth] |= hex_value;
2894f8af5cf6SDimitry Andric } else if (!computedTrailingFraction) {
2895706b4fc4SDimitry Andric auto FractOrErr = trailingHexadecimalFraction(p, end, hex_value);
2896706b4fc4SDimitry Andric if (!FractOrErr)
2897706b4fc4SDimitry Andric return FractOrErr.takeError();
2898706b4fc4SDimitry Andric lost_fraction = *FractOrErr;
2899f8af5cf6SDimitry Andric computedTrailingFraction = true;
2900009b1c42SEd Schouten }
290159850d08SRoman Divacky }
2902009b1c42SEd Schouten
2903009b1c42SEd Schouten /* Hex floats require an exponent but not a hexadecimal point. */
2904706b4fc4SDimitry Andric if (p == end)
2905706b4fc4SDimitry Andric return createError("Hex strings require an exponent");
2906706b4fc4SDimitry Andric if (*p != 'p' && *p != 'P')
2907706b4fc4SDimitry Andric return createError("Invalid character in significand");
2908706b4fc4SDimitry Andric if (p == begin)
2909706b4fc4SDimitry Andric return createError("Significand has no digits");
2910706b4fc4SDimitry Andric if (dot != end && p - begin == 1)
2911706b4fc4SDimitry Andric return createError("Significand has no digits");
2912009b1c42SEd Schouten
2913009b1c42SEd Schouten /* Ignore the exponent if we are zero. */
2914009b1c42SEd Schouten if (p != firstSignificantDigit) {
2915009b1c42SEd Schouten int expAdjustment;
2916009b1c42SEd Schouten
2917009b1c42SEd Schouten /* Implicit hexadecimal point? */
291859850d08SRoman Divacky if (dot == end)
2919009b1c42SEd Schouten dot = p;
2920009b1c42SEd Schouten
2921009b1c42SEd Schouten /* Calculate the exponent adjustment implicit in the number of
2922009b1c42SEd Schouten significant digits. */
2923009b1c42SEd Schouten expAdjustment = static_cast<int>(dot - firstSignificantDigit);
2924009b1c42SEd Schouten if (expAdjustment < 0)
2925009b1c42SEd Schouten expAdjustment++;
2926009b1c42SEd Schouten expAdjustment = expAdjustment * 4 - 1;
2927009b1c42SEd Schouten
2928009b1c42SEd Schouten /* Adjust for writing the significand starting at the most
2929009b1c42SEd Schouten significant nibble. */
2930009b1c42SEd Schouten expAdjustment += semantics->precision;
2931009b1c42SEd Schouten expAdjustment -= partsCount * integerPartWidth;
2932009b1c42SEd Schouten
2933009b1c42SEd Schouten /* Adjust for the given exponent. */
2934706b4fc4SDimitry Andric auto ExpOrErr = totalExponent(p + 1, end, expAdjustment);
2935706b4fc4SDimitry Andric if (!ExpOrErr)
2936706b4fc4SDimitry Andric return ExpOrErr.takeError();
2937706b4fc4SDimitry Andric exponent = *ExpOrErr;
2938009b1c42SEd Schouten }
2939009b1c42SEd Schouten
2940009b1c42SEd Schouten return normalize(rounding_mode, lost_fraction);
2941009b1c42SEd Schouten }
2942009b1c42SEd Schouten
2943b915e9e0SDimitry Andric IEEEFloat::opStatus
roundSignificandWithExponent(const integerPart * decSigParts,unsigned sigPartCount,int exp,roundingMode rounding_mode)2944b915e9e0SDimitry Andric IEEEFloat::roundSignificandWithExponent(const integerPart *decSigParts,
2945009b1c42SEd Schouten unsigned sigPartCount, int exp,
2946b915e9e0SDimitry Andric roundingMode rounding_mode) {
2947009b1c42SEd Schouten unsigned int parts, pow5PartCount;
2948ee8648bdSDimitry Andric fltSemantics calcSemantics = { 32767, -32767, 0, 0 };
2949009b1c42SEd Schouten integerPart pow5Parts[maxPowerOfFiveParts];
2950009b1c42SEd Schouten bool isNearest;
2951009b1c42SEd Schouten
2952104bd817SRoman Divacky isNearest = (rounding_mode == rmNearestTiesToEven ||
2953104bd817SRoman Divacky rounding_mode == rmNearestTiesToAway);
2954009b1c42SEd Schouten
2955009b1c42SEd Schouten parts = partCountForBits(semantics->precision + 11);
2956009b1c42SEd Schouten
2957009b1c42SEd Schouten /* Calculate pow(5, abs(exp)). */
2958009b1c42SEd Schouten pow5PartCount = powerOf5(pow5Parts, exp >= 0 ? exp: -exp);
2959009b1c42SEd Schouten
2960009b1c42SEd Schouten for (;; parts *= 2) {
2961009b1c42SEd Schouten opStatus sigStatus, powStatus;
2962009b1c42SEd Schouten unsigned int excessPrecision, truncatedBits;
2963009b1c42SEd Schouten
2964009b1c42SEd Schouten calcSemantics.precision = parts * integerPartWidth - 1;
2965009b1c42SEd Schouten excessPrecision = calcSemantics.precision - semantics->precision;
2966009b1c42SEd Schouten truncatedBits = excessPrecision;
2967009b1c42SEd Schouten
2968b915e9e0SDimitry Andric IEEEFloat decSig(calcSemantics, uninitialized);
2969b915e9e0SDimitry Andric decSig.makeZero(sign);
2970b915e9e0SDimitry Andric IEEEFloat pow5(calcSemantics);
2971009b1c42SEd Schouten
2972009b1c42SEd Schouten sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount,
2973009b1c42SEd Schouten rmNearestTiesToEven);
2974009b1c42SEd Schouten powStatus = pow5.convertFromUnsignedParts(pow5Parts, pow5PartCount,
2975009b1c42SEd Schouten rmNearestTiesToEven);
2976009b1c42SEd Schouten /* Add exp, as 10^n = 5^n * 2^n. */
2977009b1c42SEd Schouten decSig.exponent += exp;
2978009b1c42SEd Schouten
2979009b1c42SEd Schouten lostFraction calcLostFraction;
2980009b1c42SEd Schouten integerPart HUerr, HUdistance;
2981009b1c42SEd Schouten unsigned int powHUerr;
2982009b1c42SEd Schouten
2983009b1c42SEd Schouten if (exp >= 0) {
2984009b1c42SEd Schouten /* multiplySignificand leaves the precision-th bit set to 1. */
2985706b4fc4SDimitry Andric calcLostFraction = decSig.multiplySignificand(pow5);
2986009b1c42SEd Schouten powHUerr = powStatus != opOK;
2987009b1c42SEd Schouten } else {
2988009b1c42SEd Schouten calcLostFraction = decSig.divideSignificand(pow5);
2989009b1c42SEd Schouten /* Denormal numbers have less precision. */
2990009b1c42SEd Schouten if (decSig.exponent < semantics->minExponent) {
2991009b1c42SEd Schouten excessPrecision += (semantics->minExponent - decSig.exponent);
2992009b1c42SEd Schouten truncatedBits = excessPrecision;
2993009b1c42SEd Schouten if (excessPrecision > calcSemantics.precision)
2994009b1c42SEd Schouten excessPrecision = calcSemantics.precision;
2995009b1c42SEd Schouten }
2996009b1c42SEd Schouten /* Extra half-ulp lost in reciprocal of exponent. */
2997009b1c42SEd Schouten powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0:2;
2998009b1c42SEd Schouten }
2999009b1c42SEd Schouten
3000009b1c42SEd Schouten /* Both multiplySignificand and divideSignificand return the
3001009b1c42SEd Schouten result with the integer bit set. */
3002009b1c42SEd Schouten assert(APInt::tcExtractBit
3003009b1c42SEd Schouten (decSig.significandParts(), calcSemantics.precision - 1) == 1);
3004009b1c42SEd Schouten
3005009b1c42SEd Schouten HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus != opOK,
3006009b1c42SEd Schouten powHUerr);
3007009b1c42SEd Schouten HUdistance = 2 * ulpsFromBoundary(decSig.significandParts(),
3008009b1c42SEd Schouten excessPrecision, isNearest);
3009009b1c42SEd Schouten
3010009b1c42SEd Schouten /* Are we guaranteed to round correctly if we truncate? */
3011009b1c42SEd Schouten if (HUdistance >= HUerr) {
3012009b1c42SEd Schouten APInt::tcExtract(significandParts(), partCount(), decSig.significandParts(),
3013009b1c42SEd Schouten calcSemantics.precision - excessPrecision,
3014009b1c42SEd Schouten excessPrecision);
3015009b1c42SEd Schouten /* Take the exponent of decSig. If we tcExtract-ed less bits
3016009b1c42SEd Schouten above we must adjust our exponent to compensate for the
3017009b1c42SEd Schouten implicit right shift. */
3018009b1c42SEd Schouten exponent = (decSig.exponent + semantics->precision
3019009b1c42SEd Schouten - (calcSemantics.precision - excessPrecision));
3020009b1c42SEd Schouten calcLostFraction = lostFractionThroughTruncation(decSig.significandParts(),
3021009b1c42SEd Schouten decSig.partCount(),
3022009b1c42SEd Schouten truncatedBits);
3023009b1c42SEd Schouten return normalize(rounding_mode, calcLostFraction);
3024009b1c42SEd Schouten }
3025009b1c42SEd Schouten }
3026009b1c42SEd Schouten }
3027009b1c42SEd Schouten
3028706b4fc4SDimitry Andric Expected<IEEEFloat::opStatus>
convertFromDecimalString(StringRef str,roundingMode rounding_mode)3029b915e9e0SDimitry Andric IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) {
3030009b1c42SEd Schouten decimalInfo D;
3031009b1c42SEd Schouten opStatus fs;
3032009b1c42SEd Schouten
3033009b1c42SEd Schouten /* Scan the text. */
303459850d08SRoman Divacky StringRef::iterator p = str.begin();
3035706b4fc4SDimitry Andric if (Error Err = interpretDecimal(p, str.end(), &D))
3036706b4fc4SDimitry Andric return std::move(Err);
3037009b1c42SEd Schouten
3038009b1c42SEd Schouten /* Handle the quick cases. First the case of no significant digits,
3039009b1c42SEd Schouten i.e. zero, and then exponents that are obviously too large or too
3040009b1c42SEd Schouten small. Writing L for log 10 / log 2, a number d.ddddd*10^exp
3041009b1c42SEd Schouten definitely overflows if
3042009b1c42SEd Schouten
3043009b1c42SEd Schouten (exp - 1) * L >= maxExponent
3044009b1c42SEd Schouten
3045009b1c42SEd Schouten and definitely underflows to zero where
3046009b1c42SEd Schouten
3047009b1c42SEd Schouten (exp + 1) * L <= minExponent - precision
3048009b1c42SEd Schouten
3049009b1c42SEd Schouten With integer arithmetic the tightest bounds for L are
3050009b1c42SEd Schouten
3051009b1c42SEd Schouten 93/28 < L < 196/59 [ numerator <= 256 ]
3052009b1c42SEd Schouten 42039/12655 < L < 28738/8651 [ numerator <= 65536 ]
3053009b1c42SEd Schouten */
3054009b1c42SEd Schouten
3055f8af5cf6SDimitry Andric // Test if we have a zero number allowing for strings with no null terminators
3056f8af5cf6SDimitry Andric // and zero decimals with non-zero exponents.
3057f8af5cf6SDimitry Andric //
3058f8af5cf6SDimitry Andric // We computed firstSigDigit by ignoring all zeros and dots. Thus if
3059f8af5cf6SDimitry Andric // D->firstSigDigit equals str.end(), every digit must be a zero and there can
3060f8af5cf6SDimitry Andric // be at most one dot. On the other hand, if we have a zero with a non-zero
3061f8af5cf6SDimitry Andric // exponent, then we know that D.firstSigDigit will be non-numeric.
3062f8af5cf6SDimitry Andric if (D.firstSigDigit == str.end() || decDigitValue(*D.firstSigDigit) >= 10U) {
3063009b1c42SEd Schouten category = fcZero;
3064009b1c42SEd Schouten fs = opOK;
30657fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
30667fa27ce4SDimitry Andric sign = false;
306767a71b31SRoman Divacky
306867a71b31SRoman Divacky /* Check whether the normalized exponent is high enough to overflow
306967a71b31SRoman Divacky max during the log-rebasing in the max-exponent check below. */
307067a71b31SRoman Divacky } else if (D.normalizedExponent - 1 > INT_MAX / 42039) {
307167a71b31SRoman Divacky fs = handleOverflow(rounding_mode);
307267a71b31SRoman Divacky
307367a71b31SRoman Divacky /* If it wasn't, then it also wasn't high enough to overflow max
307467a71b31SRoman Divacky during the log-rebasing in the min-exponent check. Check that it
307567a71b31SRoman Divacky won't overflow min in either check, then perform the min-exponent
307667a71b31SRoman Divacky check. */
307767a71b31SRoman Divacky } else if (D.normalizedExponent - 1 < INT_MIN / 42039 ||
307867a71b31SRoman Divacky (D.normalizedExponent + 1) * 28738 <=
307967a71b31SRoman Divacky 8651 * (semantics->minExponent - (int) semantics->precision)) {
3080009b1c42SEd Schouten /* Underflow to zero and round. */
3081f8af5cf6SDimitry Andric category = fcNormal;
3082009b1c42SEd Schouten zeroSignificand();
3083009b1c42SEd Schouten fs = normalize(rounding_mode, lfLessThanHalf);
308467a71b31SRoman Divacky
308567a71b31SRoman Divacky /* We can finally safely perform the max-exponent check. */
3086009b1c42SEd Schouten } else if ((D.normalizedExponent - 1) * 42039
3087009b1c42SEd Schouten >= 12655 * semantics->maxExponent) {
3088009b1c42SEd Schouten /* Overflow and round. */
3089009b1c42SEd Schouten fs = handleOverflow(rounding_mode);
3090009b1c42SEd Schouten } else {
3091009b1c42SEd Schouten integerPart *decSignificand;
3092009b1c42SEd Schouten unsigned int partCount;
3093009b1c42SEd Schouten
3094009b1c42SEd Schouten /* A tight upper bound on number of bits required to hold an
3095009b1c42SEd Schouten N-digit decimal integer is N * 196 / 59. Allocate enough space
3096009b1c42SEd Schouten to hold the full significand, and an extra part required by
3097009b1c42SEd Schouten tcMultiplyPart. */
3098009b1c42SEd Schouten partCount = static_cast<unsigned int>(D.lastSigDigit - D.firstSigDigit) + 1;
3099009b1c42SEd Schouten partCount = partCountForBits(1 + 196 * partCount / 59);
3100009b1c42SEd Schouten decSignificand = new integerPart[partCount + 1];
3101009b1c42SEd Schouten partCount = 0;
3102009b1c42SEd Schouten
3103009b1c42SEd Schouten /* Convert to binary efficiently - we do almost all multiplication
3104009b1c42SEd Schouten in an integerPart. When this would overflow do we do a single
3105009b1c42SEd Schouten bignum multiplication, and then revert again to multiplication
3106009b1c42SEd Schouten in an integerPart. */
3107009b1c42SEd Schouten do {
3108009b1c42SEd Schouten integerPart decValue, val, multiplier;
3109009b1c42SEd Schouten
3110009b1c42SEd Schouten val = 0;
3111009b1c42SEd Schouten multiplier = 1;
3112009b1c42SEd Schouten
3113009b1c42SEd Schouten do {
311459850d08SRoman Divacky if (*p == '.') {
3115009b1c42SEd Schouten p++;
311659850d08SRoman Divacky if (p == str.end()) {
311759850d08SRoman Divacky break;
311859850d08SRoman Divacky }
311959850d08SRoman Divacky }
3120009b1c42SEd Schouten decValue = decDigitValue(*p++);
3121706b4fc4SDimitry Andric if (decValue >= 10U) {
3122706b4fc4SDimitry Andric delete[] decSignificand;
3123706b4fc4SDimitry Andric return createError("Invalid character in significand");
3124706b4fc4SDimitry Andric }
3125009b1c42SEd Schouten multiplier *= 10;
3126009b1c42SEd Schouten val = val * 10 + decValue;
3127009b1c42SEd Schouten /* The maximum number that can be multiplied by ten with any
3128009b1c42SEd Schouten digit added without overflowing an integerPart. */
3129009b1c42SEd Schouten } while (p <= D.lastSigDigit && multiplier <= (~ (integerPart) 0 - 9) / 10);
3130009b1c42SEd Schouten
3131009b1c42SEd Schouten /* Multiply out the current part. */
3132009b1c42SEd Schouten APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val,
3133009b1c42SEd Schouten partCount, partCount + 1, false);
3134009b1c42SEd Schouten
3135009b1c42SEd Schouten /* If we used another part (likely but not guaranteed), increase
3136009b1c42SEd Schouten the count. */
3137009b1c42SEd Schouten if (decSignificand[partCount])
3138009b1c42SEd Schouten partCount++;
3139009b1c42SEd Schouten } while (p <= D.lastSigDigit);
3140009b1c42SEd Schouten
3141009b1c42SEd Schouten category = fcNormal;
3142009b1c42SEd Schouten fs = roundSignificandWithExponent(decSignificand, partCount,
3143009b1c42SEd Schouten D.exponent, rounding_mode);
3144009b1c42SEd Schouten
3145009b1c42SEd Schouten delete [] decSignificand;
3146009b1c42SEd Schouten }
3147009b1c42SEd Schouten
3148009b1c42SEd Schouten return fs;
3149009b1c42SEd Schouten }
3150009b1c42SEd Schouten
convertFromStringSpecials(StringRef str)3151b915e9e0SDimitry Andric bool IEEEFloat::convertFromStringSpecials(StringRef str) {
3152cfca06d7SDimitry Andric const size_t MIN_NAME_SIZE = 3;
3153cfca06d7SDimitry Andric
3154cfca06d7SDimitry Andric if (str.size() < MIN_NAME_SIZE)
3155cfca06d7SDimitry Andric return false;
3156cfca06d7SDimitry Andric
3157ac9a064cSDimitry Andric if (str == "inf" || str == "INFINITY" || str == "+Inf") {
3158f8af5cf6SDimitry Andric makeInf(false);
3159f8af5cf6SDimitry Andric return true;
3160f8af5cf6SDimitry Andric }
3161f8af5cf6SDimitry Andric
3162cfca06d7SDimitry Andric bool IsNegative = str.front() == '-';
3163cfca06d7SDimitry Andric if (IsNegative) {
3164cfca06d7SDimitry Andric str = str.drop_front();
3165cfca06d7SDimitry Andric if (str.size() < MIN_NAME_SIZE)
3166cfca06d7SDimitry Andric return false;
3167cfca06d7SDimitry Andric
3168ac9a064cSDimitry Andric if (str == "inf" || str == "INFINITY" || str == "Inf") {
3169f8af5cf6SDimitry Andric makeInf(true);
3170f8af5cf6SDimitry Andric return true;
3171f8af5cf6SDimitry Andric }
3172cfca06d7SDimitry Andric }
3173f8af5cf6SDimitry Andric
3174cfca06d7SDimitry Andric // If we have a 's' (or 'S') prefix, then this is a Signaling NaN.
3175cfca06d7SDimitry Andric bool IsSignaling = str.front() == 's' || str.front() == 'S';
3176cfca06d7SDimitry Andric if (IsSignaling) {
3177cfca06d7SDimitry Andric str = str.drop_front();
3178cfca06d7SDimitry Andric if (str.size() < MIN_NAME_SIZE)
3179cfca06d7SDimitry Andric return false;
3180cfca06d7SDimitry Andric }
3181cfca06d7SDimitry Andric
3182b1c73532SDimitry Andric if (str.starts_with("nan") || str.starts_with("NaN")) {
3183cfca06d7SDimitry Andric str = str.drop_front(3);
3184cfca06d7SDimitry Andric
3185cfca06d7SDimitry Andric // A NaN without payload.
3186cfca06d7SDimitry Andric if (str.empty()) {
3187cfca06d7SDimitry Andric makeNaN(IsSignaling, IsNegative);
3188f8af5cf6SDimitry Andric return true;
3189f8af5cf6SDimitry Andric }
3190f8af5cf6SDimitry Andric
3191cfca06d7SDimitry Andric // Allow the payload to be inside parentheses.
3192cfca06d7SDimitry Andric if (str.front() == '(') {
3193cfca06d7SDimitry Andric // Parentheses should be balanced (and not empty).
3194cfca06d7SDimitry Andric if (str.size() <= 2 || str.back() != ')')
3195cfca06d7SDimitry Andric return false;
3196cfca06d7SDimitry Andric
3197cfca06d7SDimitry Andric str = str.slice(1, str.size() - 1);
3198cfca06d7SDimitry Andric }
3199cfca06d7SDimitry Andric
3200cfca06d7SDimitry Andric // Determine the payload number's radix.
3201cfca06d7SDimitry Andric unsigned Radix = 10;
3202cfca06d7SDimitry Andric if (str[0] == '0') {
3203cfca06d7SDimitry Andric if (str.size() > 1 && tolower(str[1]) == 'x') {
3204cfca06d7SDimitry Andric str = str.drop_front(2);
3205cfca06d7SDimitry Andric Radix = 16;
3206cfca06d7SDimitry Andric } else
3207cfca06d7SDimitry Andric Radix = 8;
3208cfca06d7SDimitry Andric }
3209cfca06d7SDimitry Andric
3210cfca06d7SDimitry Andric // Parse the payload and make the NaN.
3211cfca06d7SDimitry Andric APInt Payload;
3212cfca06d7SDimitry Andric if (!str.getAsInteger(Radix, Payload)) {
3213cfca06d7SDimitry Andric makeNaN(IsSignaling, IsNegative, &Payload);
3214f8af5cf6SDimitry Andric return true;
3215f8af5cf6SDimitry Andric }
3216cfca06d7SDimitry Andric }
3217f8af5cf6SDimitry Andric
3218f8af5cf6SDimitry Andric return false;
3219f8af5cf6SDimitry Andric }
3220f8af5cf6SDimitry Andric
3221706b4fc4SDimitry Andric Expected<IEEEFloat::opStatus>
convertFromString(StringRef str,roundingMode rounding_mode)3222706b4fc4SDimitry Andric IEEEFloat::convertFromString(StringRef str, roundingMode rounding_mode) {
3223706b4fc4SDimitry Andric if (str.empty())
3224706b4fc4SDimitry Andric return createError("Invalid string length");
3225009b1c42SEd Schouten
3226f8af5cf6SDimitry Andric // Handle special cases.
3227f8af5cf6SDimitry Andric if (convertFromStringSpecials(str))
3228f8af5cf6SDimitry Andric return opOK;
3229f8af5cf6SDimitry Andric
3230009b1c42SEd Schouten /* Handle a leading minus sign. */
323159850d08SRoman Divacky StringRef::iterator p = str.begin();
323259850d08SRoman Divacky size_t slen = str.size();
323359850d08SRoman Divacky sign = *p == '-' ? 1 : 0;
323459850d08SRoman Divacky if (*p == '-' || *p == '+') {
323559850d08SRoman Divacky p++;
323659850d08SRoman Divacky slen--;
3237706b4fc4SDimitry Andric if (!slen)
3238706b4fc4SDimitry Andric return createError("String has no digits");
323959850d08SRoman Divacky }
3240009b1c42SEd Schouten
324159850d08SRoman Divacky if (slen >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
3242706b4fc4SDimitry Andric if (slen == 2)
3243706b4fc4SDimitry Andric return createError("Invalid string");
324459850d08SRoman Divacky return convertFromHexadecimalString(StringRef(p + 2, slen - 2),
324559850d08SRoman Divacky rounding_mode);
324659850d08SRoman Divacky }
3247009b1c42SEd Schouten
324859850d08SRoman Divacky return convertFromDecimalString(StringRef(p, slen), rounding_mode);
3249009b1c42SEd Schouten }
3250009b1c42SEd Schouten
3251009b1c42SEd Schouten /* Write out a hexadecimal representation of the floating point value
3252009b1c42SEd Schouten to DST, which must be of sufficient size, in the C99 form
3253009b1c42SEd Schouten [-]0xh.hhhhp[+-]d. Return the number of characters written,
3254009b1c42SEd Schouten excluding the terminating NUL.
3255009b1c42SEd Schouten
3256009b1c42SEd Schouten If UPPERCASE, the output is in upper case, otherwise in lower case.
3257009b1c42SEd Schouten
3258009b1c42SEd Schouten HEXDIGITS digits appear altogether, rounding the value if
3259009b1c42SEd Schouten necessary. If HEXDIGITS is 0, the minimal precision to display the
3260009b1c42SEd Schouten number precisely is used instead. If nothing would appear after
3261009b1c42SEd Schouten the decimal point it is suppressed.
3262009b1c42SEd Schouten
3263009b1c42SEd Schouten The decimal exponent is always printed and has at least one digit.
3264009b1c42SEd Schouten Zero values display an exponent of zero. Infinities and NaNs
3265009b1c42SEd Schouten appear as "infinity" or "nan" respectively.
3266009b1c42SEd Schouten
3267009b1c42SEd Schouten The above rules are as specified by C99. There is ambiguity about
3268009b1c42SEd Schouten what the leading hexadecimal digit should be. This implementation
3269009b1c42SEd Schouten uses whatever is necessary so that the exponent is displayed as
3270009b1c42SEd Schouten stored. This implies the exponent will fall within the IEEE format
3271009b1c42SEd Schouten range, and the leading hexadecimal digit will be 0 (for denormals),
3272009b1c42SEd Schouten 1 (normal numbers) or 2 (normal numbers rounded-away-from-zero with
3273009b1c42SEd Schouten any other digits zero).
3274009b1c42SEd Schouten */
convertToHexString(char * dst,unsigned int hexDigits,bool upperCase,roundingMode rounding_mode) const3275b915e9e0SDimitry Andric unsigned int IEEEFloat::convertToHexString(char *dst, unsigned int hexDigits,
3276b915e9e0SDimitry Andric bool upperCase,
3277b915e9e0SDimitry Andric roundingMode rounding_mode) const {
3278009b1c42SEd Schouten char *p;
3279009b1c42SEd Schouten
3280009b1c42SEd Schouten p = dst;
3281009b1c42SEd Schouten if (sign)
3282009b1c42SEd Schouten *dst++ = '-';
3283009b1c42SEd Schouten
3284009b1c42SEd Schouten switch (category) {
3285009b1c42SEd Schouten case fcInfinity:
3286009b1c42SEd Schouten memcpy (dst, upperCase ? infinityU: infinityL, sizeof infinityU - 1);
3287009b1c42SEd Schouten dst += sizeof infinityL - 1;
3288009b1c42SEd Schouten break;
3289009b1c42SEd Schouten
3290009b1c42SEd Schouten case fcNaN:
3291009b1c42SEd Schouten memcpy (dst, upperCase ? NaNU: NaNL, sizeof NaNU - 1);
3292009b1c42SEd Schouten dst += sizeof NaNU - 1;
3293009b1c42SEd Schouten break;
3294009b1c42SEd Schouten
3295009b1c42SEd Schouten case fcZero:
3296009b1c42SEd Schouten *dst++ = '0';
3297009b1c42SEd Schouten *dst++ = upperCase ? 'X': 'x';
3298009b1c42SEd Schouten *dst++ = '0';
3299009b1c42SEd Schouten if (hexDigits > 1) {
3300009b1c42SEd Schouten *dst++ = '.';
3301009b1c42SEd Schouten memset (dst, '0', hexDigits - 1);
3302009b1c42SEd Schouten dst += hexDigits - 1;
3303009b1c42SEd Schouten }
3304009b1c42SEd Schouten *dst++ = upperCase ? 'P': 'p';
3305009b1c42SEd Schouten *dst++ = '0';
3306009b1c42SEd Schouten break;
3307009b1c42SEd Schouten
3308009b1c42SEd Schouten case fcNormal:
3309009b1c42SEd Schouten dst = convertNormalToHexString (dst, hexDigits, upperCase, rounding_mode);
3310009b1c42SEd Schouten break;
3311009b1c42SEd Schouten }
3312009b1c42SEd Schouten
3313009b1c42SEd Schouten *dst = 0;
3314009b1c42SEd Schouten
3315009b1c42SEd Schouten return static_cast<unsigned int>(dst - p);
3316009b1c42SEd Schouten }
3317009b1c42SEd Schouten
3318009b1c42SEd Schouten /* Does the hard work of outputting the correctly rounded hexadecimal
3319009b1c42SEd Schouten form of a normal floating point number with the specified number of
3320009b1c42SEd Schouten hexadecimal digits. If HEXDIGITS is zero the minimum number of
3321009b1c42SEd Schouten digits necessary to print the value precisely is output. */
convertNormalToHexString(char * dst,unsigned int hexDigits,bool upperCase,roundingMode rounding_mode) const3322b915e9e0SDimitry Andric char *IEEEFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
3323009b1c42SEd Schouten bool upperCase,
3324b915e9e0SDimitry Andric roundingMode rounding_mode) const {
3325009b1c42SEd Schouten unsigned int count, valueBits, shift, partsCount, outputDigits;
3326009b1c42SEd Schouten const char *hexDigitChars;
3327009b1c42SEd Schouten const integerPart *significand;
3328009b1c42SEd Schouten char *p;
3329009b1c42SEd Schouten bool roundUp;
3330009b1c42SEd Schouten
3331009b1c42SEd Schouten *dst++ = '0';
3332009b1c42SEd Schouten *dst++ = upperCase ? 'X': 'x';
3333009b1c42SEd Schouten
3334009b1c42SEd Schouten roundUp = false;
3335009b1c42SEd Schouten hexDigitChars = upperCase ? hexDigitsUpper: hexDigitsLower;
3336009b1c42SEd Schouten
3337009b1c42SEd Schouten significand = significandParts();
3338009b1c42SEd Schouten partsCount = partCount();
3339009b1c42SEd Schouten
3340009b1c42SEd Schouten /* +3 because the first digit only uses the single integer bit, so
3341009b1c42SEd Schouten we have 3 virtual zero most-significant-bits. */
3342009b1c42SEd Schouten valueBits = semantics->precision + 3;
3343009b1c42SEd Schouten shift = integerPartWidth - valueBits % integerPartWidth;
3344009b1c42SEd Schouten
3345009b1c42SEd Schouten /* The natural number of digits required ignoring trailing
3346009b1c42SEd Schouten insignificant zeroes. */
3347009b1c42SEd Schouten outputDigits = (valueBits - significandLSB () + 3) / 4;
3348009b1c42SEd Schouten
3349009b1c42SEd Schouten /* hexDigits of zero means use the required number for the
3350009b1c42SEd Schouten precision. Otherwise, see if we are truncating. If we are,
3351009b1c42SEd Schouten find out if we need to round away from zero. */
3352009b1c42SEd Schouten if (hexDigits) {
3353009b1c42SEd Schouten if (hexDigits < outputDigits) {
3354009b1c42SEd Schouten /* We are dropping non-zero bits, so need to check how to round.
3355009b1c42SEd Schouten "bits" is the number of dropped bits. */
3356009b1c42SEd Schouten unsigned int bits;
3357009b1c42SEd Schouten lostFraction fraction;
3358009b1c42SEd Schouten
3359009b1c42SEd Schouten bits = valueBits - hexDigits * 4;
3360009b1c42SEd Schouten fraction = lostFractionThroughTruncation (significand, partsCount, bits);
3361009b1c42SEd Schouten roundUp = roundAwayFromZero(rounding_mode, fraction, bits);
3362009b1c42SEd Schouten }
3363009b1c42SEd Schouten outputDigits = hexDigits;
3364009b1c42SEd Schouten }
3365009b1c42SEd Schouten
3366009b1c42SEd Schouten /* Write the digits consecutively, and start writing in the location
3367009b1c42SEd Schouten of the hexadecimal point. We move the most significant digit
3368009b1c42SEd Schouten left and add the hexadecimal point later. */
3369009b1c42SEd Schouten p = ++dst;
3370009b1c42SEd Schouten
3371009b1c42SEd Schouten count = (valueBits + integerPartWidth - 1) / integerPartWidth;
3372009b1c42SEd Schouten
3373009b1c42SEd Schouten while (outputDigits && count) {
3374009b1c42SEd Schouten integerPart part;
3375009b1c42SEd Schouten
3376009b1c42SEd Schouten /* Put the most significant integerPartWidth bits in "part". */
3377009b1c42SEd Schouten if (--count == partsCount)
3378009b1c42SEd Schouten part = 0; /* An imaginary higher zero part. */
3379009b1c42SEd Schouten else
3380009b1c42SEd Schouten part = significand[count] << shift;
3381009b1c42SEd Schouten
3382009b1c42SEd Schouten if (count && shift)
3383009b1c42SEd Schouten part |= significand[count - 1] >> (integerPartWidth - shift);
3384009b1c42SEd Schouten
3385009b1c42SEd Schouten /* Convert as much of "part" to hexdigits as we can. */
3386009b1c42SEd Schouten unsigned int curDigits = integerPartWidth / 4;
3387009b1c42SEd Schouten
3388009b1c42SEd Schouten if (curDigits > outputDigits)
3389009b1c42SEd Schouten curDigits = outputDigits;
3390009b1c42SEd Schouten dst += partAsHex (dst, part, curDigits, hexDigitChars);
3391009b1c42SEd Schouten outputDigits -= curDigits;
3392009b1c42SEd Schouten }
3393009b1c42SEd Schouten
3394009b1c42SEd Schouten if (roundUp) {
3395009b1c42SEd Schouten char *q = dst;
3396009b1c42SEd Schouten
3397009b1c42SEd Schouten /* Note that hexDigitChars has a trailing '0'. */
3398009b1c42SEd Schouten do {
3399009b1c42SEd Schouten q--;
3400009b1c42SEd Schouten *q = hexDigitChars[hexDigitValue (*q) + 1];
3401009b1c42SEd Schouten } while (*q == '0');
3402009b1c42SEd Schouten assert(q >= p);
3403009b1c42SEd Schouten } else {
3404009b1c42SEd Schouten /* Add trailing zeroes. */
3405009b1c42SEd Schouten memset (dst, '0', outputDigits);
3406009b1c42SEd Schouten dst += outputDigits;
3407009b1c42SEd Schouten }
3408009b1c42SEd Schouten
3409009b1c42SEd Schouten /* Move the most significant digit to before the point, and if there
3410009b1c42SEd Schouten is something after the decimal point add it. This must come
3411009b1c42SEd Schouten after rounding above. */
3412009b1c42SEd Schouten p[-1] = p[0];
3413009b1c42SEd Schouten if (dst -1 == p)
3414009b1c42SEd Schouten dst--;
3415009b1c42SEd Schouten else
3416009b1c42SEd Schouten p[0] = '.';
3417009b1c42SEd Schouten
3418009b1c42SEd Schouten /* Finally output the exponent. */
3419009b1c42SEd Schouten *dst++ = upperCase ? 'P': 'p';
3420009b1c42SEd Schouten
3421009b1c42SEd Schouten return writeSignedDecimal (dst, exponent);
3422009b1c42SEd Schouten }
3423009b1c42SEd Schouten
hash_value(const IEEEFloat & Arg)3424b915e9e0SDimitry Andric hash_code hash_value(const IEEEFloat &Arg) {
3425f8af5cf6SDimitry Andric if (!Arg.isFiniteNonZero())
342663faed5bSDimitry Andric return hash_combine((uint8_t)Arg.category,
342763faed5bSDimitry Andric // NaN has no sign, fix it at zero.
342863faed5bSDimitry Andric Arg.isNaN() ? (uint8_t)0 : (uint8_t)Arg.sign,
342963faed5bSDimitry Andric Arg.semantics->precision);
343063faed5bSDimitry Andric
343163faed5bSDimitry Andric // Normal floats need their exponent and significand hashed.
343263faed5bSDimitry Andric return hash_combine((uint8_t)Arg.category, (uint8_t)Arg.sign,
343363faed5bSDimitry Andric Arg.semantics->precision, Arg.exponent,
343463faed5bSDimitry Andric hash_combine_range(
343563faed5bSDimitry Andric Arg.significandParts(),
343663faed5bSDimitry Andric Arg.significandParts() + Arg.partCount()));
3437009b1c42SEd Schouten }
3438009b1c42SEd Schouten
3439009b1c42SEd Schouten // Conversion from APFloat to/from host float/double. It may eventually be
3440009b1c42SEd Schouten // possible to eliminate these and have everybody deal with APFloats, but that
3441009b1c42SEd Schouten // will take a while. This approach will not easily extend to long double.
3442009b1c42SEd Schouten // Current implementation requires integerPartWidth==64, which is correct at
3443009b1c42SEd Schouten // the moment but could be made more general.
3444009b1c42SEd Schouten
3445009b1c42SEd Schouten // Denormals have exponent minExponent in APFloat, but minExponent-1 in
3446009b1c42SEd Schouten // the actual IEEE respresentations. We compensate for that here.
3447009b1c42SEd Schouten
convertF80LongDoubleAPFloatToAPInt() const3448b915e9e0SDimitry Andric APInt IEEEFloat::convertF80LongDoubleAPFloatToAPInt() const {
3449b915e9e0SDimitry Andric assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended);
3450009b1c42SEd Schouten assert(partCount()==2);
3451009b1c42SEd Schouten
3452009b1c42SEd Schouten uint64_t myexponent, mysignificand;
3453009b1c42SEd Schouten
3454f8af5cf6SDimitry Andric if (isFiniteNonZero()) {
3455009b1c42SEd Schouten myexponent = exponent+16383; //bias
3456009b1c42SEd Schouten mysignificand = significandParts()[0];
3457009b1c42SEd Schouten if (myexponent==1 && !(mysignificand & 0x8000000000000000ULL))
3458009b1c42SEd Schouten myexponent = 0; // denormal
3459009b1c42SEd Schouten } else if (category==fcZero) {
3460009b1c42SEd Schouten myexponent = 0;
3461009b1c42SEd Schouten mysignificand = 0;
3462009b1c42SEd Schouten } else if (category==fcInfinity) {
3463009b1c42SEd Schouten myexponent = 0x7fff;
3464009b1c42SEd Schouten mysignificand = 0x8000000000000000ULL;
3465009b1c42SEd Schouten } else {
3466009b1c42SEd Schouten assert(category == fcNaN && "Unknown category");
3467009b1c42SEd Schouten myexponent = 0x7fff;
3468009b1c42SEd Schouten mysignificand = significandParts()[0];
3469009b1c42SEd Schouten }
3470009b1c42SEd Schouten
3471009b1c42SEd Schouten uint64_t words[2];
3472009b1c42SEd Schouten words[0] = mysignificand;
3473009b1c42SEd Schouten words[1] = ((uint64_t)(sign & 1) << 15) |
3474009b1c42SEd Schouten (myexponent & 0x7fffLL);
347530815c53SDimitry Andric return APInt(80, words);
3476009b1c42SEd Schouten }
3477009b1c42SEd Schouten
convertPPCDoubleDoubleAPFloatToAPInt() const3478b915e9e0SDimitry Andric APInt IEEEFloat::convertPPCDoubleDoubleAPFloatToAPInt() const {
347971d5a254SDimitry Andric assert(semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy);
3480009b1c42SEd Schouten assert(partCount()==2);
3481009b1c42SEd Schouten
3482522600a2SDimitry Andric uint64_t words[2];
3483522600a2SDimitry Andric opStatus fs;
3484522600a2SDimitry Andric bool losesInfo;
3485009b1c42SEd Schouten
3486522600a2SDimitry Andric // Convert number to double. To avoid spurious underflows, we re-
3487522600a2SDimitry Andric // normalize against the "double" minExponent first, and only *then*
3488522600a2SDimitry Andric // truncate the mantissa. The result of that second conversion
3489522600a2SDimitry Andric // may be inexact, but should never underflow.
34904a16efa3SDimitry Andric // Declare fltSemantics before APFloat that uses it (and
34914a16efa3SDimitry Andric // saves pointer to it) to ensure correct destruction order.
3492522600a2SDimitry Andric fltSemantics extendedSemantics = *semantics;
3493b915e9e0SDimitry Andric extendedSemantics.minExponent = semIEEEdouble.minExponent;
3494b915e9e0SDimitry Andric IEEEFloat extended(*this);
3495522600a2SDimitry Andric fs = extended.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
3496522600a2SDimitry Andric assert(fs == opOK && !losesInfo);
3497522600a2SDimitry Andric (void)fs;
3498522600a2SDimitry Andric
3499b915e9e0SDimitry Andric IEEEFloat u(extended);
3500b915e9e0SDimitry Andric fs = u.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo);
3501522600a2SDimitry Andric assert(fs == opOK || fs == opInexact);
3502522600a2SDimitry Andric (void)fs;
3503522600a2SDimitry Andric words[0] = *u.convertDoubleAPFloatToAPInt().getRawData();
3504522600a2SDimitry Andric
3505522600a2SDimitry Andric // If conversion was exact or resulted in a special case, we're done;
3506522600a2SDimitry Andric // just set the second double to zero. Otherwise, re-convert back to
3507522600a2SDimitry Andric // the extended format and compute the difference. This now should
3508522600a2SDimitry Andric // convert exactly to double.
3509f8af5cf6SDimitry Andric if (u.isFiniteNonZero() && losesInfo) {
3510522600a2SDimitry Andric fs = u.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
3511522600a2SDimitry Andric assert(fs == opOK && !losesInfo);
3512522600a2SDimitry Andric (void)fs;
3513522600a2SDimitry Andric
3514b915e9e0SDimitry Andric IEEEFloat v(extended);
3515522600a2SDimitry Andric v.subtract(u, rmNearestTiesToEven);
3516b915e9e0SDimitry Andric fs = v.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo);
3517522600a2SDimitry Andric assert(fs == opOK && !losesInfo);
3518522600a2SDimitry Andric (void)fs;
3519522600a2SDimitry Andric words[1] = *v.convertDoubleAPFloatToAPInt().getRawData();
3520009b1c42SEd Schouten } else {
3521522600a2SDimitry Andric words[1] = 0;
3522009b1c42SEd Schouten }
3523009b1c42SEd Schouten
352430815c53SDimitry Andric return APInt(128, words);
3525009b1c42SEd Schouten }
3526009b1c42SEd Schouten
35277fa27ce4SDimitry Andric template <const fltSemantics &S>
convertIEEEFloatToAPInt() const35287fa27ce4SDimitry Andric APInt IEEEFloat::convertIEEEFloatToAPInt() const {
35297fa27ce4SDimitry Andric assert(semantics == &S);
353059850d08SRoman Divacky
35317fa27ce4SDimitry Andric constexpr int bias = -(S.minExponent - 1);
35327fa27ce4SDimitry Andric constexpr unsigned int trailing_significand_bits = S.precision - 1;
35337fa27ce4SDimitry Andric constexpr int integer_bit_part = trailing_significand_bits / integerPartWidth;
35347fa27ce4SDimitry Andric constexpr integerPart integer_bit =
35357fa27ce4SDimitry Andric integerPart{1} << (trailing_significand_bits % integerPartWidth);
35367fa27ce4SDimitry Andric constexpr uint64_t significand_mask = integer_bit - 1;
35377fa27ce4SDimitry Andric constexpr unsigned int exponent_bits =
35387fa27ce4SDimitry Andric S.sizeInBits - 1 - trailing_significand_bits;
35397fa27ce4SDimitry Andric static_assert(exponent_bits < 64);
35407fa27ce4SDimitry Andric constexpr uint64_t exponent_mask = (uint64_t{1} << exponent_bits) - 1;
35417fa27ce4SDimitry Andric
35427fa27ce4SDimitry Andric uint64_t myexponent;
35437fa27ce4SDimitry Andric std::array<integerPart, partCountForBits(trailing_significand_bits)>
35447fa27ce4SDimitry Andric mysignificand;
354559850d08SRoman Divacky
3546f8af5cf6SDimitry Andric if (isFiniteNonZero()) {
35477fa27ce4SDimitry Andric myexponent = exponent + bias;
35487fa27ce4SDimitry Andric std::copy_n(significandParts(), mysignificand.size(),
35497fa27ce4SDimitry Andric mysignificand.begin());
35507fa27ce4SDimitry Andric if (myexponent == 1 &&
35517fa27ce4SDimitry Andric !(significandParts()[integer_bit_part] & integer_bit))
355259850d08SRoman Divacky myexponent = 0; // denormal
355359850d08SRoman Divacky } else if (category == fcZero) {
35547fa27ce4SDimitry Andric myexponent = ::exponentZero(S) + bias;
35557fa27ce4SDimitry Andric mysignificand.fill(0);
355659850d08SRoman Divacky } else if (category == fcInfinity) {
3557ac9a064cSDimitry Andric if (S.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly ||
3558ac9a064cSDimitry Andric S.nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
35597fa27ce4SDimitry Andric llvm_unreachable("semantics don't support inf!");
35607fa27ce4SDimitry Andric myexponent = ::exponentInf(S) + bias;
35617fa27ce4SDimitry Andric mysignificand.fill(0);
356259850d08SRoman Divacky } else {
356359850d08SRoman Divacky assert(category == fcNaN && "Unknown category!");
3564ac9a064cSDimitry Andric if (S.nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
3565ac9a064cSDimitry Andric llvm_unreachable("semantics don't support NaN!");
35667fa27ce4SDimitry Andric myexponent = ::exponentNaN(S) + bias;
35677fa27ce4SDimitry Andric std::copy_n(significandParts(), mysignificand.size(),
35687fa27ce4SDimitry Andric mysignificand.begin());
35697fa27ce4SDimitry Andric }
35707fa27ce4SDimitry Andric std::array<uint64_t, (S.sizeInBits + 63) / 64> words;
35717fa27ce4SDimitry Andric auto words_iter =
35727fa27ce4SDimitry Andric std::copy_n(mysignificand.begin(), mysignificand.size(), words.begin());
35737fa27ce4SDimitry Andric if constexpr (significand_mask != 0) {
35747fa27ce4SDimitry Andric // Clear the integer bit.
35757fa27ce4SDimitry Andric words[mysignificand.size() - 1] &= significand_mask;
35767fa27ce4SDimitry Andric }
35777fa27ce4SDimitry Andric std::fill(words_iter, words.end(), uint64_t{0});
35787fa27ce4SDimitry Andric constexpr size_t last_word = words.size() - 1;
35797fa27ce4SDimitry Andric uint64_t shifted_sign = static_cast<uint64_t>(sign & 1)
35807fa27ce4SDimitry Andric << ((S.sizeInBits - 1) % 64);
35817fa27ce4SDimitry Andric words[last_word] |= shifted_sign;
35827fa27ce4SDimitry Andric uint64_t shifted_exponent = (myexponent & exponent_mask)
35837fa27ce4SDimitry Andric << (trailing_significand_bits % 64);
35847fa27ce4SDimitry Andric words[last_word] |= shifted_exponent;
35857fa27ce4SDimitry Andric if constexpr (last_word == 0) {
35867fa27ce4SDimitry Andric return APInt(S.sizeInBits, words[0]);
35877fa27ce4SDimitry Andric }
35887fa27ce4SDimitry Andric return APInt(S.sizeInBits, words);
358959850d08SRoman Divacky }
359059850d08SRoman Divacky
convertQuadrupleAPFloatToAPInt() const35917fa27ce4SDimitry Andric APInt IEEEFloat::convertQuadrupleAPFloatToAPInt() const {
35927fa27ce4SDimitry Andric assert(partCount() == 2);
35937fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semIEEEquad>();
359459850d08SRoman Divacky }
359559850d08SRoman Divacky
convertDoubleAPFloatToAPInt() const3596b915e9e0SDimitry Andric APInt IEEEFloat::convertDoubleAPFloatToAPInt() const {
3597009b1c42SEd Schouten assert(partCount()==1);
35987fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semIEEEdouble>();
3599009b1c42SEd Schouten }
3600009b1c42SEd Schouten
convertFloatAPFloatToAPInt() const3601b915e9e0SDimitry Andric APInt IEEEFloat::convertFloatAPFloatToAPInt() const {
3602009b1c42SEd Schouten assert(partCount()==1);
36037fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semIEEEsingle>();
3604009b1c42SEd Schouten }
3605009b1c42SEd Schouten
convertBFloatAPFloatToAPInt() const3606cfca06d7SDimitry Andric APInt IEEEFloat::convertBFloatAPFloatToAPInt() const {
3607cfca06d7SDimitry Andric assert(partCount() == 1);
36087fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semBFloat>();
3609cfca06d7SDimitry Andric }
3610cfca06d7SDimitry Andric
convertHalfAPFloatToAPInt() const3611b915e9e0SDimitry Andric APInt IEEEFloat::convertHalfAPFloatToAPInt() const {
36124a142eb2SRoman Divacky assert(partCount()==1);
36137fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semIEEEhalf>();
36144a142eb2SRoman Divacky }
36154a142eb2SRoman Divacky
convertFloat8E5M2APFloatToAPInt() const3616e3b55780SDimitry Andric APInt IEEEFloat::convertFloat8E5M2APFloatToAPInt() const {
3617e3b55780SDimitry Andric assert(partCount() == 1);
36187fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E5M2>();
3619e3b55780SDimitry Andric }
3620e3b55780SDimitry Andric
convertFloat8E5M2FNUZAPFloatToAPInt() const36217fa27ce4SDimitry Andric APInt IEEEFloat::convertFloat8E5M2FNUZAPFloatToAPInt() const {
36227fa27ce4SDimitry Andric assert(partCount() == 1);
36237fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E5M2FNUZ>();
3624e3b55780SDimitry Andric }
3625e3b55780SDimitry Andric
convertFloat8E4M3APFloatToAPInt() const3626ac9a064cSDimitry Andric APInt IEEEFloat::convertFloat8E4M3APFloatToAPInt() const {
3627ac9a064cSDimitry Andric assert(partCount() == 1);
3628ac9a064cSDimitry Andric return convertIEEEFloatToAPInt<semFloat8E4M3>();
3629ac9a064cSDimitry Andric }
3630ac9a064cSDimitry Andric
convertFloat8E4M3FNAPFloatToAPInt() const3631e3b55780SDimitry Andric APInt IEEEFloat::convertFloat8E4M3FNAPFloatToAPInt() const {
3632e3b55780SDimitry Andric assert(partCount() == 1);
36337fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E4M3FN>();
3634e3b55780SDimitry Andric }
3635e3b55780SDimitry Andric
convertFloat8E4M3FNUZAPFloatToAPInt() const36367fa27ce4SDimitry Andric APInt IEEEFloat::convertFloat8E4M3FNUZAPFloatToAPInt() const {
36377fa27ce4SDimitry Andric assert(partCount() == 1);
36387fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E4M3FNUZ>();
36397fa27ce4SDimitry Andric }
36407fa27ce4SDimitry Andric
convertFloat8E4M3B11FNUZAPFloatToAPInt() const36417fa27ce4SDimitry Andric APInt IEEEFloat::convertFloat8E4M3B11FNUZAPFloatToAPInt() const {
36427fa27ce4SDimitry Andric assert(partCount() == 1);
36437fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E4M3B11FNUZ>();
36447fa27ce4SDimitry Andric }
36457fa27ce4SDimitry Andric
convertFloatTF32APFloatToAPInt() const36467fa27ce4SDimitry Andric APInt IEEEFloat::convertFloatTF32APFloatToAPInt() const {
36477fa27ce4SDimitry Andric assert(partCount() == 1);
36487fa27ce4SDimitry Andric return convertIEEEFloatToAPInt<semFloatTF32>();
3649e3b55780SDimitry Andric }
3650e3b55780SDimitry Andric
convertFloat6E3M2FNAPFloatToAPInt() const3651ac9a064cSDimitry Andric APInt IEEEFloat::convertFloat6E3M2FNAPFloatToAPInt() const {
3652ac9a064cSDimitry Andric assert(partCount() == 1);
3653ac9a064cSDimitry Andric return convertIEEEFloatToAPInt<semFloat6E3M2FN>();
3654ac9a064cSDimitry Andric }
3655ac9a064cSDimitry Andric
convertFloat6E2M3FNAPFloatToAPInt() const3656ac9a064cSDimitry Andric APInt IEEEFloat::convertFloat6E2M3FNAPFloatToAPInt() const {
3657ac9a064cSDimitry Andric assert(partCount() == 1);
3658ac9a064cSDimitry Andric return convertIEEEFloatToAPInt<semFloat6E2M3FN>();
3659ac9a064cSDimitry Andric }
3660ac9a064cSDimitry Andric
convertFloat4E2M1FNAPFloatToAPInt() const3661ac9a064cSDimitry Andric APInt IEEEFloat::convertFloat4E2M1FNAPFloatToAPInt() const {
3662ac9a064cSDimitry Andric assert(partCount() == 1);
3663ac9a064cSDimitry Andric return convertIEEEFloatToAPInt<semFloat4E2M1FN>();
3664ac9a064cSDimitry Andric }
3665ac9a064cSDimitry Andric
3666009b1c42SEd Schouten // This function creates an APInt that is just a bit map of the floating
3667009b1c42SEd Schouten // point constant as it would appear in memory. It is not a conversion,
3668009b1c42SEd Schouten // and treating the result as a normal integer is unlikely to be useful.
3669009b1c42SEd Schouten
bitcastToAPInt() const3670b915e9e0SDimitry Andric APInt IEEEFloat::bitcastToAPInt() const {
3671b915e9e0SDimitry Andric if (semantics == (const llvm::fltSemantics*)&semIEEEhalf)
36724a142eb2SRoman Divacky return convertHalfAPFloatToAPInt();
36734a142eb2SRoman Divacky
3674cfca06d7SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semBFloat)
3675cfca06d7SDimitry Andric return convertBFloatAPFloatToAPInt();
3676cfca06d7SDimitry Andric
3677b915e9e0SDimitry Andric if (semantics == (const llvm::fltSemantics*)&semIEEEsingle)
3678009b1c42SEd Schouten return convertFloatAPFloatToAPInt();
3679009b1c42SEd Schouten
3680b915e9e0SDimitry Andric if (semantics == (const llvm::fltSemantics*)&semIEEEdouble)
3681009b1c42SEd Schouten return convertDoubleAPFloatToAPInt();
3682009b1c42SEd Schouten
3683b915e9e0SDimitry Andric if (semantics == (const llvm::fltSemantics*)&semIEEEquad)
368459850d08SRoman Divacky return convertQuadrupleAPFloatToAPInt();
368559850d08SRoman Divacky
368671d5a254SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy)
3687009b1c42SEd Schouten return convertPPCDoubleDoubleAPFloatToAPInt();
3688009b1c42SEd Schouten
3689e3b55780SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E5M2)
3690e3b55780SDimitry Andric return convertFloat8E5M2APFloatToAPInt();
3691e3b55780SDimitry Andric
36927fa27ce4SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E5M2FNUZ)
36937fa27ce4SDimitry Andric return convertFloat8E5M2FNUZAPFloatToAPInt();
36947fa27ce4SDimitry Andric
3695ac9a064cSDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3)
3696ac9a064cSDimitry Andric return convertFloat8E4M3APFloatToAPInt();
3697ac9a064cSDimitry Andric
3698e3b55780SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3FN)
3699e3b55780SDimitry Andric return convertFloat8E4M3FNAPFloatToAPInt();
3700e3b55780SDimitry Andric
37017fa27ce4SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3FNUZ)
37027fa27ce4SDimitry Andric return convertFloat8E4M3FNUZAPFloatToAPInt();
37037fa27ce4SDimitry Andric
37047fa27ce4SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3B11FNUZ)
37057fa27ce4SDimitry Andric return convertFloat8E4M3B11FNUZAPFloatToAPInt();
37067fa27ce4SDimitry Andric
37077fa27ce4SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloatTF32)
37087fa27ce4SDimitry Andric return convertFloatTF32APFloatToAPInt();
37097fa27ce4SDimitry Andric
3710ac9a064cSDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat6E3M2FN)
3711ac9a064cSDimitry Andric return convertFloat6E3M2FNAPFloatToAPInt();
3712ac9a064cSDimitry Andric
3713ac9a064cSDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat6E2M3FN)
3714ac9a064cSDimitry Andric return convertFloat6E2M3FNAPFloatToAPInt();
3715ac9a064cSDimitry Andric
3716ac9a064cSDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat4E2M1FN)
3717ac9a064cSDimitry Andric return convertFloat4E2M1FNAPFloatToAPInt();
3718ac9a064cSDimitry Andric
3719b915e9e0SDimitry Andric assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended &&
3720009b1c42SEd Schouten "unknown format!");
3721009b1c42SEd Schouten return convertF80LongDoubleAPFloatToAPInt();
3722009b1c42SEd Schouten }
3723009b1c42SEd Schouten
convertToFloat() const3724b915e9e0SDimitry Andric float IEEEFloat::convertToFloat() const {
3725b915e9e0SDimitry Andric assert(semantics == (const llvm::fltSemantics*)&semIEEEsingle &&
372659850d08SRoman Divacky "Float semantics are not IEEEsingle");
3727009b1c42SEd Schouten APInt api = bitcastToAPInt();
3728009b1c42SEd Schouten return api.bitsToFloat();
3729009b1c42SEd Schouten }
3730009b1c42SEd Schouten
convertToDouble() const3731b915e9e0SDimitry Andric double IEEEFloat::convertToDouble() const {
3732b915e9e0SDimitry Andric assert(semantics == (const llvm::fltSemantics*)&semIEEEdouble &&
373359850d08SRoman Divacky "Float semantics are not IEEEdouble");
3734009b1c42SEd Schouten APInt api = bitcastToAPInt();
3735009b1c42SEd Schouten return api.bitsToDouble();
3736009b1c42SEd Schouten }
3737009b1c42SEd Schouten
3738ac9a064cSDimitry Andric #ifdef HAS_IEE754_FLOAT128
convertToQuad() const3739ac9a064cSDimitry Andric float128 IEEEFloat::convertToQuad() const {
3740ac9a064cSDimitry Andric assert(semantics == (const llvm::fltSemantics *)&semIEEEquad &&
3741ac9a064cSDimitry Andric "Float semantics are not IEEEquads");
3742ac9a064cSDimitry Andric APInt api = bitcastToAPInt();
3743ac9a064cSDimitry Andric return api.bitsToQuad();
3744ac9a064cSDimitry Andric }
3745ac9a064cSDimitry Andric #endif
3746ac9a064cSDimitry Andric
3747009b1c42SEd Schouten /// Integer bit is explicit in this format. Intel hardware (387 and later)
3748009b1c42SEd Schouten /// does not support these bit patterns:
3749009b1c42SEd Schouten /// exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity")
3750009b1c42SEd Schouten /// exponent = all 1's, integer bit 0, significand nonzero ("pseudoNaN")
3751009b1c42SEd Schouten /// exponent!=0 nor all 1's, integer bit 0 ("unnormal")
3752eb11fae6SDimitry Andric /// exponent = 0, integer bit 1 ("pseudodenormal")
3753eb11fae6SDimitry Andric /// At the moment, the first three are treated as NaNs, the last one as Normal.
initFromF80LongDoubleAPInt(const APInt & api)3754b915e9e0SDimitry Andric void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) {
3755009b1c42SEd Schouten uint64_t i1 = api.getRawData()[0];
3756009b1c42SEd Schouten uint64_t i2 = api.getRawData()[1];
3757009b1c42SEd Schouten uint64_t myexponent = (i2 & 0x7fff);
3758009b1c42SEd Schouten uint64_t mysignificand = i1;
3759eb11fae6SDimitry Andric uint8_t myintegerbit = mysignificand >> 63;
3760009b1c42SEd Schouten
3761b915e9e0SDimitry Andric initialize(&semX87DoubleExtended);
3762009b1c42SEd Schouten assert(partCount()==2);
3763009b1c42SEd Schouten
3764009b1c42SEd Schouten sign = static_cast<unsigned int>(i2>>15);
3765009b1c42SEd Schouten if (myexponent == 0 && mysignificand == 0) {
3766b60736ecSDimitry Andric makeZero(sign);
3767009b1c42SEd Schouten } else if (myexponent==0x7fff && mysignificand==0x8000000000000000ULL) {
3768b60736ecSDimitry Andric makeInf(sign);
3769eb11fae6SDimitry Andric } else if ((myexponent == 0x7fff && mysignificand != 0x8000000000000000ULL) ||
3770eb11fae6SDimitry Andric (myexponent != 0x7fff && myexponent != 0 && myintegerbit == 0)) {
3771009b1c42SEd Schouten category = fcNaN;
3772b60736ecSDimitry Andric exponent = exponentNaN();
3773009b1c42SEd Schouten significandParts()[0] = mysignificand;
3774009b1c42SEd Schouten significandParts()[1] = 0;
3775009b1c42SEd Schouten } else {
3776009b1c42SEd Schouten category = fcNormal;
3777009b1c42SEd Schouten exponent = myexponent - 16383;
3778009b1c42SEd Schouten significandParts()[0] = mysignificand;
3779009b1c42SEd Schouten significandParts()[1] = 0;
3780009b1c42SEd Schouten if (myexponent==0) // denormal
3781009b1c42SEd Schouten exponent = -16382;
3782009b1c42SEd Schouten }
3783009b1c42SEd Schouten }
3784009b1c42SEd Schouten
initFromPPCDoubleDoubleAPInt(const APInt & api)3785b915e9e0SDimitry Andric void IEEEFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) {
3786009b1c42SEd Schouten uint64_t i1 = api.getRawData()[0];
3787009b1c42SEd Schouten uint64_t i2 = api.getRawData()[1];
3788522600a2SDimitry Andric opStatus fs;
3789522600a2SDimitry Andric bool losesInfo;
3790009b1c42SEd Schouten
3791522600a2SDimitry Andric // Get the first double and convert to our format.
3792522600a2SDimitry Andric initFromDoubleAPInt(APInt(64, i1));
379371d5a254SDimitry Andric fs = convert(semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo);
3794522600a2SDimitry Andric assert(fs == opOK && !losesInfo);
3795522600a2SDimitry Andric (void)fs;
3796009b1c42SEd Schouten
3797522600a2SDimitry Andric // Unless we have a special case, add in second double.
3798f8af5cf6SDimitry Andric if (isFiniteNonZero()) {
3799b915e9e0SDimitry Andric IEEEFloat v(semIEEEdouble, APInt(64, i2));
380071d5a254SDimitry Andric fs = v.convert(semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo);
3801522600a2SDimitry Andric assert(fs == opOK && !losesInfo);
3802522600a2SDimitry Andric (void)fs;
3803522600a2SDimitry Andric
3804522600a2SDimitry Andric add(v, rmNearestTiesToEven);
3805009b1c42SEd Schouten }
3806009b1c42SEd Schouten }
3807009b1c42SEd Schouten
38087fa27ce4SDimitry Andric template <const fltSemantics &S>
initFromIEEEAPInt(const APInt & api)38097fa27ce4SDimitry Andric void IEEEFloat::initFromIEEEAPInt(const APInt &api) {
38107fa27ce4SDimitry Andric assert(api.getBitWidth() == S.sizeInBits);
38117fa27ce4SDimitry Andric constexpr integerPart integer_bit = integerPart{1}
38127fa27ce4SDimitry Andric << ((S.precision - 1) % integerPartWidth);
38137fa27ce4SDimitry Andric constexpr uint64_t significand_mask = integer_bit - 1;
38147fa27ce4SDimitry Andric constexpr unsigned int trailing_significand_bits = S.precision - 1;
38157fa27ce4SDimitry Andric constexpr unsigned int stored_significand_parts =
38167fa27ce4SDimitry Andric partCountForBits(trailing_significand_bits);
38177fa27ce4SDimitry Andric constexpr unsigned int exponent_bits =
38187fa27ce4SDimitry Andric S.sizeInBits - 1 - trailing_significand_bits;
38197fa27ce4SDimitry Andric static_assert(exponent_bits < 64);
38207fa27ce4SDimitry Andric constexpr uint64_t exponent_mask = (uint64_t{1} << exponent_bits) - 1;
38217fa27ce4SDimitry Andric constexpr int bias = -(S.minExponent - 1);
382259850d08SRoman Divacky
38237fa27ce4SDimitry Andric // Copy the bits of the significand. We need to clear out the exponent and
38247fa27ce4SDimitry Andric // sign bit in the last word.
38257fa27ce4SDimitry Andric std::array<integerPart, stored_significand_parts> mysignificand;
38267fa27ce4SDimitry Andric std::copy_n(api.getRawData(), mysignificand.size(), mysignificand.begin());
38277fa27ce4SDimitry Andric if constexpr (significand_mask != 0) {
38287fa27ce4SDimitry Andric mysignificand[mysignificand.size() - 1] &= significand_mask;
382959850d08SRoman Divacky }
38307fa27ce4SDimitry Andric
38317fa27ce4SDimitry Andric // We assume the last word holds the sign bit, the exponent, and potentially
38327fa27ce4SDimitry Andric // some of the trailing significand field.
38337fa27ce4SDimitry Andric uint64_t last_word = api.getRawData()[api.getNumWords() - 1];
38347fa27ce4SDimitry Andric uint64_t myexponent =
38357fa27ce4SDimitry Andric (last_word >> (trailing_significand_bits % 64)) & exponent_mask;
38367fa27ce4SDimitry Andric
38377fa27ce4SDimitry Andric initialize(&S);
38387fa27ce4SDimitry Andric assert(partCount() == mysignificand.size());
38397fa27ce4SDimitry Andric
38407fa27ce4SDimitry Andric sign = static_cast<unsigned int>(last_word >> ((S.sizeInBits - 1) % 64));
38417fa27ce4SDimitry Andric
38427fa27ce4SDimitry Andric bool all_zero_significand =
38437fa27ce4SDimitry Andric llvm::all_of(mysignificand, [](integerPart bits) { return bits == 0; });
38447fa27ce4SDimitry Andric
38457fa27ce4SDimitry Andric bool is_zero = myexponent == 0 && all_zero_significand;
38467fa27ce4SDimitry Andric
38477fa27ce4SDimitry Andric if constexpr (S.nonFiniteBehavior == fltNonfiniteBehavior::IEEE754) {
38487fa27ce4SDimitry Andric if (myexponent - bias == ::exponentInf(S) && all_zero_significand) {
38497fa27ce4SDimitry Andric makeInf(sign);
38507fa27ce4SDimitry Andric return;
38517fa27ce4SDimitry Andric }
38527fa27ce4SDimitry Andric }
38537fa27ce4SDimitry Andric
38547fa27ce4SDimitry Andric bool is_nan = false;
38557fa27ce4SDimitry Andric
38567fa27ce4SDimitry Andric if constexpr (S.nanEncoding == fltNanEncoding::IEEE) {
38577fa27ce4SDimitry Andric is_nan = myexponent - bias == ::exponentNaN(S) && !all_zero_significand;
38587fa27ce4SDimitry Andric } else if constexpr (S.nanEncoding == fltNanEncoding::AllOnes) {
38597fa27ce4SDimitry Andric bool all_ones_significand =
38607fa27ce4SDimitry Andric std::all_of(mysignificand.begin(), mysignificand.end() - 1,
38617fa27ce4SDimitry Andric [](integerPart bits) { return bits == ~integerPart{0}; }) &&
38627fa27ce4SDimitry Andric (!significand_mask ||
38637fa27ce4SDimitry Andric mysignificand[mysignificand.size() - 1] == significand_mask);
38647fa27ce4SDimitry Andric is_nan = myexponent - bias == ::exponentNaN(S) && all_ones_significand;
38657fa27ce4SDimitry Andric } else if constexpr (S.nanEncoding == fltNanEncoding::NegativeZero) {
38667fa27ce4SDimitry Andric is_nan = is_zero && sign;
38677fa27ce4SDimitry Andric }
38687fa27ce4SDimitry Andric
38697fa27ce4SDimitry Andric if (is_nan) {
38707fa27ce4SDimitry Andric category = fcNaN;
38717fa27ce4SDimitry Andric exponent = ::exponentNaN(S);
38727fa27ce4SDimitry Andric std::copy_n(mysignificand.begin(), mysignificand.size(),
38737fa27ce4SDimitry Andric significandParts());
38747fa27ce4SDimitry Andric return;
38757fa27ce4SDimitry Andric }
38767fa27ce4SDimitry Andric
38777fa27ce4SDimitry Andric if (is_zero) {
38787fa27ce4SDimitry Andric makeZero(sign);
38797fa27ce4SDimitry Andric return;
38807fa27ce4SDimitry Andric }
38817fa27ce4SDimitry Andric
38827fa27ce4SDimitry Andric category = fcNormal;
38837fa27ce4SDimitry Andric exponent = myexponent - bias;
38847fa27ce4SDimitry Andric std::copy_n(mysignificand.begin(), mysignificand.size(), significandParts());
38857fa27ce4SDimitry Andric if (myexponent == 0) // denormal
38867fa27ce4SDimitry Andric exponent = S.minExponent;
38877fa27ce4SDimitry Andric else
38887fa27ce4SDimitry Andric significandParts()[mysignificand.size()-1] |= integer_bit; // integer bit
38897fa27ce4SDimitry Andric }
38907fa27ce4SDimitry Andric
initFromQuadrupleAPInt(const APInt & api)38917fa27ce4SDimitry Andric void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) {
38927fa27ce4SDimitry Andric initFromIEEEAPInt<semIEEEquad>(api);
389359850d08SRoman Divacky }
389459850d08SRoman Divacky
initFromDoubleAPInt(const APInt & api)3895b915e9e0SDimitry Andric void IEEEFloat::initFromDoubleAPInt(const APInt &api) {
38967fa27ce4SDimitry Andric initFromIEEEAPInt<semIEEEdouble>(api);
3897009b1c42SEd Schouten }
3898009b1c42SEd Schouten
initFromFloatAPInt(const APInt & api)3899b915e9e0SDimitry Andric void IEEEFloat::initFromFloatAPInt(const APInt &api) {
39007fa27ce4SDimitry Andric initFromIEEEAPInt<semIEEEsingle>(api);
3901009b1c42SEd Schouten }
3902009b1c42SEd Schouten
initFromBFloatAPInt(const APInt & api)3903cfca06d7SDimitry Andric void IEEEFloat::initFromBFloatAPInt(const APInt &api) {
39047fa27ce4SDimitry Andric initFromIEEEAPInt<semBFloat>(api);
3905cfca06d7SDimitry Andric }
3906cfca06d7SDimitry Andric
initFromHalfAPInt(const APInt & api)3907b915e9e0SDimitry Andric void IEEEFloat::initFromHalfAPInt(const APInt &api) {
39087fa27ce4SDimitry Andric initFromIEEEAPInt<semIEEEhalf>(api);
39094a142eb2SRoman Divacky }
39104a142eb2SRoman Divacky
initFromFloat8E5M2APInt(const APInt & api)3911e3b55780SDimitry Andric void IEEEFloat::initFromFloat8E5M2APInt(const APInt &api) {
39127fa27ce4SDimitry Andric initFromIEEEAPInt<semFloat8E5M2>(api);
3913e3b55780SDimitry Andric }
39147fa27ce4SDimitry Andric
initFromFloat8E5M2FNUZAPInt(const APInt & api)39157fa27ce4SDimitry Andric void IEEEFloat::initFromFloat8E5M2FNUZAPInt(const APInt &api) {
39167fa27ce4SDimitry Andric initFromIEEEAPInt<semFloat8E5M2FNUZ>(api);
3917e3b55780SDimitry Andric }
3918e3b55780SDimitry Andric
initFromFloat8E4M3APInt(const APInt & api)3919ac9a064cSDimitry Andric void IEEEFloat::initFromFloat8E4M3APInt(const APInt &api) {
3920ac9a064cSDimitry Andric initFromIEEEAPInt<semFloat8E4M3>(api);
3921ac9a064cSDimitry Andric }
3922ac9a064cSDimitry Andric
initFromFloat8E4M3FNAPInt(const APInt & api)3923e3b55780SDimitry Andric void IEEEFloat::initFromFloat8E4M3FNAPInt(const APInt &api) {
39247fa27ce4SDimitry Andric initFromIEEEAPInt<semFloat8E4M3FN>(api);
3925e3b55780SDimitry Andric }
39267fa27ce4SDimitry Andric
initFromFloat8E4M3FNUZAPInt(const APInt & api)39277fa27ce4SDimitry Andric void IEEEFloat::initFromFloat8E4M3FNUZAPInt(const APInt &api) {
39287fa27ce4SDimitry Andric initFromIEEEAPInt<semFloat8E4M3FNUZ>(api);
39297fa27ce4SDimitry Andric }
39307fa27ce4SDimitry Andric
initFromFloat8E4M3B11FNUZAPInt(const APInt & api)39317fa27ce4SDimitry Andric void IEEEFloat::initFromFloat8E4M3B11FNUZAPInt(const APInt &api) {
39327fa27ce4SDimitry Andric initFromIEEEAPInt<semFloat8E4M3B11FNUZ>(api);
39337fa27ce4SDimitry Andric }
39347fa27ce4SDimitry Andric
initFromFloatTF32APInt(const APInt & api)39357fa27ce4SDimitry Andric void IEEEFloat::initFromFloatTF32APInt(const APInt &api) {
39367fa27ce4SDimitry Andric initFromIEEEAPInt<semFloatTF32>(api);
3937e3b55780SDimitry Andric }
3938e3b55780SDimitry Andric
initFromFloat6E3M2FNAPInt(const APInt & api)3939ac9a064cSDimitry Andric void IEEEFloat::initFromFloat6E3M2FNAPInt(const APInt &api) {
3940ac9a064cSDimitry Andric initFromIEEEAPInt<semFloat6E3M2FN>(api);
3941ac9a064cSDimitry Andric }
3942ac9a064cSDimitry Andric
initFromFloat6E2M3FNAPInt(const APInt & api)3943ac9a064cSDimitry Andric void IEEEFloat::initFromFloat6E2M3FNAPInt(const APInt &api) {
3944ac9a064cSDimitry Andric initFromIEEEAPInt<semFloat6E2M3FN>(api);
3945ac9a064cSDimitry Andric }
3946ac9a064cSDimitry Andric
initFromFloat4E2M1FNAPInt(const APInt & api)3947ac9a064cSDimitry Andric void IEEEFloat::initFromFloat4E2M1FNAPInt(const APInt &api) {
3948ac9a064cSDimitry Andric initFromIEEEAPInt<semFloat4E2M1FN>(api);
3949ac9a064cSDimitry Andric }
3950ac9a064cSDimitry Andric
3951e3b55780SDimitry Andric /// Treat api as containing the bits of a floating point number.
initFromAPInt(const fltSemantics * Sem,const APInt & api)3952b915e9e0SDimitry Andric void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
3953c0981da4SDimitry Andric assert(api.getBitWidth() == Sem->sizeInBits);
3954b915e9e0SDimitry Andric if (Sem == &semIEEEhalf)
39554a142eb2SRoman Divacky return initFromHalfAPInt(api);
3956cfca06d7SDimitry Andric if (Sem == &semBFloat)
3957cfca06d7SDimitry Andric return initFromBFloatAPInt(api);
3958b915e9e0SDimitry Andric if (Sem == &semIEEEsingle)
3959009b1c42SEd Schouten return initFromFloatAPInt(api);
3960b915e9e0SDimitry Andric if (Sem == &semIEEEdouble)
3961009b1c42SEd Schouten return initFromDoubleAPInt(api);
3962b915e9e0SDimitry Andric if (Sem == &semX87DoubleExtended)
3963009b1c42SEd Schouten return initFromF80LongDoubleAPInt(api);
3964b915e9e0SDimitry Andric if (Sem == &semIEEEquad)
39654a16efa3SDimitry Andric return initFromQuadrupleAPInt(api);
396671d5a254SDimitry Andric if (Sem == &semPPCDoubleDoubleLegacy)
39674a16efa3SDimitry Andric return initFromPPCDoubleDoubleAPInt(api);
3968e3b55780SDimitry Andric if (Sem == &semFloat8E5M2)
3969e3b55780SDimitry Andric return initFromFloat8E5M2APInt(api);
39707fa27ce4SDimitry Andric if (Sem == &semFloat8E5M2FNUZ)
39717fa27ce4SDimitry Andric return initFromFloat8E5M2FNUZAPInt(api);
3972ac9a064cSDimitry Andric if (Sem == &semFloat8E4M3)
3973ac9a064cSDimitry Andric return initFromFloat8E4M3APInt(api);
3974e3b55780SDimitry Andric if (Sem == &semFloat8E4M3FN)
3975e3b55780SDimitry Andric return initFromFloat8E4M3FNAPInt(api);
39767fa27ce4SDimitry Andric if (Sem == &semFloat8E4M3FNUZ)
39777fa27ce4SDimitry Andric return initFromFloat8E4M3FNUZAPInt(api);
39787fa27ce4SDimitry Andric if (Sem == &semFloat8E4M3B11FNUZ)
39797fa27ce4SDimitry Andric return initFromFloat8E4M3B11FNUZAPInt(api);
39807fa27ce4SDimitry Andric if (Sem == &semFloatTF32)
39817fa27ce4SDimitry Andric return initFromFloatTF32APInt(api);
3982ac9a064cSDimitry Andric if (Sem == &semFloat6E3M2FN)
3983ac9a064cSDimitry Andric return initFromFloat6E3M2FNAPInt(api);
3984ac9a064cSDimitry Andric if (Sem == &semFloat6E2M3FN)
3985ac9a064cSDimitry Andric return initFromFloat6E2M3FNAPInt(api);
3986ac9a064cSDimitry Andric if (Sem == &semFloat4E2M1FN)
3987ac9a064cSDimitry Andric return initFromFloat4E2M1FNAPInt(api);
39884a16efa3SDimitry Andric
39895ca98fd9SDimitry Andric llvm_unreachable(nullptr);
3990009b1c42SEd Schouten }
3991009b1c42SEd Schouten
3992f8af5cf6SDimitry Andric /// Make this number the largest magnitude normal number in the given
3993f8af5cf6SDimitry Andric /// semantics.
makeLargest(bool Negative)3994b915e9e0SDimitry Andric void IEEEFloat::makeLargest(bool Negative) {
39951e7804dbSRoman Divacky // We want (in interchange format):
39961e7804dbSRoman Divacky // sign = {Negative}
39971e7804dbSRoman Divacky // exponent = 1..10
39981e7804dbSRoman Divacky // significand = 1..1
3999f8af5cf6SDimitry Andric category = fcNormal;
4000f8af5cf6SDimitry Andric sign = Negative;
4001f8af5cf6SDimitry Andric exponent = semantics->maxExponent;
40021e7804dbSRoman Divacky
4003f8af5cf6SDimitry Andric // Use memset to set all but the highest integerPart to all ones.
4004f8af5cf6SDimitry Andric integerPart *significand = significandParts();
4005f8af5cf6SDimitry Andric unsigned PartCount = partCount();
4006f8af5cf6SDimitry Andric memset(significand, 0xFF, sizeof(integerPart)*(PartCount - 1));
40071e7804dbSRoman Divacky
4008f8af5cf6SDimitry Andric // Set the high integerPart especially setting all unused top bits for
4009f8af5cf6SDimitry Andric // internal consistency.
4010f8af5cf6SDimitry Andric const unsigned NumUnusedHighBits =
4011f8af5cf6SDimitry Andric PartCount*integerPartWidth - semantics->precision;
401267c32a98SDimitry Andric significand[PartCount - 1] = (NumUnusedHighBits < integerPartWidth)
401367c32a98SDimitry Andric ? (~integerPart(0) >> NumUnusedHighBits)
401467c32a98SDimitry Andric : 0;
4015e3b55780SDimitry Andric
40167fa27ce4SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly &&
40177fa27ce4SDimitry Andric semantics->nanEncoding == fltNanEncoding::AllOnes)
4018e3b55780SDimitry Andric significand[0] &= ~integerPart(1);
40191e7804dbSRoman Divacky }
40201e7804dbSRoman Divacky
4021f8af5cf6SDimitry Andric /// Make this number the smallest magnitude denormal number in the given
4022f8af5cf6SDimitry Andric /// semantics.
makeSmallest(bool Negative)4023b915e9e0SDimitry Andric void IEEEFloat::makeSmallest(bool Negative) {
40241e7804dbSRoman Divacky // We want (in interchange format):
40251e7804dbSRoman Divacky // sign = {Negative}
40261e7804dbSRoman Divacky // exponent = 0..0
40271e7804dbSRoman Divacky // significand = 0..01
4028f8af5cf6SDimitry Andric category = fcNormal;
4029f8af5cf6SDimitry Andric sign = Negative;
4030f8af5cf6SDimitry Andric exponent = semantics->minExponent;
4031f8af5cf6SDimitry Andric APInt::tcSet(significandParts(), 1, partCount());
4032f8af5cf6SDimitry Andric }
40331e7804dbSRoman Divacky
makeSmallestNormalized(bool Negative)4034b915e9e0SDimitry Andric void IEEEFloat::makeSmallestNormalized(bool Negative) {
40351e7804dbSRoman Divacky // We want (in interchange format):
40361e7804dbSRoman Divacky // sign = {Negative}
40371e7804dbSRoman Divacky // exponent = 0..0
40381e7804dbSRoman Divacky // significand = 10..0
40391e7804dbSRoman Divacky
4040b915e9e0SDimitry Andric category = fcNormal;
4041b915e9e0SDimitry Andric zeroSignificand();
4042b915e9e0SDimitry Andric sign = Negative;
4043b915e9e0SDimitry Andric exponent = semantics->minExponent;
4044e3b55780SDimitry Andric APInt::tcSetBit(significandParts(), semantics->precision - 1);
40451e7804dbSRoman Divacky }
40461e7804dbSRoman Divacky
IEEEFloat(const fltSemantics & Sem,const APInt & API)4047b915e9e0SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &Sem, const APInt &API) {
40484a16efa3SDimitry Andric initFromAPInt(&Sem, API);
4049009b1c42SEd Schouten }
4050009b1c42SEd Schouten
IEEEFloat(float f)4051b915e9e0SDimitry Andric IEEEFloat::IEEEFloat(float f) {
4052b915e9e0SDimitry Andric initFromAPInt(&semIEEEsingle, APInt::floatToBits(f));
4053009b1c42SEd Schouten }
4054009b1c42SEd Schouten
IEEEFloat(double d)4055b915e9e0SDimitry Andric IEEEFloat::IEEEFloat(double d) {
4056b915e9e0SDimitry Andric initFromAPInt(&semIEEEdouble, APInt::doubleToBits(d));
4057009b1c42SEd Schouten }
40581e7804dbSRoman Divacky
40591e7804dbSRoman Divacky namespace {
append(SmallVectorImpl<char> & Buffer,StringRef Str)406058b69754SDimitry Andric void append(SmallVectorImpl<char> &Buffer, StringRef Str) {
406158b69754SDimitry Andric Buffer.append(Str.begin(), Str.end());
40621e7804dbSRoman Divacky }
40631e7804dbSRoman Divacky
40641e7804dbSRoman Divacky /// Removes data from the given significand until it is no more
40651e7804dbSRoman Divacky /// precise than is required for the desired precision.
AdjustToPrecision(APInt & significand,int & exp,unsigned FormatPrecision)40661e7804dbSRoman Divacky void AdjustToPrecision(APInt &significand,
40671e7804dbSRoman Divacky int &exp, unsigned FormatPrecision) {
40681e7804dbSRoman Divacky unsigned bits = significand.getActiveBits();
40691e7804dbSRoman Divacky
40701e7804dbSRoman Divacky // 196/59 is a very slight overestimate of lg_2(10).
40711e7804dbSRoman Divacky unsigned bitsRequired = (FormatPrecision * 196 + 58) / 59;
40721e7804dbSRoman Divacky
40731e7804dbSRoman Divacky if (bits <= bitsRequired) return;
40741e7804dbSRoman Divacky
40751e7804dbSRoman Divacky unsigned tensRemovable = (bits - bitsRequired) * 59 / 196;
40761e7804dbSRoman Divacky if (!tensRemovable) return;
40771e7804dbSRoman Divacky
40781e7804dbSRoman Divacky exp += tensRemovable;
40791e7804dbSRoman Divacky
40801e7804dbSRoman Divacky APInt divisor(significand.getBitWidth(), 1);
40811e7804dbSRoman Divacky APInt powten(significand.getBitWidth(), 10);
40821e7804dbSRoman Divacky while (true) {
40831e7804dbSRoman Divacky if (tensRemovable & 1)
40841e7804dbSRoman Divacky divisor *= powten;
40851e7804dbSRoman Divacky tensRemovable >>= 1;
40861e7804dbSRoman Divacky if (!tensRemovable) break;
40871e7804dbSRoman Divacky powten *= powten;
40881e7804dbSRoman Divacky }
40891e7804dbSRoman Divacky
40901e7804dbSRoman Divacky significand = significand.udiv(divisor);
40911e7804dbSRoman Divacky
40924a16efa3SDimitry Andric // Truncate the significand down to its active bit count.
40934a16efa3SDimitry Andric significand = significand.trunc(significand.getActiveBits());
40941e7804dbSRoman Divacky }
40951e7804dbSRoman Divacky
40961e7804dbSRoman Divacky
AdjustToPrecision(SmallVectorImpl<char> & buffer,int & exp,unsigned FormatPrecision)40971e7804dbSRoman Divacky void AdjustToPrecision(SmallVectorImpl<char> &buffer,
40981e7804dbSRoman Divacky int &exp, unsigned FormatPrecision) {
40991e7804dbSRoman Divacky unsigned N = buffer.size();
41001e7804dbSRoman Divacky if (N <= FormatPrecision) return;
41011e7804dbSRoman Divacky
41021e7804dbSRoman Divacky // The most significant figures are the last ones in the buffer.
41031e7804dbSRoman Divacky unsigned FirstSignificant = N - FormatPrecision;
41041e7804dbSRoman Divacky
41051e7804dbSRoman Divacky // Round.
41061e7804dbSRoman Divacky // FIXME: this probably shouldn't use 'round half up'.
41071e7804dbSRoman Divacky
41081e7804dbSRoman Divacky // Rounding down is just a truncation, except we also want to drop
41091e7804dbSRoman Divacky // trailing zeros from the new result.
41101e7804dbSRoman Divacky if (buffer[FirstSignificant - 1] < '5') {
411163faed5bSDimitry Andric while (FirstSignificant < N && buffer[FirstSignificant] == '0')
41121e7804dbSRoman Divacky FirstSignificant++;
41131e7804dbSRoman Divacky
41141e7804dbSRoman Divacky exp += FirstSignificant;
41151e7804dbSRoman Divacky buffer.erase(&buffer[0], &buffer[FirstSignificant]);
41161e7804dbSRoman Divacky return;
41171e7804dbSRoman Divacky }
41181e7804dbSRoman Divacky
41191e7804dbSRoman Divacky // Rounding up requires a decimal add-with-carry. If we continue
41201e7804dbSRoman Divacky // the carry, the newly-introduced zeros will just be truncated.
41211e7804dbSRoman Divacky for (unsigned I = FirstSignificant; I != N; ++I) {
41221e7804dbSRoman Divacky if (buffer[I] == '9') {
41231e7804dbSRoman Divacky FirstSignificant++;
41241e7804dbSRoman Divacky } else {
41251e7804dbSRoman Divacky buffer[I]++;
41261e7804dbSRoman Divacky break;
41271e7804dbSRoman Divacky }
41281e7804dbSRoman Divacky }
41291e7804dbSRoman Divacky
41301e7804dbSRoman Divacky // If we carried through, we have exactly one digit of precision.
41311e7804dbSRoman Divacky if (FirstSignificant == N) {
41321e7804dbSRoman Divacky exp += FirstSignificant;
41331e7804dbSRoman Divacky buffer.clear();
41341e7804dbSRoman Divacky buffer.push_back('1');
41351e7804dbSRoman Divacky return;
41361e7804dbSRoman Divacky }
41371e7804dbSRoman Divacky
41381e7804dbSRoman Divacky exp += FirstSignificant;
41391e7804dbSRoman Divacky buffer.erase(&buffer[0], &buffer[FirstSignificant]);
41401e7804dbSRoman Divacky }
41411e7804dbSRoman Divacky
toStringImpl(SmallVectorImpl<char> & Str,const bool isNeg,int exp,APInt significand,unsigned FormatPrecision,unsigned FormatMaxPadding,bool TruncateZero)4142ac9a064cSDimitry Andric void toStringImpl(SmallVectorImpl<char> &Str, const bool isNeg, int exp,
4143ac9a064cSDimitry Andric APInt significand, unsigned FormatPrecision,
4144ac9a064cSDimitry Andric unsigned FormatMaxPadding, bool TruncateZero) {
4145ac9a064cSDimitry Andric const int semanticsPrecision = significand.getBitWidth();
41461e7804dbSRoman Divacky
4147ac9a064cSDimitry Andric if (isNeg)
41481e7804dbSRoman Divacky Str.push_back('-');
41491e7804dbSRoman Divacky
41501e7804dbSRoman Divacky // Set FormatPrecision if zero. We want to do this before we
41511e7804dbSRoman Divacky // truncate trailing zeros, as those are part of the precision.
41521e7804dbSRoman Divacky if (!FormatPrecision) {
4153f8af5cf6SDimitry Andric // We use enough digits so the number can be round-tripped back to an
4154f8af5cf6SDimitry Andric // APFloat. The formula comes from "How to Print Floating-Point Numbers
4155f8af5cf6SDimitry Andric // Accurately" by Steele and White.
4156f8af5cf6SDimitry Andric // FIXME: Using a formula based purely on the precision is conservative;
4157f8af5cf6SDimitry Andric // we can print fewer digits depending on the actual value being printed.
41581e7804dbSRoman Divacky
4159f8af5cf6SDimitry Andric // FormatPrecision = 2 + floor(significandBits / lg_2(10))
4160ac9a064cSDimitry Andric FormatPrecision = 2 + semanticsPrecision * 59 / 196;
41611e7804dbSRoman Divacky }
41621e7804dbSRoman Divacky
41631e7804dbSRoman Divacky // Ignore trailing binary zeros.
41647fa27ce4SDimitry Andric int trailingZeros = significand.countr_zero();
41651e7804dbSRoman Divacky exp += trailingZeros;
4166d99dafe2SDimitry Andric significand.lshrInPlace(trailingZeros);
41671e7804dbSRoman Divacky
41681e7804dbSRoman Divacky // Change the exponent from 2^e to 10^e.
41691e7804dbSRoman Divacky if (exp == 0) {
41701e7804dbSRoman Divacky // Nothing to do.
41711e7804dbSRoman Divacky } else if (exp > 0) {
41721e7804dbSRoman Divacky // Just shift left.
4173ac9a064cSDimitry Andric significand = significand.zext(semanticsPrecision + exp);
41741e7804dbSRoman Divacky significand <<= exp;
41751e7804dbSRoman Divacky exp = 0;
41761e7804dbSRoman Divacky } else { /* exp < 0 */
41771e7804dbSRoman Divacky int texp = -exp;
41781e7804dbSRoman Divacky
41791e7804dbSRoman Divacky // We transform this using the identity:
41801e7804dbSRoman Divacky // (N)(2^-e) == (N)(5^e)(10^-e)
41811e7804dbSRoman Divacky // This means we have to multiply N (the significand) by 5^e.
41821e7804dbSRoman Divacky // To avoid overflow, we have to operate on numbers large
41831e7804dbSRoman Divacky // enough to store N * 5^e:
41841e7804dbSRoman Divacky // log2(N * 5^e) == log2(N) + e * log2(5)
41851e7804dbSRoman Divacky // <= semantics->precision + e * 137 / 59
41861e7804dbSRoman Divacky // (log_2(5) ~ 2.321928 < 2.322034 ~ 137/59)
41871e7804dbSRoman Divacky
4188ac9a064cSDimitry Andric unsigned precision = semanticsPrecision + (137 * texp + 136) / 59;
41891e7804dbSRoman Divacky
41901e7804dbSRoman Divacky // Multiply significand by 5^e.
41911e7804dbSRoman Divacky // N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8)
4192cf099d11SDimitry Andric significand = significand.zext(precision);
41931e7804dbSRoman Divacky APInt five_to_the_i(precision, 5);
41941e7804dbSRoman Divacky while (true) {
4195ac9a064cSDimitry Andric if (texp & 1)
4196ac9a064cSDimitry Andric significand *= five_to_the_i;
41971e7804dbSRoman Divacky
41981e7804dbSRoman Divacky texp >>= 1;
4199ac9a064cSDimitry Andric if (!texp)
4200ac9a064cSDimitry Andric break;
42011e7804dbSRoman Divacky five_to_the_i *= five_to_the_i;
42021e7804dbSRoman Divacky }
42031e7804dbSRoman Divacky }
42041e7804dbSRoman Divacky
42051e7804dbSRoman Divacky AdjustToPrecision(significand, exp, FormatPrecision);
42061e7804dbSRoman Divacky
42074a16efa3SDimitry Andric SmallVector<char, 256> buffer;
42081e7804dbSRoman Divacky
42091e7804dbSRoman Divacky // Fill the buffer.
42101e7804dbSRoman Divacky unsigned precision = significand.getBitWidth();
4211e3b55780SDimitry Andric if (precision < 4) {
4212e3b55780SDimitry Andric // We need enough precision to store the value 10.
4213e3b55780SDimitry Andric precision = 4;
4214e3b55780SDimitry Andric significand = significand.zext(precision);
4215e3b55780SDimitry Andric }
42161e7804dbSRoman Divacky APInt ten(precision, 10);
42171e7804dbSRoman Divacky APInt digit(precision, 0);
42181e7804dbSRoman Divacky
42191e7804dbSRoman Divacky bool inTrail = true;
42201e7804dbSRoman Divacky while (significand != 0) {
42211e7804dbSRoman Divacky // digit <- significand % 10
42221e7804dbSRoman Divacky // significand <- significand / 10
42231e7804dbSRoman Divacky APInt::udivrem(significand, ten, significand, digit);
42241e7804dbSRoman Divacky
42251e7804dbSRoman Divacky unsigned d = digit.getZExtValue();
42261e7804dbSRoman Divacky
42271e7804dbSRoman Divacky // Drop trailing zeros.
4228ac9a064cSDimitry Andric if (inTrail && !d)
4229ac9a064cSDimitry Andric exp++;
42301e7804dbSRoman Divacky else {
42311e7804dbSRoman Divacky buffer.push_back((char) ('0' + d));
42321e7804dbSRoman Divacky inTrail = false;
42331e7804dbSRoman Divacky }
42341e7804dbSRoman Divacky }
42351e7804dbSRoman Divacky
42361e7804dbSRoman Divacky assert(!buffer.empty() && "no characters in buffer!");
42371e7804dbSRoman Divacky
42381e7804dbSRoman Divacky // Drop down to FormatPrecision.
42391e7804dbSRoman Divacky // TODO: don't do more precise calculations above than are required.
42401e7804dbSRoman Divacky AdjustToPrecision(buffer, exp, FormatPrecision);
42411e7804dbSRoman Divacky
42421e7804dbSRoman Divacky unsigned NDigits = buffer.size();
42431e7804dbSRoman Divacky
42441e7804dbSRoman Divacky // Check whether we should use scientific notation.
42451e7804dbSRoman Divacky bool FormatScientific;
42461e7804dbSRoman Divacky if (!FormatMaxPadding)
42471e7804dbSRoman Divacky FormatScientific = true;
42481e7804dbSRoman Divacky else {
42491e7804dbSRoman Divacky if (exp >= 0) {
42501e7804dbSRoman Divacky // 765e3 --> 765000
42511e7804dbSRoman Divacky // ^^^
42521e7804dbSRoman Divacky // But we shouldn't make the number look more precise than it is.
42531e7804dbSRoman Divacky FormatScientific = ((unsigned) exp > FormatMaxPadding ||
42541e7804dbSRoman Divacky NDigits + (unsigned) exp > FormatPrecision);
42551e7804dbSRoman Divacky } else {
42561e7804dbSRoman Divacky // Power of the most significant digit.
42571e7804dbSRoman Divacky int MSD = exp + (int) (NDigits - 1);
42581e7804dbSRoman Divacky if (MSD >= 0) {
42591e7804dbSRoman Divacky // 765e-2 == 7.65
42601e7804dbSRoman Divacky FormatScientific = false;
42611e7804dbSRoman Divacky } else {
42621e7804dbSRoman Divacky // 765e-5 == 0.00765
42631e7804dbSRoman Divacky // ^ ^^
42641e7804dbSRoman Divacky FormatScientific = ((unsigned) -MSD) > FormatMaxPadding;
42651e7804dbSRoman Divacky }
42661e7804dbSRoman Divacky }
42671e7804dbSRoman Divacky }
42681e7804dbSRoman Divacky
42691e7804dbSRoman Divacky // Scientific formatting is pretty straightforward.
42701e7804dbSRoman Divacky if (FormatScientific) {
42711e7804dbSRoman Divacky exp += (NDigits - 1);
42721e7804dbSRoman Divacky
42731e7804dbSRoman Divacky Str.push_back(buffer[NDigits-1]);
42741e7804dbSRoman Divacky Str.push_back('.');
427512f3ca4cSDimitry Andric if (NDigits == 1 && TruncateZero)
42761e7804dbSRoman Divacky Str.push_back('0');
42771e7804dbSRoman Divacky else
42781e7804dbSRoman Divacky for (unsigned I = 1; I != NDigits; ++I)
42791e7804dbSRoman Divacky Str.push_back(buffer[NDigits-1-I]);
428012f3ca4cSDimitry Andric // Fill with zeros up to FormatPrecision.
428112f3ca4cSDimitry Andric if (!TruncateZero && FormatPrecision > NDigits - 1)
428212f3ca4cSDimitry Andric Str.append(FormatPrecision - NDigits + 1, '0');
428312f3ca4cSDimitry Andric // For !TruncateZero we use lower 'e'.
428412f3ca4cSDimitry Andric Str.push_back(TruncateZero ? 'E' : 'e');
42851e7804dbSRoman Divacky
42861e7804dbSRoman Divacky Str.push_back(exp >= 0 ? '+' : '-');
4287ac9a064cSDimitry Andric if (exp < 0)
4288ac9a064cSDimitry Andric exp = -exp;
42891e7804dbSRoman Divacky SmallVector<char, 6> expbuf;
42901e7804dbSRoman Divacky do {
42911e7804dbSRoman Divacky expbuf.push_back((char) ('0' + (exp % 10)));
42921e7804dbSRoman Divacky exp /= 10;
42931e7804dbSRoman Divacky } while (exp);
429412f3ca4cSDimitry Andric // Exponent always at least two digits if we do not truncate zeros.
429512f3ca4cSDimitry Andric if (!TruncateZero && expbuf.size() < 2)
429612f3ca4cSDimitry Andric expbuf.push_back('0');
42971e7804dbSRoman Divacky for (unsigned I = 0, E = expbuf.size(); I != E; ++I)
42981e7804dbSRoman Divacky Str.push_back(expbuf[E-1-I]);
42991e7804dbSRoman Divacky return;
43001e7804dbSRoman Divacky }
43011e7804dbSRoman Divacky
43021e7804dbSRoman Divacky // Non-scientific, positive exponents.
43031e7804dbSRoman Divacky if (exp >= 0) {
43041e7804dbSRoman Divacky for (unsigned I = 0; I != NDigits; ++I)
43051e7804dbSRoman Divacky Str.push_back(buffer[NDigits-1-I]);
43061e7804dbSRoman Divacky for (unsigned I = 0; I != (unsigned) exp; ++I)
43071e7804dbSRoman Divacky Str.push_back('0');
43081e7804dbSRoman Divacky return;
43091e7804dbSRoman Divacky }
43101e7804dbSRoman Divacky
43111e7804dbSRoman Divacky // Non-scientific, negative exponents.
43121e7804dbSRoman Divacky
43131e7804dbSRoman Divacky // The number of digits to the left of the decimal point.
43141e7804dbSRoman Divacky int NWholeDigits = exp + (int) NDigits;
43151e7804dbSRoman Divacky
43161e7804dbSRoman Divacky unsigned I = 0;
43171e7804dbSRoman Divacky if (NWholeDigits > 0) {
43181e7804dbSRoman Divacky for (; I != (unsigned) NWholeDigits; ++I)
43191e7804dbSRoman Divacky Str.push_back(buffer[NDigits-I-1]);
43201e7804dbSRoman Divacky Str.push_back('.');
43211e7804dbSRoman Divacky } else {
43221e7804dbSRoman Divacky unsigned NZeros = 1 + (unsigned) -NWholeDigits;
43231e7804dbSRoman Divacky
43241e7804dbSRoman Divacky Str.push_back('0');
43251e7804dbSRoman Divacky Str.push_back('.');
43261e7804dbSRoman Divacky for (unsigned Z = 1; Z != NZeros; ++Z)
43271e7804dbSRoman Divacky Str.push_back('0');
43281e7804dbSRoman Divacky }
43291e7804dbSRoman Divacky
43301e7804dbSRoman Divacky for (; I != NDigits; ++I)
43311e7804dbSRoman Divacky Str.push_back(buffer[NDigits-I-1]);
4332ac9a064cSDimitry Andric
4333ac9a064cSDimitry Andric }
4334ac9a064cSDimitry Andric } // namespace
4335ac9a064cSDimitry Andric
toString(SmallVectorImpl<char> & Str,unsigned FormatPrecision,unsigned FormatMaxPadding,bool TruncateZero) const4336ac9a064cSDimitry Andric void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
4337ac9a064cSDimitry Andric unsigned FormatMaxPadding, bool TruncateZero) const {
4338ac9a064cSDimitry Andric switch (category) {
4339ac9a064cSDimitry Andric case fcInfinity:
4340ac9a064cSDimitry Andric if (isNegative())
4341ac9a064cSDimitry Andric return append(Str, "-Inf");
4342ac9a064cSDimitry Andric else
4343ac9a064cSDimitry Andric return append(Str, "+Inf");
4344ac9a064cSDimitry Andric
4345ac9a064cSDimitry Andric case fcNaN: return append(Str, "NaN");
4346ac9a064cSDimitry Andric
4347ac9a064cSDimitry Andric case fcZero:
4348ac9a064cSDimitry Andric if (isNegative())
4349ac9a064cSDimitry Andric Str.push_back('-');
4350ac9a064cSDimitry Andric
4351ac9a064cSDimitry Andric if (!FormatMaxPadding) {
4352ac9a064cSDimitry Andric if (TruncateZero)
4353ac9a064cSDimitry Andric append(Str, "0.0E+0");
4354ac9a064cSDimitry Andric else {
4355ac9a064cSDimitry Andric append(Str, "0.0");
4356ac9a064cSDimitry Andric if (FormatPrecision > 1)
4357ac9a064cSDimitry Andric Str.append(FormatPrecision - 1, '0');
4358ac9a064cSDimitry Andric append(Str, "e+00");
4359ac9a064cSDimitry Andric }
4360ac9a064cSDimitry Andric } else
4361ac9a064cSDimitry Andric Str.push_back('0');
4362ac9a064cSDimitry Andric return;
4363ac9a064cSDimitry Andric
4364ac9a064cSDimitry Andric case fcNormal:
4365ac9a064cSDimitry Andric break;
4366ac9a064cSDimitry Andric }
4367ac9a064cSDimitry Andric
4368ac9a064cSDimitry Andric // Decompose the number into an APInt and an exponent.
4369ac9a064cSDimitry Andric int exp = exponent - ((int) semantics->precision - 1);
4370ac9a064cSDimitry Andric APInt significand(
4371ac9a064cSDimitry Andric semantics->precision,
4372ac9a064cSDimitry Andric ArrayRef(significandParts(), partCountForBits(semantics->precision)));
4373ac9a064cSDimitry Andric
4374ac9a064cSDimitry Andric toStringImpl(Str, isNegative(), exp, significand, FormatPrecision,
4375ac9a064cSDimitry Andric FormatMaxPadding, TruncateZero);
4376ac9a064cSDimitry Andric
43771e7804dbSRoman Divacky }
43786b943ff3SDimitry Andric
getExactInverse(APFloat * inv) const437971d5a254SDimitry Andric bool IEEEFloat::getExactInverse(APFloat *inv) const {
43806b943ff3SDimitry Andric // Special floats and denormals have no exact inverse.
4381f8af5cf6SDimitry Andric if (!isFiniteNonZero())
43826b943ff3SDimitry Andric return false;
43836b943ff3SDimitry Andric
43846b943ff3SDimitry Andric // Check that the number is a power of two by making sure that only the
43856b943ff3SDimitry Andric // integer bit is set in the significand.
43866b943ff3SDimitry Andric if (significandLSB() != semantics->precision - 1)
43876b943ff3SDimitry Andric return false;
43886b943ff3SDimitry Andric
43896b943ff3SDimitry Andric // Get the inverse.
4390b915e9e0SDimitry Andric IEEEFloat reciprocal(*semantics, 1ULL);
43916b943ff3SDimitry Andric if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
43926b943ff3SDimitry Andric return false;
43936b943ff3SDimitry Andric
43946b943ff3SDimitry Andric // Avoid multiplication with a denormal, it is not safe on all platforms and
43956b943ff3SDimitry Andric // may be slower than a normal division.
4396f8af5cf6SDimitry Andric if (reciprocal.isDenormal())
43976b943ff3SDimitry Andric return false;
43986b943ff3SDimitry Andric
4399f8af5cf6SDimitry Andric assert(reciprocal.isFiniteNonZero() &&
44006b943ff3SDimitry Andric reciprocal.significandLSB() == reciprocal.semantics->precision - 1);
44016b943ff3SDimitry Andric
44026b943ff3SDimitry Andric if (inv)
440371d5a254SDimitry Andric *inv = APFloat(reciprocal, *semantics);
44046b943ff3SDimitry Andric
44056b943ff3SDimitry Andric return true;
44066b943ff3SDimitry Andric }
4407f8af5cf6SDimitry Andric
getExactLog2Abs() const4408b1c73532SDimitry Andric int IEEEFloat::getExactLog2Abs() const {
4409b1c73532SDimitry Andric if (!isFinite() || isZero())
4410b1c73532SDimitry Andric return INT_MIN;
4411b1c73532SDimitry Andric
4412b1c73532SDimitry Andric const integerPart *Parts = significandParts();
4413b1c73532SDimitry Andric const int PartCount = partCountForBits(semantics->precision);
4414b1c73532SDimitry Andric
4415b1c73532SDimitry Andric int PopCount = 0;
4416b1c73532SDimitry Andric for (int i = 0; i < PartCount; ++i) {
4417b1c73532SDimitry Andric PopCount += llvm::popcount(Parts[i]);
4418b1c73532SDimitry Andric if (PopCount > 1)
4419b1c73532SDimitry Andric return INT_MIN;
4420b1c73532SDimitry Andric }
4421b1c73532SDimitry Andric
4422b1c73532SDimitry Andric if (exponent != semantics->minExponent)
4423b1c73532SDimitry Andric return exponent;
4424b1c73532SDimitry Andric
4425b1c73532SDimitry Andric int CountrParts = 0;
4426b1c73532SDimitry Andric for (int i = 0; i < PartCount;
4427b1c73532SDimitry Andric ++i, CountrParts += APInt::APINT_BITS_PER_WORD) {
4428b1c73532SDimitry Andric if (Parts[i] != 0) {
4429b1c73532SDimitry Andric return exponent - semantics->precision + CountrParts +
4430b1c73532SDimitry Andric llvm::countr_zero(Parts[i]) + 1;
4431b1c73532SDimitry Andric }
4432b1c73532SDimitry Andric }
4433b1c73532SDimitry Andric
4434b1c73532SDimitry Andric llvm_unreachable("didn't find the set bit");
4435b1c73532SDimitry Andric }
4436b1c73532SDimitry Andric
isSignaling() const4437b915e9e0SDimitry Andric bool IEEEFloat::isSignaling() const {
4438f8af5cf6SDimitry Andric if (!isNaN())
4439f8af5cf6SDimitry Andric return false;
4440ac9a064cSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly ||
4441ac9a064cSDimitry Andric semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
4442e3b55780SDimitry Andric return false;
4443f8af5cf6SDimitry Andric
4444f8af5cf6SDimitry Andric // IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded with the
4445f8af5cf6SDimitry Andric // first bit of the trailing significand being 0.
4446f8af5cf6SDimitry Andric return !APInt::tcExtractBit(significandParts(), semantics->precision - 2);
4447f8af5cf6SDimitry Andric }
4448f8af5cf6SDimitry Andric
4449f8af5cf6SDimitry Andric /// IEEE-754R 2008 5.3.1: nextUp/nextDown.
4450f8af5cf6SDimitry Andric ///
4451f8af5cf6SDimitry Andric /// *NOTE* since nextDown(x) = -nextUp(-x), we only implement nextUp with
4452f8af5cf6SDimitry Andric /// appropriate sign switching before/after the computation.
next(bool nextDown)4453b915e9e0SDimitry Andric IEEEFloat::opStatus IEEEFloat::next(bool nextDown) {
4454f8af5cf6SDimitry Andric // If we are performing nextDown, swap sign so we have -x.
4455f8af5cf6SDimitry Andric if (nextDown)
4456f8af5cf6SDimitry Andric changeSign();
4457f8af5cf6SDimitry Andric
4458f8af5cf6SDimitry Andric // Compute nextUp(x)
4459f8af5cf6SDimitry Andric opStatus result = opOK;
4460f8af5cf6SDimitry Andric
4461f8af5cf6SDimitry Andric // Handle each float category separately.
4462f8af5cf6SDimitry Andric switch (category) {
4463f8af5cf6SDimitry Andric case fcInfinity:
4464f8af5cf6SDimitry Andric // nextUp(+inf) = +inf
4465f8af5cf6SDimitry Andric if (!isNegative())
4466f8af5cf6SDimitry Andric break;
4467f8af5cf6SDimitry Andric // nextUp(-inf) = -getLargest()
4468f8af5cf6SDimitry Andric makeLargest(true);
4469f8af5cf6SDimitry Andric break;
4470f8af5cf6SDimitry Andric case fcNaN:
4471f8af5cf6SDimitry Andric // IEEE-754R 2008 6.2 Par 2: nextUp(sNaN) = qNaN. Set Invalid flag.
4472f8af5cf6SDimitry Andric // IEEE-754R 2008 6.2: nextUp(qNaN) = qNaN. Must be identity so we do not
4473f8af5cf6SDimitry Andric // change the payload.
4474f8af5cf6SDimitry Andric if (isSignaling()) {
4475f8af5cf6SDimitry Andric result = opInvalidOp;
44765ca98fd9SDimitry Andric // For consistency, propagate the sign of the sNaN to the qNaN.
44775ca98fd9SDimitry Andric makeNaN(false, isNegative(), nullptr);
4478f8af5cf6SDimitry Andric }
4479f8af5cf6SDimitry Andric break;
4480f8af5cf6SDimitry Andric case fcZero:
4481f8af5cf6SDimitry Andric // nextUp(pm 0) = +getSmallest()
4482f8af5cf6SDimitry Andric makeSmallest(false);
4483f8af5cf6SDimitry Andric break;
4484f8af5cf6SDimitry Andric case fcNormal:
4485f8af5cf6SDimitry Andric // nextUp(-getSmallest()) = -0
4486f8af5cf6SDimitry Andric if (isSmallest() && isNegative()) {
4487f8af5cf6SDimitry Andric APInt::tcSet(significandParts(), 0, partCount());
4488f8af5cf6SDimitry Andric category = fcZero;
4489f8af5cf6SDimitry Andric exponent = 0;
44907fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero)
44917fa27ce4SDimitry Andric sign = false;
4492f8af5cf6SDimitry Andric break;
4493f8af5cf6SDimitry Andric }
4494f8af5cf6SDimitry Andric
4495f8af5cf6SDimitry Andric if (isLargest() && !isNegative()) {
4496e3b55780SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
4497e3b55780SDimitry Andric // nextUp(getLargest()) == NAN
4498e3b55780SDimitry Andric makeNaN();
4499e3b55780SDimitry Andric break;
4500ac9a064cSDimitry Andric } else if (semantics->nonFiniteBehavior ==
4501ac9a064cSDimitry Andric fltNonfiniteBehavior::FiniteOnly) {
4502ac9a064cSDimitry Andric // nextUp(getLargest()) == getLargest()
4503ac9a064cSDimitry Andric break;
4504e3b55780SDimitry Andric } else {
4505e3b55780SDimitry Andric // nextUp(getLargest()) == INFINITY
4506f8af5cf6SDimitry Andric APInt::tcSet(significandParts(), 0, partCount());
4507f8af5cf6SDimitry Andric category = fcInfinity;
4508f8af5cf6SDimitry Andric exponent = semantics->maxExponent + 1;
4509f8af5cf6SDimitry Andric break;
4510f8af5cf6SDimitry Andric }
4511e3b55780SDimitry Andric }
4512f8af5cf6SDimitry Andric
4513f8af5cf6SDimitry Andric // nextUp(normal) == normal + inc.
4514f8af5cf6SDimitry Andric if (isNegative()) {
4515f8af5cf6SDimitry Andric // If we are negative, we need to decrement the significand.
4516f8af5cf6SDimitry Andric
4517f8af5cf6SDimitry Andric // We only cross a binade boundary that requires adjusting the exponent
4518f8af5cf6SDimitry Andric // if:
4519f8af5cf6SDimitry Andric // 1. exponent != semantics->minExponent. This implies we are not in the
4520f8af5cf6SDimitry Andric // smallest binade or are dealing with denormals.
4521f8af5cf6SDimitry Andric // 2. Our significand excluding the integral bit is all zeros.
4522f8af5cf6SDimitry Andric bool WillCrossBinadeBoundary =
4523f8af5cf6SDimitry Andric exponent != semantics->minExponent && isSignificandAllZeros();
4524f8af5cf6SDimitry Andric
4525f8af5cf6SDimitry Andric // Decrement the significand.
4526f8af5cf6SDimitry Andric //
4527f8af5cf6SDimitry Andric // We always do this since:
45285ca98fd9SDimitry Andric // 1. If we are dealing with a non-binade decrement, by definition we
4529f8af5cf6SDimitry Andric // just decrement the significand.
4530f8af5cf6SDimitry Andric // 2. If we are dealing with a normal -> normal binade decrement, since
4531f8af5cf6SDimitry Andric // we have an explicit integral bit the fact that all bits but the
4532f8af5cf6SDimitry Andric // integral bit are zero implies that subtracting one will yield a
4533f8af5cf6SDimitry Andric // significand with 0 integral bit and 1 in all other spots. Thus we
4534f8af5cf6SDimitry Andric // must just adjust the exponent and set the integral bit to 1.
4535f8af5cf6SDimitry Andric // 3. If we are dealing with a normal -> denormal binade decrement,
4536f8af5cf6SDimitry Andric // since we set the integral bit to 0 when we represent denormals, we
4537f8af5cf6SDimitry Andric // just decrement the significand.
4538f8af5cf6SDimitry Andric integerPart *Parts = significandParts();
4539f8af5cf6SDimitry Andric APInt::tcDecrement(Parts, partCount());
4540f8af5cf6SDimitry Andric
4541f8af5cf6SDimitry Andric if (WillCrossBinadeBoundary) {
4542f8af5cf6SDimitry Andric // Our result is a normal number. Do the following:
4543f8af5cf6SDimitry Andric // 1. Set the integral bit to 1.
4544f8af5cf6SDimitry Andric // 2. Decrement the exponent.
4545f8af5cf6SDimitry Andric APInt::tcSetBit(Parts, semantics->precision - 1);
4546f8af5cf6SDimitry Andric exponent--;
4547f8af5cf6SDimitry Andric }
4548f8af5cf6SDimitry Andric } else {
4549f8af5cf6SDimitry Andric // If we are positive, we need to increment the significand.
4550f8af5cf6SDimitry Andric
4551f8af5cf6SDimitry Andric // We only cross a binade boundary that requires adjusting the exponent if
4552f8af5cf6SDimitry Andric // the input is not a denormal and all of said input's significand bits
4553f8af5cf6SDimitry Andric // are set. If all of said conditions are true: clear the significand, set
4554f8af5cf6SDimitry Andric // the integral bit to 1, and increment the exponent. If we have a
4555f8af5cf6SDimitry Andric // denormal always increment since moving denormals and the numbers in the
4556f8af5cf6SDimitry Andric // smallest normal binade have the same exponent in our representation.
4557f8af5cf6SDimitry Andric bool WillCrossBinadeBoundary = !isDenormal() && isSignificandAllOnes();
4558f8af5cf6SDimitry Andric
4559f8af5cf6SDimitry Andric if (WillCrossBinadeBoundary) {
4560f8af5cf6SDimitry Andric integerPart *Parts = significandParts();
4561f8af5cf6SDimitry Andric APInt::tcSet(Parts, 0, partCount());
4562f8af5cf6SDimitry Andric APInt::tcSetBit(Parts, semantics->precision - 1);
4563f8af5cf6SDimitry Andric assert(exponent != semantics->maxExponent &&
4564f8af5cf6SDimitry Andric "We can not increment an exponent beyond the maxExponent allowed"
4565f8af5cf6SDimitry Andric " by the given floating point semantics.");
4566f8af5cf6SDimitry Andric exponent++;
4567f8af5cf6SDimitry Andric } else {
4568f8af5cf6SDimitry Andric incrementSignificand();
4569f8af5cf6SDimitry Andric }
4570f8af5cf6SDimitry Andric }
4571f8af5cf6SDimitry Andric break;
4572f8af5cf6SDimitry Andric }
4573f8af5cf6SDimitry Andric
4574f8af5cf6SDimitry Andric // If we are performing nextDown, swap sign so we have -nextUp(-x)
4575f8af5cf6SDimitry Andric if (nextDown)
4576f8af5cf6SDimitry Andric changeSign();
4577f8af5cf6SDimitry Andric
4578f8af5cf6SDimitry Andric return result;
4579f8af5cf6SDimitry Andric }
4580f8af5cf6SDimitry Andric
exponentNaN() const4581b60736ecSDimitry Andric APFloatBase::ExponentType IEEEFloat::exponentNaN() const {
45827fa27ce4SDimitry Andric return ::exponentNaN(*semantics);
4583b60736ecSDimitry Andric }
4584b60736ecSDimitry Andric
exponentInf() const4585b60736ecSDimitry Andric APFloatBase::ExponentType IEEEFloat::exponentInf() const {
45867fa27ce4SDimitry Andric return ::exponentInf(*semantics);
4587b60736ecSDimitry Andric }
4588b60736ecSDimitry Andric
exponentZero() const4589b60736ecSDimitry Andric APFloatBase::ExponentType IEEEFloat::exponentZero() const {
45907fa27ce4SDimitry Andric return ::exponentZero(*semantics);
4591b60736ecSDimitry Andric }
4592b60736ecSDimitry Andric
makeInf(bool Negative)4593b915e9e0SDimitry Andric void IEEEFloat::makeInf(bool Negative) {
4594ac9a064cSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
4595ac9a064cSDimitry Andric llvm_unreachable("This floating point format does not support Inf");
4596ac9a064cSDimitry Andric
4597e3b55780SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
4598e3b55780SDimitry Andric // There is no Inf, so make NaN instead.
4599e3b55780SDimitry Andric makeNaN(false, Negative);
4600e3b55780SDimitry Andric return;
4601e3b55780SDimitry Andric }
4602f8af5cf6SDimitry Andric category = fcInfinity;
4603f8af5cf6SDimitry Andric sign = Negative;
4604b60736ecSDimitry Andric exponent = exponentInf();
4605f8af5cf6SDimitry Andric APInt::tcSet(significandParts(), 0, partCount());
4606f8af5cf6SDimitry Andric }
4607f8af5cf6SDimitry Andric
makeZero(bool Negative)4608b915e9e0SDimitry Andric void IEEEFloat::makeZero(bool Negative) {
4609f8af5cf6SDimitry Andric category = fcZero;
4610f8af5cf6SDimitry Andric sign = Negative;
46117fa27ce4SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) {
46127fa27ce4SDimitry Andric // Merge negative zero to positive because 0b10000...000 is used for NaN
46137fa27ce4SDimitry Andric sign = false;
46147fa27ce4SDimitry Andric }
4615b60736ecSDimitry Andric exponent = exponentZero();
4616f8af5cf6SDimitry Andric APInt::tcSet(significandParts(), 0, partCount());
4617f8af5cf6SDimitry Andric }
461867c32a98SDimitry Andric
makeQuiet()4619b915e9e0SDimitry Andric void IEEEFloat::makeQuiet() {
462001095a5dSDimitry Andric assert(isNaN());
4621e3b55780SDimitry Andric if (semantics->nonFiniteBehavior != fltNonfiniteBehavior::NanOnly)
462201095a5dSDimitry Andric APInt::tcSetBit(significandParts(), semantics->precision - 2);
462301095a5dSDimitry Andric }
462467c32a98SDimitry Andric
ilogb(const IEEEFloat & Arg)4625b915e9e0SDimitry Andric int ilogb(const IEEEFloat &Arg) {
462601095a5dSDimitry Andric if (Arg.isNaN())
4627b915e9e0SDimitry Andric return IEEEFloat::IEK_NaN;
462801095a5dSDimitry Andric if (Arg.isZero())
4629b915e9e0SDimitry Andric return IEEEFloat::IEK_Zero;
463001095a5dSDimitry Andric if (Arg.isInfinity())
4631b915e9e0SDimitry Andric return IEEEFloat::IEK_Inf;
463201095a5dSDimitry Andric if (!Arg.isDenormal())
463301095a5dSDimitry Andric return Arg.exponent;
463401095a5dSDimitry Andric
4635b915e9e0SDimitry Andric IEEEFloat Normalized(Arg);
463601095a5dSDimitry Andric int SignificandBits = Arg.getSemantics().precision - 1;
463701095a5dSDimitry Andric
463801095a5dSDimitry Andric Normalized.exponent += SignificandBits;
4639b915e9e0SDimitry Andric Normalized.normalize(IEEEFloat::rmNearestTiesToEven, lfExactlyZero);
464001095a5dSDimitry Andric return Normalized.exponent - SignificandBits;
464101095a5dSDimitry Andric }
464201095a5dSDimitry Andric
scalbn(IEEEFloat X,int Exp,IEEEFloat::roundingMode RoundingMode)4643b915e9e0SDimitry Andric IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode RoundingMode) {
464467c32a98SDimitry Andric auto MaxExp = X.getSemantics().maxExponent;
464567c32a98SDimitry Andric auto MinExp = X.getSemantics().minExponent;
464667c32a98SDimitry Andric
464701095a5dSDimitry Andric // If Exp is wildly out-of-scale, simply adding it to X.exponent will
464801095a5dSDimitry Andric // overflow; clamp it to a safe range before adding, but ensure that the range
464901095a5dSDimitry Andric // is large enough that the clamp does not change the result. The range we
465001095a5dSDimitry Andric // need to support is the difference between the largest possible exponent and
465101095a5dSDimitry Andric // the normalized exponent of half the smallest denormal.
465201095a5dSDimitry Andric
465301095a5dSDimitry Andric int SignificandBits = X.getSemantics().precision - 1;
465401095a5dSDimitry Andric int MaxIncrement = MaxExp - (MinExp - SignificandBits) + 1;
465501095a5dSDimitry Andric
465601095a5dSDimitry Andric // Clamp to one past the range ends to let normalize handle overlflow.
46577fa27ce4SDimitry Andric X.exponent += std::clamp(Exp, -MaxIncrement - 1, MaxIncrement);
465801095a5dSDimitry Andric X.normalize(RoundingMode, lfExactlyZero);
465901095a5dSDimitry Andric if (X.isNaN())
466001095a5dSDimitry Andric X.makeQuiet();
46615a5ac124SDimitry Andric return X;
466267c32a98SDimitry Andric }
466301095a5dSDimitry Andric
frexp(const IEEEFloat & Val,int & Exp,IEEEFloat::roundingMode RM)4664b915e9e0SDimitry Andric IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM) {
466501095a5dSDimitry Andric Exp = ilogb(Val);
466601095a5dSDimitry Andric
466701095a5dSDimitry Andric // Quiet signalling nans.
4668b915e9e0SDimitry Andric if (Exp == IEEEFloat::IEK_NaN) {
4669b915e9e0SDimitry Andric IEEEFloat Quiet(Val);
467001095a5dSDimitry Andric Quiet.makeQuiet();
467101095a5dSDimitry Andric return Quiet;
467201095a5dSDimitry Andric }
467301095a5dSDimitry Andric
4674b915e9e0SDimitry Andric if (Exp == IEEEFloat::IEK_Inf)
467501095a5dSDimitry Andric return Val;
467601095a5dSDimitry Andric
467701095a5dSDimitry Andric // 1 is added because frexp is defined to return a normalized fraction in
467801095a5dSDimitry Andric // +/-[0.5, 1.0), rather than the usual +/-[1.0, 2.0).
4679b915e9e0SDimitry Andric Exp = Exp == IEEEFloat::IEK_Zero ? 0 : Exp + 1;
468001095a5dSDimitry Andric return scalbn(Val, -Exp, RM);
468101095a5dSDimitry Andric }
4682b915e9e0SDimitry Andric
DoubleAPFloat(const fltSemantics & S)4683b915e9e0SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S)
468471d5a254SDimitry Andric : Semantics(&S),
468571d5a254SDimitry Andric Floats(new APFloat[2]{APFloat(semIEEEdouble), APFloat(semIEEEdouble)}) {
4686b915e9e0SDimitry Andric assert(Semantics == &semPPCDoubleDouble);
4687b915e9e0SDimitry Andric }
4688b915e9e0SDimitry Andric
DoubleAPFloat(const fltSemantics & S,uninitializedTag)4689b915e9e0SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, uninitializedTag)
4690b915e9e0SDimitry Andric : Semantics(&S),
469171d5a254SDimitry Andric Floats(new APFloat[2]{APFloat(semIEEEdouble, uninitialized),
4692b915e9e0SDimitry Andric APFloat(semIEEEdouble, uninitialized)}) {
4693b915e9e0SDimitry Andric assert(Semantics == &semPPCDoubleDouble);
4694b915e9e0SDimitry Andric }
4695b915e9e0SDimitry Andric
DoubleAPFloat(const fltSemantics & S,integerPart I)4696b915e9e0SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, integerPart I)
469771d5a254SDimitry Andric : Semantics(&S), Floats(new APFloat[2]{APFloat(semIEEEdouble, I),
4698b915e9e0SDimitry Andric APFloat(semIEEEdouble)}) {
4699b915e9e0SDimitry Andric assert(Semantics == &semPPCDoubleDouble);
4700b915e9e0SDimitry Andric }
4701b915e9e0SDimitry Andric
DoubleAPFloat(const fltSemantics & S,const APInt & I)4702b915e9e0SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, const APInt &I)
470371d5a254SDimitry Andric : Semantics(&S),
470471d5a254SDimitry Andric Floats(new APFloat[2]{
470571d5a254SDimitry Andric APFloat(semIEEEdouble, APInt(64, I.getRawData()[0])),
4706b915e9e0SDimitry Andric APFloat(semIEEEdouble, APInt(64, I.getRawData()[1]))}) {
4707b915e9e0SDimitry Andric assert(Semantics == &semPPCDoubleDouble);
4708b915e9e0SDimitry Andric }
4709b915e9e0SDimitry Andric
DoubleAPFloat(const fltSemantics & S,APFloat && First,APFloat && Second)4710b915e9e0SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, APFloat &&First,
4711b915e9e0SDimitry Andric APFloat &&Second)
4712b915e9e0SDimitry Andric : Semantics(&S),
4713b915e9e0SDimitry Andric Floats(new APFloat[2]{std::move(First), std::move(Second)}) {
4714b915e9e0SDimitry Andric assert(Semantics == &semPPCDoubleDouble);
471571d5a254SDimitry Andric assert(&Floats[0].getSemantics() == &semIEEEdouble);
4716b915e9e0SDimitry Andric assert(&Floats[1].getSemantics() == &semIEEEdouble);
4717b915e9e0SDimitry Andric }
4718b915e9e0SDimitry Andric
DoubleAPFloat(const DoubleAPFloat & RHS)4719b915e9e0SDimitry Andric DoubleAPFloat::DoubleAPFloat(const DoubleAPFloat &RHS)
4720b915e9e0SDimitry Andric : Semantics(RHS.Semantics),
4721b915e9e0SDimitry Andric Floats(RHS.Floats ? new APFloat[2]{APFloat(RHS.Floats[0]),
4722b915e9e0SDimitry Andric APFloat(RHS.Floats[1])}
4723b915e9e0SDimitry Andric : nullptr) {
4724b915e9e0SDimitry Andric assert(Semantics == &semPPCDoubleDouble);
4725b915e9e0SDimitry Andric }
4726b915e9e0SDimitry Andric
DoubleAPFloat(DoubleAPFloat && RHS)4727b915e9e0SDimitry Andric DoubleAPFloat::DoubleAPFloat(DoubleAPFloat &&RHS)
4728b915e9e0SDimitry Andric : Semantics(RHS.Semantics), Floats(std::move(RHS.Floats)) {
4729b915e9e0SDimitry Andric RHS.Semantics = &semBogus;
4730b915e9e0SDimitry Andric assert(Semantics == &semPPCDoubleDouble);
4731b915e9e0SDimitry Andric }
4732b915e9e0SDimitry Andric
operator =(const DoubleAPFloat & RHS)4733b915e9e0SDimitry Andric DoubleAPFloat &DoubleAPFloat::operator=(const DoubleAPFloat &RHS) {
4734b915e9e0SDimitry Andric if (Semantics == RHS.Semantics && RHS.Floats) {
4735b915e9e0SDimitry Andric Floats[0] = RHS.Floats[0];
4736b915e9e0SDimitry Andric Floats[1] = RHS.Floats[1];
4737b915e9e0SDimitry Andric } else if (this != &RHS) {
4738b915e9e0SDimitry Andric this->~DoubleAPFloat();
4739b915e9e0SDimitry Andric new (this) DoubleAPFloat(RHS);
4740b915e9e0SDimitry Andric }
4741b915e9e0SDimitry Andric return *this;
4742b915e9e0SDimitry Andric }
4743b915e9e0SDimitry Andric
474471d5a254SDimitry Andric // Implement addition, subtraction, multiplication and division based on:
4745b915e9e0SDimitry Andric // "Software for Doubled-Precision Floating-Point Computations",
4746b915e9e0SDimitry 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)4747b915e9e0SDimitry Andric APFloat::opStatus DoubleAPFloat::addImpl(const APFloat &a, const APFloat &aa,
4748b915e9e0SDimitry Andric const APFloat &c, const APFloat &cc,
4749b915e9e0SDimitry Andric roundingMode RM) {
4750b915e9e0SDimitry Andric int Status = opOK;
4751b915e9e0SDimitry Andric APFloat z = a;
4752b915e9e0SDimitry Andric Status |= z.add(c, RM);
4753b915e9e0SDimitry Andric if (!z.isFinite()) {
4754b915e9e0SDimitry Andric if (!z.isInfinity()) {
4755b915e9e0SDimitry Andric Floats[0] = std::move(z);
475671d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
4757b915e9e0SDimitry Andric return (opStatus)Status;
4758b915e9e0SDimitry Andric }
4759b915e9e0SDimitry Andric Status = opOK;
4760b915e9e0SDimitry Andric auto AComparedToC = a.compareAbsoluteValue(c);
4761b915e9e0SDimitry Andric z = cc;
4762b915e9e0SDimitry Andric Status |= z.add(aa, RM);
4763b915e9e0SDimitry Andric if (AComparedToC == APFloat::cmpGreaterThan) {
4764b915e9e0SDimitry Andric // z = cc + aa + c + a;
4765b915e9e0SDimitry Andric Status |= z.add(c, RM);
4766b915e9e0SDimitry Andric Status |= z.add(a, RM);
4767b915e9e0SDimitry Andric } else {
4768b915e9e0SDimitry Andric // z = cc + aa + a + c;
4769b915e9e0SDimitry Andric Status |= z.add(a, RM);
4770b915e9e0SDimitry Andric Status |= z.add(c, RM);
4771b915e9e0SDimitry Andric }
4772b915e9e0SDimitry Andric if (!z.isFinite()) {
4773b915e9e0SDimitry Andric Floats[0] = std::move(z);
477471d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
4775b915e9e0SDimitry Andric return (opStatus)Status;
4776b915e9e0SDimitry Andric }
4777b915e9e0SDimitry Andric Floats[0] = z;
4778b915e9e0SDimitry Andric APFloat zz = aa;
4779b915e9e0SDimitry Andric Status |= zz.add(cc, RM);
4780b915e9e0SDimitry Andric if (AComparedToC == APFloat::cmpGreaterThan) {
4781b915e9e0SDimitry Andric // Floats[1] = a - z + c + zz;
4782b915e9e0SDimitry Andric Floats[1] = a;
4783b915e9e0SDimitry Andric Status |= Floats[1].subtract(z, RM);
4784b915e9e0SDimitry Andric Status |= Floats[1].add(c, RM);
4785b915e9e0SDimitry Andric Status |= Floats[1].add(zz, RM);
4786b915e9e0SDimitry Andric } else {
4787b915e9e0SDimitry Andric // Floats[1] = c - z + a + zz;
4788b915e9e0SDimitry Andric Floats[1] = c;
4789b915e9e0SDimitry Andric Status |= Floats[1].subtract(z, RM);
4790b915e9e0SDimitry Andric Status |= Floats[1].add(a, RM);
4791b915e9e0SDimitry Andric Status |= Floats[1].add(zz, RM);
4792b915e9e0SDimitry Andric }
4793b915e9e0SDimitry Andric } else {
4794b915e9e0SDimitry Andric // q = a - z;
4795b915e9e0SDimitry Andric APFloat q = a;
4796b915e9e0SDimitry Andric Status |= q.subtract(z, RM);
4797b915e9e0SDimitry Andric
4798b915e9e0SDimitry Andric // zz = q + c + (a - (q + z)) + aa + cc;
4799b915e9e0SDimitry Andric // Compute a - (q + z) as -((q + z) - a) to avoid temporary copies.
4800b915e9e0SDimitry Andric auto zz = q;
4801b915e9e0SDimitry Andric Status |= zz.add(c, RM);
4802b915e9e0SDimitry Andric Status |= q.add(z, RM);
4803b915e9e0SDimitry Andric Status |= q.subtract(a, RM);
4804b915e9e0SDimitry Andric q.changeSign();
4805b915e9e0SDimitry Andric Status |= zz.add(q, RM);
4806b915e9e0SDimitry Andric Status |= zz.add(aa, RM);
4807b915e9e0SDimitry Andric Status |= zz.add(cc, RM);
4808b915e9e0SDimitry Andric if (zz.isZero() && !zz.isNegative()) {
4809b915e9e0SDimitry Andric Floats[0] = std::move(z);
481071d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
4811b915e9e0SDimitry Andric return opOK;
4812b915e9e0SDimitry Andric }
4813b915e9e0SDimitry Andric Floats[0] = z;
4814b915e9e0SDimitry Andric Status |= Floats[0].add(zz, RM);
4815b915e9e0SDimitry Andric if (!Floats[0].isFinite()) {
481671d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
4817b915e9e0SDimitry Andric return (opStatus)Status;
4818b915e9e0SDimitry Andric }
4819b915e9e0SDimitry Andric Floats[1] = std::move(z);
4820b915e9e0SDimitry Andric Status |= Floats[1].subtract(Floats[0], RM);
4821b915e9e0SDimitry Andric Status |= Floats[1].add(zz, RM);
4822b915e9e0SDimitry Andric }
4823b915e9e0SDimitry Andric return (opStatus)Status;
4824b915e9e0SDimitry Andric }
4825b915e9e0SDimitry Andric
addWithSpecial(const DoubleAPFloat & LHS,const DoubleAPFloat & RHS,DoubleAPFloat & Out,roundingMode RM)4826b915e9e0SDimitry Andric APFloat::opStatus DoubleAPFloat::addWithSpecial(const DoubleAPFloat &LHS,
4827b915e9e0SDimitry Andric const DoubleAPFloat &RHS,
4828b915e9e0SDimitry Andric DoubleAPFloat &Out,
4829b915e9e0SDimitry Andric roundingMode RM) {
4830b915e9e0SDimitry Andric if (LHS.getCategory() == fcNaN) {
4831b915e9e0SDimitry Andric Out = LHS;
4832b915e9e0SDimitry Andric return opOK;
4833b915e9e0SDimitry Andric }
4834b915e9e0SDimitry Andric if (RHS.getCategory() == fcNaN) {
4835b915e9e0SDimitry Andric Out = RHS;
4836b915e9e0SDimitry Andric return opOK;
4837b915e9e0SDimitry Andric }
4838b915e9e0SDimitry Andric if (LHS.getCategory() == fcZero) {
4839b915e9e0SDimitry Andric Out = RHS;
4840b915e9e0SDimitry Andric return opOK;
4841b915e9e0SDimitry Andric }
4842b915e9e0SDimitry Andric if (RHS.getCategory() == fcZero) {
4843b915e9e0SDimitry Andric Out = LHS;
4844b915e9e0SDimitry Andric return opOK;
4845b915e9e0SDimitry Andric }
4846b915e9e0SDimitry Andric if (LHS.getCategory() == fcInfinity && RHS.getCategory() == fcInfinity &&
4847b915e9e0SDimitry Andric LHS.isNegative() != RHS.isNegative()) {
4848b915e9e0SDimitry Andric Out.makeNaN(false, Out.isNegative(), nullptr);
4849b915e9e0SDimitry Andric return opInvalidOp;
4850b915e9e0SDimitry Andric }
4851b915e9e0SDimitry Andric if (LHS.getCategory() == fcInfinity) {
4852b915e9e0SDimitry Andric Out = LHS;
4853b915e9e0SDimitry Andric return opOK;
4854b915e9e0SDimitry Andric }
4855b915e9e0SDimitry Andric if (RHS.getCategory() == fcInfinity) {
4856b915e9e0SDimitry Andric Out = RHS;
4857b915e9e0SDimitry Andric return opOK;
4858b915e9e0SDimitry Andric }
4859b915e9e0SDimitry Andric assert(LHS.getCategory() == fcNormal && RHS.getCategory() == fcNormal);
4860b915e9e0SDimitry Andric
486171d5a254SDimitry Andric APFloat A(LHS.Floats[0]), AA(LHS.Floats[1]), C(RHS.Floats[0]),
4862b915e9e0SDimitry Andric CC(RHS.Floats[1]);
486371d5a254SDimitry Andric assert(&A.getSemantics() == &semIEEEdouble);
4864b915e9e0SDimitry Andric assert(&AA.getSemantics() == &semIEEEdouble);
486571d5a254SDimitry Andric assert(&C.getSemantics() == &semIEEEdouble);
4866b915e9e0SDimitry Andric assert(&CC.getSemantics() == &semIEEEdouble);
486771d5a254SDimitry Andric assert(&Out.Floats[0].getSemantics() == &semIEEEdouble);
4868b915e9e0SDimitry Andric assert(&Out.Floats[1].getSemantics() == &semIEEEdouble);
486971d5a254SDimitry Andric return Out.addImpl(A, AA, C, CC, RM);
4870b915e9e0SDimitry Andric }
4871b915e9e0SDimitry Andric
add(const DoubleAPFloat & RHS,roundingMode RM)4872b915e9e0SDimitry Andric APFloat::opStatus DoubleAPFloat::add(const DoubleAPFloat &RHS,
4873b915e9e0SDimitry Andric roundingMode RM) {
4874b915e9e0SDimitry Andric return addWithSpecial(*this, RHS, *this, RM);
4875b915e9e0SDimitry Andric }
4876b915e9e0SDimitry Andric
subtract(const DoubleAPFloat & RHS,roundingMode RM)4877b915e9e0SDimitry Andric APFloat::opStatus DoubleAPFloat::subtract(const DoubleAPFloat &RHS,
4878b915e9e0SDimitry Andric roundingMode RM) {
4879b915e9e0SDimitry Andric changeSign();
4880b915e9e0SDimitry Andric auto Ret = add(RHS, RM);
4881b915e9e0SDimitry Andric changeSign();
4882b915e9e0SDimitry Andric return Ret;
4883b915e9e0SDimitry Andric }
4884b915e9e0SDimitry Andric
multiply(const DoubleAPFloat & RHS,APFloat::roundingMode RM)488571d5a254SDimitry Andric APFloat::opStatus DoubleAPFloat::multiply(const DoubleAPFloat &RHS,
488671d5a254SDimitry Andric APFloat::roundingMode RM) {
488771d5a254SDimitry Andric const auto &LHS = *this;
488871d5a254SDimitry Andric auto &Out = *this;
488971d5a254SDimitry Andric /* Interesting observation: For special categories, finding the lowest
489071d5a254SDimitry Andric common ancestor of the following layered graph gives the correct
489171d5a254SDimitry Andric return category:
489271d5a254SDimitry Andric
489371d5a254SDimitry Andric NaN
489471d5a254SDimitry Andric / \
489571d5a254SDimitry Andric Zero Inf
489671d5a254SDimitry Andric \ /
489771d5a254SDimitry Andric Normal
489871d5a254SDimitry Andric
489971d5a254SDimitry Andric e.g. NaN * NaN = NaN
490071d5a254SDimitry Andric Zero * Inf = NaN
490171d5a254SDimitry Andric Normal * Zero = Zero
490271d5a254SDimitry Andric Normal * Inf = Inf
490371d5a254SDimitry Andric */
490471d5a254SDimitry Andric if (LHS.getCategory() == fcNaN) {
490571d5a254SDimitry Andric Out = LHS;
490671d5a254SDimitry Andric return opOK;
490771d5a254SDimitry Andric }
490871d5a254SDimitry Andric if (RHS.getCategory() == fcNaN) {
490971d5a254SDimitry Andric Out = RHS;
491071d5a254SDimitry Andric return opOK;
491171d5a254SDimitry Andric }
491271d5a254SDimitry Andric if ((LHS.getCategory() == fcZero && RHS.getCategory() == fcInfinity) ||
491371d5a254SDimitry Andric (LHS.getCategory() == fcInfinity && RHS.getCategory() == fcZero)) {
491471d5a254SDimitry Andric Out.makeNaN(false, false, nullptr);
491571d5a254SDimitry Andric return opOK;
491671d5a254SDimitry Andric }
491771d5a254SDimitry Andric if (LHS.getCategory() == fcZero || LHS.getCategory() == fcInfinity) {
491871d5a254SDimitry Andric Out = LHS;
491971d5a254SDimitry Andric return opOK;
492071d5a254SDimitry Andric }
492171d5a254SDimitry Andric if (RHS.getCategory() == fcZero || RHS.getCategory() == fcInfinity) {
492271d5a254SDimitry Andric Out = RHS;
492371d5a254SDimitry Andric return opOK;
492471d5a254SDimitry Andric }
492571d5a254SDimitry Andric assert(LHS.getCategory() == fcNormal && RHS.getCategory() == fcNormal &&
492671d5a254SDimitry Andric "Special cases not handled exhaustively");
492771d5a254SDimitry Andric
492871d5a254SDimitry Andric int Status = opOK;
492971d5a254SDimitry Andric APFloat A = Floats[0], B = Floats[1], C = RHS.Floats[0], D = RHS.Floats[1];
493071d5a254SDimitry Andric // t = a * c
493171d5a254SDimitry Andric APFloat T = A;
493271d5a254SDimitry Andric Status |= T.multiply(C, RM);
493371d5a254SDimitry Andric if (!T.isFiniteNonZero()) {
493471d5a254SDimitry Andric Floats[0] = T;
493571d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
493671d5a254SDimitry Andric return (opStatus)Status;
493771d5a254SDimitry Andric }
493871d5a254SDimitry Andric
493971d5a254SDimitry Andric // tau = fmsub(a, c, t), that is -fmadd(-a, c, t).
494071d5a254SDimitry Andric APFloat Tau = A;
494171d5a254SDimitry Andric T.changeSign();
494271d5a254SDimitry Andric Status |= Tau.fusedMultiplyAdd(C, T, RM);
494371d5a254SDimitry Andric T.changeSign();
494471d5a254SDimitry Andric {
494571d5a254SDimitry Andric // v = a * d
494671d5a254SDimitry Andric APFloat V = A;
494771d5a254SDimitry Andric Status |= V.multiply(D, RM);
494871d5a254SDimitry Andric // w = b * c
494971d5a254SDimitry Andric APFloat W = B;
495071d5a254SDimitry Andric Status |= W.multiply(C, RM);
495171d5a254SDimitry Andric Status |= V.add(W, RM);
495271d5a254SDimitry Andric // tau += v + w
495371d5a254SDimitry Andric Status |= Tau.add(V, RM);
495471d5a254SDimitry Andric }
495571d5a254SDimitry Andric // u = t + tau
495671d5a254SDimitry Andric APFloat U = T;
495771d5a254SDimitry Andric Status |= U.add(Tau, RM);
495871d5a254SDimitry Andric
495971d5a254SDimitry Andric Floats[0] = U;
496071d5a254SDimitry Andric if (!U.isFinite()) {
496171d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
496271d5a254SDimitry Andric } else {
496371d5a254SDimitry Andric // Floats[1] = (t - u) + tau
496471d5a254SDimitry Andric Status |= T.subtract(U, RM);
496571d5a254SDimitry Andric Status |= T.add(Tau, RM);
496671d5a254SDimitry Andric Floats[1] = T;
496771d5a254SDimitry Andric }
496871d5a254SDimitry Andric return (opStatus)Status;
496971d5a254SDimitry Andric }
497071d5a254SDimitry Andric
divide(const DoubleAPFloat & RHS,APFloat::roundingMode RM)497171d5a254SDimitry Andric APFloat::opStatus DoubleAPFloat::divide(const DoubleAPFloat &RHS,
497271d5a254SDimitry Andric APFloat::roundingMode RM) {
497371d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
497471d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
497571d5a254SDimitry Andric auto Ret =
497671d5a254SDimitry Andric Tmp.divide(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()), RM);
497771d5a254SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
497871d5a254SDimitry Andric return Ret;
497971d5a254SDimitry Andric }
498071d5a254SDimitry Andric
remainder(const DoubleAPFloat & RHS)498171d5a254SDimitry Andric APFloat::opStatus DoubleAPFloat::remainder(const DoubleAPFloat &RHS) {
498271d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
498371d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
498471d5a254SDimitry Andric auto Ret =
498571d5a254SDimitry Andric Tmp.remainder(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()));
498671d5a254SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
498771d5a254SDimitry Andric return Ret;
498871d5a254SDimitry Andric }
498971d5a254SDimitry Andric
mod(const DoubleAPFloat & RHS)499071d5a254SDimitry Andric APFloat::opStatus DoubleAPFloat::mod(const DoubleAPFloat &RHS) {
499171d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
499271d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
499371d5a254SDimitry Andric auto Ret = Tmp.mod(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()));
499471d5a254SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
499571d5a254SDimitry Andric return Ret;
499671d5a254SDimitry Andric }
499771d5a254SDimitry Andric
499871d5a254SDimitry Andric APFloat::opStatus
fusedMultiplyAdd(const DoubleAPFloat & Multiplicand,const DoubleAPFloat & Addend,APFloat::roundingMode RM)499971d5a254SDimitry Andric DoubleAPFloat::fusedMultiplyAdd(const DoubleAPFloat &Multiplicand,
500071d5a254SDimitry Andric const DoubleAPFloat &Addend,
500171d5a254SDimitry Andric APFloat::roundingMode RM) {
500271d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
500371d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
500471d5a254SDimitry Andric auto Ret = Tmp.fusedMultiplyAdd(
500571d5a254SDimitry Andric APFloat(semPPCDoubleDoubleLegacy, Multiplicand.bitcastToAPInt()),
500671d5a254SDimitry Andric APFloat(semPPCDoubleDoubleLegacy, Addend.bitcastToAPInt()), RM);
500771d5a254SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
500871d5a254SDimitry Andric return Ret;
500971d5a254SDimitry Andric }
501071d5a254SDimitry Andric
roundToIntegral(APFloat::roundingMode RM)501171d5a254SDimitry Andric APFloat::opStatus DoubleAPFloat::roundToIntegral(APFloat::roundingMode RM) {
501271d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
501371d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
501471d5a254SDimitry Andric auto Ret = Tmp.roundToIntegral(RM);
501571d5a254SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
501671d5a254SDimitry Andric return Ret;
501771d5a254SDimitry Andric }
501871d5a254SDimitry Andric
changeSign()5019b915e9e0SDimitry Andric void DoubleAPFloat::changeSign() {
5020b915e9e0SDimitry Andric Floats[0].changeSign();
5021b915e9e0SDimitry Andric Floats[1].changeSign();
5022b915e9e0SDimitry Andric }
5023b915e9e0SDimitry Andric
5024b915e9e0SDimitry Andric APFloat::cmpResult
compareAbsoluteValue(const DoubleAPFloat & RHS) const5025b915e9e0SDimitry Andric DoubleAPFloat::compareAbsoluteValue(const DoubleAPFloat &RHS) const {
5026b915e9e0SDimitry Andric auto Result = Floats[0].compareAbsoluteValue(RHS.Floats[0]);
5027b915e9e0SDimitry Andric if (Result != cmpEqual)
5028b915e9e0SDimitry Andric return Result;
5029b915e9e0SDimitry Andric Result = Floats[1].compareAbsoluteValue(RHS.Floats[1]);
5030b915e9e0SDimitry Andric if (Result == cmpLessThan || Result == cmpGreaterThan) {
5031b915e9e0SDimitry Andric auto Against = Floats[0].isNegative() ^ Floats[1].isNegative();
5032b915e9e0SDimitry Andric auto RHSAgainst = RHS.Floats[0].isNegative() ^ RHS.Floats[1].isNegative();
5033b915e9e0SDimitry Andric if (Against && !RHSAgainst)
5034b915e9e0SDimitry Andric return cmpLessThan;
5035b915e9e0SDimitry Andric if (!Against && RHSAgainst)
5036b915e9e0SDimitry Andric return cmpGreaterThan;
5037b915e9e0SDimitry Andric if (!Against && !RHSAgainst)
5038b915e9e0SDimitry Andric return Result;
5039b915e9e0SDimitry Andric if (Against && RHSAgainst)
5040b915e9e0SDimitry Andric return (cmpResult)(cmpLessThan + cmpGreaterThan - Result);
5041b915e9e0SDimitry Andric }
5042b915e9e0SDimitry Andric return Result;
5043b915e9e0SDimitry Andric }
5044b915e9e0SDimitry Andric
getCategory() const5045b915e9e0SDimitry Andric APFloat::fltCategory DoubleAPFloat::getCategory() const {
5046b915e9e0SDimitry Andric return Floats[0].getCategory();
5047b915e9e0SDimitry Andric }
5048b915e9e0SDimitry Andric
isNegative() const5049b915e9e0SDimitry Andric bool DoubleAPFloat::isNegative() const { return Floats[0].isNegative(); }
5050b915e9e0SDimitry Andric
makeInf(bool Neg)5051b915e9e0SDimitry Andric void DoubleAPFloat::makeInf(bool Neg) {
5052b915e9e0SDimitry Andric Floats[0].makeInf(Neg);
505371d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
505471d5a254SDimitry Andric }
505571d5a254SDimitry Andric
makeZero(bool Neg)505671d5a254SDimitry Andric void DoubleAPFloat::makeZero(bool Neg) {
505771d5a254SDimitry Andric Floats[0].makeZero(Neg);
505871d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
505971d5a254SDimitry Andric }
506071d5a254SDimitry Andric
makeLargest(bool Neg)506171d5a254SDimitry Andric void DoubleAPFloat::makeLargest(bool Neg) {
506271d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
506371d5a254SDimitry Andric Floats[0] = APFloat(semIEEEdouble, APInt(64, 0x7fefffffffffffffull));
506471d5a254SDimitry Andric Floats[1] = APFloat(semIEEEdouble, APInt(64, 0x7c8ffffffffffffeull));
506571d5a254SDimitry Andric if (Neg)
506671d5a254SDimitry Andric changeSign();
506771d5a254SDimitry Andric }
506871d5a254SDimitry Andric
makeSmallest(bool Neg)506971d5a254SDimitry Andric void DoubleAPFloat::makeSmallest(bool Neg) {
507071d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
507171d5a254SDimitry Andric Floats[0].makeSmallest(Neg);
507271d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
507371d5a254SDimitry Andric }
507471d5a254SDimitry Andric
makeSmallestNormalized(bool Neg)507571d5a254SDimitry Andric void DoubleAPFloat::makeSmallestNormalized(bool Neg) {
507671d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
507771d5a254SDimitry Andric Floats[0] = APFloat(semIEEEdouble, APInt(64, 0x0360000000000000ull));
507871d5a254SDimitry Andric if (Neg)
507971d5a254SDimitry Andric Floats[0].changeSign();
508071d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
5081b915e9e0SDimitry Andric }
5082b915e9e0SDimitry Andric
makeNaN(bool SNaN,bool Neg,const APInt * fill)5083b915e9e0SDimitry Andric void DoubleAPFloat::makeNaN(bool SNaN, bool Neg, const APInt *fill) {
5084b915e9e0SDimitry Andric Floats[0].makeNaN(SNaN, Neg, fill);
508571d5a254SDimitry Andric Floats[1].makeZero(/* Neg = */ false);
508671d5a254SDimitry Andric }
508771d5a254SDimitry Andric
compare(const DoubleAPFloat & RHS) const508871d5a254SDimitry Andric APFloat::cmpResult DoubleAPFloat::compare(const DoubleAPFloat &RHS) const {
508971d5a254SDimitry Andric auto Result = Floats[0].compare(RHS.Floats[0]);
509071d5a254SDimitry Andric // |Float[0]| > |Float[1]|
509171d5a254SDimitry Andric if (Result == APFloat::cmpEqual)
509271d5a254SDimitry Andric return Floats[1].compare(RHS.Floats[1]);
509371d5a254SDimitry Andric return Result;
509471d5a254SDimitry Andric }
509571d5a254SDimitry Andric
bitwiseIsEqual(const DoubleAPFloat & RHS) const509671d5a254SDimitry Andric bool DoubleAPFloat::bitwiseIsEqual(const DoubleAPFloat &RHS) const {
509771d5a254SDimitry Andric return Floats[0].bitwiseIsEqual(RHS.Floats[0]) &&
509871d5a254SDimitry Andric Floats[1].bitwiseIsEqual(RHS.Floats[1]);
509971d5a254SDimitry Andric }
510071d5a254SDimitry Andric
hash_value(const DoubleAPFloat & Arg)510171d5a254SDimitry Andric hash_code hash_value(const DoubleAPFloat &Arg) {
510271d5a254SDimitry Andric if (Arg.Floats)
510371d5a254SDimitry Andric return hash_combine(hash_value(Arg.Floats[0]), hash_value(Arg.Floats[1]));
510471d5a254SDimitry Andric return hash_combine(Arg.Semantics);
510571d5a254SDimitry Andric }
510671d5a254SDimitry Andric
bitcastToAPInt() const510771d5a254SDimitry Andric APInt DoubleAPFloat::bitcastToAPInt() const {
510871d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
510971d5a254SDimitry Andric uint64_t Data[] = {
511071d5a254SDimitry Andric Floats[0].bitcastToAPInt().getRawData()[0],
511171d5a254SDimitry Andric Floats[1].bitcastToAPInt().getRawData()[0],
511271d5a254SDimitry Andric };
511371d5a254SDimitry Andric return APInt(128, 2, Data);
511471d5a254SDimitry Andric }
511571d5a254SDimitry Andric
convertFromString(StringRef S,roundingMode RM)5116706b4fc4SDimitry Andric Expected<APFloat::opStatus> DoubleAPFloat::convertFromString(StringRef S,
511771d5a254SDimitry Andric roundingMode RM) {
511871d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
511971d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy);
512071d5a254SDimitry Andric auto Ret = Tmp.convertFromString(S, RM);
512171d5a254SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
512271d5a254SDimitry Andric return Ret;
512371d5a254SDimitry Andric }
512471d5a254SDimitry Andric
next(bool nextDown)512571d5a254SDimitry Andric APFloat::opStatus DoubleAPFloat::next(bool nextDown) {
512671d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
512771d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
512871d5a254SDimitry Andric auto Ret = Tmp.next(nextDown);
512971d5a254SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
513071d5a254SDimitry Andric return Ret;
513171d5a254SDimitry Andric }
513271d5a254SDimitry Andric
513371d5a254SDimitry Andric APFloat::opStatus
convertToInteger(MutableArrayRef<integerPart> Input,unsigned int Width,bool IsSigned,roundingMode RM,bool * IsExact) const513471d5a254SDimitry Andric DoubleAPFloat::convertToInteger(MutableArrayRef<integerPart> Input,
513571d5a254SDimitry Andric unsigned int Width, bool IsSigned,
513671d5a254SDimitry Andric roundingMode RM, bool *IsExact) const {
513771d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
513871d5a254SDimitry Andric return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
513971d5a254SDimitry Andric .convertToInteger(Input, Width, IsSigned, RM, IsExact);
514071d5a254SDimitry Andric }
514171d5a254SDimitry Andric
convertFromAPInt(const APInt & Input,bool IsSigned,roundingMode RM)514271d5a254SDimitry Andric APFloat::opStatus DoubleAPFloat::convertFromAPInt(const APInt &Input,
514371d5a254SDimitry Andric bool IsSigned,
514471d5a254SDimitry Andric roundingMode RM) {
514571d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
514671d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy);
514771d5a254SDimitry Andric auto Ret = Tmp.convertFromAPInt(Input, IsSigned, RM);
514871d5a254SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
514971d5a254SDimitry Andric return Ret;
515071d5a254SDimitry Andric }
515171d5a254SDimitry Andric
515271d5a254SDimitry Andric APFloat::opStatus
convertFromSignExtendedInteger(const integerPart * Input,unsigned int InputSize,bool IsSigned,roundingMode RM)515371d5a254SDimitry Andric DoubleAPFloat::convertFromSignExtendedInteger(const integerPart *Input,
515471d5a254SDimitry Andric unsigned int InputSize,
515571d5a254SDimitry Andric bool IsSigned, roundingMode RM) {
515671d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
515771d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy);
515871d5a254SDimitry Andric auto Ret = Tmp.convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM);
515971d5a254SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
516071d5a254SDimitry Andric return Ret;
516171d5a254SDimitry Andric }
516271d5a254SDimitry Andric
516371d5a254SDimitry Andric APFloat::opStatus
convertFromZeroExtendedInteger(const integerPart * Input,unsigned int InputSize,bool IsSigned,roundingMode RM)516471d5a254SDimitry Andric DoubleAPFloat::convertFromZeroExtendedInteger(const integerPart *Input,
516571d5a254SDimitry Andric unsigned int InputSize,
516671d5a254SDimitry Andric bool IsSigned, roundingMode RM) {
516771d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
516871d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy);
516971d5a254SDimitry Andric auto Ret = Tmp.convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM);
517071d5a254SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt());
517171d5a254SDimitry Andric return Ret;
517271d5a254SDimitry Andric }
517371d5a254SDimitry Andric
convertToHexString(char * DST,unsigned int HexDigits,bool UpperCase,roundingMode RM) const517471d5a254SDimitry Andric unsigned int DoubleAPFloat::convertToHexString(char *DST,
517571d5a254SDimitry Andric unsigned int HexDigits,
517671d5a254SDimitry Andric bool UpperCase,
517771d5a254SDimitry Andric roundingMode RM) const {
517871d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
517971d5a254SDimitry Andric return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
518071d5a254SDimitry Andric .convertToHexString(DST, HexDigits, UpperCase, RM);
518171d5a254SDimitry Andric }
518271d5a254SDimitry Andric
isDenormal() const518371d5a254SDimitry Andric bool DoubleAPFloat::isDenormal() const {
518471d5a254SDimitry Andric return getCategory() == fcNormal &&
518571d5a254SDimitry Andric (Floats[0].isDenormal() || Floats[1].isDenormal() ||
518671d5a254SDimitry Andric // (double)(Hi + Lo) == Hi defines a normal number.
5187cfca06d7SDimitry Andric Floats[0] != Floats[0] + Floats[1]);
518871d5a254SDimitry Andric }
518971d5a254SDimitry Andric
isSmallest() const519071d5a254SDimitry Andric bool DoubleAPFloat::isSmallest() const {
519171d5a254SDimitry Andric if (getCategory() != fcNormal)
519271d5a254SDimitry Andric return false;
519371d5a254SDimitry Andric DoubleAPFloat Tmp(*this);
519471d5a254SDimitry Andric Tmp.makeSmallest(this->isNegative());
519571d5a254SDimitry Andric return Tmp.compare(*this) == cmpEqual;
519671d5a254SDimitry Andric }
519771d5a254SDimitry Andric
isSmallestNormalized() const5198e3b55780SDimitry Andric bool DoubleAPFloat::isSmallestNormalized() const {
5199e3b55780SDimitry Andric if (getCategory() != fcNormal)
5200e3b55780SDimitry Andric return false;
5201e3b55780SDimitry Andric
5202e3b55780SDimitry Andric DoubleAPFloat Tmp(*this);
5203e3b55780SDimitry Andric Tmp.makeSmallestNormalized(this->isNegative());
5204e3b55780SDimitry Andric return Tmp.compare(*this) == cmpEqual;
5205e3b55780SDimitry Andric }
5206e3b55780SDimitry Andric
isLargest() const520771d5a254SDimitry Andric bool DoubleAPFloat::isLargest() const {
520871d5a254SDimitry Andric if (getCategory() != fcNormal)
520971d5a254SDimitry Andric return false;
521071d5a254SDimitry Andric DoubleAPFloat Tmp(*this);
521171d5a254SDimitry Andric Tmp.makeLargest(this->isNegative());
521271d5a254SDimitry Andric return Tmp.compare(*this) == cmpEqual;
521371d5a254SDimitry Andric }
521471d5a254SDimitry Andric
isInteger() const521571d5a254SDimitry Andric bool DoubleAPFloat::isInteger() const {
521671d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
5217044eb2f6SDimitry Andric return Floats[0].isInteger() && Floats[1].isInteger();
521871d5a254SDimitry Andric }
521971d5a254SDimitry Andric
toString(SmallVectorImpl<char> & Str,unsigned FormatPrecision,unsigned FormatMaxPadding,bool TruncateZero) const522071d5a254SDimitry Andric void DoubleAPFloat::toString(SmallVectorImpl<char> &Str,
522171d5a254SDimitry Andric unsigned FormatPrecision,
522212f3ca4cSDimitry Andric unsigned FormatMaxPadding,
522312f3ca4cSDimitry Andric bool TruncateZero) const {
522471d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
522571d5a254SDimitry Andric APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
522612f3ca4cSDimitry Andric .toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero);
522771d5a254SDimitry Andric }
522871d5a254SDimitry Andric
getExactInverse(APFloat * inv) const522971d5a254SDimitry Andric bool DoubleAPFloat::getExactInverse(APFloat *inv) const {
523071d5a254SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
523171d5a254SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt());
523271d5a254SDimitry Andric if (!inv)
523371d5a254SDimitry Andric return Tmp.getExactInverse(nullptr);
523471d5a254SDimitry Andric APFloat Inv(semPPCDoubleDoubleLegacy);
523571d5a254SDimitry Andric auto Ret = Tmp.getExactInverse(&Inv);
523671d5a254SDimitry Andric *inv = APFloat(semPPCDoubleDouble, Inv.bitcastToAPInt());
523771d5a254SDimitry Andric return Ret;
523871d5a254SDimitry Andric }
523971d5a254SDimitry Andric
getExactLog2() const5240b1c73532SDimitry Andric int DoubleAPFloat::getExactLog2() const {
5241b1c73532SDimitry Andric // TODO: Implement me
5242b1c73532SDimitry Andric return INT_MIN;
5243b1c73532SDimitry Andric }
5244b1c73532SDimitry Andric
getExactLog2Abs() const5245b1c73532SDimitry Andric int DoubleAPFloat::getExactLog2Abs() const {
5246b1c73532SDimitry Andric // TODO: Implement me
5247b1c73532SDimitry Andric return INT_MIN;
5248b1c73532SDimitry Andric }
5249b1c73532SDimitry Andric
scalbn(const DoubleAPFloat & Arg,int Exp,APFloat::roundingMode RM)5250344a3780SDimitry Andric DoubleAPFloat scalbn(const DoubleAPFloat &Arg, int Exp,
5251344a3780SDimitry Andric APFloat::roundingMode RM) {
525271d5a254SDimitry Andric assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
525371d5a254SDimitry Andric return DoubleAPFloat(semPPCDoubleDouble, scalbn(Arg.Floats[0], Exp, RM),
525471d5a254SDimitry Andric scalbn(Arg.Floats[1], Exp, RM));
525571d5a254SDimitry Andric }
525671d5a254SDimitry Andric
frexp(const DoubleAPFloat & Arg,int & Exp,APFloat::roundingMode RM)525771d5a254SDimitry Andric DoubleAPFloat frexp(const DoubleAPFloat &Arg, int &Exp,
525871d5a254SDimitry Andric APFloat::roundingMode RM) {
525971d5a254SDimitry Andric assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
526071d5a254SDimitry Andric APFloat First = frexp(Arg.Floats[0], Exp, RM);
526171d5a254SDimitry Andric APFloat Second = Arg.Floats[1];
526271d5a254SDimitry Andric if (Arg.getCategory() == APFloat::fcNormal)
526371d5a254SDimitry Andric Second = scalbn(Second, -Exp, RM);
526471d5a254SDimitry Andric return DoubleAPFloat(semPPCDoubleDouble, std::move(First), std::move(Second));
5265b915e9e0SDimitry Andric }
5266b915e9e0SDimitry Andric
5267344a3780SDimitry Andric } // namespace detail
5268b915e9e0SDimitry Andric
Storage(IEEEFloat F,const fltSemantics & Semantics)5269b915e9e0SDimitry Andric APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) {
5270b915e9e0SDimitry Andric if (usesLayout<IEEEFloat>(Semantics)) {
5271b915e9e0SDimitry Andric new (&IEEE) IEEEFloat(std::move(F));
5272b915e9e0SDimitry Andric return;
5273b915e9e0SDimitry Andric }
5274b915e9e0SDimitry Andric if (usesLayout<DoubleAPFloat>(Semantics)) {
5275e6d15924SDimitry Andric const fltSemantics& S = F.getSemantics();
5276b915e9e0SDimitry Andric new (&Double)
5277e6d15924SDimitry Andric DoubleAPFloat(Semantics, APFloat(std::move(F), S),
5278b915e9e0SDimitry Andric APFloat(semIEEEdouble));
5279b915e9e0SDimitry Andric return;
5280b915e9e0SDimitry Andric }
5281b915e9e0SDimitry Andric llvm_unreachable("Unexpected semantics");
5282b915e9e0SDimitry Andric }
5283b915e9e0SDimitry Andric
convertFromString(StringRef Str,roundingMode RM)5284706b4fc4SDimitry Andric Expected<APFloat::opStatus> APFloat::convertFromString(StringRef Str,
5285706b4fc4SDimitry Andric roundingMode RM) {
528671d5a254SDimitry Andric APFLOAT_DISPATCH_ON_SEMANTICS(convertFromString(Str, RM));
5287b915e9e0SDimitry Andric }
5288b915e9e0SDimitry Andric
hash_value(const APFloat & Arg)528971d5a254SDimitry Andric hash_code hash_value(const APFloat &Arg) {
529071d5a254SDimitry Andric if (APFloat::usesLayout<detail::IEEEFloat>(Arg.getSemantics()))
529171d5a254SDimitry Andric return hash_value(Arg.U.IEEE);
529271d5a254SDimitry Andric if (APFloat::usesLayout<detail::DoubleAPFloat>(Arg.getSemantics()))
529371d5a254SDimitry Andric return hash_value(Arg.U.Double);
529471d5a254SDimitry Andric llvm_unreachable("Unexpected semantics");
529571d5a254SDimitry Andric }
5296b915e9e0SDimitry Andric
APFloat(const fltSemantics & Semantics,StringRef S)5297b915e9e0SDimitry Andric APFloat::APFloat(const fltSemantics &Semantics, StringRef S)
5298b915e9e0SDimitry Andric : APFloat(Semantics) {
5299706b4fc4SDimitry Andric auto StatusOrErr = convertFromString(S, rmNearestTiesToEven);
5300706b4fc4SDimitry Andric assert(StatusOrErr && "Invalid floating point representation");
5301706b4fc4SDimitry Andric consumeError(StatusOrErr.takeError());
5302b915e9e0SDimitry Andric }
5303b915e9e0SDimitry Andric
classify() const53047fa27ce4SDimitry Andric FPClassTest APFloat::classify() const {
53057fa27ce4SDimitry Andric if (isZero())
53067fa27ce4SDimitry Andric return isNegative() ? fcNegZero : fcPosZero;
53077fa27ce4SDimitry Andric if (isNormal())
53087fa27ce4SDimitry Andric return isNegative() ? fcNegNormal : fcPosNormal;
53097fa27ce4SDimitry Andric if (isDenormal())
53107fa27ce4SDimitry Andric return isNegative() ? fcNegSubnormal : fcPosSubnormal;
53117fa27ce4SDimitry Andric if (isInfinity())
53127fa27ce4SDimitry Andric return isNegative() ? fcNegInf : fcPosInf;
53137fa27ce4SDimitry Andric assert(isNaN() && "Other class of FP constant");
53147fa27ce4SDimitry Andric return isSignaling() ? fcSNan : fcQNan;
53157fa27ce4SDimitry Andric }
53167fa27ce4SDimitry Andric
convert(const fltSemantics & ToSemantics,roundingMode RM,bool * losesInfo)5317b915e9e0SDimitry Andric APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics,
5318b915e9e0SDimitry Andric roundingMode RM, bool *losesInfo) {
5319eb11fae6SDimitry Andric if (&getSemantics() == &ToSemantics) {
5320eb11fae6SDimitry Andric *losesInfo = false;
5321b915e9e0SDimitry Andric return opOK;
5322eb11fae6SDimitry Andric }
5323b915e9e0SDimitry Andric if (usesLayout<IEEEFloat>(getSemantics()) &&
5324b915e9e0SDimitry Andric usesLayout<IEEEFloat>(ToSemantics))
5325b915e9e0SDimitry Andric return U.IEEE.convert(ToSemantics, RM, losesInfo);
5326b915e9e0SDimitry Andric if (usesLayout<IEEEFloat>(getSemantics()) &&
5327b915e9e0SDimitry Andric usesLayout<DoubleAPFloat>(ToSemantics)) {
5328b915e9e0SDimitry Andric assert(&ToSemantics == &semPPCDoubleDouble);
532971d5a254SDimitry Andric auto Ret = U.IEEE.convert(semPPCDoubleDoubleLegacy, RM, losesInfo);
533071d5a254SDimitry Andric *this = APFloat(ToSemantics, U.IEEE.bitcastToAPInt());
5331b915e9e0SDimitry Andric return Ret;
5332b915e9e0SDimitry Andric }
5333b915e9e0SDimitry Andric if (usesLayout<DoubleAPFloat>(getSemantics()) &&
5334b915e9e0SDimitry Andric usesLayout<IEEEFloat>(ToSemantics)) {
5335b915e9e0SDimitry Andric auto Ret = getIEEE().convert(ToSemantics, RM, losesInfo);
5336b915e9e0SDimitry Andric *this = APFloat(std::move(getIEEE()), ToSemantics);
5337b915e9e0SDimitry Andric return Ret;
5338b915e9e0SDimitry Andric }
5339b915e9e0SDimitry Andric llvm_unreachable("Unexpected semantics");
5340b915e9e0SDimitry Andric }
5341b915e9e0SDimitry Andric
getAllOnesValue(const fltSemantics & Semantics)5342c0981da4SDimitry Andric APFloat APFloat::getAllOnesValue(const fltSemantics &Semantics) {
5343c0981da4SDimitry Andric return APFloat(Semantics, APInt::getAllOnes(Semantics.sizeInBits));
5344b915e9e0SDimitry Andric }
5345b915e9e0SDimitry Andric
print(raw_ostream & OS) const5346b915e9e0SDimitry Andric void APFloat::print(raw_ostream &OS) const {
5347b915e9e0SDimitry Andric SmallVector<char, 16> Buffer;
5348b915e9e0SDimitry Andric toString(Buffer);
5349b915e9e0SDimitry Andric OS << Buffer << "\n";
5350b915e9e0SDimitry Andric }
5351b915e9e0SDimitry Andric
535271d5a254SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const535371d5a254SDimitry Andric LLVM_DUMP_METHOD void APFloat::dump() const { print(dbgs()); }
535471d5a254SDimitry Andric #endif
535571d5a254SDimitry Andric
Profile(FoldingSetNodeID & NID) const535671d5a254SDimitry Andric void APFloat::Profile(FoldingSetNodeID &NID) const {
535771d5a254SDimitry Andric NID.Add(bitcastToAPInt());
535871d5a254SDimitry Andric }
535971d5a254SDimitry Andric
536071d5a254SDimitry Andric /* Same as convertToInteger(integerPart*, ...), except the result is returned in
536171d5a254SDimitry Andric an APSInt, whose initial bit-width and signed-ness are used to determine the
536271d5a254SDimitry Andric precision of the conversion.
536371d5a254SDimitry Andric */
convertToInteger(APSInt & result,roundingMode rounding_mode,bool * isExact) const536471d5a254SDimitry Andric APFloat::opStatus APFloat::convertToInteger(APSInt &result,
536571d5a254SDimitry Andric roundingMode rounding_mode,
536671d5a254SDimitry Andric bool *isExact) const {
536771d5a254SDimitry Andric unsigned bitWidth = result.getBitWidth();
536871d5a254SDimitry Andric SmallVector<uint64_t, 4> parts(result.getNumWords());
536971d5a254SDimitry Andric opStatus status = convertToInteger(parts, bitWidth, result.isSigned(),
537071d5a254SDimitry Andric rounding_mode, isExact);
537171d5a254SDimitry Andric // Keeps the original signed-ness.
537271d5a254SDimitry Andric result = APInt(bitWidth, parts);
537371d5a254SDimitry Andric return status;
537471d5a254SDimitry Andric }
5375b915e9e0SDimitry Andric
convertToDouble() const5376344a3780SDimitry Andric double APFloat::convertToDouble() const {
5377344a3780SDimitry Andric if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEdouble)
5378344a3780SDimitry Andric return getIEEE().convertToDouble();
5379344a3780SDimitry Andric assert(getSemantics().isRepresentableBy(semIEEEdouble) &&
5380344a3780SDimitry Andric "Float semantics is not representable by IEEEdouble");
5381344a3780SDimitry Andric APFloat Temp = *this;
5382344a3780SDimitry Andric bool LosesInfo;
5383344a3780SDimitry Andric opStatus St = Temp.convert(semIEEEdouble, rmNearestTiesToEven, &LosesInfo);
5384344a3780SDimitry Andric assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision");
5385344a3780SDimitry Andric (void)St;
5386344a3780SDimitry Andric return Temp.getIEEE().convertToDouble();
5387344a3780SDimitry Andric }
5388344a3780SDimitry Andric
5389ac9a064cSDimitry Andric #ifdef HAS_IEE754_FLOAT128
convertToQuad() const5390ac9a064cSDimitry Andric float128 APFloat::convertToQuad() const {
5391ac9a064cSDimitry Andric if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEquad)
5392ac9a064cSDimitry Andric return getIEEE().convertToQuad();
5393ac9a064cSDimitry Andric assert(getSemantics().isRepresentableBy(semIEEEquad) &&
5394ac9a064cSDimitry Andric "Float semantics is not representable by IEEEquad");
5395ac9a064cSDimitry Andric APFloat Temp = *this;
5396ac9a064cSDimitry Andric bool LosesInfo;
5397ac9a064cSDimitry Andric opStatus St = Temp.convert(semIEEEquad, rmNearestTiesToEven, &LosesInfo);
5398ac9a064cSDimitry Andric assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision");
5399ac9a064cSDimitry Andric (void)St;
5400ac9a064cSDimitry Andric return Temp.getIEEE().convertToQuad();
5401ac9a064cSDimitry Andric }
5402ac9a064cSDimitry Andric #endif
5403ac9a064cSDimitry Andric
convertToFloat() const5404344a3780SDimitry Andric float APFloat::convertToFloat() const {
5405344a3780SDimitry Andric if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle)
5406344a3780SDimitry Andric return getIEEE().convertToFloat();
5407344a3780SDimitry Andric assert(getSemantics().isRepresentableBy(semIEEEsingle) &&
5408344a3780SDimitry Andric "Float semantics is not representable by IEEEsingle");
5409344a3780SDimitry Andric APFloat Temp = *this;
5410344a3780SDimitry Andric bool LosesInfo;
5411344a3780SDimitry Andric opStatus St = Temp.convert(semIEEEsingle, rmNearestTiesToEven, &LosesInfo);
5412344a3780SDimitry Andric assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision");
5413344a3780SDimitry Andric (void)St;
5414344a3780SDimitry Andric return Temp.getIEEE().convertToFloat();
5415344a3780SDimitry Andric }
5416344a3780SDimitry Andric
5417b60736ecSDimitry Andric } // namespace llvm
541871d5a254SDimitry Andric
541971d5a254SDimitry Andric #undef APFLOAT_DISPATCH_ON_SEMANTICS
5420