10b57cec5SDimitry Andric //===-- APFloat.cpp - Implement APFloat class -----------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements a class to represent arbitrary precision floating 100b57cec5SDimitry Andric // point values and provide a variety of arithmetic operations on them. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h" 150b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h" 160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 1706c3fb27SDimitry Andric #include "llvm/ADT/FloatingPointMode.h" 180b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h" 190b57cec5SDimitry Andric #include "llvm/ADT/Hashing.h" 2006c3fb27SDimitry Andric #include "llvm/ADT/STLExtras.h" 210b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 220b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 230b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h" 240b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 25480093f4SDimitry Andric #include "llvm/Support/Error.h" 260b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 270b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 280b57cec5SDimitry Andric #include <cstring> 290b57cec5SDimitry Andric #include <limits.h> 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric #define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \ 320b57cec5SDimitry Andric do { \ 330b57cec5SDimitry Andric if (usesLayout<IEEEFloat>(getSemantics())) \ 340b57cec5SDimitry Andric return U.IEEE.METHOD_CALL; \ 350b57cec5SDimitry Andric if (usesLayout<DoubleAPFloat>(getSemantics())) \ 360b57cec5SDimitry Andric return U.Double.METHOD_CALL; \ 370b57cec5SDimitry Andric llvm_unreachable("Unexpected semantics"); \ 380b57cec5SDimitry Andric } while (false) 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric using namespace llvm; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric /// A macro used to combine two fcCategory enums into one key which can be used 430b57cec5SDimitry Andric /// in a switch statement to classify how the interaction of two APFloat's 440b57cec5SDimitry Andric /// categories affects an operation. 450b57cec5SDimitry Andric /// 460b57cec5SDimitry Andric /// TODO: If clang source code is ever allowed to use constexpr in its own 470b57cec5SDimitry Andric /// codebase, change this into a static inline function. 480b57cec5SDimitry Andric #define PackCategoriesIntoKey(_lhs, _rhs) ((_lhs) * 4 + (_rhs)) 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric /* Assumed in hexadecimal significand parsing, and conversion to 510b57cec5SDimitry Andric hexadecimal strings. */ 520b57cec5SDimitry Andric static_assert(APFloatBase::integerPartWidth % 4 == 0, "Part width must be divisible by 4!"); 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric namespace llvm { 55bdd1243dSDimitry Andric 56bdd1243dSDimitry Andric // How the nonfinite values Inf and NaN are represented. 57bdd1243dSDimitry Andric enum class fltNonfiniteBehavior { 58bdd1243dSDimitry Andric // Represents standard IEEE 754 behavior. A value is nonfinite if the 59bdd1243dSDimitry Andric // exponent field is all 1s. In such cases, a value is Inf if the 60bdd1243dSDimitry Andric // significand bits are all zero, and NaN otherwise 61bdd1243dSDimitry Andric IEEE754, 62bdd1243dSDimitry Andric 6306c3fb27SDimitry Andric // This behavior is present in the Float8ExMyFN* types (Float8E4M3FN, 6406c3fb27SDimitry Andric // Float8E5M2FNUZ, Float8E4M3FNUZ, and Float8E4M3B11FNUZ). There is no 6506c3fb27SDimitry Andric // representation for Inf, and operations that would ordinarily produce Inf 6606c3fb27SDimitry Andric // produce NaN instead. 6706c3fb27SDimitry Andric // The details of the NaN representation(s) in this form are determined by the 6806c3fb27SDimitry Andric // `fltNanEncoding` enum. We treat all NaNs as quiet, as the available 6906c3fb27SDimitry Andric // encodings do not distinguish between signalling and quiet NaN. 7006c3fb27SDimitry Andric NanOnly, 71*0fca6ea1SDimitry Andric 72*0fca6ea1SDimitry Andric // This behavior is present in Float6E3M2FN, Float6E2M3FN, and 73*0fca6ea1SDimitry Andric // Float4E2M1FN types, which do not support Inf or NaN values. 74*0fca6ea1SDimitry Andric FiniteOnly, 7506c3fb27SDimitry Andric }; 7606c3fb27SDimitry Andric 7706c3fb27SDimitry Andric // How NaN values are represented. This is curently only used in combination 7806c3fb27SDimitry Andric // with fltNonfiniteBehavior::NanOnly, and using a variant other than IEEE 7906c3fb27SDimitry Andric // while having IEEE non-finite behavior is liable to lead to unexpected 8006c3fb27SDimitry Andric // results. 8106c3fb27SDimitry Andric enum class fltNanEncoding { 8206c3fb27SDimitry Andric // Represents the standard IEEE behavior where a value is NaN if its 8306c3fb27SDimitry Andric // exponent is all 1s and the significand is non-zero. 8406c3fb27SDimitry Andric IEEE, 8506c3fb27SDimitry Andric 86*0fca6ea1SDimitry Andric // Represents the behavior in the Float8E4M3FN floating point type where NaN 87*0fca6ea1SDimitry Andric // is represented by having the exponent and mantissa set to all 1s. 88bdd1243dSDimitry Andric // This behavior matches the FP8 E4M3 type described in 89bdd1243dSDimitry Andric // https://arxiv.org/abs/2209.05433. We treat both signed and unsigned NaNs 90bdd1243dSDimitry Andric // as non-signalling, although the paper does not state whether the NaN 91bdd1243dSDimitry Andric // values are signalling or not. 9206c3fb27SDimitry Andric AllOnes, 9306c3fb27SDimitry Andric 9406c3fb27SDimitry Andric // Represents the behavior in Float8E{5,4}E{2,3}FNUZ floating point types 9506c3fb27SDimitry Andric // where NaN is represented by a sign bit of 1 and all 0s in the exponent 9606c3fb27SDimitry Andric // and mantissa (i.e. the negative zero encoding in a IEEE float). Since 9706c3fb27SDimitry Andric // there is only one NaN value, it is treated as quiet NaN. This matches the 9806c3fb27SDimitry Andric // behavior described in https://arxiv.org/abs/2206.02915 . 9906c3fb27SDimitry Andric NegativeZero, 100bdd1243dSDimitry Andric }; 101bdd1243dSDimitry Andric 1020b57cec5SDimitry Andric /* Represents floating point arithmetic semantics. */ 1030b57cec5SDimitry Andric struct fltSemantics { 1040b57cec5SDimitry Andric /* The largest E such that 2^E is representable; this matches the 1050b57cec5SDimitry Andric definition of IEEE 754. */ 1060b57cec5SDimitry Andric APFloatBase::ExponentType maxExponent; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric /* The smallest E such that 2^E is a normalized number; this 1090b57cec5SDimitry Andric matches the definition of IEEE 754. */ 1100b57cec5SDimitry Andric APFloatBase::ExponentType minExponent; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric /* Number of bits in the significand. This includes the integer 1130b57cec5SDimitry Andric bit. */ 1140b57cec5SDimitry Andric unsigned int precision; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric /* Number of bits actually used in the semantics. */ 1170b57cec5SDimitry Andric unsigned int sizeInBits; 118fe6060f1SDimitry Andric 119bdd1243dSDimitry Andric fltNonfiniteBehavior nonFiniteBehavior = fltNonfiniteBehavior::IEEE754; 120bdd1243dSDimitry Andric 12106c3fb27SDimitry Andric fltNanEncoding nanEncoding = fltNanEncoding::IEEE; 122fe6060f1SDimitry Andric // Returns true if any number described by this semantics can be precisely 123bdd1243dSDimitry Andric // represented by the specified semantics. Does not take into account 124bdd1243dSDimitry Andric // the value of fltNonfiniteBehavior. 125fe6060f1SDimitry Andric bool isRepresentableBy(const fltSemantics &S) const { 126fe6060f1SDimitry Andric return maxExponent <= S.maxExponent && minExponent >= S.minExponent && 127fe6060f1SDimitry Andric precision <= S.precision; 128fe6060f1SDimitry Andric } 1290b57cec5SDimitry Andric }; 1300b57cec5SDimitry Andric 13106c3fb27SDimitry Andric static constexpr fltSemantics semIEEEhalf = {15, -14, 11, 16}; 13206c3fb27SDimitry Andric static constexpr fltSemantics semBFloat = {127, -126, 8, 16}; 13306c3fb27SDimitry Andric static constexpr fltSemantics semIEEEsingle = {127, -126, 24, 32}; 13406c3fb27SDimitry Andric static constexpr fltSemantics semIEEEdouble = {1023, -1022, 53, 64}; 13506c3fb27SDimitry Andric static constexpr fltSemantics semIEEEquad = {16383, -16382, 113, 128}; 13606c3fb27SDimitry Andric static constexpr fltSemantics semFloat8E5M2 = {15, -14, 3, 8}; 13706c3fb27SDimitry Andric static constexpr fltSemantics semFloat8E5M2FNUZ = { 13806c3fb27SDimitry Andric 15, -15, 3, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero}; 139*0fca6ea1SDimitry Andric static constexpr fltSemantics semFloat8E4M3 = {7, -6, 4, 8}; 14006c3fb27SDimitry Andric static constexpr fltSemantics semFloat8E4M3FN = { 14106c3fb27SDimitry Andric 8, -6, 4, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::AllOnes}; 14206c3fb27SDimitry Andric static constexpr fltSemantics semFloat8E4M3FNUZ = { 14306c3fb27SDimitry Andric 7, -7, 4, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero}; 14406c3fb27SDimitry Andric static constexpr fltSemantics semFloat8E4M3B11FNUZ = { 14506c3fb27SDimitry Andric 4, -10, 4, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero}; 14606c3fb27SDimitry Andric static constexpr fltSemantics semFloatTF32 = {127, -126, 11, 19}; 147*0fca6ea1SDimitry Andric static constexpr fltSemantics semFloat6E3M2FN = { 148*0fca6ea1SDimitry Andric 4, -2, 3, 6, fltNonfiniteBehavior::FiniteOnly}; 149*0fca6ea1SDimitry Andric static constexpr fltSemantics semFloat6E2M3FN = { 150*0fca6ea1SDimitry Andric 2, 0, 4, 6, fltNonfiniteBehavior::FiniteOnly}; 151*0fca6ea1SDimitry Andric static constexpr fltSemantics semFloat4E2M1FN = { 152*0fca6ea1SDimitry Andric 2, 0, 2, 4, fltNonfiniteBehavior::FiniteOnly}; 15306c3fb27SDimitry Andric static constexpr fltSemantics semX87DoubleExtended = {16383, -16382, 64, 80}; 15406c3fb27SDimitry Andric static constexpr fltSemantics semBogus = {0, 0, 0, 0}; 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric /* The IBM double-double semantics. Such a number consists of a pair of IEEE 1570b57cec5SDimitry Andric 64-bit doubles (Hi, Lo), where |Hi| > |Lo|, and if normal, 1580b57cec5SDimitry Andric (double)(Hi + Lo) == Hi. The numeric value it's modeling is Hi + Lo. 1590b57cec5SDimitry Andric Therefore it has two 53-bit mantissa parts that aren't necessarily adjacent 1600b57cec5SDimitry Andric to each other, and two 11-bit exponents. 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric Note: we need to make the value different from semBogus as otherwise 1630b57cec5SDimitry Andric an unsafe optimization may collapse both values to a single address, 1640b57cec5SDimitry Andric and we heavily rely on them having distinct addresses. */ 16506c3fb27SDimitry Andric static constexpr fltSemantics semPPCDoubleDouble = {-1, 0, 0, 128}; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric /* These are legacy semantics for the fallback, inaccrurate implementation of 1680b57cec5SDimitry Andric IBM double-double, if the accurate semPPCDoubleDouble doesn't handle the 1690b57cec5SDimitry Andric operation. It's equivalent to having an IEEE number with consecutive 106 1700b57cec5SDimitry Andric bits of mantissa and 11 bits of exponent. 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric It's not equivalent to IBM double-double. For example, a legit IBM 1730b57cec5SDimitry Andric double-double, 1 + epsilon: 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric 1 + epsilon = 1 + (1 >> 1076) 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric is not representable by a consecutive 106 bits of mantissa. 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric Currently, these semantics are used in the following way: 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric semPPCDoubleDouble -> (IEEEdouble, IEEEdouble) -> 1820b57cec5SDimitry Andric (64-bit APInt, 64-bit APInt) -> (128-bit APInt) -> 1830b57cec5SDimitry Andric semPPCDoubleDoubleLegacy -> IEEE operations 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric We use bitcastToAPInt() to get the bit representation (in APInt) of the 1860b57cec5SDimitry Andric underlying IEEEdouble, then use the APInt constructor to construct the 1870b57cec5SDimitry Andric legacy IEEE float. 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric TODO: Implement all operations in semPPCDoubleDouble, and delete these 1900b57cec5SDimitry Andric semantics. */ 19106c3fb27SDimitry Andric static constexpr fltSemantics semPPCDoubleDoubleLegacy = {1023, -1022 + 53, 1920b57cec5SDimitry Andric 53 + 53, 128}; 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) { 1950b57cec5SDimitry Andric switch (S) { 1960b57cec5SDimitry Andric case S_IEEEhalf: 1970b57cec5SDimitry Andric return IEEEhalf(); 1985ffd83dbSDimitry Andric case S_BFloat: 1995ffd83dbSDimitry Andric return BFloat(); 2000b57cec5SDimitry Andric case S_IEEEsingle: 2010b57cec5SDimitry Andric return IEEEsingle(); 2020b57cec5SDimitry Andric case S_IEEEdouble: 2030b57cec5SDimitry Andric return IEEEdouble(); 2040b57cec5SDimitry Andric case S_IEEEquad: 2050b57cec5SDimitry Andric return IEEEquad(); 2060b57cec5SDimitry Andric case S_PPCDoubleDouble: 2070b57cec5SDimitry Andric return PPCDoubleDouble(); 208bdd1243dSDimitry Andric case S_Float8E5M2: 209bdd1243dSDimitry Andric return Float8E5M2(); 21006c3fb27SDimitry Andric case S_Float8E5M2FNUZ: 21106c3fb27SDimitry Andric return Float8E5M2FNUZ(); 212*0fca6ea1SDimitry Andric case S_Float8E4M3: 213*0fca6ea1SDimitry Andric return Float8E4M3(); 214bdd1243dSDimitry Andric case S_Float8E4M3FN: 215bdd1243dSDimitry Andric return Float8E4M3FN(); 21606c3fb27SDimitry Andric case S_Float8E4M3FNUZ: 21706c3fb27SDimitry Andric return Float8E4M3FNUZ(); 21806c3fb27SDimitry Andric case S_Float8E4M3B11FNUZ: 21906c3fb27SDimitry Andric return Float8E4M3B11FNUZ(); 22006c3fb27SDimitry Andric case S_FloatTF32: 22106c3fb27SDimitry Andric return FloatTF32(); 222*0fca6ea1SDimitry Andric case S_Float6E3M2FN: 223*0fca6ea1SDimitry Andric return Float6E3M2FN(); 224*0fca6ea1SDimitry Andric case S_Float6E2M3FN: 225*0fca6ea1SDimitry Andric return Float6E2M3FN(); 226*0fca6ea1SDimitry Andric case S_Float4E2M1FN: 227*0fca6ea1SDimitry Andric return Float4E2M1FN(); 228bdd1243dSDimitry Andric case S_x87DoubleExtended: 229bdd1243dSDimitry Andric return x87DoubleExtended(); 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric llvm_unreachable("Unrecognised floating semantics"); 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric APFloatBase::Semantics 2350b57cec5SDimitry Andric APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) { 2360b57cec5SDimitry Andric if (&Sem == &llvm::APFloat::IEEEhalf()) 2370b57cec5SDimitry Andric return S_IEEEhalf; 2385ffd83dbSDimitry Andric else if (&Sem == &llvm::APFloat::BFloat()) 2395ffd83dbSDimitry Andric return S_BFloat; 2400b57cec5SDimitry Andric else if (&Sem == &llvm::APFloat::IEEEsingle()) 2410b57cec5SDimitry Andric return S_IEEEsingle; 2420b57cec5SDimitry Andric else if (&Sem == &llvm::APFloat::IEEEdouble()) 2430b57cec5SDimitry Andric return S_IEEEdouble; 2440b57cec5SDimitry Andric else if (&Sem == &llvm::APFloat::IEEEquad()) 2450b57cec5SDimitry Andric return S_IEEEquad; 2460b57cec5SDimitry Andric else if (&Sem == &llvm::APFloat::PPCDoubleDouble()) 2470b57cec5SDimitry Andric return S_PPCDoubleDouble; 248bdd1243dSDimitry Andric else if (&Sem == &llvm::APFloat::Float8E5M2()) 249bdd1243dSDimitry Andric return S_Float8E5M2; 25006c3fb27SDimitry Andric else if (&Sem == &llvm::APFloat::Float8E5M2FNUZ()) 25106c3fb27SDimitry Andric return S_Float8E5M2FNUZ; 252*0fca6ea1SDimitry Andric else if (&Sem == &llvm::APFloat::Float8E4M3()) 253*0fca6ea1SDimitry Andric return S_Float8E4M3; 254bdd1243dSDimitry Andric else if (&Sem == &llvm::APFloat::Float8E4M3FN()) 255bdd1243dSDimitry Andric return S_Float8E4M3FN; 25606c3fb27SDimitry Andric else if (&Sem == &llvm::APFloat::Float8E4M3FNUZ()) 25706c3fb27SDimitry Andric return S_Float8E4M3FNUZ; 25806c3fb27SDimitry Andric else if (&Sem == &llvm::APFloat::Float8E4M3B11FNUZ()) 25906c3fb27SDimitry Andric return S_Float8E4M3B11FNUZ; 26006c3fb27SDimitry Andric else if (&Sem == &llvm::APFloat::FloatTF32()) 26106c3fb27SDimitry Andric return S_FloatTF32; 262*0fca6ea1SDimitry Andric else if (&Sem == &llvm::APFloat::Float6E3M2FN()) 263*0fca6ea1SDimitry Andric return S_Float6E3M2FN; 264*0fca6ea1SDimitry Andric else if (&Sem == &llvm::APFloat::Float6E2M3FN()) 265*0fca6ea1SDimitry Andric return S_Float6E2M3FN; 266*0fca6ea1SDimitry Andric else if (&Sem == &llvm::APFloat::Float4E2M1FN()) 267*0fca6ea1SDimitry Andric return S_Float4E2M1FN; 268bdd1243dSDimitry Andric else if (&Sem == &llvm::APFloat::x87DoubleExtended()) 269bdd1243dSDimitry Andric return S_x87DoubleExtended; 2700b57cec5SDimitry Andric else 2710b57cec5SDimitry Andric llvm_unreachable("Unknown floating semantics"); 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric 27406c3fb27SDimitry Andric const fltSemantics &APFloatBase::IEEEhalf() { return semIEEEhalf; } 27506c3fb27SDimitry Andric const fltSemantics &APFloatBase::BFloat() { return semBFloat; } 27606c3fb27SDimitry Andric const fltSemantics &APFloatBase::IEEEsingle() { return semIEEEsingle; } 27706c3fb27SDimitry Andric const fltSemantics &APFloatBase::IEEEdouble() { return semIEEEdouble; } 278bdd1243dSDimitry Andric const fltSemantics &APFloatBase::IEEEquad() { return semIEEEquad; } 2790b57cec5SDimitry Andric const fltSemantics &APFloatBase::PPCDoubleDouble() { 2800b57cec5SDimitry Andric return semPPCDoubleDouble; 2810b57cec5SDimitry Andric } 282bdd1243dSDimitry Andric const fltSemantics &APFloatBase::Float8E5M2() { return semFloat8E5M2; } 28306c3fb27SDimitry Andric const fltSemantics &APFloatBase::Float8E5M2FNUZ() { return semFloat8E5M2FNUZ; } 284*0fca6ea1SDimitry Andric const fltSemantics &APFloatBase::Float8E4M3() { return semFloat8E4M3; } 285bdd1243dSDimitry Andric const fltSemantics &APFloatBase::Float8E4M3FN() { return semFloat8E4M3FN; } 28606c3fb27SDimitry Andric const fltSemantics &APFloatBase::Float8E4M3FNUZ() { return semFloat8E4M3FNUZ; } 28706c3fb27SDimitry Andric const fltSemantics &APFloatBase::Float8E4M3B11FNUZ() { 28806c3fb27SDimitry Andric return semFloat8E4M3B11FNUZ; 28906c3fb27SDimitry Andric } 29006c3fb27SDimitry Andric const fltSemantics &APFloatBase::FloatTF32() { return semFloatTF32; } 291*0fca6ea1SDimitry Andric const fltSemantics &APFloatBase::Float6E3M2FN() { return semFloat6E3M2FN; } 292*0fca6ea1SDimitry Andric const fltSemantics &APFloatBase::Float6E2M3FN() { return semFloat6E2M3FN; } 293*0fca6ea1SDimitry Andric const fltSemantics &APFloatBase::Float4E2M1FN() { return semFloat4E2M1FN; } 294bdd1243dSDimitry Andric const fltSemantics &APFloatBase::x87DoubleExtended() { 295bdd1243dSDimitry Andric return semX87DoubleExtended; 296bdd1243dSDimitry Andric } 297bdd1243dSDimitry Andric const fltSemantics &APFloatBase::Bogus() { return semBogus; } 2980b57cec5SDimitry Andric 2995ffd83dbSDimitry Andric constexpr RoundingMode APFloatBase::rmNearestTiesToEven; 3005ffd83dbSDimitry Andric constexpr RoundingMode APFloatBase::rmTowardPositive; 3015ffd83dbSDimitry Andric constexpr RoundingMode APFloatBase::rmTowardNegative; 3025ffd83dbSDimitry Andric constexpr RoundingMode APFloatBase::rmTowardZero; 3035ffd83dbSDimitry Andric constexpr RoundingMode APFloatBase::rmNearestTiesToAway; 3045ffd83dbSDimitry Andric 3050b57cec5SDimitry Andric /* A tight upper bound on number of parts required to hold the value 3060b57cec5SDimitry Andric pow(5, power) is 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric power * 815 / (351 * integerPartWidth) + 1 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric However, whilst the result may require only this many parts, 3110b57cec5SDimitry Andric because we are multiplying two values to get it, the 3120b57cec5SDimitry Andric multiplication may require an extra part with the excess part 3130b57cec5SDimitry Andric being zero (consider the trivial case of 1 * 1, tcFullMultiply 3140b57cec5SDimitry Andric requires two parts to hold the single-part result). So we add an 3150b57cec5SDimitry Andric extra one to guarantee enough space whilst multiplying. */ 3160b57cec5SDimitry Andric const unsigned int maxExponent = 16383; 3170b57cec5SDimitry Andric const unsigned int maxPrecision = 113; 3180b57cec5SDimitry Andric const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1; 31906c3fb27SDimitry Andric const unsigned int maxPowerOfFiveParts = 32006c3fb27SDimitry Andric 2 + 32106c3fb27SDimitry Andric ((maxPowerOfFiveExponent * 815) / (351 * APFloatBase::integerPartWidth)); 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric unsigned int APFloatBase::semanticsPrecision(const fltSemantics &semantics) { 3240b57cec5SDimitry Andric return semantics.precision; 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric APFloatBase::ExponentType 3270b57cec5SDimitry Andric APFloatBase::semanticsMaxExponent(const fltSemantics &semantics) { 3280b57cec5SDimitry Andric return semantics.maxExponent; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric APFloatBase::ExponentType 3310b57cec5SDimitry Andric APFloatBase::semanticsMinExponent(const fltSemantics &semantics) { 3320b57cec5SDimitry Andric return semantics.minExponent; 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric unsigned int APFloatBase::semanticsSizeInBits(const fltSemantics &semantics) { 3350b57cec5SDimitry Andric return semantics.sizeInBits; 3360b57cec5SDimitry Andric } 33706c3fb27SDimitry Andric unsigned int APFloatBase::semanticsIntSizeInBits(const fltSemantics &semantics, 33806c3fb27SDimitry Andric bool isSigned) { 33906c3fb27SDimitry Andric // The max FP value is pow(2, MaxExponent) * (1 + MaxFraction), so we need 34006c3fb27SDimitry Andric // at least one more bit than the MaxExponent to hold the max FP value. 34106c3fb27SDimitry Andric unsigned int MinBitWidth = semanticsMaxExponent(semantics) + 1; 34206c3fb27SDimitry Andric // Extra sign bit needed. 34306c3fb27SDimitry Andric if (isSigned) 34406c3fb27SDimitry Andric ++MinBitWidth; 34506c3fb27SDimitry Andric return MinBitWidth; 34606c3fb27SDimitry Andric } 34706c3fb27SDimitry Andric 34806c3fb27SDimitry Andric bool APFloatBase::isRepresentableAsNormalIn(const fltSemantics &Src, 34906c3fb27SDimitry Andric const fltSemantics &Dst) { 35006c3fb27SDimitry Andric // Exponent range must be larger. 35106c3fb27SDimitry Andric if (Src.maxExponent >= Dst.maxExponent || Src.minExponent <= Dst.minExponent) 35206c3fb27SDimitry Andric return false; 35306c3fb27SDimitry Andric 35406c3fb27SDimitry Andric // If the mantissa is long enough, the result value could still be denormal 35506c3fb27SDimitry Andric // with a larger exponent range. 35606c3fb27SDimitry Andric // 35706c3fb27SDimitry Andric // FIXME: This condition is probably not accurate but also shouldn't be a 35806c3fb27SDimitry Andric // practical concern with existing types. 35906c3fb27SDimitry Andric return Dst.precision >= Src.precision; 36006c3fb27SDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric unsigned APFloatBase::getSizeInBits(const fltSemantics &Sem) { 3630b57cec5SDimitry Andric return Sem.sizeInBits; 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 36606c3fb27SDimitry Andric static constexpr APFloatBase::ExponentType 36706c3fb27SDimitry Andric exponentZero(const fltSemantics &semantics) { 36806c3fb27SDimitry Andric return semantics.minExponent - 1; 36906c3fb27SDimitry Andric } 37006c3fb27SDimitry Andric 37106c3fb27SDimitry Andric static constexpr APFloatBase::ExponentType 37206c3fb27SDimitry Andric exponentInf(const fltSemantics &semantics) { 37306c3fb27SDimitry Andric return semantics.maxExponent + 1; 37406c3fb27SDimitry Andric } 37506c3fb27SDimitry Andric 37606c3fb27SDimitry Andric static constexpr APFloatBase::ExponentType 37706c3fb27SDimitry Andric exponentNaN(const fltSemantics &semantics) { 37806c3fb27SDimitry Andric if (semantics.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) { 37906c3fb27SDimitry Andric if (semantics.nanEncoding == fltNanEncoding::NegativeZero) 38006c3fb27SDimitry Andric return exponentZero(semantics); 38106c3fb27SDimitry Andric return semantics.maxExponent; 38206c3fb27SDimitry Andric } 38306c3fb27SDimitry Andric return semantics.maxExponent + 1; 38406c3fb27SDimitry Andric } 38506c3fb27SDimitry Andric 3860b57cec5SDimitry Andric /* A bunch of private, handy routines. */ 3870b57cec5SDimitry Andric 388480093f4SDimitry Andric static inline Error createError(const Twine &Err) { 389480093f4SDimitry Andric return make_error<StringError>(Err, inconvertibleErrorCode()); 390480093f4SDimitry Andric } 391480093f4SDimitry Andric 39206c3fb27SDimitry Andric static constexpr inline unsigned int partCountForBits(unsigned int bits) { 3930b57cec5SDimitry Andric return ((bits) + APFloatBase::integerPartWidth - 1) / APFloatBase::integerPartWidth; 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric /* Returns 0U-9U. Return values >= 10U are not digits. */ 3970b57cec5SDimitry Andric static inline unsigned int 3980b57cec5SDimitry Andric decDigitValue(unsigned int c) 3990b57cec5SDimitry Andric { 4000b57cec5SDimitry Andric return c - '0'; 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric /* Return the value of a decimal exponent of the form 4040b57cec5SDimitry Andric [+-]ddddddd. 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric If the exponent overflows, returns a large exponent with the 4070b57cec5SDimitry Andric appropriate sign. */ 408480093f4SDimitry Andric static Expected<int> readExponent(StringRef::iterator begin, 409480093f4SDimitry Andric StringRef::iterator end) { 4100b57cec5SDimitry Andric bool isNegative; 4110b57cec5SDimitry Andric unsigned int absExponent; 4120b57cec5SDimitry Andric const unsigned int overlargeExponent = 24000; /* FIXME. */ 4130b57cec5SDimitry Andric StringRef::iterator p = begin; 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric // Treat no exponent as 0 to match binutils 4160b57cec5SDimitry Andric if (p == end || ((*p == '-' || *p == '+') && (p + 1) == end)) { 4170b57cec5SDimitry Andric return 0; 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric isNegative = (*p == '-'); 4210b57cec5SDimitry Andric if (*p == '-' || *p == '+') { 4220b57cec5SDimitry Andric p++; 423480093f4SDimitry Andric if (p == end) 424480093f4SDimitry Andric return createError("Exponent has no digits"); 4250b57cec5SDimitry Andric } 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric absExponent = decDigitValue(*p++); 428480093f4SDimitry Andric if (absExponent >= 10U) 429480093f4SDimitry Andric return createError("Invalid character in exponent"); 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric for (; p != end; ++p) { 4320b57cec5SDimitry Andric unsigned int value; 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric value = decDigitValue(*p); 435480093f4SDimitry Andric if (value >= 10U) 436480093f4SDimitry Andric return createError("Invalid character in exponent"); 4370b57cec5SDimitry Andric 438480093f4SDimitry Andric absExponent = absExponent * 10U + value; 4390b57cec5SDimitry Andric if (absExponent >= overlargeExponent) { 4400b57cec5SDimitry Andric absExponent = overlargeExponent; 4410b57cec5SDimitry Andric break; 4420b57cec5SDimitry Andric } 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric if (isNegative) 4460b57cec5SDimitry Andric return -(int) absExponent; 4470b57cec5SDimitry Andric else 4480b57cec5SDimitry Andric return (int) absExponent; 4490b57cec5SDimitry Andric } 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric /* This is ugly and needs cleaning up, but I don't immediately see 4520b57cec5SDimitry Andric how whilst remaining safe. */ 453480093f4SDimitry Andric static Expected<int> totalExponent(StringRef::iterator p, 454480093f4SDimitry Andric StringRef::iterator end, 455480093f4SDimitry Andric int exponentAdjustment) { 4560b57cec5SDimitry Andric int unsignedExponent; 4570b57cec5SDimitry Andric bool negative, overflow; 4580b57cec5SDimitry Andric int exponent = 0; 4590b57cec5SDimitry Andric 460480093f4SDimitry Andric if (p == end) 461480093f4SDimitry Andric return createError("Exponent has no digits"); 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric negative = *p == '-'; 4640b57cec5SDimitry Andric if (*p == '-' || *p == '+') { 4650b57cec5SDimitry Andric p++; 466480093f4SDimitry Andric if (p == end) 467480093f4SDimitry Andric return createError("Exponent has no digits"); 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric unsignedExponent = 0; 4710b57cec5SDimitry Andric overflow = false; 4720b57cec5SDimitry Andric for (; p != end; ++p) { 4730b57cec5SDimitry Andric unsigned int value; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric value = decDigitValue(*p); 476480093f4SDimitry Andric if (value >= 10U) 477480093f4SDimitry Andric return createError("Invalid character in exponent"); 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric unsignedExponent = unsignedExponent * 10 + value; 4800b57cec5SDimitry Andric if (unsignedExponent > 32767) { 4810b57cec5SDimitry Andric overflow = true; 4820b57cec5SDimitry Andric break; 4830b57cec5SDimitry Andric } 4840b57cec5SDimitry Andric } 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric if (exponentAdjustment > 32767 || exponentAdjustment < -32768) 4870b57cec5SDimitry Andric overflow = true; 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric if (!overflow) { 4900b57cec5SDimitry Andric exponent = unsignedExponent; 4910b57cec5SDimitry Andric if (negative) 4920b57cec5SDimitry Andric exponent = -exponent; 4930b57cec5SDimitry Andric exponent += exponentAdjustment; 4940b57cec5SDimitry Andric if (exponent > 32767 || exponent < -32768) 4950b57cec5SDimitry Andric overflow = true; 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric if (overflow) 4990b57cec5SDimitry Andric exponent = negative ? -32768: 32767; 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric return exponent; 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric 504480093f4SDimitry Andric static Expected<StringRef::iterator> 5050b57cec5SDimitry Andric skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end, 506480093f4SDimitry Andric StringRef::iterator *dot) { 5070b57cec5SDimitry Andric StringRef::iterator p = begin; 5080b57cec5SDimitry Andric *dot = end; 5090b57cec5SDimitry Andric while (p != end && *p == '0') 5100b57cec5SDimitry Andric p++; 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric if (p != end && *p == '.') { 5130b57cec5SDimitry Andric *dot = p++; 5140b57cec5SDimitry Andric 515480093f4SDimitry Andric if (end - begin == 1) 516480093f4SDimitry Andric return createError("Significand has no digits"); 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric while (p != end && *p == '0') 5190b57cec5SDimitry Andric p++; 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric return p; 5230b57cec5SDimitry Andric } 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric /* Given a normal decimal floating point number of the form 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric dddd.dddd[eE][+-]ddd 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric where the decimal point and exponent are optional, fill out the 5300b57cec5SDimitry Andric structure D. Exponent is appropriate if the significand is 5310b57cec5SDimitry Andric treated as an integer, and normalizedExponent if the significand 5320b57cec5SDimitry Andric is taken to have the decimal point after a single leading 5330b57cec5SDimitry Andric non-zero digit. 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric If the value is zero, V->firstSigDigit points to a non-digit, and 5360b57cec5SDimitry Andric the return exponent is zero. 5370b57cec5SDimitry Andric */ 5380b57cec5SDimitry Andric struct decimalInfo { 5390b57cec5SDimitry Andric const char *firstSigDigit; 5400b57cec5SDimitry Andric const char *lastSigDigit; 5410b57cec5SDimitry Andric int exponent; 5420b57cec5SDimitry Andric int normalizedExponent; 5430b57cec5SDimitry Andric }; 5440b57cec5SDimitry Andric 545480093f4SDimitry Andric static Error interpretDecimal(StringRef::iterator begin, 546480093f4SDimitry Andric StringRef::iterator end, decimalInfo *D) { 5470b57cec5SDimitry Andric StringRef::iterator dot = end; 548480093f4SDimitry Andric 549480093f4SDimitry Andric auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot); 550480093f4SDimitry Andric if (!PtrOrErr) 551480093f4SDimitry Andric return PtrOrErr.takeError(); 552480093f4SDimitry Andric StringRef::iterator p = *PtrOrErr; 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric D->firstSigDigit = p; 5550b57cec5SDimitry Andric D->exponent = 0; 5560b57cec5SDimitry Andric D->normalizedExponent = 0; 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric for (; p != end; ++p) { 5590b57cec5SDimitry Andric if (*p == '.') { 560480093f4SDimitry Andric if (dot != end) 561480093f4SDimitry Andric return createError("String contains multiple dots"); 5620b57cec5SDimitry Andric dot = p++; 5630b57cec5SDimitry Andric if (p == end) 5640b57cec5SDimitry Andric break; 5650b57cec5SDimitry Andric } 5660b57cec5SDimitry Andric if (decDigitValue(*p) >= 10U) 5670b57cec5SDimitry Andric break; 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric if (p != end) { 571480093f4SDimitry Andric if (*p != 'e' && *p != 'E') 572480093f4SDimitry Andric return createError("Invalid character in significand"); 573480093f4SDimitry Andric if (p == begin) 574480093f4SDimitry Andric return createError("Significand has no digits"); 575480093f4SDimitry Andric if (dot != end && p - begin == 1) 576480093f4SDimitry Andric return createError("Significand has no digits"); 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric /* p points to the first non-digit in the string */ 579480093f4SDimitry Andric auto ExpOrErr = readExponent(p + 1, end); 580480093f4SDimitry Andric if (!ExpOrErr) 581480093f4SDimitry Andric return ExpOrErr.takeError(); 582480093f4SDimitry Andric D->exponent = *ExpOrErr; 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric /* Implied decimal point? */ 5850b57cec5SDimitry Andric if (dot == end) 5860b57cec5SDimitry Andric dot = p; 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric /* If number is all zeroes accept any exponent. */ 5900b57cec5SDimitry Andric if (p != D->firstSigDigit) { 5910b57cec5SDimitry Andric /* Drop insignificant trailing zeroes. */ 5920b57cec5SDimitry Andric if (p != begin) { 5930b57cec5SDimitry Andric do 5940b57cec5SDimitry Andric do 5950b57cec5SDimitry Andric p--; 5960b57cec5SDimitry Andric while (p != begin && *p == '0'); 5970b57cec5SDimitry Andric while (p != begin && *p == '.'); 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric /* Adjust the exponents for any decimal point. */ 6010b57cec5SDimitry Andric D->exponent += static_cast<APFloat::ExponentType>((dot - p) - (dot > p)); 6020b57cec5SDimitry Andric D->normalizedExponent = (D->exponent + 6030b57cec5SDimitry Andric static_cast<APFloat::ExponentType>((p - D->firstSigDigit) 6040b57cec5SDimitry Andric - (dot > D->firstSigDigit && dot < p))); 6050b57cec5SDimitry Andric } 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric D->lastSigDigit = p; 608480093f4SDimitry Andric return Error::success(); 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric /* Return the trailing fraction of a hexadecimal number. 6120b57cec5SDimitry Andric DIGITVALUE is the first hex digit of the fraction, P points to 6130b57cec5SDimitry Andric the next digit. */ 614480093f4SDimitry Andric static Expected<lostFraction> 6150b57cec5SDimitry Andric trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end, 616480093f4SDimitry Andric unsigned int digitValue) { 6170b57cec5SDimitry Andric unsigned int hexDigit; 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric /* If the first trailing digit isn't 0 or 8 we can work out the 6200b57cec5SDimitry Andric fraction immediately. */ 6210b57cec5SDimitry Andric if (digitValue > 8) 6220b57cec5SDimitry Andric return lfMoreThanHalf; 6230b57cec5SDimitry Andric else if (digitValue < 8 && digitValue > 0) 6240b57cec5SDimitry Andric return lfLessThanHalf; 6250b57cec5SDimitry Andric 6260b57cec5SDimitry Andric // Otherwise we need to find the first non-zero digit. 6270b57cec5SDimitry Andric while (p != end && (*p == '0' || *p == '.')) 6280b57cec5SDimitry Andric p++; 6290b57cec5SDimitry Andric 630480093f4SDimitry Andric if (p == end) 631480093f4SDimitry Andric return createError("Invalid trailing hexadecimal fraction!"); 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric hexDigit = hexDigitValue(*p); 6340b57cec5SDimitry Andric 6350b57cec5SDimitry Andric /* If we ran off the end it is exactly zero or one-half, otherwise 6360b57cec5SDimitry Andric a little more. */ 63706c3fb27SDimitry Andric if (hexDigit == UINT_MAX) 6380b57cec5SDimitry Andric return digitValue == 0 ? lfExactlyZero: lfExactlyHalf; 6390b57cec5SDimitry Andric else 6400b57cec5SDimitry Andric return digitValue == 0 ? lfLessThanHalf: lfMoreThanHalf; 6410b57cec5SDimitry Andric } 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andric /* Return the fraction lost were a bignum truncated losing the least 6440b57cec5SDimitry Andric significant BITS bits. */ 6450b57cec5SDimitry Andric static lostFraction 6460b57cec5SDimitry Andric lostFractionThroughTruncation(const APFloatBase::integerPart *parts, 6470b57cec5SDimitry Andric unsigned int partCount, 6480b57cec5SDimitry Andric unsigned int bits) 6490b57cec5SDimitry Andric { 6500b57cec5SDimitry Andric unsigned int lsb; 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric lsb = APInt::tcLSB(parts, partCount); 6530b57cec5SDimitry Andric 65406c3fb27SDimitry Andric /* Note this is guaranteed true if bits == 0, or LSB == UINT_MAX. */ 6550b57cec5SDimitry Andric if (bits <= lsb) 6560b57cec5SDimitry Andric return lfExactlyZero; 6570b57cec5SDimitry Andric if (bits == lsb + 1) 6580b57cec5SDimitry Andric return lfExactlyHalf; 6590b57cec5SDimitry Andric if (bits <= partCount * APFloatBase::integerPartWidth && 6600b57cec5SDimitry Andric APInt::tcExtractBit(parts, bits - 1)) 6610b57cec5SDimitry Andric return lfMoreThanHalf; 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric return lfLessThanHalf; 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric /* Shift DST right BITS bits noting lost fraction. */ 6670b57cec5SDimitry Andric static lostFraction 6680b57cec5SDimitry Andric shiftRight(APFloatBase::integerPart *dst, unsigned int parts, unsigned int bits) 6690b57cec5SDimitry Andric { 6700b57cec5SDimitry Andric lostFraction lost_fraction; 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric lost_fraction = lostFractionThroughTruncation(dst, parts, bits); 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric APInt::tcShiftRight(dst, parts, bits); 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric return lost_fraction; 6770b57cec5SDimitry Andric } 6780b57cec5SDimitry Andric 6790b57cec5SDimitry Andric /* Combine the effect of two lost fractions. */ 6800b57cec5SDimitry Andric static lostFraction 6810b57cec5SDimitry Andric combineLostFractions(lostFraction moreSignificant, 6820b57cec5SDimitry Andric lostFraction lessSignificant) 6830b57cec5SDimitry Andric { 6840b57cec5SDimitry Andric if (lessSignificant != lfExactlyZero) { 6850b57cec5SDimitry Andric if (moreSignificant == lfExactlyZero) 6860b57cec5SDimitry Andric moreSignificant = lfLessThanHalf; 6870b57cec5SDimitry Andric else if (moreSignificant == lfExactlyHalf) 6880b57cec5SDimitry Andric moreSignificant = lfMoreThanHalf; 6890b57cec5SDimitry Andric } 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric return moreSignificant; 6920b57cec5SDimitry Andric } 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric /* The error from the true value, in half-ulps, on multiplying two 6950b57cec5SDimitry Andric floating point numbers, which differ from the value they 6960b57cec5SDimitry Andric approximate by at most HUE1 and HUE2 half-ulps, is strictly less 6970b57cec5SDimitry Andric than the returned value. 6980b57cec5SDimitry Andric 6990b57cec5SDimitry Andric See "How to Read Floating Point Numbers Accurately" by William D 7000b57cec5SDimitry Andric Clinger. */ 7010b57cec5SDimitry Andric static unsigned int 7020b57cec5SDimitry Andric HUerrBound(bool inexactMultiply, unsigned int HUerr1, unsigned int HUerr2) 7030b57cec5SDimitry Andric { 7040b57cec5SDimitry Andric assert(HUerr1 < 2 || HUerr2 < 2 || (HUerr1 + HUerr2 < 8)); 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andric if (HUerr1 + HUerr2 == 0) 7070b57cec5SDimitry Andric return inexactMultiply * 2; /* <= inexactMultiply half-ulps. */ 7080b57cec5SDimitry Andric else 7090b57cec5SDimitry Andric return inexactMultiply + 2 * (HUerr1 + HUerr2); 7100b57cec5SDimitry Andric } 7110b57cec5SDimitry Andric 7120b57cec5SDimitry Andric /* The number of ulps from the boundary (zero, or half if ISNEAREST) 7130b57cec5SDimitry Andric when the least significant BITS are truncated. BITS cannot be 7140b57cec5SDimitry Andric zero. */ 7150b57cec5SDimitry Andric static APFloatBase::integerPart 7160b57cec5SDimitry Andric ulpsFromBoundary(const APFloatBase::integerPart *parts, unsigned int bits, 7170b57cec5SDimitry Andric bool isNearest) { 7180b57cec5SDimitry Andric unsigned int count, partBits; 7190b57cec5SDimitry Andric APFloatBase::integerPart part, boundary; 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric assert(bits != 0); 7220b57cec5SDimitry Andric 7230b57cec5SDimitry Andric bits--; 7240b57cec5SDimitry Andric count = bits / APFloatBase::integerPartWidth; 7250b57cec5SDimitry Andric partBits = bits % APFloatBase::integerPartWidth + 1; 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric part = parts[count] & (~(APFloatBase::integerPart) 0 >> (APFloatBase::integerPartWidth - partBits)); 7280b57cec5SDimitry Andric 7290b57cec5SDimitry Andric if (isNearest) 7300b57cec5SDimitry Andric boundary = (APFloatBase::integerPart) 1 << (partBits - 1); 7310b57cec5SDimitry Andric else 7320b57cec5SDimitry Andric boundary = 0; 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric if (count == 0) { 7350b57cec5SDimitry Andric if (part - boundary <= boundary - part) 7360b57cec5SDimitry Andric return part - boundary; 7370b57cec5SDimitry Andric else 7380b57cec5SDimitry Andric return boundary - part; 7390b57cec5SDimitry Andric } 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric if (part == boundary) { 7420b57cec5SDimitry Andric while (--count) 7430b57cec5SDimitry Andric if (parts[count]) 7440b57cec5SDimitry Andric return ~(APFloatBase::integerPart) 0; /* A lot. */ 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric return parts[0]; 7470b57cec5SDimitry Andric } else if (part == boundary - 1) { 7480b57cec5SDimitry Andric while (--count) 7490b57cec5SDimitry Andric if (~parts[count]) 7500b57cec5SDimitry Andric return ~(APFloatBase::integerPart) 0; /* A lot. */ 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric return -parts[0]; 7530b57cec5SDimitry Andric } 7540b57cec5SDimitry Andric 7550b57cec5SDimitry Andric return ~(APFloatBase::integerPart) 0; /* A lot. */ 7560b57cec5SDimitry Andric } 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric /* Place pow(5, power) in DST, and return the number of parts used. 7590b57cec5SDimitry Andric DST must be at least one part larger than size of the answer. */ 7600b57cec5SDimitry Andric static unsigned int 7610b57cec5SDimitry Andric powerOf5(APFloatBase::integerPart *dst, unsigned int power) { 7620b57cec5SDimitry Andric static const APFloatBase::integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, 15625, 78125 }; 7630b57cec5SDimitry Andric APFloatBase::integerPart pow5s[maxPowerOfFiveParts * 2 + 5]; 7640b57cec5SDimitry Andric pow5s[0] = 78125 * 5; 7650b57cec5SDimitry Andric 766*0fca6ea1SDimitry Andric unsigned int partsCount = 1; 7670b57cec5SDimitry Andric APFloatBase::integerPart scratch[maxPowerOfFiveParts], *p1, *p2, *pow5; 7680b57cec5SDimitry Andric unsigned int result; 7690b57cec5SDimitry Andric assert(power <= maxExponent); 7700b57cec5SDimitry Andric 7710b57cec5SDimitry Andric p1 = dst; 7720b57cec5SDimitry Andric p2 = scratch; 7730b57cec5SDimitry Andric 7740b57cec5SDimitry Andric *p1 = firstEightPowers[power & 7]; 7750b57cec5SDimitry Andric power >>= 3; 7760b57cec5SDimitry Andric 7770b57cec5SDimitry Andric result = 1; 7780b57cec5SDimitry Andric pow5 = pow5s; 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric for (unsigned int n = 0; power; power >>= 1, n++) { 7810b57cec5SDimitry Andric /* Calculate pow(5,pow(2,n+3)) if we haven't yet. */ 782*0fca6ea1SDimitry Andric if (n != 0) { 783*0fca6ea1SDimitry Andric APInt::tcFullMultiply(pow5, pow5 - partsCount, pow5 - partsCount, 784*0fca6ea1SDimitry Andric partsCount, partsCount); 785*0fca6ea1SDimitry Andric partsCount *= 2; 786*0fca6ea1SDimitry Andric if (pow5[partsCount - 1] == 0) 787*0fca6ea1SDimitry Andric partsCount--; 7880b57cec5SDimitry Andric } 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric if (power & 1) { 7910b57cec5SDimitry Andric APFloatBase::integerPart *tmp; 7920b57cec5SDimitry Andric 793*0fca6ea1SDimitry Andric APInt::tcFullMultiply(p2, p1, pow5, result, partsCount); 794*0fca6ea1SDimitry Andric result += partsCount; 7950b57cec5SDimitry Andric if (p2[result - 1] == 0) 7960b57cec5SDimitry Andric result--; 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric /* Now result is in p1 with partsCount parts and p2 is scratch 7990b57cec5SDimitry Andric space. */ 8000b57cec5SDimitry Andric tmp = p1; 8010b57cec5SDimitry Andric p1 = p2; 8020b57cec5SDimitry Andric p2 = tmp; 8030b57cec5SDimitry Andric } 8040b57cec5SDimitry Andric 805*0fca6ea1SDimitry Andric pow5 += partsCount; 8060b57cec5SDimitry Andric } 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric if (p1 != dst) 8090b57cec5SDimitry Andric APInt::tcAssign(dst, p1, result); 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric return result; 8120b57cec5SDimitry Andric } 8130b57cec5SDimitry Andric 8140b57cec5SDimitry Andric /* Zero at the end to avoid modular arithmetic when adding one; used 8150b57cec5SDimitry Andric when rounding up during hexadecimal output. */ 8160b57cec5SDimitry Andric static const char hexDigitsLower[] = "0123456789abcdef0"; 8170b57cec5SDimitry Andric static const char hexDigitsUpper[] = "0123456789ABCDEF0"; 8180b57cec5SDimitry Andric static const char infinityL[] = "infinity"; 8190b57cec5SDimitry Andric static const char infinityU[] = "INFINITY"; 8200b57cec5SDimitry Andric static const char NaNL[] = "nan"; 8210b57cec5SDimitry Andric static const char NaNU[] = "NAN"; 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric /* Write out an integerPart in hexadecimal, starting with the most 8240b57cec5SDimitry Andric significant nibble. Write out exactly COUNT hexdigits, return 8250b57cec5SDimitry Andric COUNT. */ 8260b57cec5SDimitry Andric static unsigned int 8270b57cec5SDimitry Andric partAsHex (char *dst, APFloatBase::integerPart part, unsigned int count, 8280b57cec5SDimitry Andric const char *hexDigitChars) 8290b57cec5SDimitry Andric { 8300b57cec5SDimitry Andric unsigned int result = count; 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric assert(count != 0 && count <= APFloatBase::integerPartWidth / 4); 8330b57cec5SDimitry Andric 8340b57cec5SDimitry Andric part >>= (APFloatBase::integerPartWidth - 4 * count); 8350b57cec5SDimitry Andric while (count--) { 8360b57cec5SDimitry Andric dst[count] = hexDigitChars[part & 0xf]; 8370b57cec5SDimitry Andric part >>= 4; 8380b57cec5SDimitry Andric } 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andric return result; 8410b57cec5SDimitry Andric } 8420b57cec5SDimitry Andric 8430b57cec5SDimitry Andric /* Write out an unsigned decimal integer. */ 8440b57cec5SDimitry Andric static char * 8450b57cec5SDimitry Andric writeUnsignedDecimal (char *dst, unsigned int n) 8460b57cec5SDimitry Andric { 8470b57cec5SDimitry Andric char buff[40], *p; 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric p = buff; 8500b57cec5SDimitry Andric do 8510b57cec5SDimitry Andric *p++ = '0' + n % 10; 8520b57cec5SDimitry Andric while (n /= 10); 8530b57cec5SDimitry Andric 8540b57cec5SDimitry Andric do 8550b57cec5SDimitry Andric *dst++ = *--p; 8560b57cec5SDimitry Andric while (p != buff); 8570b57cec5SDimitry Andric 8580b57cec5SDimitry Andric return dst; 8590b57cec5SDimitry Andric } 8600b57cec5SDimitry Andric 8610b57cec5SDimitry Andric /* Write out a signed decimal integer. */ 8620b57cec5SDimitry Andric static char * 8630b57cec5SDimitry Andric writeSignedDecimal (char *dst, int value) 8640b57cec5SDimitry Andric { 8650b57cec5SDimitry Andric if (value < 0) { 8660b57cec5SDimitry Andric *dst++ = '-'; 8670b57cec5SDimitry Andric dst = writeUnsignedDecimal(dst, -(unsigned) value); 8680b57cec5SDimitry Andric } else 8690b57cec5SDimitry Andric dst = writeUnsignedDecimal(dst, value); 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric return dst; 8720b57cec5SDimitry Andric } 8730b57cec5SDimitry Andric 8740b57cec5SDimitry Andric namespace detail { 8750b57cec5SDimitry Andric /* Constructors. */ 8760b57cec5SDimitry Andric void IEEEFloat::initialize(const fltSemantics *ourSemantics) { 8770b57cec5SDimitry Andric unsigned int count; 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric semantics = ourSemantics; 8800b57cec5SDimitry Andric count = partCount(); 8810b57cec5SDimitry Andric if (count > 1) 8820b57cec5SDimitry Andric significand.parts = new integerPart[count]; 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric 8850b57cec5SDimitry Andric void IEEEFloat::freeSignificand() { 8860b57cec5SDimitry Andric if (needsCleanup()) 8870b57cec5SDimitry Andric delete [] significand.parts; 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andric void IEEEFloat::assign(const IEEEFloat &rhs) { 8910b57cec5SDimitry Andric assert(semantics == rhs.semantics); 8920b57cec5SDimitry Andric 8930b57cec5SDimitry Andric sign = rhs.sign; 8940b57cec5SDimitry Andric category = rhs.category; 8950b57cec5SDimitry Andric exponent = rhs.exponent; 8960b57cec5SDimitry Andric if (isFiniteNonZero() || category == fcNaN) 8970b57cec5SDimitry Andric copySignificand(rhs); 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric 9000b57cec5SDimitry Andric void IEEEFloat::copySignificand(const IEEEFloat &rhs) { 9010b57cec5SDimitry Andric assert(isFiniteNonZero() || category == fcNaN); 9020b57cec5SDimitry Andric assert(rhs.partCount() >= partCount()); 9030b57cec5SDimitry Andric 9040b57cec5SDimitry Andric APInt::tcAssign(significandParts(), rhs.significandParts(), 9050b57cec5SDimitry Andric partCount()); 9060b57cec5SDimitry Andric } 9070b57cec5SDimitry Andric 9080b57cec5SDimitry Andric /* Make this number a NaN, with an arbitrary but deterministic value 9090b57cec5SDimitry Andric for the significand. If double or longer, this is a signalling NaN, 9100b57cec5SDimitry Andric which may not be ideal. If float, this is QNaN(0). */ 9110b57cec5SDimitry Andric void IEEEFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) { 912*0fca6ea1SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly) 913*0fca6ea1SDimitry Andric llvm_unreachable("This floating point format does not support NaN"); 914*0fca6ea1SDimitry Andric 9150b57cec5SDimitry Andric category = fcNaN; 9160b57cec5SDimitry Andric sign = Negative; 917e8d8bef9SDimitry Andric exponent = exponentNaN(); 9180b57cec5SDimitry Andric 9190b57cec5SDimitry Andric integerPart *significand = significandParts(); 9200b57cec5SDimitry Andric unsigned numParts = partCount(); 9210b57cec5SDimitry Andric 922bdd1243dSDimitry Andric APInt fill_storage; 923bdd1243dSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) { 92406c3fb27SDimitry Andric // Finite-only types do not distinguish signalling and quiet NaN, so 92506c3fb27SDimitry Andric // make them all signalling. 926bdd1243dSDimitry Andric SNaN = false; 92706c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) { 92806c3fb27SDimitry Andric sign = true; 92906c3fb27SDimitry Andric fill_storage = APInt::getZero(semantics->precision - 1); 93006c3fb27SDimitry Andric } else { 931bdd1243dSDimitry Andric fill_storage = APInt::getAllOnes(semantics->precision - 1); 93206c3fb27SDimitry Andric } 933bdd1243dSDimitry Andric fill = &fill_storage; 934bdd1243dSDimitry Andric } 935bdd1243dSDimitry Andric 9360b57cec5SDimitry Andric // Set the significand bits to the fill. 9370b57cec5SDimitry Andric if (!fill || fill->getNumWords() < numParts) 9380b57cec5SDimitry Andric APInt::tcSet(significand, 0, numParts); 9390b57cec5SDimitry Andric if (fill) { 9400b57cec5SDimitry Andric APInt::tcAssign(significand, fill->getRawData(), 9410b57cec5SDimitry Andric std::min(fill->getNumWords(), numParts)); 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andric // Zero out the excess bits of the significand. 9440b57cec5SDimitry Andric unsigned bitsToPreserve = semantics->precision - 1; 9450b57cec5SDimitry Andric unsigned part = bitsToPreserve / 64; 9460b57cec5SDimitry Andric bitsToPreserve %= 64; 9470b57cec5SDimitry Andric significand[part] &= ((1ULL << bitsToPreserve) - 1); 9480b57cec5SDimitry Andric for (part++; part != numParts; ++part) 9490b57cec5SDimitry Andric significand[part] = 0; 9500b57cec5SDimitry Andric } 9510b57cec5SDimitry Andric 9520b57cec5SDimitry Andric unsigned QNaNBit = semantics->precision - 2; 9530b57cec5SDimitry Andric 9540b57cec5SDimitry Andric if (SNaN) { 9550b57cec5SDimitry Andric // We always have to clear the QNaN bit to make it an SNaN. 9560b57cec5SDimitry Andric APInt::tcClearBit(significand, QNaNBit); 9570b57cec5SDimitry Andric 9580b57cec5SDimitry Andric // If there are no bits set in the payload, we have to set 9590b57cec5SDimitry Andric // *something* to make it a NaN instead of an infinity; 9600b57cec5SDimitry Andric // conventionally, this is the next bit down from the QNaN bit. 9610b57cec5SDimitry Andric if (APInt::tcIsZero(significand, numParts)) 9620b57cec5SDimitry Andric APInt::tcSetBit(significand, QNaNBit - 1); 96306c3fb27SDimitry Andric } else if (semantics->nanEncoding == fltNanEncoding::NegativeZero) { 96406c3fb27SDimitry Andric // The only NaN is a quiet NaN, and it has no bits sets in the significand. 96506c3fb27SDimitry Andric // Do nothing. 9660b57cec5SDimitry Andric } else { 9670b57cec5SDimitry Andric // We always have to set the QNaN bit to make it a QNaN. 9680b57cec5SDimitry Andric APInt::tcSetBit(significand, QNaNBit); 9690b57cec5SDimitry Andric } 9700b57cec5SDimitry Andric 9710b57cec5SDimitry Andric // For x87 extended precision, we want to make a NaN, not a 9720b57cec5SDimitry Andric // pseudo-NaN. Maybe we should expose the ability to make 9730b57cec5SDimitry Andric // pseudo-NaNs? 9740b57cec5SDimitry Andric if (semantics == &semX87DoubleExtended) 9750b57cec5SDimitry Andric APInt::tcSetBit(significand, QNaNBit + 1); 9760b57cec5SDimitry Andric } 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andric IEEEFloat &IEEEFloat::operator=(const IEEEFloat &rhs) { 9790b57cec5SDimitry Andric if (this != &rhs) { 9800b57cec5SDimitry Andric if (semantics != rhs.semantics) { 9810b57cec5SDimitry Andric freeSignificand(); 9820b57cec5SDimitry Andric initialize(rhs.semantics); 9830b57cec5SDimitry Andric } 9840b57cec5SDimitry Andric assign(rhs); 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric return *this; 9880b57cec5SDimitry Andric } 9890b57cec5SDimitry Andric 9900b57cec5SDimitry Andric IEEEFloat &IEEEFloat::operator=(IEEEFloat &&rhs) { 9910b57cec5SDimitry Andric freeSignificand(); 9920b57cec5SDimitry Andric 9930b57cec5SDimitry Andric semantics = rhs.semantics; 9940b57cec5SDimitry Andric significand = rhs.significand; 9950b57cec5SDimitry Andric exponent = rhs.exponent; 9960b57cec5SDimitry Andric category = rhs.category; 9970b57cec5SDimitry Andric sign = rhs.sign; 9980b57cec5SDimitry Andric 9990b57cec5SDimitry Andric rhs.semantics = &semBogus; 10000b57cec5SDimitry Andric return *this; 10010b57cec5SDimitry Andric } 10020b57cec5SDimitry Andric 10030b57cec5SDimitry Andric bool IEEEFloat::isDenormal() const { 10040b57cec5SDimitry Andric return isFiniteNonZero() && (exponent == semantics->minExponent) && 10050b57cec5SDimitry Andric (APInt::tcExtractBit(significandParts(), 10060b57cec5SDimitry Andric semantics->precision - 1) == 0); 10070b57cec5SDimitry Andric } 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric bool IEEEFloat::isSmallest() const { 10100b57cec5SDimitry Andric // The smallest number by magnitude in our format will be the smallest 10110b57cec5SDimitry Andric // denormal, i.e. the floating point number with exponent being minimum 10120b57cec5SDimitry Andric // exponent and significand bitwise equal to 1 (i.e. with MSB equal to 0). 10130b57cec5SDimitry Andric return isFiniteNonZero() && exponent == semantics->minExponent && 10140b57cec5SDimitry Andric significandMSB() == 0; 10150b57cec5SDimitry Andric } 10160b57cec5SDimitry Andric 1017bdd1243dSDimitry Andric bool IEEEFloat::isSmallestNormalized() const { 1018bdd1243dSDimitry Andric return getCategory() == fcNormal && exponent == semantics->minExponent && 1019bdd1243dSDimitry Andric isSignificandAllZerosExceptMSB(); 1020bdd1243dSDimitry Andric } 1021bdd1243dSDimitry Andric 10220b57cec5SDimitry Andric bool IEEEFloat::isSignificandAllOnes() const { 10230b57cec5SDimitry Andric // Test if the significand excluding the integral bit is all ones. This allows 10240b57cec5SDimitry Andric // us to test for binade boundaries. 10250b57cec5SDimitry Andric const integerPart *Parts = significandParts(); 1026e8d8bef9SDimitry Andric const unsigned PartCount = partCountForBits(semantics->precision); 10270b57cec5SDimitry Andric for (unsigned i = 0; i < PartCount - 1; i++) 10280b57cec5SDimitry Andric if (~Parts[i]) 10290b57cec5SDimitry Andric return false; 10300b57cec5SDimitry Andric 10310b57cec5SDimitry Andric // Set the unused high bits to all ones when we compare. 10320b57cec5SDimitry Andric const unsigned NumHighBits = 10330b57cec5SDimitry Andric PartCount*integerPartWidth - semantics->precision + 1; 1034e8d8bef9SDimitry Andric assert(NumHighBits <= integerPartWidth && NumHighBits > 0 && 1035e8d8bef9SDimitry Andric "Can not have more high bits to fill than integerPartWidth"); 10360b57cec5SDimitry Andric const integerPart HighBitFill = 10370b57cec5SDimitry Andric ~integerPart(0) << (integerPartWidth - NumHighBits); 10380b57cec5SDimitry Andric if (~(Parts[PartCount - 1] | HighBitFill)) 10390b57cec5SDimitry Andric return false; 10400b57cec5SDimitry Andric 10410b57cec5SDimitry Andric return true; 10420b57cec5SDimitry Andric } 10430b57cec5SDimitry Andric 1044bdd1243dSDimitry Andric bool IEEEFloat::isSignificandAllOnesExceptLSB() const { 1045bdd1243dSDimitry Andric // Test if the significand excluding the integral bit is all ones except for 1046bdd1243dSDimitry Andric // the least significant bit. 1047bdd1243dSDimitry Andric const integerPart *Parts = significandParts(); 1048bdd1243dSDimitry Andric 1049bdd1243dSDimitry Andric if (Parts[0] & 1) 1050bdd1243dSDimitry Andric return false; 1051bdd1243dSDimitry Andric 1052bdd1243dSDimitry Andric const unsigned PartCount = partCountForBits(semantics->precision); 1053bdd1243dSDimitry Andric for (unsigned i = 0; i < PartCount - 1; i++) { 1054bdd1243dSDimitry Andric if (~Parts[i] & ~unsigned{!i}) 1055bdd1243dSDimitry Andric return false; 1056bdd1243dSDimitry Andric } 1057bdd1243dSDimitry Andric 1058bdd1243dSDimitry Andric // Set the unused high bits to all ones when we compare. 1059bdd1243dSDimitry Andric const unsigned NumHighBits = 1060bdd1243dSDimitry Andric PartCount * integerPartWidth - semantics->precision + 1; 1061bdd1243dSDimitry Andric assert(NumHighBits <= integerPartWidth && NumHighBits > 0 && 1062bdd1243dSDimitry Andric "Can not have more high bits to fill than integerPartWidth"); 1063bdd1243dSDimitry Andric const integerPart HighBitFill = ~integerPart(0) 1064bdd1243dSDimitry Andric << (integerPartWidth - NumHighBits); 1065bdd1243dSDimitry Andric if (~(Parts[PartCount - 1] | HighBitFill | 0x1)) 1066bdd1243dSDimitry Andric return false; 1067bdd1243dSDimitry Andric 1068bdd1243dSDimitry Andric return true; 1069bdd1243dSDimitry Andric } 1070bdd1243dSDimitry Andric 10710b57cec5SDimitry Andric bool IEEEFloat::isSignificandAllZeros() const { 10720b57cec5SDimitry Andric // Test if the significand excluding the integral bit is all zeros. This 10730b57cec5SDimitry Andric // allows us to test for binade boundaries. 10740b57cec5SDimitry Andric const integerPart *Parts = significandParts(); 1075e8d8bef9SDimitry Andric const unsigned PartCount = partCountForBits(semantics->precision); 10760b57cec5SDimitry Andric 10770b57cec5SDimitry Andric for (unsigned i = 0; i < PartCount - 1; i++) 10780b57cec5SDimitry Andric if (Parts[i]) 10790b57cec5SDimitry Andric return false; 10800b57cec5SDimitry Andric 1081e8d8bef9SDimitry Andric // Compute how many bits are used in the final word. 10820b57cec5SDimitry Andric const unsigned NumHighBits = 10830b57cec5SDimitry Andric PartCount*integerPartWidth - semantics->precision + 1; 1084e8d8bef9SDimitry Andric assert(NumHighBits < integerPartWidth && "Can not have more high bits to " 10850b57cec5SDimitry Andric "clear than integerPartWidth"); 10860b57cec5SDimitry Andric const integerPart HighBitMask = ~integerPart(0) >> NumHighBits; 10870b57cec5SDimitry Andric 10880b57cec5SDimitry Andric if (Parts[PartCount - 1] & HighBitMask) 10890b57cec5SDimitry Andric return false; 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andric return true; 10920b57cec5SDimitry Andric } 10930b57cec5SDimitry Andric 1094bdd1243dSDimitry Andric bool IEEEFloat::isSignificandAllZerosExceptMSB() const { 1095bdd1243dSDimitry Andric const integerPart *Parts = significandParts(); 1096bdd1243dSDimitry Andric const unsigned PartCount = partCountForBits(semantics->precision); 1097bdd1243dSDimitry Andric 1098bdd1243dSDimitry Andric for (unsigned i = 0; i < PartCount - 1; i++) { 1099bdd1243dSDimitry Andric if (Parts[i]) 1100bdd1243dSDimitry Andric return false; 1101bdd1243dSDimitry Andric } 1102bdd1243dSDimitry Andric 1103bdd1243dSDimitry Andric const unsigned NumHighBits = 1104bdd1243dSDimitry Andric PartCount * integerPartWidth - semantics->precision + 1; 1105bdd1243dSDimitry Andric return Parts[PartCount - 1] == integerPart(1) 1106bdd1243dSDimitry Andric << (integerPartWidth - NumHighBits); 1107bdd1243dSDimitry Andric } 1108bdd1243dSDimitry Andric 11090b57cec5SDimitry Andric bool IEEEFloat::isLargest() const { 111006c3fb27SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly && 111106c3fb27SDimitry Andric semantics->nanEncoding == fltNanEncoding::AllOnes) { 1112bdd1243dSDimitry Andric // The largest number by magnitude in our format will be the floating point 1113bdd1243dSDimitry Andric // number with maximum exponent and with significand that is all ones except 1114bdd1243dSDimitry Andric // the LSB. 1115bdd1243dSDimitry Andric return isFiniteNonZero() && exponent == semantics->maxExponent && 1116bdd1243dSDimitry Andric isSignificandAllOnesExceptLSB(); 1117bdd1243dSDimitry Andric } else { 11180b57cec5SDimitry Andric // The largest number by magnitude in our format will be the floating point 11190b57cec5SDimitry Andric // number with maximum exponent and with significand that is all ones. 1120bdd1243dSDimitry Andric return isFiniteNonZero() && exponent == semantics->maxExponent && 1121bdd1243dSDimitry Andric isSignificandAllOnes(); 1122bdd1243dSDimitry Andric } 11230b57cec5SDimitry Andric } 11240b57cec5SDimitry Andric 11250b57cec5SDimitry Andric bool IEEEFloat::isInteger() const { 11260b57cec5SDimitry Andric // This could be made more efficient; I'm going for obviously correct. 11270b57cec5SDimitry Andric if (!isFinite()) return false; 11280b57cec5SDimitry Andric IEEEFloat truncated = *this; 11290b57cec5SDimitry Andric truncated.roundToIntegral(rmTowardZero); 11300b57cec5SDimitry Andric return compare(truncated) == cmpEqual; 11310b57cec5SDimitry Andric } 11320b57cec5SDimitry Andric 11330b57cec5SDimitry Andric bool IEEEFloat::bitwiseIsEqual(const IEEEFloat &rhs) const { 11340b57cec5SDimitry Andric if (this == &rhs) 11350b57cec5SDimitry Andric return true; 11360b57cec5SDimitry Andric if (semantics != rhs.semantics || 11370b57cec5SDimitry Andric category != rhs.category || 11380b57cec5SDimitry Andric sign != rhs.sign) 11390b57cec5SDimitry Andric return false; 11400b57cec5SDimitry Andric if (category==fcZero || category==fcInfinity) 11410b57cec5SDimitry Andric return true; 11420b57cec5SDimitry Andric 11430b57cec5SDimitry Andric if (isFiniteNonZero() && exponent != rhs.exponent) 11440b57cec5SDimitry Andric return false; 11450b57cec5SDimitry Andric 11460b57cec5SDimitry Andric return std::equal(significandParts(), significandParts() + partCount(), 11470b57cec5SDimitry Andric rhs.significandParts()); 11480b57cec5SDimitry Andric } 11490b57cec5SDimitry Andric 11500b57cec5SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, integerPart value) { 11510b57cec5SDimitry Andric initialize(&ourSemantics); 11520b57cec5SDimitry Andric sign = 0; 11530b57cec5SDimitry Andric category = fcNormal; 11540b57cec5SDimitry Andric zeroSignificand(); 11550b57cec5SDimitry Andric exponent = ourSemantics.precision - 1; 11560b57cec5SDimitry Andric significandParts()[0] = value; 11570b57cec5SDimitry Andric normalize(rmNearestTiesToEven, lfExactlyZero); 11580b57cec5SDimitry Andric } 11590b57cec5SDimitry Andric 11600b57cec5SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics) { 11610b57cec5SDimitry Andric initialize(&ourSemantics); 1162e8d8bef9SDimitry Andric makeZero(false); 11630b57cec5SDimitry Andric } 11640b57cec5SDimitry Andric 11650b57cec5SDimitry Andric // Delegate to the previous constructor, because later copy constructor may 11660b57cec5SDimitry Andric // actually inspects category, which can't be garbage. 11670b57cec5SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, uninitializedTag tag) 11680b57cec5SDimitry Andric : IEEEFloat(ourSemantics) {} 11690b57cec5SDimitry Andric 11700b57cec5SDimitry Andric IEEEFloat::IEEEFloat(const IEEEFloat &rhs) { 11710b57cec5SDimitry Andric initialize(rhs.semantics); 11720b57cec5SDimitry Andric assign(rhs); 11730b57cec5SDimitry Andric } 11740b57cec5SDimitry Andric 11750b57cec5SDimitry Andric IEEEFloat::IEEEFloat(IEEEFloat &&rhs) : semantics(&semBogus) { 11760b57cec5SDimitry Andric *this = std::move(rhs); 11770b57cec5SDimitry Andric } 11780b57cec5SDimitry Andric 11790b57cec5SDimitry Andric IEEEFloat::~IEEEFloat() { freeSignificand(); } 11800b57cec5SDimitry Andric 11810b57cec5SDimitry Andric unsigned int IEEEFloat::partCount() const { 11820b57cec5SDimitry Andric return partCountForBits(semantics->precision + 1); 11830b57cec5SDimitry Andric } 11840b57cec5SDimitry Andric 11850b57cec5SDimitry Andric const IEEEFloat::integerPart *IEEEFloat::significandParts() const { 11860b57cec5SDimitry Andric return const_cast<IEEEFloat *>(this)->significandParts(); 11870b57cec5SDimitry Andric } 11880b57cec5SDimitry Andric 11890b57cec5SDimitry Andric IEEEFloat::integerPart *IEEEFloat::significandParts() { 11900b57cec5SDimitry Andric if (partCount() > 1) 11910b57cec5SDimitry Andric return significand.parts; 11920b57cec5SDimitry Andric else 11930b57cec5SDimitry Andric return &significand.part; 11940b57cec5SDimitry Andric } 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric void IEEEFloat::zeroSignificand() { 11970b57cec5SDimitry Andric APInt::tcSet(significandParts(), 0, partCount()); 11980b57cec5SDimitry Andric } 11990b57cec5SDimitry Andric 12000b57cec5SDimitry Andric /* Increment an fcNormal floating point number's significand. */ 12010b57cec5SDimitry Andric void IEEEFloat::incrementSignificand() { 12020b57cec5SDimitry Andric integerPart carry; 12030b57cec5SDimitry Andric 12040b57cec5SDimitry Andric carry = APInt::tcIncrement(significandParts(), partCount()); 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric /* Our callers should never cause us to overflow. */ 12070b57cec5SDimitry Andric assert(carry == 0); 12080b57cec5SDimitry Andric (void)carry; 12090b57cec5SDimitry Andric } 12100b57cec5SDimitry Andric 12110b57cec5SDimitry Andric /* Add the significand of the RHS. Returns the carry flag. */ 12120b57cec5SDimitry Andric IEEEFloat::integerPart IEEEFloat::addSignificand(const IEEEFloat &rhs) { 12130b57cec5SDimitry Andric integerPart *parts; 12140b57cec5SDimitry Andric 12150b57cec5SDimitry Andric parts = significandParts(); 12160b57cec5SDimitry Andric 12170b57cec5SDimitry Andric assert(semantics == rhs.semantics); 12180b57cec5SDimitry Andric assert(exponent == rhs.exponent); 12190b57cec5SDimitry Andric 12200b57cec5SDimitry Andric return APInt::tcAdd(parts, rhs.significandParts(), 0, partCount()); 12210b57cec5SDimitry Andric } 12220b57cec5SDimitry Andric 12230b57cec5SDimitry Andric /* Subtract the significand of the RHS with a borrow flag. Returns 12240b57cec5SDimitry Andric the borrow flag. */ 12250b57cec5SDimitry Andric IEEEFloat::integerPart IEEEFloat::subtractSignificand(const IEEEFloat &rhs, 12260b57cec5SDimitry Andric integerPart borrow) { 12270b57cec5SDimitry Andric integerPart *parts; 12280b57cec5SDimitry Andric 12290b57cec5SDimitry Andric parts = significandParts(); 12300b57cec5SDimitry Andric 12310b57cec5SDimitry Andric assert(semantics == rhs.semantics); 12320b57cec5SDimitry Andric assert(exponent == rhs.exponent); 12330b57cec5SDimitry Andric 12340b57cec5SDimitry Andric return APInt::tcSubtract(parts, rhs.significandParts(), borrow, 12350b57cec5SDimitry Andric partCount()); 12360b57cec5SDimitry Andric } 12370b57cec5SDimitry Andric 12380b57cec5SDimitry Andric /* Multiply the significand of the RHS. If ADDEND is non-NULL, add it 12390b57cec5SDimitry Andric on to the full-precision result of the multiplication. Returns the 12400b57cec5SDimitry Andric lost fraction. */ 12410b57cec5SDimitry Andric lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs, 1242480093f4SDimitry Andric IEEEFloat addend) { 12430b57cec5SDimitry Andric unsigned int omsb; // One, not zero, based MSB. 12440b57cec5SDimitry Andric unsigned int partsCount, newPartsCount, precision; 12450b57cec5SDimitry Andric integerPart *lhsSignificand; 12460b57cec5SDimitry Andric integerPart scratch[4]; 12470b57cec5SDimitry Andric integerPart *fullSignificand; 12480b57cec5SDimitry Andric lostFraction lost_fraction; 12490b57cec5SDimitry Andric bool ignored; 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric assert(semantics == rhs.semantics); 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andric precision = semantics->precision; 12540b57cec5SDimitry Andric 12550b57cec5SDimitry Andric // Allocate space for twice as many bits as the original significand, plus one 12560b57cec5SDimitry Andric // extra bit for the addition to overflow into. 12570b57cec5SDimitry Andric newPartsCount = partCountForBits(precision * 2 + 1); 12580b57cec5SDimitry Andric 12590b57cec5SDimitry Andric if (newPartsCount > 4) 12600b57cec5SDimitry Andric fullSignificand = new integerPart[newPartsCount]; 12610b57cec5SDimitry Andric else 12620b57cec5SDimitry Andric fullSignificand = scratch; 12630b57cec5SDimitry Andric 12640b57cec5SDimitry Andric lhsSignificand = significandParts(); 12650b57cec5SDimitry Andric partsCount = partCount(); 12660b57cec5SDimitry Andric 12670b57cec5SDimitry Andric APInt::tcFullMultiply(fullSignificand, lhsSignificand, 12680b57cec5SDimitry Andric rhs.significandParts(), partsCount, partsCount); 12690b57cec5SDimitry Andric 12700b57cec5SDimitry Andric lost_fraction = lfExactlyZero; 12710b57cec5SDimitry Andric omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1; 12720b57cec5SDimitry Andric exponent += rhs.exponent; 12730b57cec5SDimitry Andric 12740b57cec5SDimitry Andric // Assume the operands involved in the multiplication are single-precision 12750b57cec5SDimitry Andric // FP, and the two multiplicants are: 12760b57cec5SDimitry Andric // *this = a23 . a22 ... a0 * 2^e1 12770b57cec5SDimitry Andric // rhs = b23 . b22 ... b0 * 2^e2 12780b57cec5SDimitry Andric // the result of multiplication is: 12790b57cec5SDimitry Andric // *this = c48 c47 c46 . c45 ... c0 * 2^(e1+e2) 12800b57cec5SDimitry Andric // Note that there are three significant bits at the left-hand side of the 12810b57cec5SDimitry Andric // radix point: two for the multiplication, and an overflow bit for the 12820b57cec5SDimitry Andric // addition (that will always be zero at this point). Move the radix point 12830b57cec5SDimitry Andric // toward left by two bits, and adjust exponent accordingly. 12840b57cec5SDimitry Andric exponent += 2; 12850b57cec5SDimitry Andric 1286480093f4SDimitry Andric if (addend.isNonZero()) { 12870b57cec5SDimitry Andric // The intermediate result of the multiplication has "2 * precision" 12880b57cec5SDimitry Andric // signicant bit; adjust the addend to be consistent with mul result. 12890b57cec5SDimitry Andric // 12900b57cec5SDimitry Andric Significand savedSignificand = significand; 12910b57cec5SDimitry Andric const fltSemantics *savedSemantics = semantics; 12920b57cec5SDimitry Andric fltSemantics extendedSemantics; 12930b57cec5SDimitry Andric opStatus status; 12940b57cec5SDimitry Andric unsigned int extendedPrecision; 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andric // Normalize our MSB to one below the top bit to allow for overflow. 12970b57cec5SDimitry Andric extendedPrecision = 2 * precision + 1; 12980b57cec5SDimitry Andric if (omsb != extendedPrecision - 1) { 12990b57cec5SDimitry Andric assert(extendedPrecision > omsb); 13000b57cec5SDimitry Andric APInt::tcShiftLeft(fullSignificand, newPartsCount, 13010b57cec5SDimitry Andric (extendedPrecision - 1) - omsb); 13020b57cec5SDimitry Andric exponent -= (extendedPrecision - 1) - omsb; 13030b57cec5SDimitry Andric } 13040b57cec5SDimitry Andric 13050b57cec5SDimitry Andric /* Create new semantics. */ 13060b57cec5SDimitry Andric extendedSemantics = *semantics; 13070b57cec5SDimitry Andric extendedSemantics.precision = extendedPrecision; 13080b57cec5SDimitry Andric 13090b57cec5SDimitry Andric if (newPartsCount == 1) 13100b57cec5SDimitry Andric significand.part = fullSignificand[0]; 13110b57cec5SDimitry Andric else 13120b57cec5SDimitry Andric significand.parts = fullSignificand; 13130b57cec5SDimitry Andric semantics = &extendedSemantics; 13140b57cec5SDimitry Andric 1315480093f4SDimitry Andric // Make a copy so we can convert it to the extended semantics. 1316480093f4SDimitry Andric // Note that we cannot convert the addend directly, as the extendedSemantics 1317480093f4SDimitry Andric // is a local variable (which we take a reference to). 1318480093f4SDimitry Andric IEEEFloat extendedAddend(addend); 13190b57cec5SDimitry Andric status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored); 13200b57cec5SDimitry Andric assert(status == opOK); 13210b57cec5SDimitry Andric (void)status; 13220b57cec5SDimitry Andric 13230b57cec5SDimitry Andric // Shift the significand of the addend right by one bit. This guarantees 13240b57cec5SDimitry Andric // that the high bit of the significand is zero (same as fullSignificand), 13250b57cec5SDimitry Andric // so the addition will overflow (if it does overflow at all) into the top bit. 13260b57cec5SDimitry Andric lost_fraction = extendedAddend.shiftSignificandRight(1); 13270b57cec5SDimitry Andric assert(lost_fraction == lfExactlyZero && 13280b57cec5SDimitry Andric "Lost precision while shifting addend for fused-multiply-add."); 13290b57cec5SDimitry Andric 13300b57cec5SDimitry Andric lost_fraction = addOrSubtractSignificand(extendedAddend, false); 13310b57cec5SDimitry Andric 13320b57cec5SDimitry Andric /* Restore our state. */ 13330b57cec5SDimitry Andric if (newPartsCount == 1) 13340b57cec5SDimitry Andric fullSignificand[0] = significand.part; 13350b57cec5SDimitry Andric significand = savedSignificand; 13360b57cec5SDimitry Andric semantics = savedSemantics; 13370b57cec5SDimitry Andric 13380b57cec5SDimitry Andric omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1; 13390b57cec5SDimitry Andric } 13400b57cec5SDimitry Andric 13410b57cec5SDimitry Andric // Convert the result having "2 * precision" significant-bits back to the one 13420b57cec5SDimitry Andric // having "precision" significant-bits. First, move the radix point from 13430b57cec5SDimitry Andric // poision "2*precision - 1" to "precision - 1". The exponent need to be 13440b57cec5SDimitry Andric // adjusted by "2*precision - 1" - "precision - 1" = "precision". 13450b57cec5SDimitry Andric exponent -= precision + 1; 13460b57cec5SDimitry Andric 13470b57cec5SDimitry Andric // In case MSB resides at the left-hand side of radix point, shift the 13480b57cec5SDimitry Andric // mantissa right by some amount to make sure the MSB reside right before 13490b57cec5SDimitry Andric // the radix point (i.e. "MSB . rest-significant-bits"). 13500b57cec5SDimitry Andric // 13510b57cec5SDimitry Andric // Note that the result is not normalized when "omsb < precision". So, the 13520b57cec5SDimitry Andric // caller needs to call IEEEFloat::normalize() if normalized value is 13530b57cec5SDimitry Andric // expected. 13540b57cec5SDimitry Andric if (omsb > precision) { 13550b57cec5SDimitry Andric unsigned int bits, significantParts; 13560b57cec5SDimitry Andric lostFraction lf; 13570b57cec5SDimitry Andric 13580b57cec5SDimitry Andric bits = omsb - precision; 13590b57cec5SDimitry Andric significantParts = partCountForBits(omsb); 13600b57cec5SDimitry Andric lf = shiftRight(fullSignificand, significantParts, bits); 13610b57cec5SDimitry Andric lost_fraction = combineLostFractions(lf, lost_fraction); 13620b57cec5SDimitry Andric exponent += bits; 13630b57cec5SDimitry Andric } 13640b57cec5SDimitry Andric 13650b57cec5SDimitry Andric APInt::tcAssign(lhsSignificand, fullSignificand, partsCount); 13660b57cec5SDimitry Andric 13670b57cec5SDimitry Andric if (newPartsCount > 4) 13680b57cec5SDimitry Andric delete [] fullSignificand; 13690b57cec5SDimitry Andric 13700b57cec5SDimitry Andric return lost_fraction; 13710b57cec5SDimitry Andric } 13720b57cec5SDimitry Andric 1373480093f4SDimitry Andric lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs) { 1374480093f4SDimitry Andric return multiplySignificand(rhs, IEEEFloat(*semantics)); 1375480093f4SDimitry Andric } 1376480093f4SDimitry Andric 13770b57cec5SDimitry Andric /* Multiply the significands of LHS and RHS to DST. */ 13780b57cec5SDimitry Andric lostFraction IEEEFloat::divideSignificand(const IEEEFloat &rhs) { 13790b57cec5SDimitry Andric unsigned int bit, i, partsCount; 13800b57cec5SDimitry Andric const integerPart *rhsSignificand; 13810b57cec5SDimitry Andric integerPart *lhsSignificand, *dividend, *divisor; 13820b57cec5SDimitry Andric integerPart scratch[4]; 13830b57cec5SDimitry Andric lostFraction lost_fraction; 13840b57cec5SDimitry Andric 13850b57cec5SDimitry Andric assert(semantics == rhs.semantics); 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric lhsSignificand = significandParts(); 13880b57cec5SDimitry Andric rhsSignificand = rhs.significandParts(); 13890b57cec5SDimitry Andric partsCount = partCount(); 13900b57cec5SDimitry Andric 13910b57cec5SDimitry Andric if (partsCount > 2) 13920b57cec5SDimitry Andric dividend = new integerPart[partsCount * 2]; 13930b57cec5SDimitry Andric else 13940b57cec5SDimitry Andric dividend = scratch; 13950b57cec5SDimitry Andric 13960b57cec5SDimitry Andric divisor = dividend + partsCount; 13970b57cec5SDimitry Andric 13980b57cec5SDimitry Andric /* Copy the dividend and divisor as they will be modified in-place. */ 13990b57cec5SDimitry Andric for (i = 0; i < partsCount; i++) { 14000b57cec5SDimitry Andric dividend[i] = lhsSignificand[i]; 14010b57cec5SDimitry Andric divisor[i] = rhsSignificand[i]; 14020b57cec5SDimitry Andric lhsSignificand[i] = 0; 14030b57cec5SDimitry Andric } 14040b57cec5SDimitry Andric 14050b57cec5SDimitry Andric exponent -= rhs.exponent; 14060b57cec5SDimitry Andric 14070b57cec5SDimitry Andric unsigned int precision = semantics->precision; 14080b57cec5SDimitry Andric 14090b57cec5SDimitry Andric /* Normalize the divisor. */ 14100b57cec5SDimitry Andric bit = precision - APInt::tcMSB(divisor, partsCount) - 1; 14110b57cec5SDimitry Andric if (bit) { 14120b57cec5SDimitry Andric exponent += bit; 14130b57cec5SDimitry Andric APInt::tcShiftLeft(divisor, partsCount, bit); 14140b57cec5SDimitry Andric } 14150b57cec5SDimitry Andric 14160b57cec5SDimitry Andric /* Normalize the dividend. */ 14170b57cec5SDimitry Andric bit = precision - APInt::tcMSB(dividend, partsCount) - 1; 14180b57cec5SDimitry Andric if (bit) { 14190b57cec5SDimitry Andric exponent -= bit; 14200b57cec5SDimitry Andric APInt::tcShiftLeft(dividend, partsCount, bit); 14210b57cec5SDimitry Andric } 14220b57cec5SDimitry Andric 14230b57cec5SDimitry Andric /* Ensure the dividend >= divisor initially for the loop below. 14240b57cec5SDimitry Andric Incidentally, this means that the division loop below is 14250b57cec5SDimitry Andric guaranteed to set the integer bit to one. */ 14260b57cec5SDimitry Andric if (APInt::tcCompare(dividend, divisor, partsCount) < 0) { 14270b57cec5SDimitry Andric exponent--; 14280b57cec5SDimitry Andric APInt::tcShiftLeft(dividend, partsCount, 1); 14290b57cec5SDimitry Andric assert(APInt::tcCompare(dividend, divisor, partsCount) >= 0); 14300b57cec5SDimitry Andric } 14310b57cec5SDimitry Andric 14320b57cec5SDimitry Andric /* Long division. */ 14330b57cec5SDimitry Andric for (bit = precision; bit; bit -= 1) { 14340b57cec5SDimitry Andric if (APInt::tcCompare(dividend, divisor, partsCount) >= 0) { 14350b57cec5SDimitry Andric APInt::tcSubtract(dividend, divisor, 0, partsCount); 14360b57cec5SDimitry Andric APInt::tcSetBit(lhsSignificand, bit - 1); 14370b57cec5SDimitry Andric } 14380b57cec5SDimitry Andric 14390b57cec5SDimitry Andric APInt::tcShiftLeft(dividend, partsCount, 1); 14400b57cec5SDimitry Andric } 14410b57cec5SDimitry Andric 14420b57cec5SDimitry Andric /* Figure out the lost fraction. */ 14430b57cec5SDimitry Andric int cmp = APInt::tcCompare(dividend, divisor, partsCount); 14440b57cec5SDimitry Andric 14450b57cec5SDimitry Andric if (cmp > 0) 14460b57cec5SDimitry Andric lost_fraction = lfMoreThanHalf; 14470b57cec5SDimitry Andric else if (cmp == 0) 14480b57cec5SDimitry Andric lost_fraction = lfExactlyHalf; 14490b57cec5SDimitry Andric else if (APInt::tcIsZero(dividend, partsCount)) 14500b57cec5SDimitry Andric lost_fraction = lfExactlyZero; 14510b57cec5SDimitry Andric else 14520b57cec5SDimitry Andric lost_fraction = lfLessThanHalf; 14530b57cec5SDimitry Andric 14540b57cec5SDimitry Andric if (partsCount > 2) 14550b57cec5SDimitry Andric delete [] dividend; 14560b57cec5SDimitry Andric 14570b57cec5SDimitry Andric return lost_fraction; 14580b57cec5SDimitry Andric } 14590b57cec5SDimitry Andric 14600b57cec5SDimitry Andric unsigned int IEEEFloat::significandMSB() const { 14610b57cec5SDimitry Andric return APInt::tcMSB(significandParts(), partCount()); 14620b57cec5SDimitry Andric } 14630b57cec5SDimitry Andric 14640b57cec5SDimitry Andric unsigned int IEEEFloat::significandLSB() const { 14650b57cec5SDimitry Andric return APInt::tcLSB(significandParts(), partCount()); 14660b57cec5SDimitry Andric } 14670b57cec5SDimitry Andric 14680b57cec5SDimitry Andric /* Note that a zero result is NOT normalized to fcZero. */ 14690b57cec5SDimitry Andric lostFraction IEEEFloat::shiftSignificandRight(unsigned int bits) { 14700b57cec5SDimitry Andric /* Our exponent should not overflow. */ 14710b57cec5SDimitry Andric assert((ExponentType) (exponent + bits) >= exponent); 14720b57cec5SDimitry Andric 14730b57cec5SDimitry Andric exponent += bits; 14740b57cec5SDimitry Andric 14750b57cec5SDimitry Andric return shiftRight(significandParts(), partCount(), bits); 14760b57cec5SDimitry Andric } 14770b57cec5SDimitry Andric 14780b57cec5SDimitry Andric /* Shift the significand left BITS bits, subtract BITS from its exponent. */ 14790b57cec5SDimitry Andric void IEEEFloat::shiftSignificandLeft(unsigned int bits) { 14800b57cec5SDimitry Andric assert(bits < semantics->precision); 14810b57cec5SDimitry Andric 14820b57cec5SDimitry Andric if (bits) { 14830b57cec5SDimitry Andric unsigned int partsCount = partCount(); 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric APInt::tcShiftLeft(significandParts(), partsCount, bits); 14860b57cec5SDimitry Andric exponent -= bits; 14870b57cec5SDimitry Andric 14880b57cec5SDimitry Andric assert(!APInt::tcIsZero(significandParts(), partsCount)); 14890b57cec5SDimitry Andric } 14900b57cec5SDimitry Andric } 14910b57cec5SDimitry Andric 14920b57cec5SDimitry Andric IEEEFloat::cmpResult 14930b57cec5SDimitry Andric IEEEFloat::compareAbsoluteValue(const IEEEFloat &rhs) const { 14940b57cec5SDimitry Andric int compare; 14950b57cec5SDimitry Andric 14960b57cec5SDimitry Andric assert(semantics == rhs.semantics); 14970b57cec5SDimitry Andric assert(isFiniteNonZero()); 14980b57cec5SDimitry Andric assert(rhs.isFiniteNonZero()); 14990b57cec5SDimitry Andric 15000b57cec5SDimitry Andric compare = exponent - rhs.exponent; 15010b57cec5SDimitry Andric 15020b57cec5SDimitry Andric /* If exponents are equal, do an unsigned bignum comparison of the 15030b57cec5SDimitry Andric significands. */ 15040b57cec5SDimitry Andric if (compare == 0) 15050b57cec5SDimitry Andric compare = APInt::tcCompare(significandParts(), rhs.significandParts(), 15060b57cec5SDimitry Andric partCount()); 15070b57cec5SDimitry Andric 15080b57cec5SDimitry Andric if (compare > 0) 15090b57cec5SDimitry Andric return cmpGreaterThan; 15100b57cec5SDimitry Andric else if (compare < 0) 15110b57cec5SDimitry Andric return cmpLessThan; 15120b57cec5SDimitry Andric else 15130b57cec5SDimitry Andric return cmpEqual; 15140b57cec5SDimitry Andric } 15150b57cec5SDimitry Andric 1516349cc55cSDimitry Andric /* Set the least significant BITS bits of a bignum, clear the 1517349cc55cSDimitry Andric rest. */ 1518349cc55cSDimitry Andric static void tcSetLeastSignificantBits(APInt::WordType *dst, unsigned parts, 1519349cc55cSDimitry Andric unsigned bits) { 1520349cc55cSDimitry Andric unsigned i = 0; 1521349cc55cSDimitry Andric while (bits > APInt::APINT_BITS_PER_WORD) { 1522349cc55cSDimitry Andric dst[i++] = ~(APInt::WordType)0; 1523349cc55cSDimitry Andric bits -= APInt::APINT_BITS_PER_WORD; 1524349cc55cSDimitry Andric } 1525349cc55cSDimitry Andric 1526349cc55cSDimitry Andric if (bits) 1527349cc55cSDimitry Andric dst[i++] = ~(APInt::WordType)0 >> (APInt::APINT_BITS_PER_WORD - bits); 1528349cc55cSDimitry Andric 1529349cc55cSDimitry Andric while (i < parts) 1530349cc55cSDimitry Andric dst[i++] = 0; 1531349cc55cSDimitry Andric } 1532349cc55cSDimitry Andric 15330b57cec5SDimitry Andric /* Handle overflow. Sign is preserved. We either become infinity or 15340b57cec5SDimitry Andric the largest finite number. */ 15350b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::handleOverflow(roundingMode rounding_mode) { 1536*0fca6ea1SDimitry Andric if (semantics->nonFiniteBehavior != fltNonfiniteBehavior::FiniteOnly) { 15370b57cec5SDimitry Andric /* Infinity? */ 15380b57cec5SDimitry Andric if (rounding_mode == rmNearestTiesToEven || 15390b57cec5SDimitry Andric rounding_mode == rmNearestTiesToAway || 15400b57cec5SDimitry Andric (rounding_mode == rmTowardPositive && !sign) || 15410b57cec5SDimitry Andric (rounding_mode == rmTowardNegative && sign)) { 1542bdd1243dSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) 1543bdd1243dSDimitry Andric makeNaN(false, sign); 1544bdd1243dSDimitry Andric else 15450b57cec5SDimitry Andric category = fcInfinity; 1546*0fca6ea1SDimitry Andric return static_cast<opStatus>(opOverflow | opInexact); 1547*0fca6ea1SDimitry Andric } 15480b57cec5SDimitry Andric } 15490b57cec5SDimitry Andric 15500b57cec5SDimitry Andric /* Otherwise we become the largest finite number. */ 15510b57cec5SDimitry Andric category = fcNormal; 15520b57cec5SDimitry Andric exponent = semantics->maxExponent; 1553349cc55cSDimitry Andric tcSetLeastSignificantBits(significandParts(), partCount(), 15540b57cec5SDimitry Andric semantics->precision); 155506c3fb27SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly && 155606c3fb27SDimitry Andric semantics->nanEncoding == fltNanEncoding::AllOnes) 1557bdd1243dSDimitry Andric APInt::tcClearBit(significandParts(), 0); 15580b57cec5SDimitry Andric 15590b57cec5SDimitry Andric return opInexact; 15600b57cec5SDimitry Andric } 15610b57cec5SDimitry Andric 15620b57cec5SDimitry Andric /* Returns TRUE if, when truncating the current number, with BIT the 15630b57cec5SDimitry Andric new LSB, with the given lost fraction and rounding mode, the result 15640b57cec5SDimitry Andric would need to be rounded away from zero (i.e., by increasing the 15650b57cec5SDimitry Andric signficand). This routine must work for fcZero of both signs, and 15660b57cec5SDimitry Andric fcNormal numbers. */ 15670b57cec5SDimitry Andric bool IEEEFloat::roundAwayFromZero(roundingMode rounding_mode, 15680b57cec5SDimitry Andric lostFraction lost_fraction, 15690b57cec5SDimitry Andric unsigned int bit) const { 15700b57cec5SDimitry Andric /* NaNs and infinities should not have lost fractions. */ 15710b57cec5SDimitry Andric assert(isFiniteNonZero() || category == fcZero); 15720b57cec5SDimitry Andric 15730b57cec5SDimitry Andric /* Current callers never pass this so we don't handle it. */ 15740b57cec5SDimitry Andric assert(lost_fraction != lfExactlyZero); 15750b57cec5SDimitry Andric 15760b57cec5SDimitry Andric switch (rounding_mode) { 15770b57cec5SDimitry Andric case rmNearestTiesToAway: 15780b57cec5SDimitry Andric return lost_fraction == lfExactlyHalf || lost_fraction == lfMoreThanHalf; 15790b57cec5SDimitry Andric 15800b57cec5SDimitry Andric case rmNearestTiesToEven: 15810b57cec5SDimitry Andric if (lost_fraction == lfMoreThanHalf) 15820b57cec5SDimitry Andric return true; 15830b57cec5SDimitry Andric 15840b57cec5SDimitry Andric /* Our zeroes don't have a significand to test. */ 15850b57cec5SDimitry Andric if (lost_fraction == lfExactlyHalf && category != fcZero) 15860b57cec5SDimitry Andric return APInt::tcExtractBit(significandParts(), bit); 15870b57cec5SDimitry Andric 15880b57cec5SDimitry Andric return false; 15890b57cec5SDimitry Andric 15900b57cec5SDimitry Andric case rmTowardZero: 15910b57cec5SDimitry Andric return false; 15920b57cec5SDimitry Andric 15930b57cec5SDimitry Andric case rmTowardPositive: 15940b57cec5SDimitry Andric return !sign; 15950b57cec5SDimitry Andric 15960b57cec5SDimitry Andric case rmTowardNegative: 15970b57cec5SDimitry Andric return sign; 15985ffd83dbSDimitry Andric 15995ffd83dbSDimitry Andric default: 16005ffd83dbSDimitry Andric break; 16010b57cec5SDimitry Andric } 16020b57cec5SDimitry Andric llvm_unreachable("Invalid rounding mode found"); 16030b57cec5SDimitry Andric } 16040b57cec5SDimitry Andric 16050b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::normalize(roundingMode rounding_mode, 16060b57cec5SDimitry Andric lostFraction lost_fraction) { 16070b57cec5SDimitry Andric unsigned int omsb; /* One, not zero, based MSB. */ 16080b57cec5SDimitry Andric int exponentChange; 16090b57cec5SDimitry Andric 16100b57cec5SDimitry Andric if (!isFiniteNonZero()) 16110b57cec5SDimitry Andric return opOK; 16120b57cec5SDimitry Andric 16130b57cec5SDimitry Andric /* Before rounding normalize the exponent of fcNormal numbers. */ 16140b57cec5SDimitry Andric omsb = significandMSB() + 1; 16150b57cec5SDimitry Andric 16160b57cec5SDimitry Andric if (omsb) { 16170b57cec5SDimitry Andric /* OMSB is numbered from 1. We want to place it in the integer 16180b57cec5SDimitry Andric bit numbered PRECISION if possible, with a compensating change in 16190b57cec5SDimitry Andric the exponent. */ 16200b57cec5SDimitry Andric exponentChange = omsb - semantics->precision; 16210b57cec5SDimitry Andric 16220b57cec5SDimitry Andric /* If the resulting exponent is too high, overflow according to 16230b57cec5SDimitry Andric the rounding mode. */ 16240b57cec5SDimitry Andric if (exponent + exponentChange > semantics->maxExponent) 16250b57cec5SDimitry Andric return handleOverflow(rounding_mode); 16260b57cec5SDimitry Andric 16270b57cec5SDimitry Andric /* Subnormal numbers have exponent minExponent, and their MSB 16280b57cec5SDimitry Andric is forced based on that. */ 16290b57cec5SDimitry Andric if (exponent + exponentChange < semantics->minExponent) 16300b57cec5SDimitry Andric exponentChange = semantics->minExponent - exponent; 16310b57cec5SDimitry Andric 16320b57cec5SDimitry Andric /* Shifting left is easy as we don't lose precision. */ 16330b57cec5SDimitry Andric if (exponentChange < 0) { 16340b57cec5SDimitry Andric assert(lost_fraction == lfExactlyZero); 16350b57cec5SDimitry Andric 16360b57cec5SDimitry Andric shiftSignificandLeft(-exponentChange); 16370b57cec5SDimitry Andric 16380b57cec5SDimitry Andric return opOK; 16390b57cec5SDimitry Andric } 16400b57cec5SDimitry Andric 16410b57cec5SDimitry Andric if (exponentChange > 0) { 16420b57cec5SDimitry Andric lostFraction lf; 16430b57cec5SDimitry Andric 16440b57cec5SDimitry Andric /* Shift right and capture any new lost fraction. */ 16450b57cec5SDimitry Andric lf = shiftSignificandRight(exponentChange); 16460b57cec5SDimitry Andric 16470b57cec5SDimitry Andric lost_fraction = combineLostFractions(lf, lost_fraction); 16480b57cec5SDimitry Andric 16490b57cec5SDimitry Andric /* Keep OMSB up-to-date. */ 16500b57cec5SDimitry Andric if (omsb > (unsigned) exponentChange) 16510b57cec5SDimitry Andric omsb -= exponentChange; 16520b57cec5SDimitry Andric else 16530b57cec5SDimitry Andric omsb = 0; 16540b57cec5SDimitry Andric } 16550b57cec5SDimitry Andric } 16560b57cec5SDimitry Andric 165706c3fb27SDimitry Andric // The all-ones values is an overflow if NaN is all ones. If NaN is 165806c3fb27SDimitry Andric // represented by negative zero, then it is a valid finite value. 1659bdd1243dSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly && 166006c3fb27SDimitry Andric semantics->nanEncoding == fltNanEncoding::AllOnes && 1661bdd1243dSDimitry Andric exponent == semantics->maxExponent && isSignificandAllOnes()) 1662bdd1243dSDimitry Andric return handleOverflow(rounding_mode); 1663bdd1243dSDimitry Andric 16640b57cec5SDimitry Andric /* Now round the number according to rounding_mode given the lost 16650b57cec5SDimitry Andric fraction. */ 16660b57cec5SDimitry Andric 16670b57cec5SDimitry Andric /* As specified in IEEE 754, since we do not trap we do not report 16680b57cec5SDimitry Andric underflow for exact results. */ 16690b57cec5SDimitry Andric if (lost_fraction == lfExactlyZero) { 16700b57cec5SDimitry Andric /* Canonicalize zeroes. */ 167106c3fb27SDimitry Andric if (omsb == 0) { 16720b57cec5SDimitry Andric category = fcZero; 167306c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) 167406c3fb27SDimitry Andric sign = false; 167506c3fb27SDimitry Andric } 16760b57cec5SDimitry Andric 16770b57cec5SDimitry Andric return opOK; 16780b57cec5SDimitry Andric } 16790b57cec5SDimitry Andric 16800b57cec5SDimitry Andric /* Increment the significand if we're rounding away from zero. */ 16810b57cec5SDimitry Andric if (roundAwayFromZero(rounding_mode, lost_fraction, 0)) { 16820b57cec5SDimitry Andric if (omsb == 0) 16830b57cec5SDimitry Andric exponent = semantics->minExponent; 16840b57cec5SDimitry Andric 16850b57cec5SDimitry Andric incrementSignificand(); 16860b57cec5SDimitry Andric omsb = significandMSB() + 1; 16870b57cec5SDimitry Andric 16880b57cec5SDimitry Andric /* Did the significand increment overflow? */ 16890b57cec5SDimitry Andric if (omsb == (unsigned) semantics->precision + 1) { 16900b57cec5SDimitry Andric /* Renormalize by incrementing the exponent and shifting our 16910b57cec5SDimitry Andric significand right one. However if we already have the 16920b57cec5SDimitry Andric maximum exponent we overflow to infinity. */ 169306c3fb27SDimitry Andric if (exponent == semantics->maxExponent) 169406c3fb27SDimitry Andric // Invoke overflow handling with a rounding mode that will guarantee 169506c3fb27SDimitry Andric // that the result gets turned into the correct infinity representation. 169606c3fb27SDimitry Andric // This is needed instead of just setting the category to infinity to 169706c3fb27SDimitry Andric // account for 8-bit floating point types that have no inf, only NaN. 169806c3fb27SDimitry Andric return handleOverflow(sign ? rmTowardNegative : rmTowardPositive); 16990b57cec5SDimitry Andric 17000b57cec5SDimitry Andric shiftSignificandRight(1); 17010b57cec5SDimitry Andric 17020b57cec5SDimitry Andric return opInexact; 17030b57cec5SDimitry Andric } 1704bdd1243dSDimitry Andric 170506c3fb27SDimitry Andric // The all-ones values is an overflow if NaN is all ones. If NaN is 170606c3fb27SDimitry Andric // represented by negative zero, then it is a valid finite value. 1707bdd1243dSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly && 170806c3fb27SDimitry Andric semantics->nanEncoding == fltNanEncoding::AllOnes && 1709bdd1243dSDimitry Andric exponent == semantics->maxExponent && isSignificandAllOnes()) 1710bdd1243dSDimitry Andric return handleOverflow(rounding_mode); 17110b57cec5SDimitry Andric } 17120b57cec5SDimitry Andric 17130b57cec5SDimitry Andric /* The normal case - we were and are not denormal, and any 17140b57cec5SDimitry Andric significand increment above didn't overflow. */ 17150b57cec5SDimitry Andric if (omsb == semantics->precision) 17160b57cec5SDimitry Andric return opInexact; 17170b57cec5SDimitry Andric 17180b57cec5SDimitry Andric /* We have a non-zero denormal. */ 17190b57cec5SDimitry Andric assert(omsb < semantics->precision); 17200b57cec5SDimitry Andric 17210b57cec5SDimitry Andric /* Canonicalize zeroes. */ 172206c3fb27SDimitry Andric if (omsb == 0) { 17230b57cec5SDimitry Andric category = fcZero; 172406c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) 172506c3fb27SDimitry Andric sign = false; 172606c3fb27SDimitry Andric } 17270b57cec5SDimitry Andric 17280b57cec5SDimitry Andric /* The fcZero case is a denormal that underflowed to zero. */ 17290b57cec5SDimitry Andric return (opStatus) (opUnderflow | opInexact); 17300b57cec5SDimitry Andric } 17310b57cec5SDimitry Andric 17320b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::addOrSubtractSpecials(const IEEEFloat &rhs, 17330b57cec5SDimitry Andric bool subtract) { 17340b57cec5SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) { 17350b57cec5SDimitry Andric default: 17360b57cec5SDimitry Andric llvm_unreachable(nullptr); 17370b57cec5SDimitry Andric 17385ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN): 17395ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN): 17405ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN): 17415ffd83dbSDimitry Andric assign(rhs); 1742bdd1243dSDimitry Andric [[fallthrough]]; 17430b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero): 17440b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal): 17450b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity): 17460b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN): 17475ffd83dbSDimitry Andric if (isSignaling()) { 17485ffd83dbSDimitry Andric makeQuiet(); 17495ffd83dbSDimitry Andric return opInvalidOp; 17505ffd83dbSDimitry Andric } 17515ffd83dbSDimitry Andric return rhs.isSignaling() ? opInvalidOp : opOK; 17525ffd83dbSDimitry Andric 17530b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero): 17540b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal): 17550b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero): 17560b57cec5SDimitry Andric return opOK; 17570b57cec5SDimitry Andric 17580b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity): 17590b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity): 17600b57cec5SDimitry Andric category = fcInfinity; 17610b57cec5SDimitry Andric sign = rhs.sign ^ subtract; 17620b57cec5SDimitry Andric return opOK; 17630b57cec5SDimitry Andric 17640b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal): 17650b57cec5SDimitry Andric assign(rhs); 17660b57cec5SDimitry Andric sign = rhs.sign ^ subtract; 17670b57cec5SDimitry Andric return opOK; 17680b57cec5SDimitry Andric 17690b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero): 17700b57cec5SDimitry Andric /* Sign depends on rounding mode; handled by caller. */ 17710b57cec5SDimitry Andric return opOK; 17720b57cec5SDimitry Andric 17730b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity): 17740b57cec5SDimitry Andric /* Differently signed infinities can only be validly 17750b57cec5SDimitry Andric subtracted. */ 17760b57cec5SDimitry Andric if (((sign ^ rhs.sign)!=0) != subtract) { 17770b57cec5SDimitry Andric makeNaN(); 17780b57cec5SDimitry Andric return opInvalidOp; 17790b57cec5SDimitry Andric } 17800b57cec5SDimitry Andric 17810b57cec5SDimitry Andric return opOK; 17820b57cec5SDimitry Andric 17830b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal): 17840b57cec5SDimitry Andric return opDivByZero; 17850b57cec5SDimitry Andric } 17860b57cec5SDimitry Andric } 17870b57cec5SDimitry Andric 17880b57cec5SDimitry Andric /* Add or subtract two normal numbers. */ 17890b57cec5SDimitry Andric lostFraction IEEEFloat::addOrSubtractSignificand(const IEEEFloat &rhs, 17900b57cec5SDimitry Andric bool subtract) { 17910b57cec5SDimitry Andric integerPart carry; 17920b57cec5SDimitry Andric lostFraction lost_fraction; 17930b57cec5SDimitry Andric int bits; 17940b57cec5SDimitry Andric 17950b57cec5SDimitry Andric /* Determine if the operation on the absolute values is effectively 17960b57cec5SDimitry Andric an addition or subtraction. */ 17970b57cec5SDimitry Andric subtract ^= static_cast<bool>(sign ^ rhs.sign); 17980b57cec5SDimitry Andric 17990b57cec5SDimitry Andric /* Are we bigger exponent-wise than the RHS? */ 18000b57cec5SDimitry Andric bits = exponent - rhs.exponent; 18010b57cec5SDimitry Andric 18020b57cec5SDimitry Andric /* Subtraction is more subtle than one might naively expect. */ 18030b57cec5SDimitry Andric if (subtract) { 18040b57cec5SDimitry Andric IEEEFloat temp_rhs(rhs); 18050b57cec5SDimitry Andric 1806480093f4SDimitry Andric if (bits == 0) 18070b57cec5SDimitry Andric lost_fraction = lfExactlyZero; 1808480093f4SDimitry Andric else if (bits > 0) { 18090b57cec5SDimitry Andric lost_fraction = temp_rhs.shiftSignificandRight(bits - 1); 18100b57cec5SDimitry Andric shiftSignificandLeft(1); 18110b57cec5SDimitry Andric } else { 18120b57cec5SDimitry Andric lost_fraction = shiftSignificandRight(-bits - 1); 18130b57cec5SDimitry Andric temp_rhs.shiftSignificandLeft(1); 18140b57cec5SDimitry Andric } 18150b57cec5SDimitry Andric 1816480093f4SDimitry Andric // Should we reverse the subtraction. 1817480093f4SDimitry Andric if (compareAbsoluteValue(temp_rhs) == cmpLessThan) { 18180b57cec5SDimitry Andric carry = temp_rhs.subtractSignificand 18190b57cec5SDimitry Andric (*this, lost_fraction != lfExactlyZero); 18200b57cec5SDimitry Andric copySignificand(temp_rhs); 18210b57cec5SDimitry Andric sign = !sign; 18220b57cec5SDimitry Andric } else { 18230b57cec5SDimitry Andric carry = subtractSignificand 18240b57cec5SDimitry Andric (temp_rhs, lost_fraction != lfExactlyZero); 18250b57cec5SDimitry Andric } 18260b57cec5SDimitry Andric 18270b57cec5SDimitry Andric /* Invert the lost fraction - it was on the RHS and 18280b57cec5SDimitry Andric subtracted. */ 18290b57cec5SDimitry Andric if (lost_fraction == lfLessThanHalf) 18300b57cec5SDimitry Andric lost_fraction = lfMoreThanHalf; 18310b57cec5SDimitry Andric else if (lost_fraction == lfMoreThanHalf) 18320b57cec5SDimitry Andric lost_fraction = lfLessThanHalf; 18330b57cec5SDimitry Andric 18340b57cec5SDimitry Andric /* The code above is intended to ensure that no borrow is 18350b57cec5SDimitry Andric necessary. */ 18360b57cec5SDimitry Andric assert(!carry); 18370b57cec5SDimitry Andric (void)carry; 18380b57cec5SDimitry Andric } else { 18390b57cec5SDimitry Andric if (bits > 0) { 18400b57cec5SDimitry Andric IEEEFloat temp_rhs(rhs); 18410b57cec5SDimitry Andric 18420b57cec5SDimitry Andric lost_fraction = temp_rhs.shiftSignificandRight(bits); 18430b57cec5SDimitry Andric carry = addSignificand(temp_rhs); 18440b57cec5SDimitry Andric } else { 18450b57cec5SDimitry Andric lost_fraction = shiftSignificandRight(-bits); 18460b57cec5SDimitry Andric carry = addSignificand(rhs); 18470b57cec5SDimitry Andric } 18480b57cec5SDimitry Andric 18490b57cec5SDimitry Andric /* We have a guard bit; generating a carry cannot happen. */ 18500b57cec5SDimitry Andric assert(!carry); 18510b57cec5SDimitry Andric (void)carry; 18520b57cec5SDimitry Andric } 18530b57cec5SDimitry Andric 18540b57cec5SDimitry Andric return lost_fraction; 18550b57cec5SDimitry Andric } 18560b57cec5SDimitry Andric 18570b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::multiplySpecials(const IEEEFloat &rhs) { 18580b57cec5SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) { 18590b57cec5SDimitry Andric default: 18600b57cec5SDimitry Andric llvm_unreachable(nullptr); 18610b57cec5SDimitry Andric 18625ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN): 18635ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN): 18645ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN): 18655ffd83dbSDimitry Andric assign(rhs); 18665ffd83dbSDimitry Andric sign = false; 1867bdd1243dSDimitry Andric [[fallthrough]]; 18680b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero): 18690b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal): 18700b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity): 18710b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN): 18725ffd83dbSDimitry Andric sign ^= rhs.sign; // restore the original sign 18735ffd83dbSDimitry Andric if (isSignaling()) { 18745ffd83dbSDimitry Andric makeQuiet(); 18755ffd83dbSDimitry Andric return opInvalidOp; 18765ffd83dbSDimitry Andric } 18775ffd83dbSDimitry Andric return rhs.isSignaling() ? opInvalidOp : opOK; 18780b57cec5SDimitry Andric 18790b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity): 18800b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal): 18810b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity): 18820b57cec5SDimitry Andric category = fcInfinity; 18830b57cec5SDimitry Andric return opOK; 18840b57cec5SDimitry Andric 18850b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal): 18860b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero): 18870b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero): 18880b57cec5SDimitry Andric category = fcZero; 18890b57cec5SDimitry Andric return opOK; 18900b57cec5SDimitry Andric 18910b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity): 18920b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero): 18930b57cec5SDimitry Andric makeNaN(); 18940b57cec5SDimitry Andric return opInvalidOp; 18950b57cec5SDimitry Andric 18960b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal): 18970b57cec5SDimitry Andric return opOK; 18980b57cec5SDimitry Andric } 18990b57cec5SDimitry Andric } 19000b57cec5SDimitry Andric 19010b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::divideSpecials(const IEEEFloat &rhs) { 19020b57cec5SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) { 19030b57cec5SDimitry Andric default: 19040b57cec5SDimitry Andric llvm_unreachable(nullptr); 19050b57cec5SDimitry Andric 19060b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN): 19070b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN): 19080b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN): 19095ffd83dbSDimitry Andric assign(rhs); 19105ffd83dbSDimitry Andric sign = false; 1911bdd1243dSDimitry Andric [[fallthrough]]; 19120b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero): 19130b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal): 19140b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity): 19150b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN): 19165ffd83dbSDimitry Andric sign ^= rhs.sign; // restore the original sign 19175ffd83dbSDimitry Andric if (isSignaling()) { 19185ffd83dbSDimitry Andric makeQuiet(); 19195ffd83dbSDimitry Andric return opInvalidOp; 19205ffd83dbSDimitry Andric } 19215ffd83dbSDimitry Andric return rhs.isSignaling() ? opInvalidOp : opOK; 19225ffd83dbSDimitry Andric 19230b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero): 19240b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal): 19250b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity): 19260b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal): 19270b57cec5SDimitry Andric return opOK; 19280b57cec5SDimitry Andric 19290b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity): 19300b57cec5SDimitry Andric category = fcZero; 19310b57cec5SDimitry Andric return opOK; 19320b57cec5SDimitry Andric 19330b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero): 1934bdd1243dSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) 1935bdd1243dSDimitry Andric makeNaN(false, sign); 1936bdd1243dSDimitry Andric else 19370b57cec5SDimitry Andric category = fcInfinity; 19380b57cec5SDimitry Andric return opDivByZero; 19390b57cec5SDimitry Andric 19400b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity): 19410b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero): 19420b57cec5SDimitry Andric makeNaN(); 19430b57cec5SDimitry Andric return opInvalidOp; 19440b57cec5SDimitry Andric 19450b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal): 19460b57cec5SDimitry Andric return opOK; 19470b57cec5SDimitry Andric } 19480b57cec5SDimitry Andric } 19490b57cec5SDimitry Andric 19500b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::modSpecials(const IEEEFloat &rhs) { 19510b57cec5SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) { 19520b57cec5SDimitry Andric default: 19530b57cec5SDimitry Andric llvm_unreachable(nullptr); 19540b57cec5SDimitry Andric 19555ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN): 19565ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN): 19575ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN): 19585ffd83dbSDimitry Andric assign(rhs); 1959bdd1243dSDimitry Andric [[fallthrough]]; 19600b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero): 19610b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal): 19620b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity): 19630b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN): 19645ffd83dbSDimitry Andric if (isSignaling()) { 19655ffd83dbSDimitry Andric makeQuiet(); 19665ffd83dbSDimitry Andric return opInvalidOp; 19675ffd83dbSDimitry Andric } 19685ffd83dbSDimitry Andric return rhs.isSignaling() ? opInvalidOp : opOK; 19695ffd83dbSDimitry Andric 19700b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity): 19710b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal): 19720b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity): 19730b57cec5SDimitry Andric return opOK; 19740b57cec5SDimitry Andric 19750b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero): 19760b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero): 19770b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal): 19780b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity): 19790b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero): 19800b57cec5SDimitry Andric makeNaN(); 19810b57cec5SDimitry Andric return opInvalidOp; 19820b57cec5SDimitry Andric 19830b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal): 19840b57cec5SDimitry Andric return opOK; 19850b57cec5SDimitry Andric } 19860b57cec5SDimitry Andric } 19870b57cec5SDimitry Andric 19885ffd83dbSDimitry Andric IEEEFloat::opStatus IEEEFloat::remainderSpecials(const IEEEFloat &rhs) { 19895ffd83dbSDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) { 19905ffd83dbSDimitry Andric default: 19915ffd83dbSDimitry Andric llvm_unreachable(nullptr); 19925ffd83dbSDimitry Andric 19935ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN): 19945ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN): 19955ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN): 19965ffd83dbSDimitry Andric assign(rhs); 1997bdd1243dSDimitry Andric [[fallthrough]]; 19985ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero): 19995ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal): 20005ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity): 20015ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN): 20025ffd83dbSDimitry Andric if (isSignaling()) { 20035ffd83dbSDimitry Andric makeQuiet(); 20045ffd83dbSDimitry Andric return opInvalidOp; 20055ffd83dbSDimitry Andric } 20065ffd83dbSDimitry Andric return rhs.isSignaling() ? opInvalidOp : opOK; 20075ffd83dbSDimitry Andric 20085ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity): 20095ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal): 20105ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity): 20115ffd83dbSDimitry Andric return opOK; 20125ffd83dbSDimitry Andric 20135ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero): 20145ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero): 20155ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal): 20165ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity): 20175ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero): 20185ffd83dbSDimitry Andric makeNaN(); 20195ffd83dbSDimitry Andric return opInvalidOp; 20205ffd83dbSDimitry Andric 20215ffd83dbSDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal): 20225ffd83dbSDimitry Andric return opDivByZero; // fake status, indicating this is not a special case 20235ffd83dbSDimitry Andric } 20245ffd83dbSDimitry Andric } 20255ffd83dbSDimitry Andric 20260b57cec5SDimitry Andric /* Change sign. */ 20270b57cec5SDimitry Andric void IEEEFloat::changeSign() { 202806c3fb27SDimitry Andric // With NaN-as-negative-zero, neither NaN or negative zero can change 202906c3fb27SDimitry Andric // their signs. 203006c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero && 203106c3fb27SDimitry Andric (isZero() || isNaN())) 203206c3fb27SDimitry Andric return; 20330b57cec5SDimitry Andric /* Look mummy, this one's easy. */ 20340b57cec5SDimitry Andric sign = !sign; 20350b57cec5SDimitry Andric } 20360b57cec5SDimitry Andric 20370b57cec5SDimitry Andric /* Normalized addition or subtraction. */ 20380b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::addOrSubtract(const IEEEFloat &rhs, 20390b57cec5SDimitry Andric roundingMode rounding_mode, 20400b57cec5SDimitry Andric bool subtract) { 20410b57cec5SDimitry Andric opStatus fs; 20420b57cec5SDimitry Andric 20430b57cec5SDimitry Andric fs = addOrSubtractSpecials(rhs, subtract); 20440b57cec5SDimitry Andric 20450b57cec5SDimitry Andric /* This return code means it was not a simple case. */ 20460b57cec5SDimitry Andric if (fs == opDivByZero) { 20470b57cec5SDimitry Andric lostFraction lost_fraction; 20480b57cec5SDimitry Andric 20490b57cec5SDimitry Andric lost_fraction = addOrSubtractSignificand(rhs, subtract); 20500b57cec5SDimitry Andric fs = normalize(rounding_mode, lost_fraction); 20510b57cec5SDimitry Andric 20520b57cec5SDimitry Andric /* Can only be zero if we lost no fraction. */ 20530b57cec5SDimitry Andric assert(category != fcZero || lost_fraction == lfExactlyZero); 20540b57cec5SDimitry Andric } 20550b57cec5SDimitry Andric 20560b57cec5SDimitry Andric /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a 20570b57cec5SDimitry Andric positive zero unless rounding to minus infinity, except that 20580b57cec5SDimitry Andric adding two like-signed zeroes gives that zero. */ 20590b57cec5SDimitry Andric if (category == fcZero) { 20600b57cec5SDimitry Andric if (rhs.category != fcZero || (sign == rhs.sign) == subtract) 20610b57cec5SDimitry Andric sign = (rounding_mode == rmTowardNegative); 206206c3fb27SDimitry Andric // NaN-in-negative-zero means zeros need to be normalized to +0. 206306c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) 206406c3fb27SDimitry Andric sign = false; 20650b57cec5SDimitry Andric } 20660b57cec5SDimitry Andric 20670b57cec5SDimitry Andric return fs; 20680b57cec5SDimitry Andric } 20690b57cec5SDimitry Andric 20700b57cec5SDimitry Andric /* Normalized addition. */ 20710b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::add(const IEEEFloat &rhs, 20720b57cec5SDimitry Andric roundingMode rounding_mode) { 20730b57cec5SDimitry Andric return addOrSubtract(rhs, rounding_mode, false); 20740b57cec5SDimitry Andric } 20750b57cec5SDimitry Andric 20760b57cec5SDimitry Andric /* Normalized subtraction. */ 20770b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::subtract(const IEEEFloat &rhs, 20780b57cec5SDimitry Andric roundingMode rounding_mode) { 20790b57cec5SDimitry Andric return addOrSubtract(rhs, rounding_mode, true); 20800b57cec5SDimitry Andric } 20810b57cec5SDimitry Andric 20820b57cec5SDimitry Andric /* Normalized multiply. */ 20830b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::multiply(const IEEEFloat &rhs, 20840b57cec5SDimitry Andric roundingMode rounding_mode) { 20850b57cec5SDimitry Andric opStatus fs; 20860b57cec5SDimitry Andric 20870b57cec5SDimitry Andric sign ^= rhs.sign; 20880b57cec5SDimitry Andric fs = multiplySpecials(rhs); 20890b57cec5SDimitry Andric 209006c3fb27SDimitry Andric if (isZero() && semantics->nanEncoding == fltNanEncoding::NegativeZero) 209106c3fb27SDimitry Andric sign = false; 20920b57cec5SDimitry Andric if (isFiniteNonZero()) { 2093480093f4SDimitry Andric lostFraction lost_fraction = multiplySignificand(rhs); 20940b57cec5SDimitry Andric fs = normalize(rounding_mode, lost_fraction); 20950b57cec5SDimitry Andric if (lost_fraction != lfExactlyZero) 20960b57cec5SDimitry Andric fs = (opStatus) (fs | opInexact); 20970b57cec5SDimitry Andric } 20980b57cec5SDimitry Andric 20990b57cec5SDimitry Andric return fs; 21000b57cec5SDimitry Andric } 21010b57cec5SDimitry Andric 21020b57cec5SDimitry Andric /* Normalized divide. */ 21030b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::divide(const IEEEFloat &rhs, 21040b57cec5SDimitry Andric roundingMode rounding_mode) { 21050b57cec5SDimitry Andric opStatus fs; 21060b57cec5SDimitry Andric 21070b57cec5SDimitry Andric sign ^= rhs.sign; 21080b57cec5SDimitry Andric fs = divideSpecials(rhs); 21090b57cec5SDimitry Andric 211006c3fb27SDimitry Andric if (isZero() && semantics->nanEncoding == fltNanEncoding::NegativeZero) 211106c3fb27SDimitry Andric sign = false; 21120b57cec5SDimitry Andric if (isFiniteNonZero()) { 21130b57cec5SDimitry Andric lostFraction lost_fraction = divideSignificand(rhs); 21140b57cec5SDimitry Andric fs = normalize(rounding_mode, lost_fraction); 21150b57cec5SDimitry Andric if (lost_fraction != lfExactlyZero) 21160b57cec5SDimitry Andric fs = (opStatus) (fs | opInexact); 21170b57cec5SDimitry Andric } 21180b57cec5SDimitry Andric 21190b57cec5SDimitry Andric return fs; 21200b57cec5SDimitry Andric } 21210b57cec5SDimitry Andric 21225ffd83dbSDimitry Andric /* Normalized remainder. */ 21230b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::remainder(const IEEEFloat &rhs) { 21240b57cec5SDimitry Andric opStatus fs; 21250b57cec5SDimitry Andric unsigned int origSign = sign; 21260b57cec5SDimitry Andric 21275ffd83dbSDimitry Andric // First handle the special cases. 21285ffd83dbSDimitry Andric fs = remainderSpecials(rhs); 21295ffd83dbSDimitry Andric if (fs != opDivByZero) 21300b57cec5SDimitry Andric return fs; 21310b57cec5SDimitry Andric 21325ffd83dbSDimitry Andric fs = opOK; 21335ffd83dbSDimitry Andric 21345ffd83dbSDimitry Andric // Make sure the current value is less than twice the denom. If the addition 21355ffd83dbSDimitry Andric // did not succeed (an overflow has happened), which means that the finite 21365ffd83dbSDimitry Andric // value we currently posses must be less than twice the denom (as we are 21375ffd83dbSDimitry Andric // using the same semantics). 21385ffd83dbSDimitry Andric IEEEFloat P2 = rhs; 21395ffd83dbSDimitry Andric if (P2.add(rhs, rmNearestTiesToEven) == opOK) { 21405ffd83dbSDimitry Andric fs = mod(P2); 21415ffd83dbSDimitry Andric assert(fs == opOK); 21420b57cec5SDimitry Andric } 21430b57cec5SDimitry Andric 21445ffd83dbSDimitry Andric // Lets work with absolute numbers. 21455ffd83dbSDimitry Andric IEEEFloat P = rhs; 21465ffd83dbSDimitry Andric P.sign = false; 21475ffd83dbSDimitry Andric sign = false; 21480b57cec5SDimitry Andric 21495ffd83dbSDimitry Andric // 21505ffd83dbSDimitry Andric // To calculate the remainder we use the following scheme. 21515ffd83dbSDimitry Andric // 21525ffd83dbSDimitry Andric // The remainder is defained as follows: 21535ffd83dbSDimitry Andric // 21545ffd83dbSDimitry Andric // remainder = numer - rquot * denom = x - r * p 21555ffd83dbSDimitry Andric // 21565ffd83dbSDimitry Andric // Where r is the result of: x/p, rounded toward the nearest integral value 21575ffd83dbSDimitry Andric // (with halfway cases rounded toward the even number). 21585ffd83dbSDimitry Andric // 21595ffd83dbSDimitry Andric // Currently, (after x mod 2p): 21605ffd83dbSDimitry Andric // r is the number of 2p's present inside x, which is inherently, an even 21615ffd83dbSDimitry Andric // number of p's. 21625ffd83dbSDimitry Andric // 21635ffd83dbSDimitry Andric // We may split the remaining calculation into 4 options: 21645ffd83dbSDimitry Andric // - if x < 0.5p then we round to the nearest number with is 0, and are done. 21655ffd83dbSDimitry Andric // - if x == 0.5p then we round to the nearest even number which is 0, and we 21665ffd83dbSDimitry Andric // are done as well. 21675ffd83dbSDimitry Andric // - if 0.5p < x < p then we round to nearest number which is 1, and we have 21685ffd83dbSDimitry Andric // to subtract 1p at least once. 21695ffd83dbSDimitry Andric // - if x >= p then we must subtract p at least once, as x must be a 21705ffd83dbSDimitry Andric // remainder. 21715ffd83dbSDimitry Andric // 21725ffd83dbSDimitry Andric // By now, we were done, or we added 1 to r, which in turn, now an odd number. 21735ffd83dbSDimitry Andric // 21745ffd83dbSDimitry Andric // We can now split the remaining calculation to the following 3 options: 21755ffd83dbSDimitry Andric // - if x < 0.5p then we round to the nearest number with is 0, and are done. 21765ffd83dbSDimitry Andric // - if x == 0.5p then we round to the nearest even number. As r is odd, we 21775ffd83dbSDimitry Andric // must round up to the next even number. so we must subtract p once more. 21785ffd83dbSDimitry Andric // - if x > 0.5p (and inherently x < p) then we must round r up to the next 21795ffd83dbSDimitry Andric // integral, and subtract p once more. 21805ffd83dbSDimitry Andric // 21810b57cec5SDimitry Andric 21825ffd83dbSDimitry Andric // Extend the semantics to prevent an overflow/underflow or inexact result. 21835ffd83dbSDimitry Andric bool losesInfo; 21845ffd83dbSDimitry Andric fltSemantics extendedSemantics = *semantics; 21855ffd83dbSDimitry Andric extendedSemantics.maxExponent++; 21865ffd83dbSDimitry Andric extendedSemantics.minExponent--; 21875ffd83dbSDimitry Andric extendedSemantics.precision += 2; 21885ffd83dbSDimitry Andric 21895ffd83dbSDimitry Andric IEEEFloat VEx = *this; 21905ffd83dbSDimitry Andric fs = VEx.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo); 21915ffd83dbSDimitry Andric assert(fs == opOK && !losesInfo); 21925ffd83dbSDimitry Andric IEEEFloat PEx = P; 21935ffd83dbSDimitry Andric fs = PEx.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo); 21945ffd83dbSDimitry Andric assert(fs == opOK && !losesInfo); 21955ffd83dbSDimitry Andric 21965ffd83dbSDimitry Andric // It is simpler to work with 2x instead of 0.5p, and we do not need to lose 21975ffd83dbSDimitry Andric // any fraction. 21985ffd83dbSDimitry Andric fs = VEx.add(VEx, rmNearestTiesToEven); 21995ffd83dbSDimitry Andric assert(fs == opOK); 22005ffd83dbSDimitry Andric 22015ffd83dbSDimitry Andric if (VEx.compare(PEx) == cmpGreaterThan) { 22025ffd83dbSDimitry Andric fs = subtract(P, rmNearestTiesToEven); 22035ffd83dbSDimitry Andric assert(fs == opOK); 22045ffd83dbSDimitry Andric 22055ffd83dbSDimitry Andric // Make VEx = this.add(this), but because we have different semantics, we do 22065ffd83dbSDimitry Andric // not want to `convert` again, so we just subtract PEx twice (which equals 22075ffd83dbSDimitry Andric // to the desired value). 22085ffd83dbSDimitry Andric fs = VEx.subtract(PEx, rmNearestTiesToEven); 22095ffd83dbSDimitry Andric assert(fs == opOK); 22105ffd83dbSDimitry Andric fs = VEx.subtract(PEx, rmNearestTiesToEven); 22115ffd83dbSDimitry Andric assert(fs == opOK); 22125ffd83dbSDimitry Andric 22135ffd83dbSDimitry Andric cmpResult result = VEx.compare(PEx); 22145ffd83dbSDimitry Andric if (result == cmpGreaterThan || result == cmpEqual) { 22155ffd83dbSDimitry Andric fs = subtract(P, rmNearestTiesToEven); 22165ffd83dbSDimitry Andric assert(fs == opOK); 22175ffd83dbSDimitry Andric } 22185ffd83dbSDimitry Andric } 22190b57cec5SDimitry Andric 222006c3fb27SDimitry Andric if (isZero()) { 22210b57cec5SDimitry Andric sign = origSign; // IEEE754 requires this 222206c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) 222306c3fb27SDimitry Andric // But some 8-bit floats only have positive 0. 222406c3fb27SDimitry Andric sign = false; 222506c3fb27SDimitry Andric } 222606c3fb27SDimitry Andric 22275ffd83dbSDimitry Andric else 22285ffd83dbSDimitry Andric sign ^= origSign; 22290b57cec5SDimitry Andric return fs; 22300b57cec5SDimitry Andric } 22310b57cec5SDimitry Andric 22320b57cec5SDimitry Andric /* Normalized llvm frem (C fmod). */ 22330b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::mod(const IEEEFloat &rhs) { 22340b57cec5SDimitry Andric opStatus fs; 22350b57cec5SDimitry Andric fs = modSpecials(rhs); 22360b57cec5SDimitry Andric unsigned int origSign = sign; 22370b57cec5SDimitry Andric 22380b57cec5SDimitry Andric while (isFiniteNonZero() && rhs.isFiniteNonZero() && 22390b57cec5SDimitry Andric compareAbsoluteValue(rhs) != cmpLessThan) { 2240bdd1243dSDimitry Andric int Exp = ilogb(*this) - ilogb(rhs); 2241bdd1243dSDimitry Andric IEEEFloat V = scalbn(rhs, Exp, rmNearestTiesToEven); 2242bdd1243dSDimitry Andric // V can overflow to NaN with fltNonfiniteBehavior::NanOnly, so explicitly 2243bdd1243dSDimitry Andric // check for it. 2244bdd1243dSDimitry Andric if (V.isNaN() || compareAbsoluteValue(V) == cmpLessThan) 2245bdd1243dSDimitry Andric V = scalbn(rhs, Exp - 1, rmNearestTiesToEven); 22460b57cec5SDimitry Andric V.sign = sign; 22470b57cec5SDimitry Andric 22480b57cec5SDimitry Andric fs = subtract(V, rmNearestTiesToEven); 22490b57cec5SDimitry Andric assert(fs==opOK); 22500b57cec5SDimitry Andric } 225106c3fb27SDimitry Andric if (isZero()) { 22520b57cec5SDimitry Andric sign = origSign; // fmod requires this 225306c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) 225406c3fb27SDimitry Andric sign = false; 225506c3fb27SDimitry Andric } 22560b57cec5SDimitry Andric return fs; 22570b57cec5SDimitry Andric } 22580b57cec5SDimitry Andric 22590b57cec5SDimitry Andric /* Normalized fused-multiply-add. */ 22600b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::fusedMultiplyAdd(const IEEEFloat &multiplicand, 22610b57cec5SDimitry Andric const IEEEFloat &addend, 22620b57cec5SDimitry Andric roundingMode rounding_mode) { 22630b57cec5SDimitry Andric opStatus fs; 22640b57cec5SDimitry Andric 22650b57cec5SDimitry Andric /* Post-multiplication sign, before addition. */ 22660b57cec5SDimitry Andric sign ^= multiplicand.sign; 22670b57cec5SDimitry Andric 22680b57cec5SDimitry Andric /* If and only if all arguments are normal do we need to do an 22690b57cec5SDimitry Andric extended-precision calculation. */ 22700b57cec5SDimitry Andric if (isFiniteNonZero() && 22710b57cec5SDimitry Andric multiplicand.isFiniteNonZero() && 22720b57cec5SDimitry Andric addend.isFinite()) { 22730b57cec5SDimitry Andric lostFraction lost_fraction; 22740b57cec5SDimitry Andric 2275480093f4SDimitry Andric lost_fraction = multiplySignificand(multiplicand, addend); 22760b57cec5SDimitry Andric fs = normalize(rounding_mode, lost_fraction); 22770b57cec5SDimitry Andric if (lost_fraction != lfExactlyZero) 22780b57cec5SDimitry Andric fs = (opStatus) (fs | opInexact); 22790b57cec5SDimitry Andric 22800b57cec5SDimitry Andric /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a 22810b57cec5SDimitry Andric positive zero unless rounding to minus infinity, except that 22820b57cec5SDimitry Andric adding two like-signed zeroes gives that zero. */ 228306c3fb27SDimitry Andric if (category == fcZero && !(fs & opUnderflow) && sign != addend.sign) { 22840b57cec5SDimitry Andric sign = (rounding_mode == rmTowardNegative); 228506c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) 228606c3fb27SDimitry Andric sign = false; 228706c3fb27SDimitry Andric } 22880b57cec5SDimitry Andric } else { 22890b57cec5SDimitry Andric fs = multiplySpecials(multiplicand); 22900b57cec5SDimitry Andric 22910b57cec5SDimitry Andric /* FS can only be opOK or opInvalidOp. There is no more work 22920b57cec5SDimitry Andric to do in the latter case. The IEEE-754R standard says it is 22930b57cec5SDimitry Andric implementation-defined in this case whether, if ADDEND is a 22940b57cec5SDimitry Andric quiet NaN, we raise invalid op; this implementation does so. 22950b57cec5SDimitry Andric 22960b57cec5SDimitry Andric If we need to do the addition we can do so with normal 22970b57cec5SDimitry Andric precision. */ 22980b57cec5SDimitry Andric if (fs == opOK) 22990b57cec5SDimitry Andric fs = addOrSubtract(addend, rounding_mode, false); 23000b57cec5SDimitry Andric } 23010b57cec5SDimitry Andric 23020b57cec5SDimitry Andric return fs; 23030b57cec5SDimitry Andric } 23040b57cec5SDimitry Andric 23055ffd83dbSDimitry Andric /* Rounding-mode correct round to integral value. */ 23060b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::roundToIntegral(roundingMode rounding_mode) { 23070b57cec5SDimitry Andric opStatus fs; 23080b57cec5SDimitry Andric 23095ffd83dbSDimitry Andric if (isInfinity()) 23105ffd83dbSDimitry Andric // [IEEE Std 754-2008 6.1]: 23115ffd83dbSDimitry Andric // The behavior of infinity in floating-point arithmetic is derived from the 23125ffd83dbSDimitry Andric // limiting cases of real arithmetic with operands of arbitrarily 23135ffd83dbSDimitry Andric // large magnitude, when such a limit exists. 23145ffd83dbSDimitry Andric // ... 23155ffd83dbSDimitry Andric // Operations on infinite operands are usually exact and therefore signal no 23165ffd83dbSDimitry Andric // exceptions ... 23175ffd83dbSDimitry Andric return opOK; 23185ffd83dbSDimitry Andric 23195ffd83dbSDimitry Andric if (isNaN()) { 23205ffd83dbSDimitry Andric if (isSignaling()) { 23215ffd83dbSDimitry Andric // [IEEE Std 754-2008 6.2]: 23225ffd83dbSDimitry Andric // Under default exception handling, any operation signaling an invalid 23235ffd83dbSDimitry Andric // operation exception and for which a floating-point result is to be 23245ffd83dbSDimitry Andric // delivered shall deliver a quiet NaN. 23255ffd83dbSDimitry Andric makeQuiet(); 23265ffd83dbSDimitry Andric // [IEEE Std 754-2008 6.2]: 23275ffd83dbSDimitry Andric // Signaling NaNs shall be reserved operands that, under default exception 23285ffd83dbSDimitry Andric // handling, signal the invalid operation exception(see 7.2) for every 23295ffd83dbSDimitry Andric // general-computational and signaling-computational operation except for 23305ffd83dbSDimitry Andric // the conversions described in 5.12. 23315ffd83dbSDimitry Andric return opInvalidOp; 23325ffd83dbSDimitry Andric } else { 23335ffd83dbSDimitry Andric // [IEEE Std 754-2008 6.2]: 23345ffd83dbSDimitry Andric // For an operation with quiet NaN inputs, other than maximum and minimum 23355ffd83dbSDimitry Andric // operations, if a floating-point result is to be delivered the result 23365ffd83dbSDimitry Andric // shall be a quiet NaN which should be one of the input NaNs. 23375ffd83dbSDimitry Andric // ... 23385ffd83dbSDimitry Andric // Every general-computational and quiet-computational operation involving 23395ffd83dbSDimitry Andric // one or more input NaNs, none of them signaling, shall signal no 23405ffd83dbSDimitry Andric // exception, except fusedMultiplyAdd might signal the invalid operation 23415ffd83dbSDimitry Andric // exception(see 7.2). 23425ffd83dbSDimitry Andric return opOK; 23435ffd83dbSDimitry Andric } 23445ffd83dbSDimitry Andric } 23455ffd83dbSDimitry Andric 23465ffd83dbSDimitry Andric if (isZero()) { 23475ffd83dbSDimitry Andric // [IEEE Std 754-2008 6.3]: 23485ffd83dbSDimitry Andric // ... the sign of the result of conversions, the quantize operation, the 23495ffd83dbSDimitry Andric // roundToIntegral operations, and the roundToIntegralExact(see 5.3.1) is 23505ffd83dbSDimitry Andric // the sign of the first or only operand. 23515ffd83dbSDimitry Andric return opOK; 23525ffd83dbSDimitry Andric } 23535ffd83dbSDimitry Andric 23540b57cec5SDimitry Andric // If the exponent is large enough, we know that this value is already 23550b57cec5SDimitry Andric // integral, and the arithmetic below would potentially cause it to saturate 23560b57cec5SDimitry Andric // to +/-Inf. Bail out early instead. 23575ffd83dbSDimitry Andric if (exponent+1 >= (int)semanticsPrecision(*semantics)) 23580b57cec5SDimitry Andric return opOK; 23590b57cec5SDimitry Andric 23600b57cec5SDimitry Andric // The algorithm here is quite simple: we add 2^(p-1), where p is the 23610b57cec5SDimitry Andric // precision of our format, and then subtract it back off again. The choice 23620b57cec5SDimitry Andric // of rounding modes for the addition/subtraction determines the rounding mode 23630b57cec5SDimitry Andric // for our integral rounding as well. 23640b57cec5SDimitry Andric // NOTE: When the input value is negative, we do subtraction followed by 23650b57cec5SDimitry Andric // addition instead. 23660b57cec5SDimitry Andric APInt IntegerConstant(NextPowerOf2(semanticsPrecision(*semantics)), 1); 23670b57cec5SDimitry Andric IntegerConstant <<= semanticsPrecision(*semantics)-1; 23680b57cec5SDimitry Andric IEEEFloat MagicConstant(*semantics); 23690b57cec5SDimitry Andric fs = MagicConstant.convertFromAPInt(IntegerConstant, false, 23700b57cec5SDimitry Andric rmNearestTiesToEven); 23715ffd83dbSDimitry Andric assert(fs == opOK); 23720b57cec5SDimitry Andric MagicConstant.sign = sign; 23730b57cec5SDimitry Andric 23745ffd83dbSDimitry Andric // Preserve the input sign so that we can handle the case of zero result 23755ffd83dbSDimitry Andric // correctly. 23760b57cec5SDimitry Andric bool inputSign = isNegative(); 23770b57cec5SDimitry Andric 23780b57cec5SDimitry Andric fs = add(MagicConstant, rounding_mode); 23790b57cec5SDimitry Andric 23805ffd83dbSDimitry Andric // Current value and 'MagicConstant' are both integers, so the result of the 23815ffd83dbSDimitry Andric // subtraction is always exact according to Sterbenz' lemma. 23825ffd83dbSDimitry Andric subtract(MagicConstant, rounding_mode); 23830b57cec5SDimitry Andric 23840b57cec5SDimitry Andric // Restore the input sign. 23850b57cec5SDimitry Andric if (inputSign != isNegative()) 23860b57cec5SDimitry Andric changeSign(); 23870b57cec5SDimitry Andric 23880b57cec5SDimitry Andric return fs; 23890b57cec5SDimitry Andric } 23900b57cec5SDimitry Andric 23910b57cec5SDimitry Andric 23920b57cec5SDimitry Andric /* Comparison requires normalized numbers. */ 23930b57cec5SDimitry Andric IEEEFloat::cmpResult IEEEFloat::compare(const IEEEFloat &rhs) const { 23940b57cec5SDimitry Andric cmpResult result; 23950b57cec5SDimitry Andric 23960b57cec5SDimitry Andric assert(semantics == rhs.semantics); 23970b57cec5SDimitry Andric 23980b57cec5SDimitry Andric switch (PackCategoriesIntoKey(category, rhs.category)) { 23990b57cec5SDimitry Andric default: 24000b57cec5SDimitry Andric llvm_unreachable(nullptr); 24010b57cec5SDimitry Andric 24020b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcZero): 24030b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNormal): 24040b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcInfinity): 24050b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNaN, fcNaN): 24060b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNaN): 24070b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNaN): 24080b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNaN): 24090b57cec5SDimitry Andric return cmpUnordered; 24100b57cec5SDimitry Andric 24110b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcNormal): 24120b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcZero): 24130b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcZero): 24140b57cec5SDimitry Andric if (sign) 24150b57cec5SDimitry Andric return cmpLessThan; 24160b57cec5SDimitry Andric else 24170b57cec5SDimitry Andric return cmpGreaterThan; 24180b57cec5SDimitry Andric 24190b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcInfinity): 24200b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcInfinity): 24210b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcNormal): 24220b57cec5SDimitry Andric if (rhs.sign) 24230b57cec5SDimitry Andric return cmpGreaterThan; 24240b57cec5SDimitry Andric else 24250b57cec5SDimitry Andric return cmpLessThan; 24260b57cec5SDimitry Andric 24270b57cec5SDimitry Andric case PackCategoriesIntoKey(fcInfinity, fcInfinity): 24280b57cec5SDimitry Andric if (sign == rhs.sign) 24290b57cec5SDimitry Andric return cmpEqual; 24300b57cec5SDimitry Andric else if (sign) 24310b57cec5SDimitry Andric return cmpLessThan; 24320b57cec5SDimitry Andric else 24330b57cec5SDimitry Andric return cmpGreaterThan; 24340b57cec5SDimitry Andric 24350b57cec5SDimitry Andric case PackCategoriesIntoKey(fcZero, fcZero): 24360b57cec5SDimitry Andric return cmpEqual; 24370b57cec5SDimitry Andric 24380b57cec5SDimitry Andric case PackCategoriesIntoKey(fcNormal, fcNormal): 24390b57cec5SDimitry Andric break; 24400b57cec5SDimitry Andric } 24410b57cec5SDimitry Andric 24420b57cec5SDimitry Andric /* Two normal numbers. Do they have the same sign? */ 24430b57cec5SDimitry Andric if (sign != rhs.sign) { 24440b57cec5SDimitry Andric if (sign) 24450b57cec5SDimitry Andric result = cmpLessThan; 24460b57cec5SDimitry Andric else 24470b57cec5SDimitry Andric result = cmpGreaterThan; 24480b57cec5SDimitry Andric } else { 24490b57cec5SDimitry Andric /* Compare absolute values; invert result if negative. */ 24500b57cec5SDimitry Andric result = compareAbsoluteValue(rhs); 24510b57cec5SDimitry Andric 24520b57cec5SDimitry Andric if (sign) { 24530b57cec5SDimitry Andric if (result == cmpLessThan) 24540b57cec5SDimitry Andric result = cmpGreaterThan; 24550b57cec5SDimitry Andric else if (result == cmpGreaterThan) 24560b57cec5SDimitry Andric result = cmpLessThan; 24570b57cec5SDimitry Andric } 24580b57cec5SDimitry Andric } 24590b57cec5SDimitry Andric 24600b57cec5SDimitry Andric return result; 24610b57cec5SDimitry Andric } 24620b57cec5SDimitry Andric 24630b57cec5SDimitry Andric /// IEEEFloat::convert - convert a value of one floating point type to another. 24640b57cec5SDimitry Andric /// The return value corresponds to the IEEE754 exceptions. *losesInfo 24650b57cec5SDimitry Andric /// records whether the transformation lost information, i.e. whether 24660b57cec5SDimitry Andric /// converting the result back to the original type will produce the 24670b57cec5SDimitry Andric /// original value (this is almost the same as return value==fsOK, but there 24680b57cec5SDimitry Andric /// are edge cases where this is not so). 24690b57cec5SDimitry Andric 24700b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics, 24710b57cec5SDimitry Andric roundingMode rounding_mode, 24720b57cec5SDimitry Andric bool *losesInfo) { 24730b57cec5SDimitry Andric lostFraction lostFraction; 24740b57cec5SDimitry Andric unsigned int newPartCount, oldPartCount; 24750b57cec5SDimitry Andric opStatus fs; 24760b57cec5SDimitry Andric int shift; 24770b57cec5SDimitry Andric const fltSemantics &fromSemantics = *semantics; 2478bdd1243dSDimitry Andric bool is_signaling = isSignaling(); 24790b57cec5SDimitry Andric 24800b57cec5SDimitry Andric lostFraction = lfExactlyZero; 24810b57cec5SDimitry Andric newPartCount = partCountForBits(toSemantics.precision + 1); 24820b57cec5SDimitry Andric oldPartCount = partCount(); 24830b57cec5SDimitry Andric shift = toSemantics.precision - fromSemantics.precision; 24840b57cec5SDimitry Andric 24850b57cec5SDimitry Andric bool X86SpecialNan = false; 24860b57cec5SDimitry Andric if (&fromSemantics == &semX87DoubleExtended && 24870b57cec5SDimitry Andric &toSemantics != &semX87DoubleExtended && category == fcNaN && 24880b57cec5SDimitry Andric (!(*significandParts() & 0x8000000000000000ULL) || 24890b57cec5SDimitry Andric !(*significandParts() & 0x4000000000000000ULL))) { 24900b57cec5SDimitry Andric // x86 has some unusual NaNs which cannot be represented in any other 24910b57cec5SDimitry Andric // format; note them here. 24920b57cec5SDimitry Andric X86SpecialNan = true; 24930b57cec5SDimitry Andric } 24940b57cec5SDimitry Andric 24950b57cec5SDimitry Andric // If this is a truncation of a denormal number, and the target semantics 24960b57cec5SDimitry Andric // has larger exponent range than the source semantics (this can happen 24970b57cec5SDimitry Andric // when truncating from PowerPC double-double to double format), the 24980b57cec5SDimitry Andric // right shift could lose result mantissa bits. Adjust exponent instead 24990b57cec5SDimitry Andric // of performing excessive shift. 250081ad6265SDimitry Andric // Also do a similar trick in case shifting denormal would produce zero 250181ad6265SDimitry Andric // significand as this case isn't handled correctly by normalize. 25020b57cec5SDimitry Andric if (shift < 0 && isFiniteNonZero()) { 250381ad6265SDimitry Andric int omsb = significandMSB() + 1; 250481ad6265SDimitry Andric int exponentChange = omsb - fromSemantics.precision; 25050b57cec5SDimitry Andric if (exponent + exponentChange < toSemantics.minExponent) 25060b57cec5SDimitry Andric exponentChange = toSemantics.minExponent - exponent; 25070b57cec5SDimitry Andric if (exponentChange < shift) 25080b57cec5SDimitry Andric exponentChange = shift; 25090b57cec5SDimitry Andric if (exponentChange < 0) { 25100b57cec5SDimitry Andric shift -= exponentChange; 25110b57cec5SDimitry Andric exponent += exponentChange; 251281ad6265SDimitry Andric } else if (omsb <= -shift) { 251381ad6265SDimitry Andric exponentChange = omsb + shift - 1; // leave at least one bit set 251481ad6265SDimitry Andric shift -= exponentChange; 251581ad6265SDimitry Andric exponent += exponentChange; 25160b57cec5SDimitry Andric } 25170b57cec5SDimitry Andric } 25180b57cec5SDimitry Andric 25190b57cec5SDimitry Andric // If this is a truncation, perform the shift before we narrow the storage. 2520bdd1243dSDimitry Andric if (shift < 0 && (isFiniteNonZero() || 2521bdd1243dSDimitry Andric (category == fcNaN && semantics->nonFiniteBehavior != 2522bdd1243dSDimitry Andric fltNonfiniteBehavior::NanOnly))) 25230b57cec5SDimitry Andric lostFraction = shiftRight(significandParts(), oldPartCount, -shift); 25240b57cec5SDimitry Andric 25250b57cec5SDimitry Andric // Fix the storage so it can hold to new value. 25260b57cec5SDimitry Andric if (newPartCount > oldPartCount) { 25270b57cec5SDimitry Andric // The new type requires more storage; make it available. 25280b57cec5SDimitry Andric integerPart *newParts; 25290b57cec5SDimitry Andric newParts = new integerPart[newPartCount]; 25300b57cec5SDimitry Andric APInt::tcSet(newParts, 0, newPartCount); 25310b57cec5SDimitry Andric if (isFiniteNonZero() || category==fcNaN) 25320b57cec5SDimitry Andric APInt::tcAssign(newParts, significandParts(), oldPartCount); 25330b57cec5SDimitry Andric freeSignificand(); 25340b57cec5SDimitry Andric significand.parts = newParts; 25350b57cec5SDimitry Andric } else if (newPartCount == 1 && oldPartCount != 1) { 25360b57cec5SDimitry Andric // Switch to built-in storage for a single part. 25370b57cec5SDimitry Andric integerPart newPart = 0; 25380b57cec5SDimitry Andric if (isFiniteNonZero() || category==fcNaN) 25390b57cec5SDimitry Andric newPart = significandParts()[0]; 25400b57cec5SDimitry Andric freeSignificand(); 25410b57cec5SDimitry Andric significand.part = newPart; 25420b57cec5SDimitry Andric } 25430b57cec5SDimitry Andric 25440b57cec5SDimitry Andric // Now that we have the right storage, switch the semantics. 25450b57cec5SDimitry Andric semantics = &toSemantics; 25460b57cec5SDimitry Andric 25470b57cec5SDimitry Andric // If this is an extension, perform the shift now that the storage is 25480b57cec5SDimitry Andric // available. 25490b57cec5SDimitry Andric if (shift > 0 && (isFiniteNonZero() || category==fcNaN)) 25500b57cec5SDimitry Andric APInt::tcShiftLeft(significandParts(), newPartCount, shift); 25510b57cec5SDimitry Andric 25520b57cec5SDimitry Andric if (isFiniteNonZero()) { 25530b57cec5SDimitry Andric fs = normalize(rounding_mode, lostFraction); 25540b57cec5SDimitry Andric *losesInfo = (fs != opOK); 25550b57cec5SDimitry Andric } else if (category == fcNaN) { 2556bdd1243dSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) { 2557bdd1243dSDimitry Andric *losesInfo = 2558bdd1243dSDimitry Andric fromSemantics.nonFiniteBehavior != fltNonfiniteBehavior::NanOnly; 2559bdd1243dSDimitry Andric makeNaN(false, sign); 2560bdd1243dSDimitry Andric return is_signaling ? opInvalidOp : opOK; 2561bdd1243dSDimitry Andric } 2562bdd1243dSDimitry Andric 256306c3fb27SDimitry Andric // If NaN is negative zero, we need to create a new NaN to avoid converting 256406c3fb27SDimitry Andric // NaN to -Inf. 256506c3fb27SDimitry Andric if (fromSemantics.nanEncoding == fltNanEncoding::NegativeZero && 256606c3fb27SDimitry Andric semantics->nanEncoding != fltNanEncoding::NegativeZero) 256706c3fb27SDimitry Andric makeNaN(false, false); 256806c3fb27SDimitry Andric 25690b57cec5SDimitry Andric *losesInfo = lostFraction != lfExactlyZero || X86SpecialNan; 25700b57cec5SDimitry Andric 25710b57cec5SDimitry Andric // For x87 extended precision, we want to make a NaN, not a special NaN if 25720b57cec5SDimitry Andric // the input wasn't special either. 25730b57cec5SDimitry Andric if (!X86SpecialNan && semantics == &semX87DoubleExtended) 25740b57cec5SDimitry Andric APInt::tcSetBit(significandParts(), semantics->precision - 1); 25750b57cec5SDimitry Andric 2576e8d8bef9SDimitry Andric // Convert of sNaN creates qNaN and raises an exception (invalid op). 2577e8d8bef9SDimitry Andric // This also guarantees that a sNaN does not become Inf on a truncation 2578e8d8bef9SDimitry Andric // that loses all payload bits. 2579bdd1243dSDimitry Andric if (is_signaling) { 2580e8d8bef9SDimitry Andric makeQuiet(); 2581e8d8bef9SDimitry Andric fs = opInvalidOp; 2582e8d8bef9SDimitry Andric } else { 25830b57cec5SDimitry Andric fs = opOK; 2584e8d8bef9SDimitry Andric } 2585bdd1243dSDimitry Andric } else if (category == fcInfinity && 2586bdd1243dSDimitry Andric semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) { 2587bdd1243dSDimitry Andric makeNaN(false, sign); 2588bdd1243dSDimitry Andric *losesInfo = true; 2589bdd1243dSDimitry Andric fs = opInexact; 259006c3fb27SDimitry Andric } else if (category == fcZero && 259106c3fb27SDimitry Andric semantics->nanEncoding == fltNanEncoding::NegativeZero) { 259206c3fb27SDimitry Andric // Negative zero loses info, but positive zero doesn't. 259306c3fb27SDimitry Andric *losesInfo = 259406c3fb27SDimitry Andric fromSemantics.nanEncoding != fltNanEncoding::NegativeZero && sign; 259506c3fb27SDimitry Andric fs = *losesInfo ? opInexact : opOK; 259606c3fb27SDimitry Andric // NaN is negative zero means -0 -> +0, which can lose information 259706c3fb27SDimitry Andric sign = false; 25980b57cec5SDimitry Andric } else { 25990b57cec5SDimitry Andric *losesInfo = false; 26000b57cec5SDimitry Andric fs = opOK; 26010b57cec5SDimitry Andric } 26020b57cec5SDimitry Andric 26030b57cec5SDimitry Andric return fs; 26040b57cec5SDimitry Andric } 26050b57cec5SDimitry Andric 26060b57cec5SDimitry Andric /* Convert a floating point number to an integer according to the 26070b57cec5SDimitry Andric rounding mode. If the rounded integer value is out of range this 26080b57cec5SDimitry Andric returns an invalid operation exception and the contents of the 26090b57cec5SDimitry Andric destination parts are unspecified. If the rounded value is in 26100b57cec5SDimitry Andric range but the floating point number is not the exact integer, the C 26110b57cec5SDimitry Andric standard doesn't require an inexact exception to be raised. IEEE 26120b57cec5SDimitry Andric 854 does require it so we do that. 26130b57cec5SDimitry Andric 26140b57cec5SDimitry Andric Note that for conversions to integer type the C standard requires 26150b57cec5SDimitry Andric round-to-zero to always be used. */ 26160b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger( 26170b57cec5SDimitry Andric MutableArrayRef<integerPart> parts, unsigned int width, bool isSigned, 26180b57cec5SDimitry Andric roundingMode rounding_mode, bool *isExact) const { 26190b57cec5SDimitry Andric lostFraction lost_fraction; 26200b57cec5SDimitry Andric const integerPart *src; 26210b57cec5SDimitry Andric unsigned int dstPartsCount, truncatedBits; 26220b57cec5SDimitry Andric 26230b57cec5SDimitry Andric *isExact = false; 26240b57cec5SDimitry Andric 26250b57cec5SDimitry Andric /* Handle the three special cases first. */ 26260b57cec5SDimitry Andric if (category == fcInfinity || category == fcNaN) 26270b57cec5SDimitry Andric return opInvalidOp; 26280b57cec5SDimitry Andric 26290b57cec5SDimitry Andric dstPartsCount = partCountForBits(width); 26300b57cec5SDimitry Andric assert(dstPartsCount <= parts.size() && "Integer too big"); 26310b57cec5SDimitry Andric 26320b57cec5SDimitry Andric if (category == fcZero) { 26330b57cec5SDimitry Andric APInt::tcSet(parts.data(), 0, dstPartsCount); 26340b57cec5SDimitry Andric // Negative zero can't be represented as an int. 26350b57cec5SDimitry Andric *isExact = !sign; 26360b57cec5SDimitry Andric return opOK; 26370b57cec5SDimitry Andric } 26380b57cec5SDimitry Andric 26390b57cec5SDimitry Andric src = significandParts(); 26400b57cec5SDimitry Andric 26410b57cec5SDimitry Andric /* Step 1: place our absolute value, with any fraction truncated, in 26420b57cec5SDimitry Andric the destination. */ 26430b57cec5SDimitry Andric if (exponent < 0) { 26440b57cec5SDimitry Andric /* Our absolute value is less than one; truncate everything. */ 26450b57cec5SDimitry Andric APInt::tcSet(parts.data(), 0, dstPartsCount); 26460b57cec5SDimitry Andric /* For exponent -1 the integer bit represents .5, look at that. 26470b57cec5SDimitry Andric For smaller exponents leftmost truncated bit is 0. */ 26480b57cec5SDimitry Andric truncatedBits = semantics->precision -1U - exponent; 26490b57cec5SDimitry Andric } else { 26500b57cec5SDimitry Andric /* We want the most significant (exponent + 1) bits; the rest are 26510b57cec5SDimitry Andric truncated. */ 26520b57cec5SDimitry Andric unsigned int bits = exponent + 1U; 26530b57cec5SDimitry Andric 26540b57cec5SDimitry Andric /* Hopelessly large in magnitude? */ 26550b57cec5SDimitry Andric if (bits > width) 26560b57cec5SDimitry Andric return opInvalidOp; 26570b57cec5SDimitry Andric 26580b57cec5SDimitry Andric if (bits < semantics->precision) { 26590b57cec5SDimitry Andric /* We truncate (semantics->precision - bits) bits. */ 26600b57cec5SDimitry Andric truncatedBits = semantics->precision - bits; 26610b57cec5SDimitry Andric APInt::tcExtract(parts.data(), dstPartsCount, src, bits, truncatedBits); 26620b57cec5SDimitry Andric } else { 26630b57cec5SDimitry Andric /* We want at least as many bits as are available. */ 26640b57cec5SDimitry Andric APInt::tcExtract(parts.data(), dstPartsCount, src, semantics->precision, 26650b57cec5SDimitry Andric 0); 26660b57cec5SDimitry Andric APInt::tcShiftLeft(parts.data(), dstPartsCount, 26670b57cec5SDimitry Andric bits - semantics->precision); 26680b57cec5SDimitry Andric truncatedBits = 0; 26690b57cec5SDimitry Andric } 26700b57cec5SDimitry Andric } 26710b57cec5SDimitry Andric 26720b57cec5SDimitry Andric /* Step 2: work out any lost fraction, and increment the absolute 26730b57cec5SDimitry Andric value if we would round away from zero. */ 26740b57cec5SDimitry Andric if (truncatedBits) { 26750b57cec5SDimitry Andric lost_fraction = lostFractionThroughTruncation(src, partCount(), 26760b57cec5SDimitry Andric truncatedBits); 26770b57cec5SDimitry Andric if (lost_fraction != lfExactlyZero && 26780b57cec5SDimitry Andric roundAwayFromZero(rounding_mode, lost_fraction, truncatedBits)) { 26790b57cec5SDimitry Andric if (APInt::tcIncrement(parts.data(), dstPartsCount)) 26800b57cec5SDimitry Andric return opInvalidOp; /* Overflow. */ 26810b57cec5SDimitry Andric } 26820b57cec5SDimitry Andric } else { 26830b57cec5SDimitry Andric lost_fraction = lfExactlyZero; 26840b57cec5SDimitry Andric } 26850b57cec5SDimitry Andric 26860b57cec5SDimitry Andric /* Step 3: check if we fit in the destination. */ 26870b57cec5SDimitry Andric unsigned int omsb = APInt::tcMSB(parts.data(), dstPartsCount) + 1; 26880b57cec5SDimitry Andric 26890b57cec5SDimitry Andric if (sign) { 26900b57cec5SDimitry Andric if (!isSigned) { 26910b57cec5SDimitry Andric /* Negative numbers cannot be represented as unsigned. */ 26920b57cec5SDimitry Andric if (omsb != 0) 26930b57cec5SDimitry Andric return opInvalidOp; 26940b57cec5SDimitry Andric } else { 26950b57cec5SDimitry Andric /* It takes omsb bits to represent the unsigned integer value. 26960b57cec5SDimitry Andric We lose a bit for the sign, but care is needed as the 26970b57cec5SDimitry Andric maximally negative integer is a special case. */ 26980b57cec5SDimitry Andric if (omsb == width && 26990b57cec5SDimitry Andric APInt::tcLSB(parts.data(), dstPartsCount) + 1 != omsb) 27000b57cec5SDimitry Andric return opInvalidOp; 27010b57cec5SDimitry Andric 27020b57cec5SDimitry Andric /* This case can happen because of rounding. */ 27030b57cec5SDimitry Andric if (omsb > width) 27040b57cec5SDimitry Andric return opInvalidOp; 27050b57cec5SDimitry Andric } 27060b57cec5SDimitry Andric 27070b57cec5SDimitry Andric APInt::tcNegate (parts.data(), dstPartsCount); 27080b57cec5SDimitry Andric } else { 27090b57cec5SDimitry Andric if (omsb >= width + !isSigned) 27100b57cec5SDimitry Andric return opInvalidOp; 27110b57cec5SDimitry Andric } 27120b57cec5SDimitry Andric 27130b57cec5SDimitry Andric if (lost_fraction == lfExactlyZero) { 27140b57cec5SDimitry Andric *isExact = true; 27150b57cec5SDimitry Andric return opOK; 27160b57cec5SDimitry Andric } else 27170b57cec5SDimitry Andric return opInexact; 27180b57cec5SDimitry Andric } 27190b57cec5SDimitry Andric 27200b57cec5SDimitry Andric /* Same as convertToSignExtendedInteger, except we provide 27210b57cec5SDimitry Andric deterministic values in case of an invalid operation exception, 27220b57cec5SDimitry Andric namely zero for NaNs and the minimal or maximal value respectively 27230b57cec5SDimitry Andric for underflow or overflow. 27240b57cec5SDimitry Andric The *isExact output tells whether the result is exact, in the sense 27250b57cec5SDimitry Andric that converting it back to the original floating point type produces 27260b57cec5SDimitry Andric the original value. This is almost equivalent to result==opOK, 27270b57cec5SDimitry Andric except for negative zeroes. 27280b57cec5SDimitry Andric */ 27290b57cec5SDimitry Andric IEEEFloat::opStatus 27300b57cec5SDimitry Andric IEEEFloat::convertToInteger(MutableArrayRef<integerPart> parts, 27310b57cec5SDimitry Andric unsigned int width, bool isSigned, 27320b57cec5SDimitry Andric roundingMode rounding_mode, bool *isExact) const { 27330b57cec5SDimitry Andric opStatus fs; 27340b57cec5SDimitry Andric 27350b57cec5SDimitry Andric fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode, 27360b57cec5SDimitry Andric isExact); 27370b57cec5SDimitry Andric 27380b57cec5SDimitry Andric if (fs == opInvalidOp) { 27390b57cec5SDimitry Andric unsigned int bits, dstPartsCount; 27400b57cec5SDimitry Andric 27410b57cec5SDimitry Andric dstPartsCount = partCountForBits(width); 27420b57cec5SDimitry Andric assert(dstPartsCount <= parts.size() && "Integer too big"); 27430b57cec5SDimitry Andric 27440b57cec5SDimitry Andric if (category == fcNaN) 27450b57cec5SDimitry Andric bits = 0; 27460b57cec5SDimitry Andric else if (sign) 27470b57cec5SDimitry Andric bits = isSigned; 27480b57cec5SDimitry Andric else 27490b57cec5SDimitry Andric bits = width - isSigned; 27500b57cec5SDimitry Andric 2751349cc55cSDimitry Andric tcSetLeastSignificantBits(parts.data(), dstPartsCount, bits); 27520b57cec5SDimitry Andric if (sign && isSigned) 27530b57cec5SDimitry Andric APInt::tcShiftLeft(parts.data(), dstPartsCount, width - 1); 27540b57cec5SDimitry Andric } 27550b57cec5SDimitry Andric 27560b57cec5SDimitry Andric return fs; 27570b57cec5SDimitry Andric } 27580b57cec5SDimitry Andric 27590b57cec5SDimitry Andric /* Convert an unsigned integer SRC to a floating point number, 27600b57cec5SDimitry Andric rounding according to ROUNDING_MODE. The sign of the floating 27610b57cec5SDimitry Andric point number is not modified. */ 27620b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::convertFromUnsignedParts( 27630b57cec5SDimitry Andric const integerPart *src, unsigned int srcCount, roundingMode rounding_mode) { 27640b57cec5SDimitry Andric unsigned int omsb, precision, dstCount; 27650b57cec5SDimitry Andric integerPart *dst; 27660b57cec5SDimitry Andric lostFraction lost_fraction; 27670b57cec5SDimitry Andric 27680b57cec5SDimitry Andric category = fcNormal; 27690b57cec5SDimitry Andric omsb = APInt::tcMSB(src, srcCount) + 1; 27700b57cec5SDimitry Andric dst = significandParts(); 27710b57cec5SDimitry Andric dstCount = partCount(); 27720b57cec5SDimitry Andric precision = semantics->precision; 27730b57cec5SDimitry Andric 27740b57cec5SDimitry Andric /* We want the most significant PRECISION bits of SRC. There may not 27750b57cec5SDimitry Andric be that many; extract what we can. */ 27760b57cec5SDimitry Andric if (precision <= omsb) { 27770b57cec5SDimitry Andric exponent = omsb - 1; 27780b57cec5SDimitry Andric lost_fraction = lostFractionThroughTruncation(src, srcCount, 27790b57cec5SDimitry Andric omsb - precision); 27800b57cec5SDimitry Andric APInt::tcExtract(dst, dstCount, src, precision, omsb - precision); 27810b57cec5SDimitry Andric } else { 27820b57cec5SDimitry Andric exponent = precision - 1; 27830b57cec5SDimitry Andric lost_fraction = lfExactlyZero; 27840b57cec5SDimitry Andric APInt::tcExtract(dst, dstCount, src, omsb, 0); 27850b57cec5SDimitry Andric } 27860b57cec5SDimitry Andric 27870b57cec5SDimitry Andric return normalize(rounding_mode, lost_fraction); 27880b57cec5SDimitry Andric } 27890b57cec5SDimitry Andric 27900b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::convertFromAPInt(const APInt &Val, bool isSigned, 27910b57cec5SDimitry Andric roundingMode rounding_mode) { 27920b57cec5SDimitry Andric unsigned int partCount = Val.getNumWords(); 27930b57cec5SDimitry Andric APInt api = Val; 27940b57cec5SDimitry Andric 27950b57cec5SDimitry Andric sign = false; 27960b57cec5SDimitry Andric if (isSigned && api.isNegative()) { 27970b57cec5SDimitry Andric sign = true; 27980b57cec5SDimitry Andric api = -api; 27990b57cec5SDimitry Andric } 28000b57cec5SDimitry Andric 28010b57cec5SDimitry Andric return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode); 28020b57cec5SDimitry Andric } 28030b57cec5SDimitry Andric 28040b57cec5SDimitry Andric /* Convert a two's complement integer SRC to a floating point number, 28050b57cec5SDimitry Andric rounding according to ROUNDING_MODE. ISSIGNED is true if the 28060b57cec5SDimitry Andric integer is signed, in which case it must be sign-extended. */ 28070b57cec5SDimitry Andric IEEEFloat::opStatus 28080b57cec5SDimitry Andric IEEEFloat::convertFromSignExtendedInteger(const integerPart *src, 28090b57cec5SDimitry Andric unsigned int srcCount, bool isSigned, 28100b57cec5SDimitry Andric roundingMode rounding_mode) { 28110b57cec5SDimitry Andric opStatus status; 28120b57cec5SDimitry Andric 28130b57cec5SDimitry Andric if (isSigned && 28140b57cec5SDimitry Andric APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) { 28150b57cec5SDimitry Andric integerPart *copy; 28160b57cec5SDimitry Andric 28170b57cec5SDimitry Andric /* If we're signed and negative negate a copy. */ 28180b57cec5SDimitry Andric sign = true; 28190b57cec5SDimitry Andric copy = new integerPart[srcCount]; 28200b57cec5SDimitry Andric APInt::tcAssign(copy, src, srcCount); 28210b57cec5SDimitry Andric APInt::tcNegate(copy, srcCount); 28220b57cec5SDimitry Andric status = convertFromUnsignedParts(copy, srcCount, rounding_mode); 28230b57cec5SDimitry Andric delete [] copy; 28240b57cec5SDimitry Andric } else { 28250b57cec5SDimitry Andric sign = false; 28260b57cec5SDimitry Andric status = convertFromUnsignedParts(src, srcCount, rounding_mode); 28270b57cec5SDimitry Andric } 28280b57cec5SDimitry Andric 28290b57cec5SDimitry Andric return status; 28300b57cec5SDimitry Andric } 28310b57cec5SDimitry Andric 28320b57cec5SDimitry Andric /* FIXME: should this just take a const APInt reference? */ 28330b57cec5SDimitry Andric IEEEFloat::opStatus 28340b57cec5SDimitry Andric IEEEFloat::convertFromZeroExtendedInteger(const integerPart *parts, 28350b57cec5SDimitry Andric unsigned int width, bool isSigned, 28360b57cec5SDimitry Andric roundingMode rounding_mode) { 28370b57cec5SDimitry Andric unsigned int partCount = partCountForBits(width); 2838bdd1243dSDimitry Andric APInt api = APInt(width, ArrayRef(parts, partCount)); 28390b57cec5SDimitry Andric 28400b57cec5SDimitry Andric sign = false; 28410b57cec5SDimitry Andric if (isSigned && APInt::tcExtractBit(parts, width - 1)) { 28420b57cec5SDimitry Andric sign = true; 28430b57cec5SDimitry Andric api = -api; 28440b57cec5SDimitry Andric } 28450b57cec5SDimitry Andric 28460b57cec5SDimitry Andric return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode); 28470b57cec5SDimitry Andric } 28480b57cec5SDimitry Andric 2849480093f4SDimitry Andric Expected<IEEEFloat::opStatus> 28500b57cec5SDimitry Andric IEEEFloat::convertFromHexadecimalString(StringRef s, 28510b57cec5SDimitry Andric roundingMode rounding_mode) { 28520b57cec5SDimitry Andric lostFraction lost_fraction = lfExactlyZero; 28530b57cec5SDimitry Andric 28540b57cec5SDimitry Andric category = fcNormal; 28550b57cec5SDimitry Andric zeroSignificand(); 28560b57cec5SDimitry Andric exponent = 0; 28570b57cec5SDimitry Andric 28580b57cec5SDimitry Andric integerPart *significand = significandParts(); 28590b57cec5SDimitry Andric unsigned partsCount = partCount(); 28600b57cec5SDimitry Andric unsigned bitPos = partsCount * integerPartWidth; 28610b57cec5SDimitry Andric bool computedTrailingFraction = false; 28620b57cec5SDimitry Andric 28630b57cec5SDimitry Andric // Skip leading zeroes and any (hexa)decimal point. 28640b57cec5SDimitry Andric StringRef::iterator begin = s.begin(); 28650b57cec5SDimitry Andric StringRef::iterator end = s.end(); 28660b57cec5SDimitry Andric StringRef::iterator dot; 2867480093f4SDimitry Andric auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot); 2868480093f4SDimitry Andric if (!PtrOrErr) 2869480093f4SDimitry Andric return PtrOrErr.takeError(); 2870480093f4SDimitry Andric StringRef::iterator p = *PtrOrErr; 28710b57cec5SDimitry Andric StringRef::iterator firstSignificantDigit = p; 28720b57cec5SDimitry Andric 28730b57cec5SDimitry Andric while (p != end) { 28740b57cec5SDimitry Andric integerPart hex_value; 28750b57cec5SDimitry Andric 28760b57cec5SDimitry Andric if (*p == '.') { 2877480093f4SDimitry Andric if (dot != end) 2878480093f4SDimitry Andric return createError("String contains multiple dots"); 28790b57cec5SDimitry Andric dot = p++; 28800b57cec5SDimitry Andric continue; 28810b57cec5SDimitry Andric } 28820b57cec5SDimitry Andric 28830b57cec5SDimitry Andric hex_value = hexDigitValue(*p); 288406c3fb27SDimitry Andric if (hex_value == UINT_MAX) 28850b57cec5SDimitry Andric break; 28860b57cec5SDimitry Andric 28870b57cec5SDimitry Andric p++; 28880b57cec5SDimitry Andric 28890b57cec5SDimitry Andric // Store the number while we have space. 28900b57cec5SDimitry Andric if (bitPos) { 28910b57cec5SDimitry Andric bitPos -= 4; 28920b57cec5SDimitry Andric hex_value <<= bitPos % integerPartWidth; 28930b57cec5SDimitry Andric significand[bitPos / integerPartWidth] |= hex_value; 28940b57cec5SDimitry Andric } else if (!computedTrailingFraction) { 2895480093f4SDimitry Andric auto FractOrErr = trailingHexadecimalFraction(p, end, hex_value); 2896480093f4SDimitry Andric if (!FractOrErr) 2897480093f4SDimitry Andric return FractOrErr.takeError(); 2898480093f4SDimitry Andric lost_fraction = *FractOrErr; 28990b57cec5SDimitry Andric computedTrailingFraction = true; 29000b57cec5SDimitry Andric } 29010b57cec5SDimitry Andric } 29020b57cec5SDimitry Andric 29030b57cec5SDimitry Andric /* Hex floats require an exponent but not a hexadecimal point. */ 2904480093f4SDimitry Andric if (p == end) 2905480093f4SDimitry Andric return createError("Hex strings require an exponent"); 2906480093f4SDimitry Andric if (*p != 'p' && *p != 'P') 2907480093f4SDimitry Andric return createError("Invalid character in significand"); 2908480093f4SDimitry Andric if (p == begin) 2909480093f4SDimitry Andric return createError("Significand has no digits"); 2910480093f4SDimitry Andric if (dot != end && p - begin == 1) 2911480093f4SDimitry Andric return createError("Significand has no digits"); 29120b57cec5SDimitry Andric 29130b57cec5SDimitry Andric /* Ignore the exponent if we are zero. */ 29140b57cec5SDimitry Andric if (p != firstSignificantDigit) { 29150b57cec5SDimitry Andric int expAdjustment; 29160b57cec5SDimitry Andric 29170b57cec5SDimitry Andric /* Implicit hexadecimal point? */ 29180b57cec5SDimitry Andric if (dot == end) 29190b57cec5SDimitry Andric dot = p; 29200b57cec5SDimitry Andric 29210b57cec5SDimitry Andric /* Calculate the exponent adjustment implicit in the number of 29220b57cec5SDimitry Andric significant digits. */ 29230b57cec5SDimitry Andric expAdjustment = static_cast<int>(dot - firstSignificantDigit); 29240b57cec5SDimitry Andric if (expAdjustment < 0) 29250b57cec5SDimitry Andric expAdjustment++; 29260b57cec5SDimitry Andric expAdjustment = expAdjustment * 4 - 1; 29270b57cec5SDimitry Andric 29280b57cec5SDimitry Andric /* Adjust for writing the significand starting at the most 29290b57cec5SDimitry Andric significant nibble. */ 29300b57cec5SDimitry Andric expAdjustment += semantics->precision; 29310b57cec5SDimitry Andric expAdjustment -= partsCount * integerPartWidth; 29320b57cec5SDimitry Andric 29330b57cec5SDimitry Andric /* Adjust for the given exponent. */ 2934480093f4SDimitry Andric auto ExpOrErr = totalExponent(p + 1, end, expAdjustment); 2935480093f4SDimitry Andric if (!ExpOrErr) 2936480093f4SDimitry Andric return ExpOrErr.takeError(); 2937480093f4SDimitry Andric exponent = *ExpOrErr; 29380b57cec5SDimitry Andric } 29390b57cec5SDimitry Andric 29400b57cec5SDimitry Andric return normalize(rounding_mode, lost_fraction); 29410b57cec5SDimitry Andric } 29420b57cec5SDimitry Andric 29430b57cec5SDimitry Andric IEEEFloat::opStatus 29440b57cec5SDimitry Andric IEEEFloat::roundSignificandWithExponent(const integerPart *decSigParts, 29450b57cec5SDimitry Andric unsigned sigPartCount, int exp, 29460b57cec5SDimitry Andric roundingMode rounding_mode) { 29470b57cec5SDimitry Andric unsigned int parts, pow5PartCount; 29480b57cec5SDimitry Andric fltSemantics calcSemantics = { 32767, -32767, 0, 0 }; 29490b57cec5SDimitry Andric integerPart pow5Parts[maxPowerOfFiveParts]; 29500b57cec5SDimitry Andric bool isNearest; 29510b57cec5SDimitry Andric 29520b57cec5SDimitry Andric isNearest = (rounding_mode == rmNearestTiesToEven || 29530b57cec5SDimitry Andric rounding_mode == rmNearestTiesToAway); 29540b57cec5SDimitry Andric 29550b57cec5SDimitry Andric parts = partCountForBits(semantics->precision + 11); 29560b57cec5SDimitry Andric 29570b57cec5SDimitry Andric /* Calculate pow(5, abs(exp)). */ 29580b57cec5SDimitry Andric pow5PartCount = powerOf5(pow5Parts, exp >= 0 ? exp: -exp); 29590b57cec5SDimitry Andric 29600b57cec5SDimitry Andric for (;; parts *= 2) { 29610b57cec5SDimitry Andric opStatus sigStatus, powStatus; 29620b57cec5SDimitry Andric unsigned int excessPrecision, truncatedBits; 29630b57cec5SDimitry Andric 29640b57cec5SDimitry Andric calcSemantics.precision = parts * integerPartWidth - 1; 29650b57cec5SDimitry Andric excessPrecision = calcSemantics.precision - semantics->precision; 29660b57cec5SDimitry Andric truncatedBits = excessPrecision; 29670b57cec5SDimitry Andric 29680b57cec5SDimitry Andric IEEEFloat decSig(calcSemantics, uninitialized); 29690b57cec5SDimitry Andric decSig.makeZero(sign); 29700b57cec5SDimitry Andric IEEEFloat pow5(calcSemantics); 29710b57cec5SDimitry Andric 29720b57cec5SDimitry Andric sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount, 29730b57cec5SDimitry Andric rmNearestTiesToEven); 29740b57cec5SDimitry Andric powStatus = pow5.convertFromUnsignedParts(pow5Parts, pow5PartCount, 29750b57cec5SDimitry Andric rmNearestTiesToEven); 29760b57cec5SDimitry Andric /* Add exp, as 10^n = 5^n * 2^n. */ 29770b57cec5SDimitry Andric decSig.exponent += exp; 29780b57cec5SDimitry Andric 29790b57cec5SDimitry Andric lostFraction calcLostFraction; 29800b57cec5SDimitry Andric integerPart HUerr, HUdistance; 29810b57cec5SDimitry Andric unsigned int powHUerr; 29820b57cec5SDimitry Andric 29830b57cec5SDimitry Andric if (exp >= 0) { 29840b57cec5SDimitry Andric /* multiplySignificand leaves the precision-th bit set to 1. */ 2985480093f4SDimitry Andric calcLostFraction = decSig.multiplySignificand(pow5); 29860b57cec5SDimitry Andric powHUerr = powStatus != opOK; 29870b57cec5SDimitry Andric } else { 29880b57cec5SDimitry Andric calcLostFraction = decSig.divideSignificand(pow5); 29890b57cec5SDimitry Andric /* Denormal numbers have less precision. */ 29900b57cec5SDimitry Andric if (decSig.exponent < semantics->minExponent) { 29910b57cec5SDimitry Andric excessPrecision += (semantics->minExponent - decSig.exponent); 29920b57cec5SDimitry Andric truncatedBits = excessPrecision; 29930b57cec5SDimitry Andric if (excessPrecision > calcSemantics.precision) 29940b57cec5SDimitry Andric excessPrecision = calcSemantics.precision; 29950b57cec5SDimitry Andric } 29960b57cec5SDimitry Andric /* Extra half-ulp lost in reciprocal of exponent. */ 29970b57cec5SDimitry Andric powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0:2; 29980b57cec5SDimitry Andric } 29990b57cec5SDimitry Andric 30000b57cec5SDimitry Andric /* Both multiplySignificand and divideSignificand return the 30010b57cec5SDimitry Andric result with the integer bit set. */ 30020b57cec5SDimitry Andric assert(APInt::tcExtractBit 30030b57cec5SDimitry Andric (decSig.significandParts(), calcSemantics.precision - 1) == 1); 30040b57cec5SDimitry Andric 30050b57cec5SDimitry Andric HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus != opOK, 30060b57cec5SDimitry Andric powHUerr); 30070b57cec5SDimitry Andric HUdistance = 2 * ulpsFromBoundary(decSig.significandParts(), 30080b57cec5SDimitry Andric excessPrecision, isNearest); 30090b57cec5SDimitry Andric 30100b57cec5SDimitry Andric /* Are we guaranteed to round correctly if we truncate? */ 30110b57cec5SDimitry Andric if (HUdistance >= HUerr) { 30120b57cec5SDimitry Andric APInt::tcExtract(significandParts(), partCount(), decSig.significandParts(), 30130b57cec5SDimitry Andric calcSemantics.precision - excessPrecision, 30140b57cec5SDimitry Andric excessPrecision); 30150b57cec5SDimitry Andric /* Take the exponent of decSig. If we tcExtract-ed less bits 30160b57cec5SDimitry Andric above we must adjust our exponent to compensate for the 30170b57cec5SDimitry Andric implicit right shift. */ 30180b57cec5SDimitry Andric exponent = (decSig.exponent + semantics->precision 30190b57cec5SDimitry Andric - (calcSemantics.precision - excessPrecision)); 30200b57cec5SDimitry Andric calcLostFraction = lostFractionThroughTruncation(decSig.significandParts(), 30210b57cec5SDimitry Andric decSig.partCount(), 30220b57cec5SDimitry Andric truncatedBits); 30230b57cec5SDimitry Andric return normalize(rounding_mode, calcLostFraction); 30240b57cec5SDimitry Andric } 30250b57cec5SDimitry Andric } 30260b57cec5SDimitry Andric } 30270b57cec5SDimitry Andric 3028480093f4SDimitry Andric Expected<IEEEFloat::opStatus> 30290b57cec5SDimitry Andric IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) { 30300b57cec5SDimitry Andric decimalInfo D; 30310b57cec5SDimitry Andric opStatus fs; 30320b57cec5SDimitry Andric 30330b57cec5SDimitry Andric /* Scan the text. */ 30340b57cec5SDimitry Andric StringRef::iterator p = str.begin(); 3035480093f4SDimitry Andric if (Error Err = interpretDecimal(p, str.end(), &D)) 3036480093f4SDimitry Andric return std::move(Err); 30370b57cec5SDimitry Andric 30380b57cec5SDimitry Andric /* Handle the quick cases. First the case of no significant digits, 30390b57cec5SDimitry Andric i.e. zero, and then exponents that are obviously too large or too 30400b57cec5SDimitry Andric small. Writing L for log 10 / log 2, a number d.ddddd*10^exp 30410b57cec5SDimitry Andric definitely overflows if 30420b57cec5SDimitry Andric 30430b57cec5SDimitry Andric (exp - 1) * L >= maxExponent 30440b57cec5SDimitry Andric 30450b57cec5SDimitry Andric and definitely underflows to zero where 30460b57cec5SDimitry Andric 30470b57cec5SDimitry Andric (exp + 1) * L <= minExponent - precision 30480b57cec5SDimitry Andric 30490b57cec5SDimitry Andric With integer arithmetic the tightest bounds for L are 30500b57cec5SDimitry Andric 30510b57cec5SDimitry Andric 93/28 < L < 196/59 [ numerator <= 256 ] 30520b57cec5SDimitry Andric 42039/12655 < L < 28738/8651 [ numerator <= 65536 ] 30530b57cec5SDimitry Andric */ 30540b57cec5SDimitry Andric 30550b57cec5SDimitry Andric // Test if we have a zero number allowing for strings with no null terminators 30560b57cec5SDimitry Andric // and zero decimals with non-zero exponents. 30570b57cec5SDimitry Andric // 30580b57cec5SDimitry Andric // We computed firstSigDigit by ignoring all zeros and dots. Thus if 30590b57cec5SDimitry Andric // D->firstSigDigit equals str.end(), every digit must be a zero and there can 30600b57cec5SDimitry Andric // be at most one dot. On the other hand, if we have a zero with a non-zero 30610b57cec5SDimitry Andric // exponent, then we know that D.firstSigDigit will be non-numeric. 30620b57cec5SDimitry Andric if (D.firstSigDigit == str.end() || decDigitValue(*D.firstSigDigit) >= 10U) { 30630b57cec5SDimitry Andric category = fcZero; 30640b57cec5SDimitry Andric fs = opOK; 306506c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) 306606c3fb27SDimitry Andric sign = false; 30670b57cec5SDimitry Andric 30680b57cec5SDimitry Andric /* Check whether the normalized exponent is high enough to overflow 30690b57cec5SDimitry Andric max during the log-rebasing in the max-exponent check below. */ 30700b57cec5SDimitry Andric } else if (D.normalizedExponent - 1 > INT_MAX / 42039) { 30710b57cec5SDimitry Andric fs = handleOverflow(rounding_mode); 30720b57cec5SDimitry Andric 30730b57cec5SDimitry Andric /* If it wasn't, then it also wasn't high enough to overflow max 30740b57cec5SDimitry Andric during the log-rebasing in the min-exponent check. Check that it 30750b57cec5SDimitry Andric won't overflow min in either check, then perform the min-exponent 30760b57cec5SDimitry Andric check. */ 30770b57cec5SDimitry Andric } else if (D.normalizedExponent - 1 < INT_MIN / 42039 || 30780b57cec5SDimitry Andric (D.normalizedExponent + 1) * 28738 <= 30790b57cec5SDimitry Andric 8651 * (semantics->minExponent - (int) semantics->precision)) { 30800b57cec5SDimitry Andric /* Underflow to zero and round. */ 30810b57cec5SDimitry Andric category = fcNormal; 30820b57cec5SDimitry Andric zeroSignificand(); 30830b57cec5SDimitry Andric fs = normalize(rounding_mode, lfLessThanHalf); 30840b57cec5SDimitry Andric 30850b57cec5SDimitry Andric /* We can finally safely perform the max-exponent check. */ 30860b57cec5SDimitry Andric } else if ((D.normalizedExponent - 1) * 42039 30870b57cec5SDimitry Andric >= 12655 * semantics->maxExponent) { 30880b57cec5SDimitry Andric /* Overflow and round. */ 30890b57cec5SDimitry Andric fs = handleOverflow(rounding_mode); 30900b57cec5SDimitry Andric } else { 30910b57cec5SDimitry Andric integerPart *decSignificand; 30920b57cec5SDimitry Andric unsigned int partCount; 30930b57cec5SDimitry Andric 30940b57cec5SDimitry Andric /* A tight upper bound on number of bits required to hold an 30950b57cec5SDimitry Andric N-digit decimal integer is N * 196 / 59. Allocate enough space 30960b57cec5SDimitry Andric to hold the full significand, and an extra part required by 30970b57cec5SDimitry Andric tcMultiplyPart. */ 30980b57cec5SDimitry Andric partCount = static_cast<unsigned int>(D.lastSigDigit - D.firstSigDigit) + 1; 30990b57cec5SDimitry Andric partCount = partCountForBits(1 + 196 * partCount / 59); 31000b57cec5SDimitry Andric decSignificand = new integerPart[partCount + 1]; 31010b57cec5SDimitry Andric partCount = 0; 31020b57cec5SDimitry Andric 31030b57cec5SDimitry Andric /* Convert to binary efficiently - we do almost all multiplication 31040b57cec5SDimitry Andric in an integerPart. When this would overflow do we do a single 31050b57cec5SDimitry Andric bignum multiplication, and then revert again to multiplication 31060b57cec5SDimitry Andric in an integerPart. */ 31070b57cec5SDimitry Andric do { 31080b57cec5SDimitry Andric integerPart decValue, val, multiplier; 31090b57cec5SDimitry Andric 31100b57cec5SDimitry Andric val = 0; 31110b57cec5SDimitry Andric multiplier = 1; 31120b57cec5SDimitry Andric 31130b57cec5SDimitry Andric do { 31140b57cec5SDimitry Andric if (*p == '.') { 31150b57cec5SDimitry Andric p++; 31160b57cec5SDimitry Andric if (p == str.end()) { 31170b57cec5SDimitry Andric break; 31180b57cec5SDimitry Andric } 31190b57cec5SDimitry Andric } 31200b57cec5SDimitry Andric decValue = decDigitValue(*p++); 3121480093f4SDimitry Andric if (decValue >= 10U) { 3122480093f4SDimitry Andric delete[] decSignificand; 3123480093f4SDimitry Andric return createError("Invalid character in significand"); 3124480093f4SDimitry Andric } 31250b57cec5SDimitry Andric multiplier *= 10; 31260b57cec5SDimitry Andric val = val * 10 + decValue; 31270b57cec5SDimitry Andric /* The maximum number that can be multiplied by ten with any 31280b57cec5SDimitry Andric digit added without overflowing an integerPart. */ 31290b57cec5SDimitry Andric } while (p <= D.lastSigDigit && multiplier <= (~ (integerPart) 0 - 9) / 10); 31300b57cec5SDimitry Andric 31310b57cec5SDimitry Andric /* Multiply out the current part. */ 31320b57cec5SDimitry Andric APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val, 31330b57cec5SDimitry Andric partCount, partCount + 1, false); 31340b57cec5SDimitry Andric 31350b57cec5SDimitry Andric /* If we used another part (likely but not guaranteed), increase 31360b57cec5SDimitry Andric the count. */ 31370b57cec5SDimitry Andric if (decSignificand[partCount]) 31380b57cec5SDimitry Andric partCount++; 31390b57cec5SDimitry Andric } while (p <= D.lastSigDigit); 31400b57cec5SDimitry Andric 31410b57cec5SDimitry Andric category = fcNormal; 31420b57cec5SDimitry Andric fs = roundSignificandWithExponent(decSignificand, partCount, 31430b57cec5SDimitry Andric D.exponent, rounding_mode); 31440b57cec5SDimitry Andric 31450b57cec5SDimitry Andric delete [] decSignificand; 31460b57cec5SDimitry Andric } 31470b57cec5SDimitry Andric 31480b57cec5SDimitry Andric return fs; 31490b57cec5SDimitry Andric } 31500b57cec5SDimitry Andric 31510b57cec5SDimitry Andric bool IEEEFloat::convertFromStringSpecials(StringRef str) { 31525ffd83dbSDimitry Andric const size_t MIN_NAME_SIZE = 3; 31535ffd83dbSDimitry Andric 31545ffd83dbSDimitry Andric if (str.size() < MIN_NAME_SIZE) 31555ffd83dbSDimitry Andric return false; 31565ffd83dbSDimitry Andric 3157*0fca6ea1SDimitry Andric if (str == "inf" || str == "INFINITY" || str == "+Inf") { 31580b57cec5SDimitry Andric makeInf(false); 31590b57cec5SDimitry Andric return true; 31600b57cec5SDimitry Andric } 31610b57cec5SDimitry Andric 31625ffd83dbSDimitry Andric bool IsNegative = str.front() == '-'; 31635ffd83dbSDimitry Andric if (IsNegative) { 31645ffd83dbSDimitry Andric str = str.drop_front(); 31655ffd83dbSDimitry Andric if (str.size() < MIN_NAME_SIZE) 31665ffd83dbSDimitry Andric return false; 31675ffd83dbSDimitry Andric 3168*0fca6ea1SDimitry Andric if (str == "inf" || str == "INFINITY" || str == "Inf") { 31690b57cec5SDimitry Andric makeInf(true); 31700b57cec5SDimitry Andric return true; 31710b57cec5SDimitry Andric } 31725ffd83dbSDimitry Andric } 31730b57cec5SDimitry Andric 31745ffd83dbSDimitry Andric // If we have a 's' (or 'S') prefix, then this is a Signaling NaN. 31755ffd83dbSDimitry Andric bool IsSignaling = str.front() == 's' || str.front() == 'S'; 31765ffd83dbSDimitry Andric if (IsSignaling) { 31775ffd83dbSDimitry Andric str = str.drop_front(); 31785ffd83dbSDimitry Andric if (str.size() < MIN_NAME_SIZE) 31795ffd83dbSDimitry Andric return false; 31805ffd83dbSDimitry Andric } 31815ffd83dbSDimitry Andric 31825f757f3fSDimitry Andric if (str.starts_with("nan") || str.starts_with("NaN")) { 31835ffd83dbSDimitry Andric str = str.drop_front(3); 31845ffd83dbSDimitry Andric 31855ffd83dbSDimitry Andric // A NaN without payload. 31865ffd83dbSDimitry Andric if (str.empty()) { 31875ffd83dbSDimitry Andric makeNaN(IsSignaling, IsNegative); 31880b57cec5SDimitry Andric return true; 31890b57cec5SDimitry Andric } 31900b57cec5SDimitry Andric 31915ffd83dbSDimitry Andric // Allow the payload to be inside parentheses. 31925ffd83dbSDimitry Andric if (str.front() == '(') { 31935ffd83dbSDimitry Andric // Parentheses should be balanced (and not empty). 31945ffd83dbSDimitry Andric if (str.size() <= 2 || str.back() != ')') 31955ffd83dbSDimitry Andric return false; 31965ffd83dbSDimitry Andric 31975ffd83dbSDimitry Andric str = str.slice(1, str.size() - 1); 31985ffd83dbSDimitry Andric } 31995ffd83dbSDimitry Andric 32005ffd83dbSDimitry Andric // Determine the payload number's radix. 32015ffd83dbSDimitry Andric unsigned Radix = 10; 32025ffd83dbSDimitry Andric if (str[0] == '0') { 32035ffd83dbSDimitry Andric if (str.size() > 1 && tolower(str[1]) == 'x') { 32045ffd83dbSDimitry Andric str = str.drop_front(2); 32055ffd83dbSDimitry Andric Radix = 16; 32065ffd83dbSDimitry Andric } else 32075ffd83dbSDimitry Andric Radix = 8; 32085ffd83dbSDimitry Andric } 32095ffd83dbSDimitry Andric 32105ffd83dbSDimitry Andric // Parse the payload and make the NaN. 32115ffd83dbSDimitry Andric APInt Payload; 32125ffd83dbSDimitry Andric if (!str.getAsInteger(Radix, Payload)) { 32135ffd83dbSDimitry Andric makeNaN(IsSignaling, IsNegative, &Payload); 32140b57cec5SDimitry Andric return true; 32150b57cec5SDimitry Andric } 32165ffd83dbSDimitry Andric } 32170b57cec5SDimitry Andric 32180b57cec5SDimitry Andric return false; 32190b57cec5SDimitry Andric } 32200b57cec5SDimitry Andric 3221480093f4SDimitry Andric Expected<IEEEFloat::opStatus> 3222480093f4SDimitry Andric IEEEFloat::convertFromString(StringRef str, roundingMode rounding_mode) { 3223480093f4SDimitry Andric if (str.empty()) 3224480093f4SDimitry Andric return createError("Invalid string length"); 32250b57cec5SDimitry Andric 32260b57cec5SDimitry Andric // Handle special cases. 32270b57cec5SDimitry Andric if (convertFromStringSpecials(str)) 32280b57cec5SDimitry Andric return opOK; 32290b57cec5SDimitry Andric 32300b57cec5SDimitry Andric /* Handle a leading minus sign. */ 32310b57cec5SDimitry Andric StringRef::iterator p = str.begin(); 32320b57cec5SDimitry Andric size_t slen = str.size(); 32330b57cec5SDimitry Andric sign = *p == '-' ? 1 : 0; 32340b57cec5SDimitry Andric if (*p == '-' || *p == '+') { 32350b57cec5SDimitry Andric p++; 32360b57cec5SDimitry Andric slen--; 3237480093f4SDimitry Andric if (!slen) 3238480093f4SDimitry Andric return createError("String has no digits"); 32390b57cec5SDimitry Andric } 32400b57cec5SDimitry Andric 32410b57cec5SDimitry Andric if (slen >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { 3242480093f4SDimitry Andric if (slen == 2) 3243480093f4SDimitry Andric return createError("Invalid string"); 32440b57cec5SDimitry Andric return convertFromHexadecimalString(StringRef(p + 2, slen - 2), 32450b57cec5SDimitry Andric rounding_mode); 32460b57cec5SDimitry Andric } 32470b57cec5SDimitry Andric 32480b57cec5SDimitry Andric return convertFromDecimalString(StringRef(p, slen), rounding_mode); 32490b57cec5SDimitry Andric } 32500b57cec5SDimitry Andric 32510b57cec5SDimitry Andric /* Write out a hexadecimal representation of the floating point value 32520b57cec5SDimitry Andric to DST, which must be of sufficient size, in the C99 form 32530b57cec5SDimitry Andric [-]0xh.hhhhp[+-]d. Return the number of characters written, 32540b57cec5SDimitry Andric excluding the terminating NUL. 32550b57cec5SDimitry Andric 32560b57cec5SDimitry Andric If UPPERCASE, the output is in upper case, otherwise in lower case. 32570b57cec5SDimitry Andric 32580b57cec5SDimitry Andric HEXDIGITS digits appear altogether, rounding the value if 32590b57cec5SDimitry Andric necessary. If HEXDIGITS is 0, the minimal precision to display the 32600b57cec5SDimitry Andric number precisely is used instead. If nothing would appear after 32610b57cec5SDimitry Andric the decimal point it is suppressed. 32620b57cec5SDimitry Andric 32630b57cec5SDimitry Andric The decimal exponent is always printed and has at least one digit. 32640b57cec5SDimitry Andric Zero values display an exponent of zero. Infinities and NaNs 32650b57cec5SDimitry Andric appear as "infinity" or "nan" respectively. 32660b57cec5SDimitry Andric 32670b57cec5SDimitry Andric The above rules are as specified by C99. There is ambiguity about 32680b57cec5SDimitry Andric what the leading hexadecimal digit should be. This implementation 32690b57cec5SDimitry Andric uses whatever is necessary so that the exponent is displayed as 32700b57cec5SDimitry Andric stored. This implies the exponent will fall within the IEEE format 32710b57cec5SDimitry Andric range, and the leading hexadecimal digit will be 0 (for denormals), 32720b57cec5SDimitry Andric 1 (normal numbers) or 2 (normal numbers rounded-away-from-zero with 32730b57cec5SDimitry Andric any other digits zero). 32740b57cec5SDimitry Andric */ 32750b57cec5SDimitry Andric unsigned int IEEEFloat::convertToHexString(char *dst, unsigned int hexDigits, 32760b57cec5SDimitry Andric bool upperCase, 32770b57cec5SDimitry Andric roundingMode rounding_mode) const { 32780b57cec5SDimitry Andric char *p; 32790b57cec5SDimitry Andric 32800b57cec5SDimitry Andric p = dst; 32810b57cec5SDimitry Andric if (sign) 32820b57cec5SDimitry Andric *dst++ = '-'; 32830b57cec5SDimitry Andric 32840b57cec5SDimitry Andric switch (category) { 32850b57cec5SDimitry Andric case fcInfinity: 32860b57cec5SDimitry Andric memcpy (dst, upperCase ? infinityU: infinityL, sizeof infinityU - 1); 32870b57cec5SDimitry Andric dst += sizeof infinityL - 1; 32880b57cec5SDimitry Andric break; 32890b57cec5SDimitry Andric 32900b57cec5SDimitry Andric case fcNaN: 32910b57cec5SDimitry Andric memcpy (dst, upperCase ? NaNU: NaNL, sizeof NaNU - 1); 32920b57cec5SDimitry Andric dst += sizeof NaNU - 1; 32930b57cec5SDimitry Andric break; 32940b57cec5SDimitry Andric 32950b57cec5SDimitry Andric case fcZero: 32960b57cec5SDimitry Andric *dst++ = '0'; 32970b57cec5SDimitry Andric *dst++ = upperCase ? 'X': 'x'; 32980b57cec5SDimitry Andric *dst++ = '0'; 32990b57cec5SDimitry Andric if (hexDigits > 1) { 33000b57cec5SDimitry Andric *dst++ = '.'; 33010b57cec5SDimitry Andric memset (dst, '0', hexDigits - 1); 33020b57cec5SDimitry Andric dst += hexDigits - 1; 33030b57cec5SDimitry Andric } 33040b57cec5SDimitry Andric *dst++ = upperCase ? 'P': 'p'; 33050b57cec5SDimitry Andric *dst++ = '0'; 33060b57cec5SDimitry Andric break; 33070b57cec5SDimitry Andric 33080b57cec5SDimitry Andric case fcNormal: 33090b57cec5SDimitry Andric dst = convertNormalToHexString (dst, hexDigits, upperCase, rounding_mode); 33100b57cec5SDimitry Andric break; 33110b57cec5SDimitry Andric } 33120b57cec5SDimitry Andric 33130b57cec5SDimitry Andric *dst = 0; 33140b57cec5SDimitry Andric 33150b57cec5SDimitry Andric return static_cast<unsigned int>(dst - p); 33160b57cec5SDimitry Andric } 33170b57cec5SDimitry Andric 33180b57cec5SDimitry Andric /* Does the hard work of outputting the correctly rounded hexadecimal 33190b57cec5SDimitry Andric form of a normal floating point number with the specified number of 33200b57cec5SDimitry Andric hexadecimal digits. If HEXDIGITS is zero the minimum number of 33210b57cec5SDimitry Andric digits necessary to print the value precisely is output. */ 33220b57cec5SDimitry Andric char *IEEEFloat::convertNormalToHexString(char *dst, unsigned int hexDigits, 33230b57cec5SDimitry Andric bool upperCase, 33240b57cec5SDimitry Andric roundingMode rounding_mode) const { 33250b57cec5SDimitry Andric unsigned int count, valueBits, shift, partsCount, outputDigits; 33260b57cec5SDimitry Andric const char *hexDigitChars; 33270b57cec5SDimitry Andric const integerPart *significand; 33280b57cec5SDimitry Andric char *p; 33290b57cec5SDimitry Andric bool roundUp; 33300b57cec5SDimitry Andric 33310b57cec5SDimitry Andric *dst++ = '0'; 33320b57cec5SDimitry Andric *dst++ = upperCase ? 'X': 'x'; 33330b57cec5SDimitry Andric 33340b57cec5SDimitry Andric roundUp = false; 33350b57cec5SDimitry Andric hexDigitChars = upperCase ? hexDigitsUpper: hexDigitsLower; 33360b57cec5SDimitry Andric 33370b57cec5SDimitry Andric significand = significandParts(); 33380b57cec5SDimitry Andric partsCount = partCount(); 33390b57cec5SDimitry Andric 33400b57cec5SDimitry Andric /* +3 because the first digit only uses the single integer bit, so 33410b57cec5SDimitry Andric we have 3 virtual zero most-significant-bits. */ 33420b57cec5SDimitry Andric valueBits = semantics->precision + 3; 33430b57cec5SDimitry Andric shift = integerPartWidth - valueBits % integerPartWidth; 33440b57cec5SDimitry Andric 33450b57cec5SDimitry Andric /* The natural number of digits required ignoring trailing 33460b57cec5SDimitry Andric insignificant zeroes. */ 33470b57cec5SDimitry Andric outputDigits = (valueBits - significandLSB () + 3) / 4; 33480b57cec5SDimitry Andric 33490b57cec5SDimitry Andric /* hexDigits of zero means use the required number for the 33500b57cec5SDimitry Andric precision. Otherwise, see if we are truncating. If we are, 33510b57cec5SDimitry Andric find out if we need to round away from zero. */ 33520b57cec5SDimitry Andric if (hexDigits) { 33530b57cec5SDimitry Andric if (hexDigits < outputDigits) { 33540b57cec5SDimitry Andric /* We are dropping non-zero bits, so need to check how to round. 33550b57cec5SDimitry Andric "bits" is the number of dropped bits. */ 33560b57cec5SDimitry Andric unsigned int bits; 33570b57cec5SDimitry Andric lostFraction fraction; 33580b57cec5SDimitry Andric 33590b57cec5SDimitry Andric bits = valueBits - hexDigits * 4; 33600b57cec5SDimitry Andric fraction = lostFractionThroughTruncation (significand, partsCount, bits); 33610b57cec5SDimitry Andric roundUp = roundAwayFromZero(rounding_mode, fraction, bits); 33620b57cec5SDimitry Andric } 33630b57cec5SDimitry Andric outputDigits = hexDigits; 33640b57cec5SDimitry Andric } 33650b57cec5SDimitry Andric 33660b57cec5SDimitry Andric /* Write the digits consecutively, and start writing in the location 33670b57cec5SDimitry Andric of the hexadecimal point. We move the most significant digit 33680b57cec5SDimitry Andric left and add the hexadecimal point later. */ 33690b57cec5SDimitry Andric p = ++dst; 33700b57cec5SDimitry Andric 33710b57cec5SDimitry Andric count = (valueBits + integerPartWidth - 1) / integerPartWidth; 33720b57cec5SDimitry Andric 33730b57cec5SDimitry Andric while (outputDigits && count) { 33740b57cec5SDimitry Andric integerPart part; 33750b57cec5SDimitry Andric 33760b57cec5SDimitry Andric /* Put the most significant integerPartWidth bits in "part". */ 33770b57cec5SDimitry Andric if (--count == partsCount) 33780b57cec5SDimitry Andric part = 0; /* An imaginary higher zero part. */ 33790b57cec5SDimitry Andric else 33800b57cec5SDimitry Andric part = significand[count] << shift; 33810b57cec5SDimitry Andric 33820b57cec5SDimitry Andric if (count && shift) 33830b57cec5SDimitry Andric part |= significand[count - 1] >> (integerPartWidth - shift); 33840b57cec5SDimitry Andric 33850b57cec5SDimitry Andric /* Convert as much of "part" to hexdigits as we can. */ 33860b57cec5SDimitry Andric unsigned int curDigits = integerPartWidth / 4; 33870b57cec5SDimitry Andric 33880b57cec5SDimitry Andric if (curDigits > outputDigits) 33890b57cec5SDimitry Andric curDigits = outputDigits; 33900b57cec5SDimitry Andric dst += partAsHex (dst, part, curDigits, hexDigitChars); 33910b57cec5SDimitry Andric outputDigits -= curDigits; 33920b57cec5SDimitry Andric } 33930b57cec5SDimitry Andric 33940b57cec5SDimitry Andric if (roundUp) { 33950b57cec5SDimitry Andric char *q = dst; 33960b57cec5SDimitry Andric 33970b57cec5SDimitry Andric /* Note that hexDigitChars has a trailing '0'. */ 33980b57cec5SDimitry Andric do { 33990b57cec5SDimitry Andric q--; 34000b57cec5SDimitry Andric *q = hexDigitChars[hexDigitValue (*q) + 1]; 34010b57cec5SDimitry Andric } while (*q == '0'); 34020b57cec5SDimitry Andric assert(q >= p); 34030b57cec5SDimitry Andric } else { 34040b57cec5SDimitry Andric /* Add trailing zeroes. */ 34050b57cec5SDimitry Andric memset (dst, '0', outputDigits); 34060b57cec5SDimitry Andric dst += outputDigits; 34070b57cec5SDimitry Andric } 34080b57cec5SDimitry Andric 34090b57cec5SDimitry Andric /* Move the most significant digit to before the point, and if there 34100b57cec5SDimitry Andric is something after the decimal point add it. This must come 34110b57cec5SDimitry Andric after rounding above. */ 34120b57cec5SDimitry Andric p[-1] = p[0]; 34130b57cec5SDimitry Andric if (dst -1 == p) 34140b57cec5SDimitry Andric dst--; 34150b57cec5SDimitry Andric else 34160b57cec5SDimitry Andric p[0] = '.'; 34170b57cec5SDimitry Andric 34180b57cec5SDimitry Andric /* Finally output the exponent. */ 34190b57cec5SDimitry Andric *dst++ = upperCase ? 'P': 'p'; 34200b57cec5SDimitry Andric 34210b57cec5SDimitry Andric return writeSignedDecimal (dst, exponent); 34220b57cec5SDimitry Andric } 34230b57cec5SDimitry Andric 34240b57cec5SDimitry Andric hash_code hash_value(const IEEEFloat &Arg) { 34250b57cec5SDimitry Andric if (!Arg.isFiniteNonZero()) 34260b57cec5SDimitry Andric return hash_combine((uint8_t)Arg.category, 34270b57cec5SDimitry Andric // NaN has no sign, fix it at zero. 34280b57cec5SDimitry Andric Arg.isNaN() ? (uint8_t)0 : (uint8_t)Arg.sign, 34290b57cec5SDimitry Andric Arg.semantics->precision); 34300b57cec5SDimitry Andric 34310b57cec5SDimitry Andric // Normal floats need their exponent and significand hashed. 34320b57cec5SDimitry Andric return hash_combine((uint8_t)Arg.category, (uint8_t)Arg.sign, 34330b57cec5SDimitry Andric Arg.semantics->precision, Arg.exponent, 34340b57cec5SDimitry Andric hash_combine_range( 34350b57cec5SDimitry Andric Arg.significandParts(), 34360b57cec5SDimitry Andric Arg.significandParts() + Arg.partCount())); 34370b57cec5SDimitry Andric } 34380b57cec5SDimitry Andric 34390b57cec5SDimitry Andric // Conversion from APFloat to/from host float/double. It may eventually be 34400b57cec5SDimitry Andric // possible to eliminate these and have everybody deal with APFloats, but that 34410b57cec5SDimitry Andric // will take a while. This approach will not easily extend to long double. 34420b57cec5SDimitry Andric // Current implementation requires integerPartWidth==64, which is correct at 34430b57cec5SDimitry Andric // the moment but could be made more general. 34440b57cec5SDimitry Andric 34450b57cec5SDimitry Andric // Denormals have exponent minExponent in APFloat, but minExponent-1 in 34460b57cec5SDimitry Andric // the actual IEEE respresentations. We compensate for that here. 34470b57cec5SDimitry Andric 34480b57cec5SDimitry Andric APInt IEEEFloat::convertF80LongDoubleAPFloatToAPInt() const { 34490b57cec5SDimitry Andric assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended); 34500b57cec5SDimitry Andric assert(partCount()==2); 34510b57cec5SDimitry Andric 34520b57cec5SDimitry Andric uint64_t myexponent, mysignificand; 34530b57cec5SDimitry Andric 34540b57cec5SDimitry Andric if (isFiniteNonZero()) { 34550b57cec5SDimitry Andric myexponent = exponent+16383; //bias 34560b57cec5SDimitry Andric mysignificand = significandParts()[0]; 34570b57cec5SDimitry Andric if (myexponent==1 && !(mysignificand & 0x8000000000000000ULL)) 34580b57cec5SDimitry Andric myexponent = 0; // denormal 34590b57cec5SDimitry Andric } else if (category==fcZero) { 34600b57cec5SDimitry Andric myexponent = 0; 34610b57cec5SDimitry Andric mysignificand = 0; 34620b57cec5SDimitry Andric } else if (category==fcInfinity) { 34630b57cec5SDimitry Andric myexponent = 0x7fff; 34640b57cec5SDimitry Andric mysignificand = 0x8000000000000000ULL; 34650b57cec5SDimitry Andric } else { 34660b57cec5SDimitry Andric assert(category == fcNaN && "Unknown category"); 34670b57cec5SDimitry Andric myexponent = 0x7fff; 34680b57cec5SDimitry Andric mysignificand = significandParts()[0]; 34690b57cec5SDimitry Andric } 34700b57cec5SDimitry Andric 34710b57cec5SDimitry Andric uint64_t words[2]; 34720b57cec5SDimitry Andric words[0] = mysignificand; 34730b57cec5SDimitry Andric words[1] = ((uint64_t)(sign & 1) << 15) | 34740b57cec5SDimitry Andric (myexponent & 0x7fffLL); 34750b57cec5SDimitry Andric return APInt(80, words); 34760b57cec5SDimitry Andric } 34770b57cec5SDimitry Andric 34780b57cec5SDimitry Andric APInt IEEEFloat::convertPPCDoubleDoubleAPFloatToAPInt() const { 34790b57cec5SDimitry Andric assert(semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy); 34800b57cec5SDimitry Andric assert(partCount()==2); 34810b57cec5SDimitry Andric 34820b57cec5SDimitry Andric uint64_t words[2]; 34830b57cec5SDimitry Andric opStatus fs; 34840b57cec5SDimitry Andric bool losesInfo; 34850b57cec5SDimitry Andric 34860b57cec5SDimitry Andric // Convert number to double. To avoid spurious underflows, we re- 34870b57cec5SDimitry Andric // normalize against the "double" minExponent first, and only *then* 34880b57cec5SDimitry Andric // truncate the mantissa. The result of that second conversion 34890b57cec5SDimitry Andric // may be inexact, but should never underflow. 34900b57cec5SDimitry Andric // Declare fltSemantics before APFloat that uses it (and 34910b57cec5SDimitry Andric // saves pointer to it) to ensure correct destruction order. 34920b57cec5SDimitry Andric fltSemantics extendedSemantics = *semantics; 34930b57cec5SDimitry Andric extendedSemantics.minExponent = semIEEEdouble.minExponent; 34940b57cec5SDimitry Andric IEEEFloat extended(*this); 34950b57cec5SDimitry Andric fs = extended.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo); 34960b57cec5SDimitry Andric assert(fs == opOK && !losesInfo); 34970b57cec5SDimitry Andric (void)fs; 34980b57cec5SDimitry Andric 34990b57cec5SDimitry Andric IEEEFloat u(extended); 35000b57cec5SDimitry Andric fs = u.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo); 35010b57cec5SDimitry Andric assert(fs == opOK || fs == opInexact); 35020b57cec5SDimitry Andric (void)fs; 35030b57cec5SDimitry Andric words[0] = *u.convertDoubleAPFloatToAPInt().getRawData(); 35040b57cec5SDimitry Andric 35050b57cec5SDimitry Andric // If conversion was exact or resulted in a special case, we're done; 35060b57cec5SDimitry Andric // just set the second double to zero. Otherwise, re-convert back to 35070b57cec5SDimitry Andric // the extended format and compute the difference. This now should 35080b57cec5SDimitry Andric // convert exactly to double. 35090b57cec5SDimitry Andric if (u.isFiniteNonZero() && losesInfo) { 35100b57cec5SDimitry Andric fs = u.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo); 35110b57cec5SDimitry Andric assert(fs == opOK && !losesInfo); 35120b57cec5SDimitry Andric (void)fs; 35130b57cec5SDimitry Andric 35140b57cec5SDimitry Andric IEEEFloat v(extended); 35150b57cec5SDimitry Andric v.subtract(u, rmNearestTiesToEven); 35160b57cec5SDimitry Andric fs = v.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo); 35170b57cec5SDimitry Andric assert(fs == opOK && !losesInfo); 35180b57cec5SDimitry Andric (void)fs; 35190b57cec5SDimitry Andric words[1] = *v.convertDoubleAPFloatToAPInt().getRawData(); 35200b57cec5SDimitry Andric } else { 35210b57cec5SDimitry Andric words[1] = 0; 35220b57cec5SDimitry Andric } 35230b57cec5SDimitry Andric 35240b57cec5SDimitry Andric return APInt(128, words); 35250b57cec5SDimitry Andric } 35260b57cec5SDimitry Andric 352706c3fb27SDimitry Andric template <const fltSemantics &S> 352806c3fb27SDimitry Andric APInt IEEEFloat::convertIEEEFloatToAPInt() const { 352906c3fb27SDimitry Andric assert(semantics == &S); 35300b57cec5SDimitry Andric 353106c3fb27SDimitry Andric constexpr int bias = -(S.minExponent - 1); 353206c3fb27SDimitry Andric constexpr unsigned int trailing_significand_bits = S.precision - 1; 353306c3fb27SDimitry Andric constexpr int integer_bit_part = trailing_significand_bits / integerPartWidth; 353406c3fb27SDimitry Andric constexpr integerPart integer_bit = 353506c3fb27SDimitry Andric integerPart{1} << (trailing_significand_bits % integerPartWidth); 353606c3fb27SDimitry Andric constexpr uint64_t significand_mask = integer_bit - 1; 353706c3fb27SDimitry Andric constexpr unsigned int exponent_bits = 353806c3fb27SDimitry Andric S.sizeInBits - 1 - trailing_significand_bits; 353906c3fb27SDimitry Andric static_assert(exponent_bits < 64); 354006c3fb27SDimitry Andric constexpr uint64_t exponent_mask = (uint64_t{1} << exponent_bits) - 1; 354106c3fb27SDimitry Andric 354206c3fb27SDimitry Andric uint64_t myexponent; 354306c3fb27SDimitry Andric std::array<integerPart, partCountForBits(trailing_significand_bits)> 354406c3fb27SDimitry Andric mysignificand; 35450b57cec5SDimitry Andric 35460b57cec5SDimitry Andric if (isFiniteNonZero()) { 354706c3fb27SDimitry Andric myexponent = exponent + bias; 354806c3fb27SDimitry Andric std::copy_n(significandParts(), mysignificand.size(), 354906c3fb27SDimitry Andric mysignificand.begin()); 355006c3fb27SDimitry Andric if (myexponent == 1 && 355106c3fb27SDimitry Andric !(significandParts()[integer_bit_part] & integer_bit)) 35520b57cec5SDimitry Andric myexponent = 0; // denormal 35530b57cec5SDimitry Andric } else if (category == fcZero) { 355406c3fb27SDimitry Andric myexponent = ::exponentZero(S) + bias; 355506c3fb27SDimitry Andric mysignificand.fill(0); 35560b57cec5SDimitry Andric } else if (category == fcInfinity) { 3557*0fca6ea1SDimitry Andric if (S.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly || 3558*0fca6ea1SDimitry Andric S.nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly) 355906c3fb27SDimitry Andric llvm_unreachable("semantics don't support inf!"); 356006c3fb27SDimitry Andric myexponent = ::exponentInf(S) + bias; 356106c3fb27SDimitry Andric mysignificand.fill(0); 35620b57cec5SDimitry Andric } else { 35630b57cec5SDimitry Andric assert(category == fcNaN && "Unknown category!"); 3564*0fca6ea1SDimitry Andric if (S.nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly) 3565*0fca6ea1SDimitry Andric llvm_unreachable("semantics don't support NaN!"); 356606c3fb27SDimitry Andric myexponent = ::exponentNaN(S) + bias; 356706c3fb27SDimitry Andric std::copy_n(significandParts(), mysignificand.size(), 356806c3fb27SDimitry Andric mysignificand.begin()); 356906c3fb27SDimitry Andric } 357006c3fb27SDimitry Andric std::array<uint64_t, (S.sizeInBits + 63) / 64> words; 357106c3fb27SDimitry Andric auto words_iter = 357206c3fb27SDimitry Andric std::copy_n(mysignificand.begin(), mysignificand.size(), words.begin()); 357306c3fb27SDimitry Andric if constexpr (significand_mask != 0) { 357406c3fb27SDimitry Andric // Clear the integer bit. 357506c3fb27SDimitry Andric words[mysignificand.size() - 1] &= significand_mask; 357606c3fb27SDimitry Andric } 357706c3fb27SDimitry Andric std::fill(words_iter, words.end(), uint64_t{0}); 357806c3fb27SDimitry Andric constexpr size_t last_word = words.size() - 1; 357906c3fb27SDimitry Andric uint64_t shifted_sign = static_cast<uint64_t>(sign & 1) 358006c3fb27SDimitry Andric << ((S.sizeInBits - 1) % 64); 358106c3fb27SDimitry Andric words[last_word] |= shifted_sign; 358206c3fb27SDimitry Andric uint64_t shifted_exponent = (myexponent & exponent_mask) 358306c3fb27SDimitry Andric << (trailing_significand_bits % 64); 358406c3fb27SDimitry Andric words[last_word] |= shifted_exponent; 358506c3fb27SDimitry Andric if constexpr (last_word == 0) { 358606c3fb27SDimitry Andric return APInt(S.sizeInBits, words[0]); 358706c3fb27SDimitry Andric } 358806c3fb27SDimitry Andric return APInt(S.sizeInBits, words); 35890b57cec5SDimitry Andric } 35900b57cec5SDimitry Andric 359106c3fb27SDimitry Andric APInt IEEEFloat::convertQuadrupleAPFloatToAPInt() const { 359206c3fb27SDimitry Andric assert(partCount() == 2); 359306c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semIEEEquad>(); 35940b57cec5SDimitry Andric } 35950b57cec5SDimitry Andric 35960b57cec5SDimitry Andric APInt IEEEFloat::convertDoubleAPFloatToAPInt() const { 35970b57cec5SDimitry Andric assert(partCount()==1); 359806c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semIEEEdouble>(); 35990b57cec5SDimitry Andric } 36000b57cec5SDimitry Andric 36010b57cec5SDimitry Andric APInt IEEEFloat::convertFloatAPFloatToAPInt() const { 36020b57cec5SDimitry Andric assert(partCount()==1); 360306c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semIEEEsingle>(); 36040b57cec5SDimitry Andric } 36050b57cec5SDimitry Andric 36065ffd83dbSDimitry Andric APInt IEEEFloat::convertBFloatAPFloatToAPInt() const { 36075ffd83dbSDimitry Andric assert(partCount() == 1); 360806c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semBFloat>(); 36095ffd83dbSDimitry Andric } 36105ffd83dbSDimitry Andric 36110b57cec5SDimitry Andric APInt IEEEFloat::convertHalfAPFloatToAPInt() const { 36120b57cec5SDimitry Andric assert(partCount()==1); 361306c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semIEEEhalf>(); 36140b57cec5SDimitry Andric } 36150b57cec5SDimitry Andric 3616bdd1243dSDimitry Andric APInt IEEEFloat::convertFloat8E5M2APFloatToAPInt() const { 3617bdd1243dSDimitry Andric assert(partCount() == 1); 361806c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E5M2>(); 3619bdd1243dSDimitry Andric } 3620bdd1243dSDimitry Andric 362106c3fb27SDimitry Andric APInt IEEEFloat::convertFloat8E5M2FNUZAPFloatToAPInt() const { 362206c3fb27SDimitry Andric assert(partCount() == 1); 362306c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E5M2FNUZ>(); 3624bdd1243dSDimitry Andric } 3625bdd1243dSDimitry Andric 3626*0fca6ea1SDimitry Andric APInt IEEEFloat::convertFloat8E4M3APFloatToAPInt() const { 3627*0fca6ea1SDimitry Andric assert(partCount() == 1); 3628*0fca6ea1SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E4M3>(); 3629*0fca6ea1SDimitry Andric } 3630*0fca6ea1SDimitry Andric 3631bdd1243dSDimitry Andric APInt IEEEFloat::convertFloat8E4M3FNAPFloatToAPInt() const { 3632bdd1243dSDimitry Andric assert(partCount() == 1); 363306c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E4M3FN>(); 3634bdd1243dSDimitry Andric } 3635bdd1243dSDimitry Andric 363606c3fb27SDimitry Andric APInt IEEEFloat::convertFloat8E4M3FNUZAPFloatToAPInt() const { 363706c3fb27SDimitry Andric assert(partCount() == 1); 363806c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E4M3FNUZ>(); 363906c3fb27SDimitry Andric } 364006c3fb27SDimitry Andric 364106c3fb27SDimitry Andric APInt IEEEFloat::convertFloat8E4M3B11FNUZAPFloatToAPInt() const { 364206c3fb27SDimitry Andric assert(partCount() == 1); 364306c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semFloat8E4M3B11FNUZ>(); 364406c3fb27SDimitry Andric } 364506c3fb27SDimitry Andric 364606c3fb27SDimitry Andric APInt IEEEFloat::convertFloatTF32APFloatToAPInt() const { 364706c3fb27SDimitry Andric assert(partCount() == 1); 364806c3fb27SDimitry Andric return convertIEEEFloatToAPInt<semFloatTF32>(); 3649bdd1243dSDimitry Andric } 3650bdd1243dSDimitry Andric 3651*0fca6ea1SDimitry Andric APInt IEEEFloat::convertFloat6E3M2FNAPFloatToAPInt() const { 3652*0fca6ea1SDimitry Andric assert(partCount() == 1); 3653*0fca6ea1SDimitry Andric return convertIEEEFloatToAPInt<semFloat6E3M2FN>(); 3654*0fca6ea1SDimitry Andric } 3655*0fca6ea1SDimitry Andric 3656*0fca6ea1SDimitry Andric APInt IEEEFloat::convertFloat6E2M3FNAPFloatToAPInt() const { 3657*0fca6ea1SDimitry Andric assert(partCount() == 1); 3658*0fca6ea1SDimitry Andric return convertIEEEFloatToAPInt<semFloat6E2M3FN>(); 3659*0fca6ea1SDimitry Andric } 3660*0fca6ea1SDimitry Andric 3661*0fca6ea1SDimitry Andric APInt IEEEFloat::convertFloat4E2M1FNAPFloatToAPInt() const { 3662*0fca6ea1SDimitry Andric assert(partCount() == 1); 3663*0fca6ea1SDimitry Andric return convertIEEEFloatToAPInt<semFloat4E2M1FN>(); 3664*0fca6ea1SDimitry Andric } 3665*0fca6ea1SDimitry Andric 36660b57cec5SDimitry Andric // This function creates an APInt that is just a bit map of the floating 36670b57cec5SDimitry Andric // point constant as it would appear in memory. It is not a conversion, 36680b57cec5SDimitry Andric // and treating the result as a normal integer is unlikely to be useful. 36690b57cec5SDimitry Andric 36700b57cec5SDimitry Andric APInt IEEEFloat::bitcastToAPInt() const { 36710b57cec5SDimitry Andric if (semantics == (const llvm::fltSemantics*)&semIEEEhalf) 36720b57cec5SDimitry Andric return convertHalfAPFloatToAPInt(); 36730b57cec5SDimitry Andric 36745ffd83dbSDimitry Andric if (semantics == (const llvm::fltSemantics *)&semBFloat) 36755ffd83dbSDimitry Andric return convertBFloatAPFloatToAPInt(); 36765ffd83dbSDimitry Andric 36770b57cec5SDimitry Andric if (semantics == (const llvm::fltSemantics*)&semIEEEsingle) 36780b57cec5SDimitry Andric return convertFloatAPFloatToAPInt(); 36790b57cec5SDimitry Andric 36800b57cec5SDimitry Andric if (semantics == (const llvm::fltSemantics*)&semIEEEdouble) 36810b57cec5SDimitry Andric return convertDoubleAPFloatToAPInt(); 36820b57cec5SDimitry Andric 36830b57cec5SDimitry Andric if (semantics == (const llvm::fltSemantics*)&semIEEEquad) 36840b57cec5SDimitry Andric return convertQuadrupleAPFloatToAPInt(); 36850b57cec5SDimitry Andric 36860b57cec5SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy) 36870b57cec5SDimitry Andric return convertPPCDoubleDoubleAPFloatToAPInt(); 36880b57cec5SDimitry Andric 3689bdd1243dSDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E5M2) 3690bdd1243dSDimitry Andric return convertFloat8E5M2APFloatToAPInt(); 3691bdd1243dSDimitry Andric 369206c3fb27SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E5M2FNUZ) 369306c3fb27SDimitry Andric return convertFloat8E5M2FNUZAPFloatToAPInt(); 369406c3fb27SDimitry Andric 3695*0fca6ea1SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3) 3696*0fca6ea1SDimitry Andric return convertFloat8E4M3APFloatToAPInt(); 3697*0fca6ea1SDimitry Andric 3698bdd1243dSDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3FN) 3699bdd1243dSDimitry Andric return convertFloat8E4M3FNAPFloatToAPInt(); 3700bdd1243dSDimitry Andric 370106c3fb27SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3FNUZ) 370206c3fb27SDimitry Andric return convertFloat8E4M3FNUZAPFloatToAPInt(); 370306c3fb27SDimitry Andric 370406c3fb27SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3B11FNUZ) 370506c3fb27SDimitry Andric return convertFloat8E4M3B11FNUZAPFloatToAPInt(); 370606c3fb27SDimitry Andric 370706c3fb27SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloatTF32) 370806c3fb27SDimitry Andric return convertFloatTF32APFloatToAPInt(); 370906c3fb27SDimitry Andric 3710*0fca6ea1SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat6E3M2FN) 3711*0fca6ea1SDimitry Andric return convertFloat6E3M2FNAPFloatToAPInt(); 3712*0fca6ea1SDimitry Andric 3713*0fca6ea1SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat6E2M3FN) 3714*0fca6ea1SDimitry Andric return convertFloat6E2M3FNAPFloatToAPInt(); 3715*0fca6ea1SDimitry Andric 3716*0fca6ea1SDimitry Andric if (semantics == (const llvm::fltSemantics *)&semFloat4E2M1FN) 3717*0fca6ea1SDimitry Andric return convertFloat4E2M1FNAPFloatToAPInt(); 3718*0fca6ea1SDimitry Andric 37190b57cec5SDimitry Andric assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended && 37200b57cec5SDimitry Andric "unknown format!"); 37210b57cec5SDimitry Andric return convertF80LongDoubleAPFloatToAPInt(); 37220b57cec5SDimitry Andric } 37230b57cec5SDimitry Andric 37240b57cec5SDimitry Andric float IEEEFloat::convertToFloat() const { 37250b57cec5SDimitry Andric assert(semantics == (const llvm::fltSemantics*)&semIEEEsingle && 37260b57cec5SDimitry Andric "Float semantics are not IEEEsingle"); 37270b57cec5SDimitry Andric APInt api = bitcastToAPInt(); 37280b57cec5SDimitry Andric return api.bitsToFloat(); 37290b57cec5SDimitry Andric } 37300b57cec5SDimitry Andric 37310b57cec5SDimitry Andric double IEEEFloat::convertToDouble() const { 37320b57cec5SDimitry Andric assert(semantics == (const llvm::fltSemantics*)&semIEEEdouble && 37330b57cec5SDimitry Andric "Float semantics are not IEEEdouble"); 37340b57cec5SDimitry Andric APInt api = bitcastToAPInt(); 37350b57cec5SDimitry Andric return api.bitsToDouble(); 37360b57cec5SDimitry Andric } 37370b57cec5SDimitry Andric 3738*0fca6ea1SDimitry Andric #ifdef HAS_IEE754_FLOAT128 3739*0fca6ea1SDimitry Andric float128 IEEEFloat::convertToQuad() const { 3740*0fca6ea1SDimitry Andric assert(semantics == (const llvm::fltSemantics *)&semIEEEquad && 3741*0fca6ea1SDimitry Andric "Float semantics are not IEEEquads"); 3742*0fca6ea1SDimitry Andric APInt api = bitcastToAPInt(); 3743*0fca6ea1SDimitry Andric return api.bitsToQuad(); 3744*0fca6ea1SDimitry Andric } 3745*0fca6ea1SDimitry Andric #endif 3746*0fca6ea1SDimitry Andric 37470b57cec5SDimitry Andric /// Integer bit is explicit in this format. Intel hardware (387 and later) 37480b57cec5SDimitry Andric /// does not support these bit patterns: 37490b57cec5SDimitry Andric /// exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity") 37500b57cec5SDimitry Andric /// exponent = all 1's, integer bit 0, significand nonzero ("pseudoNaN") 37510b57cec5SDimitry Andric /// exponent!=0 nor all 1's, integer bit 0 ("unnormal") 37520b57cec5SDimitry Andric /// exponent = 0, integer bit 1 ("pseudodenormal") 37530b57cec5SDimitry Andric /// At the moment, the first three are treated as NaNs, the last one as Normal. 37540b57cec5SDimitry Andric void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) { 37550b57cec5SDimitry Andric uint64_t i1 = api.getRawData()[0]; 37560b57cec5SDimitry Andric uint64_t i2 = api.getRawData()[1]; 37570b57cec5SDimitry Andric uint64_t myexponent = (i2 & 0x7fff); 37580b57cec5SDimitry Andric uint64_t mysignificand = i1; 37590b57cec5SDimitry Andric uint8_t myintegerbit = mysignificand >> 63; 37600b57cec5SDimitry Andric 37610b57cec5SDimitry Andric initialize(&semX87DoubleExtended); 37620b57cec5SDimitry Andric assert(partCount()==2); 37630b57cec5SDimitry Andric 37640b57cec5SDimitry Andric sign = static_cast<unsigned int>(i2>>15); 37650b57cec5SDimitry Andric if (myexponent == 0 && mysignificand == 0) { 3766e8d8bef9SDimitry Andric makeZero(sign); 37670b57cec5SDimitry Andric } else if (myexponent==0x7fff && mysignificand==0x8000000000000000ULL) { 3768e8d8bef9SDimitry Andric makeInf(sign); 37690b57cec5SDimitry Andric } else if ((myexponent == 0x7fff && mysignificand != 0x8000000000000000ULL) || 37700b57cec5SDimitry Andric (myexponent != 0x7fff && myexponent != 0 && myintegerbit == 0)) { 37710b57cec5SDimitry Andric category = fcNaN; 3772e8d8bef9SDimitry Andric exponent = exponentNaN(); 37730b57cec5SDimitry Andric significandParts()[0] = mysignificand; 37740b57cec5SDimitry Andric significandParts()[1] = 0; 37750b57cec5SDimitry Andric } else { 37760b57cec5SDimitry Andric category = fcNormal; 37770b57cec5SDimitry Andric exponent = myexponent - 16383; 37780b57cec5SDimitry Andric significandParts()[0] = mysignificand; 37790b57cec5SDimitry Andric significandParts()[1] = 0; 37800b57cec5SDimitry Andric if (myexponent==0) // denormal 37810b57cec5SDimitry Andric exponent = -16382; 37820b57cec5SDimitry Andric } 37830b57cec5SDimitry Andric } 37840b57cec5SDimitry Andric 37850b57cec5SDimitry Andric void IEEEFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) { 37860b57cec5SDimitry Andric uint64_t i1 = api.getRawData()[0]; 37870b57cec5SDimitry Andric uint64_t i2 = api.getRawData()[1]; 37880b57cec5SDimitry Andric opStatus fs; 37890b57cec5SDimitry Andric bool losesInfo; 37900b57cec5SDimitry Andric 37910b57cec5SDimitry Andric // Get the first double and convert to our format. 37920b57cec5SDimitry Andric initFromDoubleAPInt(APInt(64, i1)); 37930b57cec5SDimitry Andric fs = convert(semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo); 37940b57cec5SDimitry Andric assert(fs == opOK && !losesInfo); 37950b57cec5SDimitry Andric (void)fs; 37960b57cec5SDimitry Andric 37970b57cec5SDimitry Andric // Unless we have a special case, add in second double. 37980b57cec5SDimitry Andric if (isFiniteNonZero()) { 37990b57cec5SDimitry Andric IEEEFloat v(semIEEEdouble, APInt(64, i2)); 38000b57cec5SDimitry Andric fs = v.convert(semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo); 38010b57cec5SDimitry Andric assert(fs == opOK && !losesInfo); 38020b57cec5SDimitry Andric (void)fs; 38030b57cec5SDimitry Andric 38040b57cec5SDimitry Andric add(v, rmNearestTiesToEven); 38050b57cec5SDimitry Andric } 38060b57cec5SDimitry Andric } 38070b57cec5SDimitry Andric 380806c3fb27SDimitry Andric template <const fltSemantics &S> 380906c3fb27SDimitry Andric void IEEEFloat::initFromIEEEAPInt(const APInt &api) { 381006c3fb27SDimitry Andric assert(api.getBitWidth() == S.sizeInBits); 381106c3fb27SDimitry Andric constexpr integerPart integer_bit = integerPart{1} 381206c3fb27SDimitry Andric << ((S.precision - 1) % integerPartWidth); 381306c3fb27SDimitry Andric constexpr uint64_t significand_mask = integer_bit - 1; 381406c3fb27SDimitry Andric constexpr unsigned int trailing_significand_bits = S.precision - 1; 381506c3fb27SDimitry Andric constexpr unsigned int stored_significand_parts = 381606c3fb27SDimitry Andric partCountForBits(trailing_significand_bits); 381706c3fb27SDimitry Andric constexpr unsigned int exponent_bits = 381806c3fb27SDimitry Andric S.sizeInBits - 1 - trailing_significand_bits; 381906c3fb27SDimitry Andric static_assert(exponent_bits < 64); 382006c3fb27SDimitry Andric constexpr uint64_t exponent_mask = (uint64_t{1} << exponent_bits) - 1; 382106c3fb27SDimitry Andric constexpr int bias = -(S.minExponent - 1); 38220b57cec5SDimitry Andric 382306c3fb27SDimitry Andric // Copy the bits of the significand. We need to clear out the exponent and 382406c3fb27SDimitry Andric // sign bit in the last word. 382506c3fb27SDimitry Andric std::array<integerPart, stored_significand_parts> mysignificand; 382606c3fb27SDimitry Andric std::copy_n(api.getRawData(), mysignificand.size(), mysignificand.begin()); 382706c3fb27SDimitry Andric if constexpr (significand_mask != 0) { 382806c3fb27SDimitry Andric mysignificand[mysignificand.size() - 1] &= significand_mask; 38290b57cec5SDimitry Andric } 383006c3fb27SDimitry Andric 383106c3fb27SDimitry Andric // We assume the last word holds the sign bit, the exponent, and potentially 383206c3fb27SDimitry Andric // some of the trailing significand field. 383306c3fb27SDimitry Andric uint64_t last_word = api.getRawData()[api.getNumWords() - 1]; 383406c3fb27SDimitry Andric uint64_t myexponent = 383506c3fb27SDimitry Andric (last_word >> (trailing_significand_bits % 64)) & exponent_mask; 383606c3fb27SDimitry Andric 383706c3fb27SDimitry Andric initialize(&S); 383806c3fb27SDimitry Andric assert(partCount() == mysignificand.size()); 383906c3fb27SDimitry Andric 384006c3fb27SDimitry Andric sign = static_cast<unsigned int>(last_word >> ((S.sizeInBits - 1) % 64)); 384106c3fb27SDimitry Andric 384206c3fb27SDimitry Andric bool all_zero_significand = 384306c3fb27SDimitry Andric llvm::all_of(mysignificand, [](integerPart bits) { return bits == 0; }); 384406c3fb27SDimitry Andric 384506c3fb27SDimitry Andric bool is_zero = myexponent == 0 && all_zero_significand; 384606c3fb27SDimitry Andric 384706c3fb27SDimitry Andric if constexpr (S.nonFiniteBehavior == fltNonfiniteBehavior::IEEE754) { 384806c3fb27SDimitry Andric if (myexponent - bias == ::exponentInf(S) && all_zero_significand) { 384906c3fb27SDimitry Andric makeInf(sign); 385006c3fb27SDimitry Andric return; 385106c3fb27SDimitry Andric } 385206c3fb27SDimitry Andric } 385306c3fb27SDimitry Andric 385406c3fb27SDimitry Andric bool is_nan = false; 385506c3fb27SDimitry Andric 385606c3fb27SDimitry Andric if constexpr (S.nanEncoding == fltNanEncoding::IEEE) { 385706c3fb27SDimitry Andric is_nan = myexponent - bias == ::exponentNaN(S) && !all_zero_significand; 385806c3fb27SDimitry Andric } else if constexpr (S.nanEncoding == fltNanEncoding::AllOnes) { 385906c3fb27SDimitry Andric bool all_ones_significand = 386006c3fb27SDimitry Andric std::all_of(mysignificand.begin(), mysignificand.end() - 1, 386106c3fb27SDimitry Andric [](integerPart bits) { return bits == ~integerPart{0}; }) && 386206c3fb27SDimitry Andric (!significand_mask || 386306c3fb27SDimitry Andric mysignificand[mysignificand.size() - 1] == significand_mask); 386406c3fb27SDimitry Andric is_nan = myexponent - bias == ::exponentNaN(S) && all_ones_significand; 386506c3fb27SDimitry Andric } else if constexpr (S.nanEncoding == fltNanEncoding::NegativeZero) { 386606c3fb27SDimitry Andric is_nan = is_zero && sign; 386706c3fb27SDimitry Andric } 386806c3fb27SDimitry Andric 386906c3fb27SDimitry Andric if (is_nan) { 387006c3fb27SDimitry Andric category = fcNaN; 387106c3fb27SDimitry Andric exponent = ::exponentNaN(S); 387206c3fb27SDimitry Andric std::copy_n(mysignificand.begin(), mysignificand.size(), 387306c3fb27SDimitry Andric significandParts()); 387406c3fb27SDimitry Andric return; 387506c3fb27SDimitry Andric } 387606c3fb27SDimitry Andric 387706c3fb27SDimitry Andric if (is_zero) { 387806c3fb27SDimitry Andric makeZero(sign); 387906c3fb27SDimitry Andric return; 388006c3fb27SDimitry Andric } 388106c3fb27SDimitry Andric 388206c3fb27SDimitry Andric category = fcNormal; 388306c3fb27SDimitry Andric exponent = myexponent - bias; 388406c3fb27SDimitry Andric std::copy_n(mysignificand.begin(), mysignificand.size(), significandParts()); 388506c3fb27SDimitry Andric if (myexponent == 0) // denormal 388606c3fb27SDimitry Andric exponent = S.minExponent; 388706c3fb27SDimitry Andric else 388806c3fb27SDimitry Andric significandParts()[mysignificand.size()-1] |= integer_bit; // integer bit 388906c3fb27SDimitry Andric } 389006c3fb27SDimitry Andric 389106c3fb27SDimitry Andric void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) { 389206c3fb27SDimitry Andric initFromIEEEAPInt<semIEEEquad>(api); 38930b57cec5SDimitry Andric } 38940b57cec5SDimitry Andric 38950b57cec5SDimitry Andric void IEEEFloat::initFromDoubleAPInt(const APInt &api) { 389606c3fb27SDimitry Andric initFromIEEEAPInt<semIEEEdouble>(api); 38970b57cec5SDimitry Andric } 38980b57cec5SDimitry Andric 38990b57cec5SDimitry Andric void IEEEFloat::initFromFloatAPInt(const APInt &api) { 390006c3fb27SDimitry Andric initFromIEEEAPInt<semIEEEsingle>(api); 39010b57cec5SDimitry Andric } 39020b57cec5SDimitry Andric 39035ffd83dbSDimitry Andric void IEEEFloat::initFromBFloatAPInt(const APInt &api) { 390406c3fb27SDimitry Andric initFromIEEEAPInt<semBFloat>(api); 39055ffd83dbSDimitry Andric } 39065ffd83dbSDimitry Andric 39070b57cec5SDimitry Andric void IEEEFloat::initFromHalfAPInt(const APInt &api) { 390806c3fb27SDimitry Andric initFromIEEEAPInt<semIEEEhalf>(api); 39090b57cec5SDimitry Andric } 39100b57cec5SDimitry Andric 3911bdd1243dSDimitry Andric void IEEEFloat::initFromFloat8E5M2APInt(const APInt &api) { 391206c3fb27SDimitry Andric initFromIEEEAPInt<semFloat8E5M2>(api); 3913bdd1243dSDimitry Andric } 391406c3fb27SDimitry Andric 391506c3fb27SDimitry Andric void IEEEFloat::initFromFloat8E5M2FNUZAPInt(const APInt &api) { 391606c3fb27SDimitry Andric initFromIEEEAPInt<semFloat8E5M2FNUZ>(api); 3917bdd1243dSDimitry Andric } 3918bdd1243dSDimitry Andric 3919*0fca6ea1SDimitry Andric void IEEEFloat::initFromFloat8E4M3APInt(const APInt &api) { 3920*0fca6ea1SDimitry Andric initFromIEEEAPInt<semFloat8E4M3>(api); 3921*0fca6ea1SDimitry Andric } 3922*0fca6ea1SDimitry Andric 3923bdd1243dSDimitry Andric void IEEEFloat::initFromFloat8E4M3FNAPInt(const APInt &api) { 392406c3fb27SDimitry Andric initFromIEEEAPInt<semFloat8E4M3FN>(api); 3925bdd1243dSDimitry Andric } 392606c3fb27SDimitry Andric 392706c3fb27SDimitry Andric void IEEEFloat::initFromFloat8E4M3FNUZAPInt(const APInt &api) { 392806c3fb27SDimitry Andric initFromIEEEAPInt<semFloat8E4M3FNUZ>(api); 392906c3fb27SDimitry Andric } 393006c3fb27SDimitry Andric 393106c3fb27SDimitry Andric void IEEEFloat::initFromFloat8E4M3B11FNUZAPInt(const APInt &api) { 393206c3fb27SDimitry Andric initFromIEEEAPInt<semFloat8E4M3B11FNUZ>(api); 393306c3fb27SDimitry Andric } 393406c3fb27SDimitry Andric 393506c3fb27SDimitry Andric void IEEEFloat::initFromFloatTF32APInt(const APInt &api) { 393606c3fb27SDimitry Andric initFromIEEEAPInt<semFloatTF32>(api); 3937bdd1243dSDimitry Andric } 3938bdd1243dSDimitry Andric 3939*0fca6ea1SDimitry Andric void IEEEFloat::initFromFloat6E3M2FNAPInt(const APInt &api) { 3940*0fca6ea1SDimitry Andric initFromIEEEAPInt<semFloat6E3M2FN>(api); 3941*0fca6ea1SDimitry Andric } 3942*0fca6ea1SDimitry Andric 3943*0fca6ea1SDimitry Andric void IEEEFloat::initFromFloat6E2M3FNAPInt(const APInt &api) { 3944*0fca6ea1SDimitry Andric initFromIEEEAPInt<semFloat6E2M3FN>(api); 3945*0fca6ea1SDimitry Andric } 3946*0fca6ea1SDimitry Andric 3947*0fca6ea1SDimitry Andric void IEEEFloat::initFromFloat4E2M1FNAPInt(const APInt &api) { 3948*0fca6ea1SDimitry Andric initFromIEEEAPInt<semFloat4E2M1FN>(api); 3949*0fca6ea1SDimitry Andric } 3950*0fca6ea1SDimitry Andric 3951bdd1243dSDimitry Andric /// Treat api as containing the bits of a floating point number. 39520b57cec5SDimitry Andric void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) { 3953349cc55cSDimitry Andric assert(api.getBitWidth() == Sem->sizeInBits); 39540b57cec5SDimitry Andric if (Sem == &semIEEEhalf) 39550b57cec5SDimitry Andric return initFromHalfAPInt(api); 39565ffd83dbSDimitry Andric if (Sem == &semBFloat) 39575ffd83dbSDimitry Andric return initFromBFloatAPInt(api); 39580b57cec5SDimitry Andric if (Sem == &semIEEEsingle) 39590b57cec5SDimitry Andric return initFromFloatAPInt(api); 39600b57cec5SDimitry Andric if (Sem == &semIEEEdouble) 39610b57cec5SDimitry Andric return initFromDoubleAPInt(api); 39620b57cec5SDimitry Andric if (Sem == &semX87DoubleExtended) 39630b57cec5SDimitry Andric return initFromF80LongDoubleAPInt(api); 39640b57cec5SDimitry Andric if (Sem == &semIEEEquad) 39650b57cec5SDimitry Andric return initFromQuadrupleAPInt(api); 39660b57cec5SDimitry Andric if (Sem == &semPPCDoubleDoubleLegacy) 39670b57cec5SDimitry Andric return initFromPPCDoubleDoubleAPInt(api); 3968bdd1243dSDimitry Andric if (Sem == &semFloat8E5M2) 3969bdd1243dSDimitry Andric return initFromFloat8E5M2APInt(api); 397006c3fb27SDimitry Andric if (Sem == &semFloat8E5M2FNUZ) 397106c3fb27SDimitry Andric return initFromFloat8E5M2FNUZAPInt(api); 3972*0fca6ea1SDimitry Andric if (Sem == &semFloat8E4M3) 3973*0fca6ea1SDimitry Andric return initFromFloat8E4M3APInt(api); 3974bdd1243dSDimitry Andric if (Sem == &semFloat8E4M3FN) 3975bdd1243dSDimitry Andric return initFromFloat8E4M3FNAPInt(api); 397606c3fb27SDimitry Andric if (Sem == &semFloat8E4M3FNUZ) 397706c3fb27SDimitry Andric return initFromFloat8E4M3FNUZAPInt(api); 397806c3fb27SDimitry Andric if (Sem == &semFloat8E4M3B11FNUZ) 397906c3fb27SDimitry Andric return initFromFloat8E4M3B11FNUZAPInt(api); 398006c3fb27SDimitry Andric if (Sem == &semFloatTF32) 398106c3fb27SDimitry Andric return initFromFloatTF32APInt(api); 3982*0fca6ea1SDimitry Andric if (Sem == &semFloat6E3M2FN) 3983*0fca6ea1SDimitry Andric return initFromFloat6E3M2FNAPInt(api); 3984*0fca6ea1SDimitry Andric if (Sem == &semFloat6E2M3FN) 3985*0fca6ea1SDimitry Andric return initFromFloat6E2M3FNAPInt(api); 3986*0fca6ea1SDimitry Andric if (Sem == &semFloat4E2M1FN) 3987*0fca6ea1SDimitry Andric return initFromFloat4E2M1FNAPInt(api); 39880b57cec5SDimitry Andric 39890b57cec5SDimitry Andric llvm_unreachable(nullptr); 39900b57cec5SDimitry Andric } 39910b57cec5SDimitry Andric 39920b57cec5SDimitry Andric /// Make this number the largest magnitude normal number in the given 39930b57cec5SDimitry Andric /// semantics. 39940b57cec5SDimitry Andric void IEEEFloat::makeLargest(bool Negative) { 39950b57cec5SDimitry Andric // We want (in interchange format): 39960b57cec5SDimitry Andric // sign = {Negative} 39970b57cec5SDimitry Andric // exponent = 1..10 39980b57cec5SDimitry Andric // significand = 1..1 39990b57cec5SDimitry Andric category = fcNormal; 40000b57cec5SDimitry Andric sign = Negative; 40010b57cec5SDimitry Andric exponent = semantics->maxExponent; 40020b57cec5SDimitry Andric 40030b57cec5SDimitry Andric // Use memset to set all but the highest integerPart to all ones. 40040b57cec5SDimitry Andric integerPart *significand = significandParts(); 40050b57cec5SDimitry Andric unsigned PartCount = partCount(); 40060b57cec5SDimitry Andric memset(significand, 0xFF, sizeof(integerPart)*(PartCount - 1)); 40070b57cec5SDimitry Andric 40080b57cec5SDimitry Andric // Set the high integerPart especially setting all unused top bits for 40090b57cec5SDimitry Andric // internal consistency. 40100b57cec5SDimitry Andric const unsigned NumUnusedHighBits = 40110b57cec5SDimitry Andric PartCount*integerPartWidth - semantics->precision; 40120b57cec5SDimitry Andric significand[PartCount - 1] = (NumUnusedHighBits < integerPartWidth) 40130b57cec5SDimitry Andric ? (~integerPart(0) >> NumUnusedHighBits) 40140b57cec5SDimitry Andric : 0; 4015bdd1243dSDimitry Andric 401606c3fb27SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly && 401706c3fb27SDimitry Andric semantics->nanEncoding == fltNanEncoding::AllOnes) 4018bdd1243dSDimitry Andric significand[0] &= ~integerPart(1); 40190b57cec5SDimitry Andric } 40200b57cec5SDimitry Andric 40210b57cec5SDimitry Andric /// Make this number the smallest magnitude denormal number in the given 40220b57cec5SDimitry Andric /// semantics. 40230b57cec5SDimitry Andric void IEEEFloat::makeSmallest(bool Negative) { 40240b57cec5SDimitry Andric // We want (in interchange format): 40250b57cec5SDimitry Andric // sign = {Negative} 40260b57cec5SDimitry Andric // exponent = 0..0 40270b57cec5SDimitry Andric // significand = 0..01 40280b57cec5SDimitry Andric category = fcNormal; 40290b57cec5SDimitry Andric sign = Negative; 40300b57cec5SDimitry Andric exponent = semantics->minExponent; 40310b57cec5SDimitry Andric APInt::tcSet(significandParts(), 1, partCount()); 40320b57cec5SDimitry Andric } 40330b57cec5SDimitry Andric 40340b57cec5SDimitry Andric void IEEEFloat::makeSmallestNormalized(bool Negative) { 40350b57cec5SDimitry Andric // We want (in interchange format): 40360b57cec5SDimitry Andric // sign = {Negative} 40370b57cec5SDimitry Andric // exponent = 0..0 40380b57cec5SDimitry Andric // significand = 10..0 40390b57cec5SDimitry Andric 40400b57cec5SDimitry Andric category = fcNormal; 40410b57cec5SDimitry Andric zeroSignificand(); 40420b57cec5SDimitry Andric sign = Negative; 40430b57cec5SDimitry Andric exponent = semantics->minExponent; 4044bdd1243dSDimitry Andric APInt::tcSetBit(significandParts(), semantics->precision - 1); 40450b57cec5SDimitry Andric } 40460b57cec5SDimitry Andric 40470b57cec5SDimitry Andric IEEEFloat::IEEEFloat(const fltSemantics &Sem, const APInt &API) { 40480b57cec5SDimitry Andric initFromAPInt(&Sem, API); 40490b57cec5SDimitry Andric } 40500b57cec5SDimitry Andric 40510b57cec5SDimitry Andric IEEEFloat::IEEEFloat(float f) { 40520b57cec5SDimitry Andric initFromAPInt(&semIEEEsingle, APInt::floatToBits(f)); 40530b57cec5SDimitry Andric } 40540b57cec5SDimitry Andric 40550b57cec5SDimitry Andric IEEEFloat::IEEEFloat(double d) { 40560b57cec5SDimitry Andric initFromAPInt(&semIEEEdouble, APInt::doubleToBits(d)); 40570b57cec5SDimitry Andric } 40580b57cec5SDimitry Andric 40590b57cec5SDimitry Andric namespace { 40600b57cec5SDimitry Andric void append(SmallVectorImpl<char> &Buffer, StringRef Str) { 40610b57cec5SDimitry Andric Buffer.append(Str.begin(), Str.end()); 40620b57cec5SDimitry Andric } 40630b57cec5SDimitry Andric 40640b57cec5SDimitry Andric /// Removes data from the given significand until it is no more 40650b57cec5SDimitry Andric /// precise than is required for the desired precision. 40660b57cec5SDimitry Andric void AdjustToPrecision(APInt &significand, 40670b57cec5SDimitry Andric int &exp, unsigned FormatPrecision) { 40680b57cec5SDimitry Andric unsigned bits = significand.getActiveBits(); 40690b57cec5SDimitry Andric 40700b57cec5SDimitry Andric // 196/59 is a very slight overestimate of lg_2(10). 40710b57cec5SDimitry Andric unsigned bitsRequired = (FormatPrecision * 196 + 58) / 59; 40720b57cec5SDimitry Andric 40730b57cec5SDimitry Andric if (bits <= bitsRequired) return; 40740b57cec5SDimitry Andric 40750b57cec5SDimitry Andric unsigned tensRemovable = (bits - bitsRequired) * 59 / 196; 40760b57cec5SDimitry Andric if (!tensRemovable) return; 40770b57cec5SDimitry Andric 40780b57cec5SDimitry Andric exp += tensRemovable; 40790b57cec5SDimitry Andric 40800b57cec5SDimitry Andric APInt divisor(significand.getBitWidth(), 1); 40810b57cec5SDimitry Andric APInt powten(significand.getBitWidth(), 10); 40820b57cec5SDimitry Andric while (true) { 40830b57cec5SDimitry Andric if (tensRemovable & 1) 40840b57cec5SDimitry Andric divisor *= powten; 40850b57cec5SDimitry Andric tensRemovable >>= 1; 40860b57cec5SDimitry Andric if (!tensRemovable) break; 40870b57cec5SDimitry Andric powten *= powten; 40880b57cec5SDimitry Andric } 40890b57cec5SDimitry Andric 40900b57cec5SDimitry Andric significand = significand.udiv(divisor); 40910b57cec5SDimitry Andric 40920b57cec5SDimitry Andric // Truncate the significand down to its active bit count. 40930b57cec5SDimitry Andric significand = significand.trunc(significand.getActiveBits()); 40940b57cec5SDimitry Andric } 40950b57cec5SDimitry Andric 40960b57cec5SDimitry Andric 40970b57cec5SDimitry Andric void AdjustToPrecision(SmallVectorImpl<char> &buffer, 40980b57cec5SDimitry Andric int &exp, unsigned FormatPrecision) { 40990b57cec5SDimitry Andric unsigned N = buffer.size(); 41000b57cec5SDimitry Andric if (N <= FormatPrecision) return; 41010b57cec5SDimitry Andric 41020b57cec5SDimitry Andric // The most significant figures are the last ones in the buffer. 41030b57cec5SDimitry Andric unsigned FirstSignificant = N - FormatPrecision; 41040b57cec5SDimitry Andric 41050b57cec5SDimitry Andric // Round. 41060b57cec5SDimitry Andric // FIXME: this probably shouldn't use 'round half up'. 41070b57cec5SDimitry Andric 41080b57cec5SDimitry Andric // Rounding down is just a truncation, except we also want to drop 41090b57cec5SDimitry Andric // trailing zeros from the new result. 41100b57cec5SDimitry Andric if (buffer[FirstSignificant - 1] < '5') { 41110b57cec5SDimitry Andric while (FirstSignificant < N && buffer[FirstSignificant] == '0') 41120b57cec5SDimitry Andric FirstSignificant++; 41130b57cec5SDimitry Andric 41140b57cec5SDimitry Andric exp += FirstSignificant; 41150b57cec5SDimitry Andric buffer.erase(&buffer[0], &buffer[FirstSignificant]); 41160b57cec5SDimitry Andric return; 41170b57cec5SDimitry Andric } 41180b57cec5SDimitry Andric 41190b57cec5SDimitry Andric // Rounding up requires a decimal add-with-carry. If we continue 41200b57cec5SDimitry Andric // the carry, the newly-introduced zeros will just be truncated. 41210b57cec5SDimitry Andric for (unsigned I = FirstSignificant; I != N; ++I) { 41220b57cec5SDimitry Andric if (buffer[I] == '9') { 41230b57cec5SDimitry Andric FirstSignificant++; 41240b57cec5SDimitry Andric } else { 41250b57cec5SDimitry Andric buffer[I]++; 41260b57cec5SDimitry Andric break; 41270b57cec5SDimitry Andric } 41280b57cec5SDimitry Andric } 41290b57cec5SDimitry Andric 41300b57cec5SDimitry Andric // If we carried through, we have exactly one digit of precision. 41310b57cec5SDimitry Andric if (FirstSignificant == N) { 41320b57cec5SDimitry Andric exp += FirstSignificant; 41330b57cec5SDimitry Andric buffer.clear(); 41340b57cec5SDimitry Andric buffer.push_back('1'); 41350b57cec5SDimitry Andric return; 41360b57cec5SDimitry Andric } 41370b57cec5SDimitry Andric 41380b57cec5SDimitry Andric exp += FirstSignificant; 41390b57cec5SDimitry Andric buffer.erase(&buffer[0], &buffer[FirstSignificant]); 41400b57cec5SDimitry Andric } 41410b57cec5SDimitry Andric 4142*0fca6ea1SDimitry Andric void toStringImpl(SmallVectorImpl<char> &Str, const bool isNeg, int exp, 4143*0fca6ea1SDimitry Andric APInt significand, unsigned FormatPrecision, 4144*0fca6ea1SDimitry Andric unsigned FormatMaxPadding, bool TruncateZero) { 4145*0fca6ea1SDimitry Andric const int semanticsPrecision = significand.getBitWidth(); 41460b57cec5SDimitry Andric 4147*0fca6ea1SDimitry Andric if (isNeg) 41480b57cec5SDimitry Andric Str.push_back('-'); 41490b57cec5SDimitry Andric 41500b57cec5SDimitry Andric // Set FormatPrecision if zero. We want to do this before we 41510b57cec5SDimitry Andric // truncate trailing zeros, as those are part of the precision. 41520b57cec5SDimitry Andric if (!FormatPrecision) { 41530b57cec5SDimitry Andric // We use enough digits so the number can be round-tripped back to an 41540b57cec5SDimitry Andric // APFloat. The formula comes from "How to Print Floating-Point Numbers 41550b57cec5SDimitry Andric // Accurately" by Steele and White. 41560b57cec5SDimitry Andric // FIXME: Using a formula based purely on the precision is conservative; 41570b57cec5SDimitry Andric // we can print fewer digits depending on the actual value being printed. 41580b57cec5SDimitry Andric 41590b57cec5SDimitry Andric // FormatPrecision = 2 + floor(significandBits / lg_2(10)) 4160*0fca6ea1SDimitry Andric FormatPrecision = 2 + semanticsPrecision * 59 / 196; 41610b57cec5SDimitry Andric } 41620b57cec5SDimitry Andric 41630b57cec5SDimitry Andric // Ignore trailing binary zeros. 416406c3fb27SDimitry Andric int trailingZeros = significand.countr_zero(); 41650b57cec5SDimitry Andric exp += trailingZeros; 41660b57cec5SDimitry Andric significand.lshrInPlace(trailingZeros); 41670b57cec5SDimitry Andric 41680b57cec5SDimitry Andric // Change the exponent from 2^e to 10^e. 41690b57cec5SDimitry Andric if (exp == 0) { 41700b57cec5SDimitry Andric // Nothing to do. 41710b57cec5SDimitry Andric } else if (exp > 0) { 41720b57cec5SDimitry Andric // Just shift left. 4173*0fca6ea1SDimitry Andric significand = significand.zext(semanticsPrecision + exp); 41740b57cec5SDimitry Andric significand <<= exp; 41750b57cec5SDimitry Andric exp = 0; 41760b57cec5SDimitry Andric } else { /* exp < 0 */ 41770b57cec5SDimitry Andric int texp = -exp; 41780b57cec5SDimitry Andric 41790b57cec5SDimitry Andric // We transform this using the identity: 41800b57cec5SDimitry Andric // (N)(2^-e) == (N)(5^e)(10^-e) 41810b57cec5SDimitry Andric // This means we have to multiply N (the significand) by 5^e. 41820b57cec5SDimitry Andric // To avoid overflow, we have to operate on numbers large 41830b57cec5SDimitry Andric // enough to store N * 5^e: 41840b57cec5SDimitry Andric // log2(N * 5^e) == log2(N) + e * log2(5) 41850b57cec5SDimitry Andric // <= semantics->precision + e * 137 / 59 41860b57cec5SDimitry Andric // (log_2(5) ~ 2.321928 < 2.322034 ~ 137/59) 41870b57cec5SDimitry Andric 4188*0fca6ea1SDimitry Andric unsigned precision = semanticsPrecision + (137 * texp + 136) / 59; 41890b57cec5SDimitry Andric 41900b57cec5SDimitry Andric // Multiply significand by 5^e. 41910b57cec5SDimitry Andric // N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8) 41920b57cec5SDimitry Andric significand = significand.zext(precision); 41930b57cec5SDimitry Andric APInt five_to_the_i(precision, 5); 41940b57cec5SDimitry Andric while (true) { 4195*0fca6ea1SDimitry Andric if (texp & 1) 4196*0fca6ea1SDimitry Andric significand *= five_to_the_i; 41970b57cec5SDimitry Andric 41980b57cec5SDimitry Andric texp >>= 1; 4199*0fca6ea1SDimitry Andric if (!texp) 4200*0fca6ea1SDimitry Andric break; 42010b57cec5SDimitry Andric five_to_the_i *= five_to_the_i; 42020b57cec5SDimitry Andric } 42030b57cec5SDimitry Andric } 42040b57cec5SDimitry Andric 42050b57cec5SDimitry Andric AdjustToPrecision(significand, exp, FormatPrecision); 42060b57cec5SDimitry Andric 42070b57cec5SDimitry Andric SmallVector<char, 256> buffer; 42080b57cec5SDimitry Andric 42090b57cec5SDimitry Andric // Fill the buffer. 42100b57cec5SDimitry Andric unsigned precision = significand.getBitWidth(); 4211bdd1243dSDimitry Andric if (precision < 4) { 4212bdd1243dSDimitry Andric // We need enough precision to store the value 10. 4213bdd1243dSDimitry Andric precision = 4; 4214bdd1243dSDimitry Andric significand = significand.zext(precision); 4215bdd1243dSDimitry Andric } 42160b57cec5SDimitry Andric APInt ten(precision, 10); 42170b57cec5SDimitry Andric APInt digit(precision, 0); 42180b57cec5SDimitry Andric 42190b57cec5SDimitry Andric bool inTrail = true; 42200b57cec5SDimitry Andric while (significand != 0) { 42210b57cec5SDimitry Andric // digit <- significand % 10 42220b57cec5SDimitry Andric // significand <- significand / 10 42230b57cec5SDimitry Andric APInt::udivrem(significand, ten, significand, digit); 42240b57cec5SDimitry Andric 42250b57cec5SDimitry Andric unsigned d = digit.getZExtValue(); 42260b57cec5SDimitry Andric 42270b57cec5SDimitry Andric // Drop trailing zeros. 4228*0fca6ea1SDimitry Andric if (inTrail && !d) 4229*0fca6ea1SDimitry Andric exp++; 42300b57cec5SDimitry Andric else { 42310b57cec5SDimitry Andric buffer.push_back((char) ('0' + d)); 42320b57cec5SDimitry Andric inTrail = false; 42330b57cec5SDimitry Andric } 42340b57cec5SDimitry Andric } 42350b57cec5SDimitry Andric 42360b57cec5SDimitry Andric assert(!buffer.empty() && "no characters in buffer!"); 42370b57cec5SDimitry Andric 42380b57cec5SDimitry Andric // Drop down to FormatPrecision. 42390b57cec5SDimitry Andric // TODO: don't do more precise calculations above than are required. 42400b57cec5SDimitry Andric AdjustToPrecision(buffer, exp, FormatPrecision); 42410b57cec5SDimitry Andric 42420b57cec5SDimitry Andric unsigned NDigits = buffer.size(); 42430b57cec5SDimitry Andric 42440b57cec5SDimitry Andric // Check whether we should use scientific notation. 42450b57cec5SDimitry Andric bool FormatScientific; 42460b57cec5SDimitry Andric if (!FormatMaxPadding) 42470b57cec5SDimitry Andric FormatScientific = true; 42480b57cec5SDimitry Andric else { 42490b57cec5SDimitry Andric if (exp >= 0) { 42500b57cec5SDimitry Andric // 765e3 --> 765000 42510b57cec5SDimitry Andric // ^^^ 42520b57cec5SDimitry Andric // But we shouldn't make the number look more precise than it is. 42530b57cec5SDimitry Andric FormatScientific = ((unsigned) exp > FormatMaxPadding || 42540b57cec5SDimitry Andric NDigits + (unsigned) exp > FormatPrecision); 42550b57cec5SDimitry Andric } else { 42560b57cec5SDimitry Andric // Power of the most significant digit. 42570b57cec5SDimitry Andric int MSD = exp + (int) (NDigits - 1); 42580b57cec5SDimitry Andric if (MSD >= 0) { 42590b57cec5SDimitry Andric // 765e-2 == 7.65 42600b57cec5SDimitry Andric FormatScientific = false; 42610b57cec5SDimitry Andric } else { 42620b57cec5SDimitry Andric // 765e-5 == 0.00765 42630b57cec5SDimitry Andric // ^ ^^ 42640b57cec5SDimitry Andric FormatScientific = ((unsigned) -MSD) > FormatMaxPadding; 42650b57cec5SDimitry Andric } 42660b57cec5SDimitry Andric } 42670b57cec5SDimitry Andric } 42680b57cec5SDimitry Andric 42690b57cec5SDimitry Andric // Scientific formatting is pretty straightforward. 42700b57cec5SDimitry Andric if (FormatScientific) { 42710b57cec5SDimitry Andric exp += (NDigits - 1); 42720b57cec5SDimitry Andric 42730b57cec5SDimitry Andric Str.push_back(buffer[NDigits-1]); 42740b57cec5SDimitry Andric Str.push_back('.'); 42750b57cec5SDimitry Andric if (NDigits == 1 && TruncateZero) 42760b57cec5SDimitry Andric Str.push_back('0'); 42770b57cec5SDimitry Andric else 42780b57cec5SDimitry Andric for (unsigned I = 1; I != NDigits; ++I) 42790b57cec5SDimitry Andric Str.push_back(buffer[NDigits-1-I]); 42800b57cec5SDimitry Andric // Fill with zeros up to FormatPrecision. 42810b57cec5SDimitry Andric if (!TruncateZero && FormatPrecision > NDigits - 1) 42820b57cec5SDimitry Andric Str.append(FormatPrecision - NDigits + 1, '0'); 42830b57cec5SDimitry Andric // For !TruncateZero we use lower 'e'. 42840b57cec5SDimitry Andric Str.push_back(TruncateZero ? 'E' : 'e'); 42850b57cec5SDimitry Andric 42860b57cec5SDimitry Andric Str.push_back(exp >= 0 ? '+' : '-'); 4287*0fca6ea1SDimitry Andric if (exp < 0) 4288*0fca6ea1SDimitry Andric exp = -exp; 42890b57cec5SDimitry Andric SmallVector<char, 6> expbuf; 42900b57cec5SDimitry Andric do { 42910b57cec5SDimitry Andric expbuf.push_back((char) ('0' + (exp % 10))); 42920b57cec5SDimitry Andric exp /= 10; 42930b57cec5SDimitry Andric } while (exp); 42940b57cec5SDimitry Andric // Exponent always at least two digits if we do not truncate zeros. 42950b57cec5SDimitry Andric if (!TruncateZero && expbuf.size() < 2) 42960b57cec5SDimitry Andric expbuf.push_back('0'); 42970b57cec5SDimitry Andric for (unsigned I = 0, E = expbuf.size(); I != E; ++I) 42980b57cec5SDimitry Andric Str.push_back(expbuf[E-1-I]); 42990b57cec5SDimitry Andric return; 43000b57cec5SDimitry Andric } 43010b57cec5SDimitry Andric 43020b57cec5SDimitry Andric // Non-scientific, positive exponents. 43030b57cec5SDimitry Andric if (exp >= 0) { 43040b57cec5SDimitry Andric for (unsigned I = 0; I != NDigits; ++I) 43050b57cec5SDimitry Andric Str.push_back(buffer[NDigits-1-I]); 43060b57cec5SDimitry Andric for (unsigned I = 0; I != (unsigned) exp; ++I) 43070b57cec5SDimitry Andric Str.push_back('0'); 43080b57cec5SDimitry Andric return; 43090b57cec5SDimitry Andric } 43100b57cec5SDimitry Andric 43110b57cec5SDimitry Andric // Non-scientific, negative exponents. 43120b57cec5SDimitry Andric 43130b57cec5SDimitry Andric // The number of digits to the left of the decimal point. 43140b57cec5SDimitry Andric int NWholeDigits = exp + (int) NDigits; 43150b57cec5SDimitry Andric 43160b57cec5SDimitry Andric unsigned I = 0; 43170b57cec5SDimitry Andric if (NWholeDigits > 0) { 43180b57cec5SDimitry Andric for (; I != (unsigned) NWholeDigits; ++I) 43190b57cec5SDimitry Andric Str.push_back(buffer[NDigits-I-1]); 43200b57cec5SDimitry Andric Str.push_back('.'); 43210b57cec5SDimitry Andric } else { 43220b57cec5SDimitry Andric unsigned NZeros = 1 + (unsigned) -NWholeDigits; 43230b57cec5SDimitry Andric 43240b57cec5SDimitry Andric Str.push_back('0'); 43250b57cec5SDimitry Andric Str.push_back('.'); 43260b57cec5SDimitry Andric for (unsigned Z = 1; Z != NZeros; ++Z) 43270b57cec5SDimitry Andric Str.push_back('0'); 43280b57cec5SDimitry Andric } 43290b57cec5SDimitry Andric 43300b57cec5SDimitry Andric for (; I != NDigits; ++I) 43310b57cec5SDimitry Andric Str.push_back(buffer[NDigits-I-1]); 4332*0fca6ea1SDimitry Andric 4333*0fca6ea1SDimitry Andric } 4334*0fca6ea1SDimitry Andric } // namespace 4335*0fca6ea1SDimitry Andric 4336*0fca6ea1SDimitry Andric void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision, 4337*0fca6ea1SDimitry Andric unsigned FormatMaxPadding, bool TruncateZero) const { 4338*0fca6ea1SDimitry Andric switch (category) { 4339*0fca6ea1SDimitry Andric case fcInfinity: 4340*0fca6ea1SDimitry Andric if (isNegative()) 4341*0fca6ea1SDimitry Andric return append(Str, "-Inf"); 4342*0fca6ea1SDimitry Andric else 4343*0fca6ea1SDimitry Andric return append(Str, "+Inf"); 4344*0fca6ea1SDimitry Andric 4345*0fca6ea1SDimitry Andric case fcNaN: return append(Str, "NaN"); 4346*0fca6ea1SDimitry Andric 4347*0fca6ea1SDimitry Andric case fcZero: 4348*0fca6ea1SDimitry Andric if (isNegative()) 4349*0fca6ea1SDimitry Andric Str.push_back('-'); 4350*0fca6ea1SDimitry Andric 4351*0fca6ea1SDimitry Andric if (!FormatMaxPadding) { 4352*0fca6ea1SDimitry Andric if (TruncateZero) 4353*0fca6ea1SDimitry Andric append(Str, "0.0E+0"); 4354*0fca6ea1SDimitry Andric else { 4355*0fca6ea1SDimitry Andric append(Str, "0.0"); 4356*0fca6ea1SDimitry Andric if (FormatPrecision > 1) 4357*0fca6ea1SDimitry Andric Str.append(FormatPrecision - 1, '0'); 4358*0fca6ea1SDimitry Andric append(Str, "e+00"); 4359*0fca6ea1SDimitry Andric } 4360*0fca6ea1SDimitry Andric } else 4361*0fca6ea1SDimitry Andric Str.push_back('0'); 4362*0fca6ea1SDimitry Andric return; 4363*0fca6ea1SDimitry Andric 4364*0fca6ea1SDimitry Andric case fcNormal: 4365*0fca6ea1SDimitry Andric break; 4366*0fca6ea1SDimitry Andric } 4367*0fca6ea1SDimitry Andric 4368*0fca6ea1SDimitry Andric // Decompose the number into an APInt and an exponent. 4369*0fca6ea1SDimitry Andric int exp = exponent - ((int) semantics->precision - 1); 4370*0fca6ea1SDimitry Andric APInt significand( 4371*0fca6ea1SDimitry Andric semantics->precision, 4372*0fca6ea1SDimitry Andric ArrayRef(significandParts(), partCountForBits(semantics->precision))); 4373*0fca6ea1SDimitry Andric 4374*0fca6ea1SDimitry Andric toStringImpl(Str, isNegative(), exp, significand, FormatPrecision, 4375*0fca6ea1SDimitry Andric FormatMaxPadding, TruncateZero); 4376*0fca6ea1SDimitry Andric 43770b57cec5SDimitry Andric } 43780b57cec5SDimitry Andric 43790b57cec5SDimitry Andric bool IEEEFloat::getExactInverse(APFloat *inv) const { 43800b57cec5SDimitry Andric // Special floats and denormals have no exact inverse. 43810b57cec5SDimitry Andric if (!isFiniteNonZero()) 43820b57cec5SDimitry Andric return false; 43830b57cec5SDimitry Andric 43840b57cec5SDimitry Andric // Check that the number is a power of two by making sure that only the 43850b57cec5SDimitry Andric // integer bit is set in the significand. 43860b57cec5SDimitry Andric if (significandLSB() != semantics->precision - 1) 43870b57cec5SDimitry Andric return false; 43880b57cec5SDimitry Andric 43890b57cec5SDimitry Andric // Get the inverse. 43900b57cec5SDimitry Andric IEEEFloat reciprocal(*semantics, 1ULL); 43910b57cec5SDimitry Andric if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK) 43920b57cec5SDimitry Andric return false; 43930b57cec5SDimitry Andric 43940b57cec5SDimitry Andric // Avoid multiplication with a denormal, it is not safe on all platforms and 43950b57cec5SDimitry Andric // may be slower than a normal division. 43960b57cec5SDimitry Andric if (reciprocal.isDenormal()) 43970b57cec5SDimitry Andric return false; 43980b57cec5SDimitry Andric 43990b57cec5SDimitry Andric assert(reciprocal.isFiniteNonZero() && 44000b57cec5SDimitry Andric reciprocal.significandLSB() == reciprocal.semantics->precision - 1); 44010b57cec5SDimitry Andric 44020b57cec5SDimitry Andric if (inv) 44030b57cec5SDimitry Andric *inv = APFloat(reciprocal, *semantics); 44040b57cec5SDimitry Andric 44050b57cec5SDimitry Andric return true; 44060b57cec5SDimitry Andric } 44070b57cec5SDimitry Andric 44085f757f3fSDimitry Andric int IEEEFloat::getExactLog2Abs() const { 44095f757f3fSDimitry Andric if (!isFinite() || isZero()) 44105f757f3fSDimitry Andric return INT_MIN; 44115f757f3fSDimitry Andric 44125f757f3fSDimitry Andric const integerPart *Parts = significandParts(); 44135f757f3fSDimitry Andric const int PartCount = partCountForBits(semantics->precision); 44145f757f3fSDimitry Andric 44155f757f3fSDimitry Andric int PopCount = 0; 44165f757f3fSDimitry Andric for (int i = 0; i < PartCount; ++i) { 44175f757f3fSDimitry Andric PopCount += llvm::popcount(Parts[i]); 44185f757f3fSDimitry Andric if (PopCount > 1) 44195f757f3fSDimitry Andric return INT_MIN; 44205f757f3fSDimitry Andric } 44215f757f3fSDimitry Andric 44225f757f3fSDimitry Andric if (exponent != semantics->minExponent) 44235f757f3fSDimitry Andric return exponent; 44245f757f3fSDimitry Andric 44255f757f3fSDimitry Andric int CountrParts = 0; 44265f757f3fSDimitry Andric for (int i = 0; i < PartCount; 44275f757f3fSDimitry Andric ++i, CountrParts += APInt::APINT_BITS_PER_WORD) { 44285f757f3fSDimitry Andric if (Parts[i] != 0) { 44295f757f3fSDimitry Andric return exponent - semantics->precision + CountrParts + 44305f757f3fSDimitry Andric llvm::countr_zero(Parts[i]) + 1; 44315f757f3fSDimitry Andric } 44325f757f3fSDimitry Andric } 44335f757f3fSDimitry Andric 44345f757f3fSDimitry Andric llvm_unreachable("didn't find the set bit"); 44355f757f3fSDimitry Andric } 44365f757f3fSDimitry Andric 44370b57cec5SDimitry Andric bool IEEEFloat::isSignaling() const { 44380b57cec5SDimitry Andric if (!isNaN()) 44390b57cec5SDimitry Andric return false; 4440*0fca6ea1SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly || 4441*0fca6ea1SDimitry Andric semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly) 4442bdd1243dSDimitry Andric return false; 44430b57cec5SDimitry Andric 44440b57cec5SDimitry Andric // IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded with the 44450b57cec5SDimitry Andric // first bit of the trailing significand being 0. 44460b57cec5SDimitry Andric return !APInt::tcExtractBit(significandParts(), semantics->precision - 2); 44470b57cec5SDimitry Andric } 44480b57cec5SDimitry Andric 44490b57cec5SDimitry Andric /// IEEE-754R 2008 5.3.1: nextUp/nextDown. 44500b57cec5SDimitry Andric /// 44510b57cec5SDimitry Andric /// *NOTE* since nextDown(x) = -nextUp(-x), we only implement nextUp with 44520b57cec5SDimitry Andric /// appropriate sign switching before/after the computation. 44530b57cec5SDimitry Andric IEEEFloat::opStatus IEEEFloat::next(bool nextDown) { 44540b57cec5SDimitry Andric // If we are performing nextDown, swap sign so we have -x. 44550b57cec5SDimitry Andric if (nextDown) 44560b57cec5SDimitry Andric changeSign(); 44570b57cec5SDimitry Andric 44580b57cec5SDimitry Andric // Compute nextUp(x) 44590b57cec5SDimitry Andric opStatus result = opOK; 44600b57cec5SDimitry Andric 44610b57cec5SDimitry Andric // Handle each float category separately. 44620b57cec5SDimitry Andric switch (category) { 44630b57cec5SDimitry Andric case fcInfinity: 44640b57cec5SDimitry Andric // nextUp(+inf) = +inf 44650b57cec5SDimitry Andric if (!isNegative()) 44660b57cec5SDimitry Andric break; 44670b57cec5SDimitry Andric // nextUp(-inf) = -getLargest() 44680b57cec5SDimitry Andric makeLargest(true); 44690b57cec5SDimitry Andric break; 44700b57cec5SDimitry Andric case fcNaN: 44710b57cec5SDimitry Andric // IEEE-754R 2008 6.2 Par 2: nextUp(sNaN) = qNaN. Set Invalid flag. 44720b57cec5SDimitry Andric // IEEE-754R 2008 6.2: nextUp(qNaN) = qNaN. Must be identity so we do not 44730b57cec5SDimitry Andric // change the payload. 44740b57cec5SDimitry Andric if (isSignaling()) { 44750b57cec5SDimitry Andric result = opInvalidOp; 44760b57cec5SDimitry Andric // For consistency, propagate the sign of the sNaN to the qNaN. 44770b57cec5SDimitry Andric makeNaN(false, isNegative(), nullptr); 44780b57cec5SDimitry Andric } 44790b57cec5SDimitry Andric break; 44800b57cec5SDimitry Andric case fcZero: 44810b57cec5SDimitry Andric // nextUp(pm 0) = +getSmallest() 44820b57cec5SDimitry Andric makeSmallest(false); 44830b57cec5SDimitry Andric break; 44840b57cec5SDimitry Andric case fcNormal: 44850b57cec5SDimitry Andric // nextUp(-getSmallest()) = -0 44860b57cec5SDimitry Andric if (isSmallest() && isNegative()) { 44870b57cec5SDimitry Andric APInt::tcSet(significandParts(), 0, partCount()); 44880b57cec5SDimitry Andric category = fcZero; 44890b57cec5SDimitry Andric exponent = 0; 449006c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) 449106c3fb27SDimitry Andric sign = false; 44920b57cec5SDimitry Andric break; 44930b57cec5SDimitry Andric } 44940b57cec5SDimitry Andric 44950b57cec5SDimitry Andric if (isLargest() && !isNegative()) { 4496bdd1243dSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) { 4497bdd1243dSDimitry Andric // nextUp(getLargest()) == NAN 4498bdd1243dSDimitry Andric makeNaN(); 4499bdd1243dSDimitry Andric break; 4500*0fca6ea1SDimitry Andric } else if (semantics->nonFiniteBehavior == 4501*0fca6ea1SDimitry Andric fltNonfiniteBehavior::FiniteOnly) { 4502*0fca6ea1SDimitry Andric // nextUp(getLargest()) == getLargest() 4503*0fca6ea1SDimitry Andric break; 4504bdd1243dSDimitry Andric } else { 4505bdd1243dSDimitry Andric // nextUp(getLargest()) == INFINITY 45060b57cec5SDimitry Andric APInt::tcSet(significandParts(), 0, partCount()); 45070b57cec5SDimitry Andric category = fcInfinity; 45080b57cec5SDimitry Andric exponent = semantics->maxExponent + 1; 45090b57cec5SDimitry Andric break; 45100b57cec5SDimitry Andric } 4511bdd1243dSDimitry Andric } 45120b57cec5SDimitry Andric 45130b57cec5SDimitry Andric // nextUp(normal) == normal + inc. 45140b57cec5SDimitry Andric if (isNegative()) { 45150b57cec5SDimitry Andric // If we are negative, we need to decrement the significand. 45160b57cec5SDimitry Andric 45170b57cec5SDimitry Andric // We only cross a binade boundary that requires adjusting the exponent 45180b57cec5SDimitry Andric // if: 45190b57cec5SDimitry Andric // 1. exponent != semantics->minExponent. This implies we are not in the 45200b57cec5SDimitry Andric // smallest binade or are dealing with denormals. 45210b57cec5SDimitry Andric // 2. Our significand excluding the integral bit is all zeros. 45220b57cec5SDimitry Andric bool WillCrossBinadeBoundary = 45230b57cec5SDimitry Andric exponent != semantics->minExponent && isSignificandAllZeros(); 45240b57cec5SDimitry Andric 45250b57cec5SDimitry Andric // Decrement the significand. 45260b57cec5SDimitry Andric // 45270b57cec5SDimitry Andric // We always do this since: 45280b57cec5SDimitry Andric // 1. If we are dealing with a non-binade decrement, by definition we 45290b57cec5SDimitry Andric // just decrement the significand. 45300b57cec5SDimitry Andric // 2. If we are dealing with a normal -> normal binade decrement, since 45310b57cec5SDimitry Andric // we have an explicit integral bit the fact that all bits but the 45320b57cec5SDimitry Andric // integral bit are zero implies that subtracting one will yield a 45330b57cec5SDimitry Andric // significand with 0 integral bit and 1 in all other spots. Thus we 45340b57cec5SDimitry Andric // must just adjust the exponent and set the integral bit to 1. 45350b57cec5SDimitry Andric // 3. If we are dealing with a normal -> denormal binade decrement, 45360b57cec5SDimitry Andric // since we set the integral bit to 0 when we represent denormals, we 45370b57cec5SDimitry Andric // just decrement the significand. 45380b57cec5SDimitry Andric integerPart *Parts = significandParts(); 45390b57cec5SDimitry Andric APInt::tcDecrement(Parts, partCount()); 45400b57cec5SDimitry Andric 45410b57cec5SDimitry Andric if (WillCrossBinadeBoundary) { 45420b57cec5SDimitry Andric // Our result is a normal number. Do the following: 45430b57cec5SDimitry Andric // 1. Set the integral bit to 1. 45440b57cec5SDimitry Andric // 2. Decrement the exponent. 45450b57cec5SDimitry Andric APInt::tcSetBit(Parts, semantics->precision - 1); 45460b57cec5SDimitry Andric exponent--; 45470b57cec5SDimitry Andric } 45480b57cec5SDimitry Andric } else { 45490b57cec5SDimitry Andric // If we are positive, we need to increment the significand. 45500b57cec5SDimitry Andric 45510b57cec5SDimitry Andric // We only cross a binade boundary that requires adjusting the exponent if 45520b57cec5SDimitry Andric // the input is not a denormal and all of said input's significand bits 45530b57cec5SDimitry Andric // are set. If all of said conditions are true: clear the significand, set 45540b57cec5SDimitry Andric // the integral bit to 1, and increment the exponent. If we have a 45550b57cec5SDimitry Andric // denormal always increment since moving denormals and the numbers in the 45560b57cec5SDimitry Andric // smallest normal binade have the same exponent in our representation. 45570b57cec5SDimitry Andric bool WillCrossBinadeBoundary = !isDenormal() && isSignificandAllOnes(); 45580b57cec5SDimitry Andric 45590b57cec5SDimitry Andric if (WillCrossBinadeBoundary) { 45600b57cec5SDimitry Andric integerPart *Parts = significandParts(); 45610b57cec5SDimitry Andric APInt::tcSet(Parts, 0, partCount()); 45620b57cec5SDimitry Andric APInt::tcSetBit(Parts, semantics->precision - 1); 45630b57cec5SDimitry Andric assert(exponent != semantics->maxExponent && 45640b57cec5SDimitry Andric "We can not increment an exponent beyond the maxExponent allowed" 45650b57cec5SDimitry Andric " by the given floating point semantics."); 45660b57cec5SDimitry Andric exponent++; 45670b57cec5SDimitry Andric } else { 45680b57cec5SDimitry Andric incrementSignificand(); 45690b57cec5SDimitry Andric } 45700b57cec5SDimitry Andric } 45710b57cec5SDimitry Andric break; 45720b57cec5SDimitry Andric } 45730b57cec5SDimitry Andric 45740b57cec5SDimitry Andric // If we are performing nextDown, swap sign so we have -nextUp(-x) 45750b57cec5SDimitry Andric if (nextDown) 45760b57cec5SDimitry Andric changeSign(); 45770b57cec5SDimitry Andric 45780b57cec5SDimitry Andric return result; 45790b57cec5SDimitry Andric } 45800b57cec5SDimitry Andric 4581e8d8bef9SDimitry Andric APFloatBase::ExponentType IEEEFloat::exponentNaN() const { 458206c3fb27SDimitry Andric return ::exponentNaN(*semantics); 4583e8d8bef9SDimitry Andric } 4584e8d8bef9SDimitry Andric 4585e8d8bef9SDimitry Andric APFloatBase::ExponentType IEEEFloat::exponentInf() const { 458606c3fb27SDimitry Andric return ::exponentInf(*semantics); 4587e8d8bef9SDimitry Andric } 4588e8d8bef9SDimitry Andric 4589e8d8bef9SDimitry Andric APFloatBase::ExponentType IEEEFloat::exponentZero() const { 459006c3fb27SDimitry Andric return ::exponentZero(*semantics); 4591e8d8bef9SDimitry Andric } 4592e8d8bef9SDimitry Andric 45930b57cec5SDimitry Andric void IEEEFloat::makeInf(bool Negative) { 4594*0fca6ea1SDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly) 4595*0fca6ea1SDimitry Andric llvm_unreachable("This floating point format does not support Inf"); 4596*0fca6ea1SDimitry Andric 4597bdd1243dSDimitry Andric if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) { 4598bdd1243dSDimitry Andric // There is no Inf, so make NaN instead. 4599bdd1243dSDimitry Andric makeNaN(false, Negative); 4600bdd1243dSDimitry Andric return; 4601bdd1243dSDimitry Andric } 46020b57cec5SDimitry Andric category = fcInfinity; 46030b57cec5SDimitry Andric sign = Negative; 4604e8d8bef9SDimitry Andric exponent = exponentInf(); 46050b57cec5SDimitry Andric APInt::tcSet(significandParts(), 0, partCount()); 46060b57cec5SDimitry Andric } 46070b57cec5SDimitry Andric 46080b57cec5SDimitry Andric void IEEEFloat::makeZero(bool Negative) { 46090b57cec5SDimitry Andric category = fcZero; 46100b57cec5SDimitry Andric sign = Negative; 461106c3fb27SDimitry Andric if (semantics->nanEncoding == fltNanEncoding::NegativeZero) { 461206c3fb27SDimitry Andric // Merge negative zero to positive because 0b10000...000 is used for NaN 461306c3fb27SDimitry Andric sign = false; 461406c3fb27SDimitry Andric } 4615e8d8bef9SDimitry Andric exponent = exponentZero(); 46160b57cec5SDimitry Andric APInt::tcSet(significandParts(), 0, partCount()); 46170b57cec5SDimitry Andric } 46180b57cec5SDimitry Andric 46190b57cec5SDimitry Andric void IEEEFloat::makeQuiet() { 46200b57cec5SDimitry Andric assert(isNaN()); 4621bdd1243dSDimitry Andric if (semantics->nonFiniteBehavior != fltNonfiniteBehavior::NanOnly) 46220b57cec5SDimitry Andric APInt::tcSetBit(significandParts(), semantics->precision - 2); 46230b57cec5SDimitry Andric } 46240b57cec5SDimitry Andric 46250b57cec5SDimitry Andric int ilogb(const IEEEFloat &Arg) { 46260b57cec5SDimitry Andric if (Arg.isNaN()) 46270b57cec5SDimitry Andric return IEEEFloat::IEK_NaN; 46280b57cec5SDimitry Andric if (Arg.isZero()) 46290b57cec5SDimitry Andric return IEEEFloat::IEK_Zero; 46300b57cec5SDimitry Andric if (Arg.isInfinity()) 46310b57cec5SDimitry Andric return IEEEFloat::IEK_Inf; 46320b57cec5SDimitry Andric if (!Arg.isDenormal()) 46330b57cec5SDimitry Andric return Arg.exponent; 46340b57cec5SDimitry Andric 46350b57cec5SDimitry Andric IEEEFloat Normalized(Arg); 46360b57cec5SDimitry Andric int SignificandBits = Arg.getSemantics().precision - 1; 46370b57cec5SDimitry Andric 46380b57cec5SDimitry Andric Normalized.exponent += SignificandBits; 46390b57cec5SDimitry Andric Normalized.normalize(IEEEFloat::rmNearestTiesToEven, lfExactlyZero); 46400b57cec5SDimitry Andric return Normalized.exponent - SignificandBits; 46410b57cec5SDimitry Andric } 46420b57cec5SDimitry Andric 46430b57cec5SDimitry Andric IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode RoundingMode) { 46440b57cec5SDimitry Andric auto MaxExp = X.getSemantics().maxExponent; 46450b57cec5SDimitry Andric auto MinExp = X.getSemantics().minExponent; 46460b57cec5SDimitry Andric 46470b57cec5SDimitry Andric // If Exp is wildly out-of-scale, simply adding it to X.exponent will 46480b57cec5SDimitry Andric // overflow; clamp it to a safe range before adding, but ensure that the range 46490b57cec5SDimitry Andric // is large enough that the clamp does not change the result. The range we 46500b57cec5SDimitry Andric // need to support is the difference between the largest possible exponent and 46510b57cec5SDimitry Andric // the normalized exponent of half the smallest denormal. 46520b57cec5SDimitry Andric 46530b57cec5SDimitry Andric int SignificandBits = X.getSemantics().precision - 1; 46540b57cec5SDimitry Andric int MaxIncrement = MaxExp - (MinExp - SignificandBits) + 1; 46550b57cec5SDimitry Andric 46560b57cec5SDimitry Andric // Clamp to one past the range ends to let normalize handle overlflow. 465706c3fb27SDimitry Andric X.exponent += std::clamp(Exp, -MaxIncrement - 1, MaxIncrement); 46580b57cec5SDimitry Andric X.normalize(RoundingMode, lfExactlyZero); 46590b57cec5SDimitry Andric if (X.isNaN()) 46600b57cec5SDimitry Andric X.makeQuiet(); 46610b57cec5SDimitry Andric return X; 46620b57cec5SDimitry Andric } 46630b57cec5SDimitry Andric 46640b57cec5SDimitry Andric IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM) { 46650b57cec5SDimitry Andric Exp = ilogb(Val); 46660b57cec5SDimitry Andric 46670b57cec5SDimitry Andric // Quiet signalling nans. 46680b57cec5SDimitry Andric if (Exp == IEEEFloat::IEK_NaN) { 46690b57cec5SDimitry Andric IEEEFloat Quiet(Val); 46700b57cec5SDimitry Andric Quiet.makeQuiet(); 46710b57cec5SDimitry Andric return Quiet; 46720b57cec5SDimitry Andric } 46730b57cec5SDimitry Andric 46740b57cec5SDimitry Andric if (Exp == IEEEFloat::IEK_Inf) 46750b57cec5SDimitry Andric return Val; 46760b57cec5SDimitry Andric 46770b57cec5SDimitry Andric // 1 is added because frexp is defined to return a normalized fraction in 46780b57cec5SDimitry Andric // +/-[0.5, 1.0), rather than the usual +/-[1.0, 2.0). 46790b57cec5SDimitry Andric Exp = Exp == IEEEFloat::IEK_Zero ? 0 : Exp + 1; 46800b57cec5SDimitry Andric return scalbn(Val, -Exp, RM); 46810b57cec5SDimitry Andric } 46820b57cec5SDimitry Andric 46830b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S) 46840b57cec5SDimitry Andric : Semantics(&S), 46850b57cec5SDimitry Andric Floats(new APFloat[2]{APFloat(semIEEEdouble), APFloat(semIEEEdouble)}) { 46860b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble); 46870b57cec5SDimitry Andric } 46880b57cec5SDimitry Andric 46890b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, uninitializedTag) 46900b57cec5SDimitry Andric : Semantics(&S), 46910b57cec5SDimitry Andric Floats(new APFloat[2]{APFloat(semIEEEdouble, uninitialized), 46920b57cec5SDimitry Andric APFloat(semIEEEdouble, uninitialized)}) { 46930b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble); 46940b57cec5SDimitry Andric } 46950b57cec5SDimitry Andric 46960b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, integerPart I) 46970b57cec5SDimitry Andric : Semantics(&S), Floats(new APFloat[2]{APFloat(semIEEEdouble, I), 46980b57cec5SDimitry Andric APFloat(semIEEEdouble)}) { 46990b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble); 47000b57cec5SDimitry Andric } 47010b57cec5SDimitry Andric 47020b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, const APInt &I) 47030b57cec5SDimitry Andric : Semantics(&S), 47040b57cec5SDimitry Andric Floats(new APFloat[2]{ 47050b57cec5SDimitry Andric APFloat(semIEEEdouble, APInt(64, I.getRawData()[0])), 47060b57cec5SDimitry Andric APFloat(semIEEEdouble, APInt(64, I.getRawData()[1]))}) { 47070b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble); 47080b57cec5SDimitry Andric } 47090b57cec5SDimitry Andric 47100b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, APFloat &&First, 47110b57cec5SDimitry Andric APFloat &&Second) 47120b57cec5SDimitry Andric : Semantics(&S), 47130b57cec5SDimitry Andric Floats(new APFloat[2]{std::move(First), std::move(Second)}) { 47140b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble); 47150b57cec5SDimitry Andric assert(&Floats[0].getSemantics() == &semIEEEdouble); 47160b57cec5SDimitry Andric assert(&Floats[1].getSemantics() == &semIEEEdouble); 47170b57cec5SDimitry Andric } 47180b57cec5SDimitry Andric 47190b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(const DoubleAPFloat &RHS) 47200b57cec5SDimitry Andric : Semantics(RHS.Semantics), 47210b57cec5SDimitry Andric Floats(RHS.Floats ? new APFloat[2]{APFloat(RHS.Floats[0]), 47220b57cec5SDimitry Andric APFloat(RHS.Floats[1])} 47230b57cec5SDimitry Andric : nullptr) { 47240b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble); 47250b57cec5SDimitry Andric } 47260b57cec5SDimitry Andric 47270b57cec5SDimitry Andric DoubleAPFloat::DoubleAPFloat(DoubleAPFloat &&RHS) 47280b57cec5SDimitry Andric : Semantics(RHS.Semantics), Floats(std::move(RHS.Floats)) { 47290b57cec5SDimitry Andric RHS.Semantics = &semBogus; 47300b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble); 47310b57cec5SDimitry Andric } 47320b57cec5SDimitry Andric 47330b57cec5SDimitry Andric DoubleAPFloat &DoubleAPFloat::operator=(const DoubleAPFloat &RHS) { 47340b57cec5SDimitry Andric if (Semantics == RHS.Semantics && RHS.Floats) { 47350b57cec5SDimitry Andric Floats[0] = RHS.Floats[0]; 47360b57cec5SDimitry Andric Floats[1] = RHS.Floats[1]; 47370b57cec5SDimitry Andric } else if (this != &RHS) { 47380b57cec5SDimitry Andric this->~DoubleAPFloat(); 47390b57cec5SDimitry Andric new (this) DoubleAPFloat(RHS); 47400b57cec5SDimitry Andric } 47410b57cec5SDimitry Andric return *this; 47420b57cec5SDimitry Andric } 47430b57cec5SDimitry Andric 47440b57cec5SDimitry Andric // Implement addition, subtraction, multiplication and division based on: 47450b57cec5SDimitry Andric // "Software for Doubled-Precision Floating-Point Computations", 47460b57cec5SDimitry Andric // by Seppo Linnainmaa, ACM TOMS vol 7 no 3, September 1981, pages 272-283. 47470b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::addImpl(const APFloat &a, const APFloat &aa, 47480b57cec5SDimitry Andric const APFloat &c, const APFloat &cc, 47490b57cec5SDimitry Andric roundingMode RM) { 47500b57cec5SDimitry Andric int Status = opOK; 47510b57cec5SDimitry Andric APFloat z = a; 47520b57cec5SDimitry Andric Status |= z.add(c, RM); 47530b57cec5SDimitry Andric if (!z.isFinite()) { 47540b57cec5SDimitry Andric if (!z.isInfinity()) { 47550b57cec5SDimitry Andric Floats[0] = std::move(z); 47560b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 47570b57cec5SDimitry Andric return (opStatus)Status; 47580b57cec5SDimitry Andric } 47590b57cec5SDimitry Andric Status = opOK; 47600b57cec5SDimitry Andric auto AComparedToC = a.compareAbsoluteValue(c); 47610b57cec5SDimitry Andric z = cc; 47620b57cec5SDimitry Andric Status |= z.add(aa, RM); 47630b57cec5SDimitry Andric if (AComparedToC == APFloat::cmpGreaterThan) { 47640b57cec5SDimitry Andric // z = cc + aa + c + a; 47650b57cec5SDimitry Andric Status |= z.add(c, RM); 47660b57cec5SDimitry Andric Status |= z.add(a, RM); 47670b57cec5SDimitry Andric } else { 47680b57cec5SDimitry Andric // z = cc + aa + a + c; 47690b57cec5SDimitry Andric Status |= z.add(a, RM); 47700b57cec5SDimitry Andric Status |= z.add(c, RM); 47710b57cec5SDimitry Andric } 47720b57cec5SDimitry Andric if (!z.isFinite()) { 47730b57cec5SDimitry Andric Floats[0] = std::move(z); 47740b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 47750b57cec5SDimitry Andric return (opStatus)Status; 47760b57cec5SDimitry Andric } 47770b57cec5SDimitry Andric Floats[0] = z; 47780b57cec5SDimitry Andric APFloat zz = aa; 47790b57cec5SDimitry Andric Status |= zz.add(cc, RM); 47800b57cec5SDimitry Andric if (AComparedToC == APFloat::cmpGreaterThan) { 47810b57cec5SDimitry Andric // Floats[1] = a - z + c + zz; 47820b57cec5SDimitry Andric Floats[1] = a; 47830b57cec5SDimitry Andric Status |= Floats[1].subtract(z, RM); 47840b57cec5SDimitry Andric Status |= Floats[1].add(c, RM); 47850b57cec5SDimitry Andric Status |= Floats[1].add(zz, RM); 47860b57cec5SDimitry Andric } else { 47870b57cec5SDimitry Andric // Floats[1] = c - z + a + zz; 47880b57cec5SDimitry Andric Floats[1] = c; 47890b57cec5SDimitry Andric Status |= Floats[1].subtract(z, RM); 47900b57cec5SDimitry Andric Status |= Floats[1].add(a, RM); 47910b57cec5SDimitry Andric Status |= Floats[1].add(zz, RM); 47920b57cec5SDimitry Andric } 47930b57cec5SDimitry Andric } else { 47940b57cec5SDimitry Andric // q = a - z; 47950b57cec5SDimitry Andric APFloat q = a; 47960b57cec5SDimitry Andric Status |= q.subtract(z, RM); 47970b57cec5SDimitry Andric 47980b57cec5SDimitry Andric // zz = q + c + (a - (q + z)) + aa + cc; 47990b57cec5SDimitry Andric // Compute a - (q + z) as -((q + z) - a) to avoid temporary copies. 48000b57cec5SDimitry Andric auto zz = q; 48010b57cec5SDimitry Andric Status |= zz.add(c, RM); 48020b57cec5SDimitry Andric Status |= q.add(z, RM); 48030b57cec5SDimitry Andric Status |= q.subtract(a, RM); 48040b57cec5SDimitry Andric q.changeSign(); 48050b57cec5SDimitry Andric Status |= zz.add(q, RM); 48060b57cec5SDimitry Andric Status |= zz.add(aa, RM); 48070b57cec5SDimitry Andric Status |= zz.add(cc, RM); 48080b57cec5SDimitry Andric if (zz.isZero() && !zz.isNegative()) { 48090b57cec5SDimitry Andric Floats[0] = std::move(z); 48100b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 48110b57cec5SDimitry Andric return opOK; 48120b57cec5SDimitry Andric } 48130b57cec5SDimitry Andric Floats[0] = z; 48140b57cec5SDimitry Andric Status |= Floats[0].add(zz, RM); 48150b57cec5SDimitry Andric if (!Floats[0].isFinite()) { 48160b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 48170b57cec5SDimitry Andric return (opStatus)Status; 48180b57cec5SDimitry Andric } 48190b57cec5SDimitry Andric Floats[1] = std::move(z); 48200b57cec5SDimitry Andric Status |= Floats[1].subtract(Floats[0], RM); 48210b57cec5SDimitry Andric Status |= Floats[1].add(zz, RM); 48220b57cec5SDimitry Andric } 48230b57cec5SDimitry Andric return (opStatus)Status; 48240b57cec5SDimitry Andric } 48250b57cec5SDimitry Andric 48260b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::addWithSpecial(const DoubleAPFloat &LHS, 48270b57cec5SDimitry Andric const DoubleAPFloat &RHS, 48280b57cec5SDimitry Andric DoubleAPFloat &Out, 48290b57cec5SDimitry Andric roundingMode RM) { 48300b57cec5SDimitry Andric if (LHS.getCategory() == fcNaN) { 48310b57cec5SDimitry Andric Out = LHS; 48320b57cec5SDimitry Andric return opOK; 48330b57cec5SDimitry Andric } 48340b57cec5SDimitry Andric if (RHS.getCategory() == fcNaN) { 48350b57cec5SDimitry Andric Out = RHS; 48360b57cec5SDimitry Andric return opOK; 48370b57cec5SDimitry Andric } 48380b57cec5SDimitry Andric if (LHS.getCategory() == fcZero) { 48390b57cec5SDimitry Andric Out = RHS; 48400b57cec5SDimitry Andric return opOK; 48410b57cec5SDimitry Andric } 48420b57cec5SDimitry Andric if (RHS.getCategory() == fcZero) { 48430b57cec5SDimitry Andric Out = LHS; 48440b57cec5SDimitry Andric return opOK; 48450b57cec5SDimitry Andric } 48460b57cec5SDimitry Andric if (LHS.getCategory() == fcInfinity && RHS.getCategory() == fcInfinity && 48470b57cec5SDimitry Andric LHS.isNegative() != RHS.isNegative()) { 48480b57cec5SDimitry Andric Out.makeNaN(false, Out.isNegative(), nullptr); 48490b57cec5SDimitry Andric return opInvalidOp; 48500b57cec5SDimitry Andric } 48510b57cec5SDimitry Andric if (LHS.getCategory() == fcInfinity) { 48520b57cec5SDimitry Andric Out = LHS; 48530b57cec5SDimitry Andric return opOK; 48540b57cec5SDimitry Andric } 48550b57cec5SDimitry Andric if (RHS.getCategory() == fcInfinity) { 48560b57cec5SDimitry Andric Out = RHS; 48570b57cec5SDimitry Andric return opOK; 48580b57cec5SDimitry Andric } 48590b57cec5SDimitry Andric assert(LHS.getCategory() == fcNormal && RHS.getCategory() == fcNormal); 48600b57cec5SDimitry Andric 48610b57cec5SDimitry Andric APFloat A(LHS.Floats[0]), AA(LHS.Floats[1]), C(RHS.Floats[0]), 48620b57cec5SDimitry Andric CC(RHS.Floats[1]); 48630b57cec5SDimitry Andric assert(&A.getSemantics() == &semIEEEdouble); 48640b57cec5SDimitry Andric assert(&AA.getSemantics() == &semIEEEdouble); 48650b57cec5SDimitry Andric assert(&C.getSemantics() == &semIEEEdouble); 48660b57cec5SDimitry Andric assert(&CC.getSemantics() == &semIEEEdouble); 48670b57cec5SDimitry Andric assert(&Out.Floats[0].getSemantics() == &semIEEEdouble); 48680b57cec5SDimitry Andric assert(&Out.Floats[1].getSemantics() == &semIEEEdouble); 48690b57cec5SDimitry Andric return Out.addImpl(A, AA, C, CC, RM); 48700b57cec5SDimitry Andric } 48710b57cec5SDimitry Andric 48720b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::add(const DoubleAPFloat &RHS, 48730b57cec5SDimitry Andric roundingMode RM) { 48740b57cec5SDimitry Andric return addWithSpecial(*this, RHS, *this, RM); 48750b57cec5SDimitry Andric } 48760b57cec5SDimitry Andric 48770b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::subtract(const DoubleAPFloat &RHS, 48780b57cec5SDimitry Andric roundingMode RM) { 48790b57cec5SDimitry Andric changeSign(); 48800b57cec5SDimitry Andric auto Ret = add(RHS, RM); 48810b57cec5SDimitry Andric changeSign(); 48820b57cec5SDimitry Andric return Ret; 48830b57cec5SDimitry Andric } 48840b57cec5SDimitry Andric 48850b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::multiply(const DoubleAPFloat &RHS, 48860b57cec5SDimitry Andric APFloat::roundingMode RM) { 48870b57cec5SDimitry Andric const auto &LHS = *this; 48880b57cec5SDimitry Andric auto &Out = *this; 48890b57cec5SDimitry Andric /* Interesting observation: For special categories, finding the lowest 48900b57cec5SDimitry Andric common ancestor of the following layered graph gives the correct 48910b57cec5SDimitry Andric return category: 48920b57cec5SDimitry Andric 48930b57cec5SDimitry Andric NaN 48940b57cec5SDimitry Andric / \ 48950b57cec5SDimitry Andric Zero Inf 48960b57cec5SDimitry Andric \ / 48970b57cec5SDimitry Andric Normal 48980b57cec5SDimitry Andric 48990b57cec5SDimitry Andric e.g. NaN * NaN = NaN 49000b57cec5SDimitry Andric Zero * Inf = NaN 49010b57cec5SDimitry Andric Normal * Zero = Zero 49020b57cec5SDimitry Andric Normal * Inf = Inf 49030b57cec5SDimitry Andric */ 49040b57cec5SDimitry Andric if (LHS.getCategory() == fcNaN) { 49050b57cec5SDimitry Andric Out = LHS; 49060b57cec5SDimitry Andric return opOK; 49070b57cec5SDimitry Andric } 49080b57cec5SDimitry Andric if (RHS.getCategory() == fcNaN) { 49090b57cec5SDimitry Andric Out = RHS; 49100b57cec5SDimitry Andric return opOK; 49110b57cec5SDimitry Andric } 49120b57cec5SDimitry Andric if ((LHS.getCategory() == fcZero && RHS.getCategory() == fcInfinity) || 49130b57cec5SDimitry Andric (LHS.getCategory() == fcInfinity && RHS.getCategory() == fcZero)) { 49140b57cec5SDimitry Andric Out.makeNaN(false, false, nullptr); 49150b57cec5SDimitry Andric return opOK; 49160b57cec5SDimitry Andric } 49170b57cec5SDimitry Andric if (LHS.getCategory() == fcZero || LHS.getCategory() == fcInfinity) { 49180b57cec5SDimitry Andric Out = LHS; 49190b57cec5SDimitry Andric return opOK; 49200b57cec5SDimitry Andric } 49210b57cec5SDimitry Andric if (RHS.getCategory() == fcZero || RHS.getCategory() == fcInfinity) { 49220b57cec5SDimitry Andric Out = RHS; 49230b57cec5SDimitry Andric return opOK; 49240b57cec5SDimitry Andric } 49250b57cec5SDimitry Andric assert(LHS.getCategory() == fcNormal && RHS.getCategory() == fcNormal && 49260b57cec5SDimitry Andric "Special cases not handled exhaustively"); 49270b57cec5SDimitry Andric 49280b57cec5SDimitry Andric int Status = opOK; 49290b57cec5SDimitry Andric APFloat A = Floats[0], B = Floats[1], C = RHS.Floats[0], D = RHS.Floats[1]; 49300b57cec5SDimitry Andric // t = a * c 49310b57cec5SDimitry Andric APFloat T = A; 49320b57cec5SDimitry Andric Status |= T.multiply(C, RM); 49330b57cec5SDimitry Andric if (!T.isFiniteNonZero()) { 49340b57cec5SDimitry Andric Floats[0] = T; 49350b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 49360b57cec5SDimitry Andric return (opStatus)Status; 49370b57cec5SDimitry Andric } 49380b57cec5SDimitry Andric 49390b57cec5SDimitry Andric // tau = fmsub(a, c, t), that is -fmadd(-a, c, t). 49400b57cec5SDimitry Andric APFloat Tau = A; 49410b57cec5SDimitry Andric T.changeSign(); 49420b57cec5SDimitry Andric Status |= Tau.fusedMultiplyAdd(C, T, RM); 49430b57cec5SDimitry Andric T.changeSign(); 49440b57cec5SDimitry Andric { 49450b57cec5SDimitry Andric // v = a * d 49460b57cec5SDimitry Andric APFloat V = A; 49470b57cec5SDimitry Andric Status |= V.multiply(D, RM); 49480b57cec5SDimitry Andric // w = b * c 49490b57cec5SDimitry Andric APFloat W = B; 49500b57cec5SDimitry Andric Status |= W.multiply(C, RM); 49510b57cec5SDimitry Andric Status |= V.add(W, RM); 49520b57cec5SDimitry Andric // tau += v + w 49530b57cec5SDimitry Andric Status |= Tau.add(V, RM); 49540b57cec5SDimitry Andric } 49550b57cec5SDimitry Andric // u = t + tau 49560b57cec5SDimitry Andric APFloat U = T; 49570b57cec5SDimitry Andric Status |= U.add(Tau, RM); 49580b57cec5SDimitry Andric 49590b57cec5SDimitry Andric Floats[0] = U; 49600b57cec5SDimitry Andric if (!U.isFinite()) { 49610b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 49620b57cec5SDimitry Andric } else { 49630b57cec5SDimitry Andric // Floats[1] = (t - u) + tau 49640b57cec5SDimitry Andric Status |= T.subtract(U, RM); 49650b57cec5SDimitry Andric Status |= T.add(Tau, RM); 49660b57cec5SDimitry Andric Floats[1] = T; 49670b57cec5SDimitry Andric } 49680b57cec5SDimitry Andric return (opStatus)Status; 49690b57cec5SDimitry Andric } 49700b57cec5SDimitry Andric 49710b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::divide(const DoubleAPFloat &RHS, 49720b57cec5SDimitry Andric APFloat::roundingMode RM) { 49730b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 49740b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); 49750b57cec5SDimitry Andric auto Ret = 49760b57cec5SDimitry Andric Tmp.divide(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()), RM); 49770b57cec5SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); 49780b57cec5SDimitry Andric return Ret; 49790b57cec5SDimitry Andric } 49800b57cec5SDimitry Andric 49810b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::remainder(const DoubleAPFloat &RHS) { 49820b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 49830b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); 49840b57cec5SDimitry Andric auto Ret = 49850b57cec5SDimitry Andric Tmp.remainder(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt())); 49860b57cec5SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); 49870b57cec5SDimitry Andric return Ret; 49880b57cec5SDimitry Andric } 49890b57cec5SDimitry Andric 49900b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::mod(const DoubleAPFloat &RHS) { 49910b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 49920b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); 49930b57cec5SDimitry Andric auto Ret = Tmp.mod(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt())); 49940b57cec5SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); 49950b57cec5SDimitry Andric return Ret; 49960b57cec5SDimitry Andric } 49970b57cec5SDimitry Andric 49980b57cec5SDimitry Andric APFloat::opStatus 49990b57cec5SDimitry Andric DoubleAPFloat::fusedMultiplyAdd(const DoubleAPFloat &Multiplicand, 50000b57cec5SDimitry Andric const DoubleAPFloat &Addend, 50010b57cec5SDimitry Andric APFloat::roundingMode RM) { 50020b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 50030b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); 50040b57cec5SDimitry Andric auto Ret = Tmp.fusedMultiplyAdd( 50050b57cec5SDimitry Andric APFloat(semPPCDoubleDoubleLegacy, Multiplicand.bitcastToAPInt()), 50060b57cec5SDimitry Andric APFloat(semPPCDoubleDoubleLegacy, Addend.bitcastToAPInt()), RM); 50070b57cec5SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); 50080b57cec5SDimitry Andric return Ret; 50090b57cec5SDimitry Andric } 50100b57cec5SDimitry Andric 50110b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::roundToIntegral(APFloat::roundingMode RM) { 50120b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 50130b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); 50140b57cec5SDimitry Andric auto Ret = Tmp.roundToIntegral(RM); 50150b57cec5SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); 50160b57cec5SDimitry Andric return Ret; 50170b57cec5SDimitry Andric } 50180b57cec5SDimitry Andric 50190b57cec5SDimitry Andric void DoubleAPFloat::changeSign() { 50200b57cec5SDimitry Andric Floats[0].changeSign(); 50210b57cec5SDimitry Andric Floats[1].changeSign(); 50220b57cec5SDimitry Andric } 50230b57cec5SDimitry Andric 50240b57cec5SDimitry Andric APFloat::cmpResult 50250b57cec5SDimitry Andric DoubleAPFloat::compareAbsoluteValue(const DoubleAPFloat &RHS) const { 50260b57cec5SDimitry Andric auto Result = Floats[0].compareAbsoluteValue(RHS.Floats[0]); 50270b57cec5SDimitry Andric if (Result != cmpEqual) 50280b57cec5SDimitry Andric return Result; 50290b57cec5SDimitry Andric Result = Floats[1].compareAbsoluteValue(RHS.Floats[1]); 50300b57cec5SDimitry Andric if (Result == cmpLessThan || Result == cmpGreaterThan) { 50310b57cec5SDimitry Andric auto Against = Floats[0].isNegative() ^ Floats[1].isNegative(); 50320b57cec5SDimitry Andric auto RHSAgainst = RHS.Floats[0].isNegative() ^ RHS.Floats[1].isNegative(); 50330b57cec5SDimitry Andric if (Against && !RHSAgainst) 50340b57cec5SDimitry Andric return cmpLessThan; 50350b57cec5SDimitry Andric if (!Against && RHSAgainst) 50360b57cec5SDimitry Andric return cmpGreaterThan; 50370b57cec5SDimitry Andric if (!Against && !RHSAgainst) 50380b57cec5SDimitry Andric return Result; 50390b57cec5SDimitry Andric if (Against && RHSAgainst) 50400b57cec5SDimitry Andric return (cmpResult)(cmpLessThan + cmpGreaterThan - Result); 50410b57cec5SDimitry Andric } 50420b57cec5SDimitry Andric return Result; 50430b57cec5SDimitry Andric } 50440b57cec5SDimitry Andric 50450b57cec5SDimitry Andric APFloat::fltCategory DoubleAPFloat::getCategory() const { 50460b57cec5SDimitry Andric return Floats[0].getCategory(); 50470b57cec5SDimitry Andric } 50480b57cec5SDimitry Andric 50490b57cec5SDimitry Andric bool DoubleAPFloat::isNegative() const { return Floats[0].isNegative(); } 50500b57cec5SDimitry Andric 50510b57cec5SDimitry Andric void DoubleAPFloat::makeInf(bool Neg) { 50520b57cec5SDimitry Andric Floats[0].makeInf(Neg); 50530b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 50540b57cec5SDimitry Andric } 50550b57cec5SDimitry Andric 50560b57cec5SDimitry Andric void DoubleAPFloat::makeZero(bool Neg) { 50570b57cec5SDimitry Andric Floats[0].makeZero(Neg); 50580b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 50590b57cec5SDimitry Andric } 50600b57cec5SDimitry Andric 50610b57cec5SDimitry Andric void DoubleAPFloat::makeLargest(bool Neg) { 50620b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 50630b57cec5SDimitry Andric Floats[0] = APFloat(semIEEEdouble, APInt(64, 0x7fefffffffffffffull)); 50640b57cec5SDimitry Andric Floats[1] = APFloat(semIEEEdouble, APInt(64, 0x7c8ffffffffffffeull)); 50650b57cec5SDimitry Andric if (Neg) 50660b57cec5SDimitry Andric changeSign(); 50670b57cec5SDimitry Andric } 50680b57cec5SDimitry Andric 50690b57cec5SDimitry Andric void DoubleAPFloat::makeSmallest(bool Neg) { 50700b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 50710b57cec5SDimitry Andric Floats[0].makeSmallest(Neg); 50720b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 50730b57cec5SDimitry Andric } 50740b57cec5SDimitry Andric 50750b57cec5SDimitry Andric void DoubleAPFloat::makeSmallestNormalized(bool Neg) { 50760b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 50770b57cec5SDimitry Andric Floats[0] = APFloat(semIEEEdouble, APInt(64, 0x0360000000000000ull)); 50780b57cec5SDimitry Andric if (Neg) 50790b57cec5SDimitry Andric Floats[0].changeSign(); 50800b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 50810b57cec5SDimitry Andric } 50820b57cec5SDimitry Andric 50830b57cec5SDimitry Andric void DoubleAPFloat::makeNaN(bool SNaN, bool Neg, const APInt *fill) { 50840b57cec5SDimitry Andric Floats[0].makeNaN(SNaN, Neg, fill); 50850b57cec5SDimitry Andric Floats[1].makeZero(/* Neg = */ false); 50860b57cec5SDimitry Andric } 50870b57cec5SDimitry Andric 50880b57cec5SDimitry Andric APFloat::cmpResult DoubleAPFloat::compare(const DoubleAPFloat &RHS) const { 50890b57cec5SDimitry Andric auto Result = Floats[0].compare(RHS.Floats[0]); 50900b57cec5SDimitry Andric // |Float[0]| > |Float[1]| 50910b57cec5SDimitry Andric if (Result == APFloat::cmpEqual) 50920b57cec5SDimitry Andric return Floats[1].compare(RHS.Floats[1]); 50930b57cec5SDimitry Andric return Result; 50940b57cec5SDimitry Andric } 50950b57cec5SDimitry Andric 50960b57cec5SDimitry Andric bool DoubleAPFloat::bitwiseIsEqual(const DoubleAPFloat &RHS) const { 50970b57cec5SDimitry Andric return Floats[0].bitwiseIsEqual(RHS.Floats[0]) && 50980b57cec5SDimitry Andric Floats[1].bitwiseIsEqual(RHS.Floats[1]); 50990b57cec5SDimitry Andric } 51000b57cec5SDimitry Andric 51010b57cec5SDimitry Andric hash_code hash_value(const DoubleAPFloat &Arg) { 51020b57cec5SDimitry Andric if (Arg.Floats) 51030b57cec5SDimitry Andric return hash_combine(hash_value(Arg.Floats[0]), hash_value(Arg.Floats[1])); 51040b57cec5SDimitry Andric return hash_combine(Arg.Semantics); 51050b57cec5SDimitry Andric } 51060b57cec5SDimitry Andric 51070b57cec5SDimitry Andric APInt DoubleAPFloat::bitcastToAPInt() const { 51080b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 51090b57cec5SDimitry Andric uint64_t Data[] = { 51100b57cec5SDimitry Andric Floats[0].bitcastToAPInt().getRawData()[0], 51110b57cec5SDimitry Andric Floats[1].bitcastToAPInt().getRawData()[0], 51120b57cec5SDimitry Andric }; 51130b57cec5SDimitry Andric return APInt(128, 2, Data); 51140b57cec5SDimitry Andric } 51150b57cec5SDimitry Andric 5116480093f4SDimitry Andric Expected<APFloat::opStatus> DoubleAPFloat::convertFromString(StringRef S, 51170b57cec5SDimitry Andric roundingMode RM) { 51180b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 51190b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy); 51200b57cec5SDimitry Andric auto Ret = Tmp.convertFromString(S, RM); 51210b57cec5SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); 51220b57cec5SDimitry Andric return Ret; 51230b57cec5SDimitry Andric } 51240b57cec5SDimitry Andric 51250b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::next(bool nextDown) { 51260b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 51270b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); 51280b57cec5SDimitry Andric auto Ret = Tmp.next(nextDown); 51290b57cec5SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); 51300b57cec5SDimitry Andric return Ret; 51310b57cec5SDimitry Andric } 51320b57cec5SDimitry Andric 51330b57cec5SDimitry Andric APFloat::opStatus 51340b57cec5SDimitry Andric DoubleAPFloat::convertToInteger(MutableArrayRef<integerPart> Input, 51350b57cec5SDimitry Andric unsigned int Width, bool IsSigned, 51360b57cec5SDimitry Andric roundingMode RM, bool *IsExact) const { 51370b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 51380b57cec5SDimitry Andric return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt()) 51390b57cec5SDimitry Andric .convertToInteger(Input, Width, IsSigned, RM, IsExact); 51400b57cec5SDimitry Andric } 51410b57cec5SDimitry Andric 51420b57cec5SDimitry Andric APFloat::opStatus DoubleAPFloat::convertFromAPInt(const APInt &Input, 51430b57cec5SDimitry Andric bool IsSigned, 51440b57cec5SDimitry Andric roundingMode RM) { 51450b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 51460b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy); 51470b57cec5SDimitry Andric auto Ret = Tmp.convertFromAPInt(Input, IsSigned, RM); 51480b57cec5SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); 51490b57cec5SDimitry Andric return Ret; 51500b57cec5SDimitry Andric } 51510b57cec5SDimitry Andric 51520b57cec5SDimitry Andric APFloat::opStatus 51530b57cec5SDimitry Andric DoubleAPFloat::convertFromSignExtendedInteger(const integerPart *Input, 51540b57cec5SDimitry Andric unsigned int InputSize, 51550b57cec5SDimitry Andric bool IsSigned, roundingMode RM) { 51560b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 51570b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy); 51580b57cec5SDimitry Andric auto Ret = Tmp.convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM); 51590b57cec5SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); 51600b57cec5SDimitry Andric return Ret; 51610b57cec5SDimitry Andric } 51620b57cec5SDimitry Andric 51630b57cec5SDimitry Andric APFloat::opStatus 51640b57cec5SDimitry Andric DoubleAPFloat::convertFromZeroExtendedInteger(const integerPart *Input, 51650b57cec5SDimitry Andric unsigned int InputSize, 51660b57cec5SDimitry Andric bool IsSigned, roundingMode RM) { 51670b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 51680b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy); 51690b57cec5SDimitry Andric auto Ret = Tmp.convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM); 51700b57cec5SDimitry Andric *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); 51710b57cec5SDimitry Andric return Ret; 51720b57cec5SDimitry Andric } 51730b57cec5SDimitry Andric 51740b57cec5SDimitry Andric unsigned int DoubleAPFloat::convertToHexString(char *DST, 51750b57cec5SDimitry Andric unsigned int HexDigits, 51760b57cec5SDimitry Andric bool UpperCase, 51770b57cec5SDimitry Andric roundingMode RM) const { 51780b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 51790b57cec5SDimitry Andric return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt()) 51800b57cec5SDimitry Andric .convertToHexString(DST, HexDigits, UpperCase, RM); 51810b57cec5SDimitry Andric } 51820b57cec5SDimitry Andric 51830b57cec5SDimitry Andric bool DoubleAPFloat::isDenormal() const { 51840b57cec5SDimitry Andric return getCategory() == fcNormal && 51850b57cec5SDimitry Andric (Floats[0].isDenormal() || Floats[1].isDenormal() || 51860b57cec5SDimitry Andric // (double)(Hi + Lo) == Hi defines a normal number. 51875ffd83dbSDimitry Andric Floats[0] != Floats[0] + Floats[1]); 51880b57cec5SDimitry Andric } 51890b57cec5SDimitry Andric 51900b57cec5SDimitry Andric bool DoubleAPFloat::isSmallest() const { 51910b57cec5SDimitry Andric if (getCategory() != fcNormal) 51920b57cec5SDimitry Andric return false; 51930b57cec5SDimitry Andric DoubleAPFloat Tmp(*this); 51940b57cec5SDimitry Andric Tmp.makeSmallest(this->isNegative()); 51950b57cec5SDimitry Andric return Tmp.compare(*this) == cmpEqual; 51960b57cec5SDimitry Andric } 51970b57cec5SDimitry Andric 5198bdd1243dSDimitry Andric bool DoubleAPFloat::isSmallestNormalized() const { 5199bdd1243dSDimitry Andric if (getCategory() != fcNormal) 5200bdd1243dSDimitry Andric return false; 5201bdd1243dSDimitry Andric 5202bdd1243dSDimitry Andric DoubleAPFloat Tmp(*this); 5203bdd1243dSDimitry Andric Tmp.makeSmallestNormalized(this->isNegative()); 5204bdd1243dSDimitry Andric return Tmp.compare(*this) == cmpEqual; 5205bdd1243dSDimitry Andric } 5206bdd1243dSDimitry Andric 52070b57cec5SDimitry Andric bool DoubleAPFloat::isLargest() const { 52080b57cec5SDimitry Andric if (getCategory() != fcNormal) 52090b57cec5SDimitry Andric return false; 52100b57cec5SDimitry Andric DoubleAPFloat Tmp(*this); 52110b57cec5SDimitry Andric Tmp.makeLargest(this->isNegative()); 52120b57cec5SDimitry Andric return Tmp.compare(*this) == cmpEqual; 52130b57cec5SDimitry Andric } 52140b57cec5SDimitry Andric 52150b57cec5SDimitry Andric bool DoubleAPFloat::isInteger() const { 52160b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 52170b57cec5SDimitry Andric return Floats[0].isInteger() && Floats[1].isInteger(); 52180b57cec5SDimitry Andric } 52190b57cec5SDimitry Andric 52200b57cec5SDimitry Andric void DoubleAPFloat::toString(SmallVectorImpl<char> &Str, 52210b57cec5SDimitry Andric unsigned FormatPrecision, 52220b57cec5SDimitry Andric unsigned FormatMaxPadding, 52230b57cec5SDimitry Andric bool TruncateZero) const { 52240b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 52250b57cec5SDimitry Andric APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt()) 52260b57cec5SDimitry Andric .toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero); 52270b57cec5SDimitry Andric } 52280b57cec5SDimitry Andric 52290b57cec5SDimitry Andric bool DoubleAPFloat::getExactInverse(APFloat *inv) const { 52300b57cec5SDimitry Andric assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 52310b57cec5SDimitry Andric APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); 52320b57cec5SDimitry Andric if (!inv) 52330b57cec5SDimitry Andric return Tmp.getExactInverse(nullptr); 52340b57cec5SDimitry Andric APFloat Inv(semPPCDoubleDoubleLegacy); 52350b57cec5SDimitry Andric auto Ret = Tmp.getExactInverse(&Inv); 52360b57cec5SDimitry Andric *inv = APFloat(semPPCDoubleDouble, Inv.bitcastToAPInt()); 52370b57cec5SDimitry Andric return Ret; 52380b57cec5SDimitry Andric } 52390b57cec5SDimitry Andric 52405f757f3fSDimitry Andric int DoubleAPFloat::getExactLog2() const { 52415f757f3fSDimitry Andric // TODO: Implement me 52425f757f3fSDimitry Andric return INT_MIN; 52435f757f3fSDimitry Andric } 52445f757f3fSDimitry Andric 52455f757f3fSDimitry Andric int DoubleAPFloat::getExactLog2Abs() const { 52465f757f3fSDimitry Andric // TODO: Implement me 52475f757f3fSDimitry Andric return INT_MIN; 52485f757f3fSDimitry Andric } 52495f757f3fSDimitry Andric 5250fe6060f1SDimitry Andric DoubleAPFloat scalbn(const DoubleAPFloat &Arg, int Exp, 5251fe6060f1SDimitry Andric APFloat::roundingMode RM) { 52520b57cec5SDimitry Andric assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 52530b57cec5SDimitry Andric return DoubleAPFloat(semPPCDoubleDouble, scalbn(Arg.Floats[0], Exp, RM), 52540b57cec5SDimitry Andric scalbn(Arg.Floats[1], Exp, RM)); 52550b57cec5SDimitry Andric } 52560b57cec5SDimitry Andric 52570b57cec5SDimitry Andric DoubleAPFloat frexp(const DoubleAPFloat &Arg, int &Exp, 52580b57cec5SDimitry Andric APFloat::roundingMode RM) { 52590b57cec5SDimitry Andric assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); 52600b57cec5SDimitry Andric APFloat First = frexp(Arg.Floats[0], Exp, RM); 52610b57cec5SDimitry Andric APFloat Second = Arg.Floats[1]; 52620b57cec5SDimitry Andric if (Arg.getCategory() == APFloat::fcNormal) 52630b57cec5SDimitry Andric Second = scalbn(Second, -Exp, RM); 52640b57cec5SDimitry Andric return DoubleAPFloat(semPPCDoubleDouble, std::move(First), std::move(Second)); 52650b57cec5SDimitry Andric } 52660b57cec5SDimitry Andric 5267fe6060f1SDimitry Andric } // namespace detail 52680b57cec5SDimitry Andric 52690b57cec5SDimitry Andric APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) { 52700b57cec5SDimitry Andric if (usesLayout<IEEEFloat>(Semantics)) { 52710b57cec5SDimitry Andric new (&IEEE) IEEEFloat(std::move(F)); 52720b57cec5SDimitry Andric return; 52730b57cec5SDimitry Andric } 52740b57cec5SDimitry Andric if (usesLayout<DoubleAPFloat>(Semantics)) { 52750b57cec5SDimitry Andric const fltSemantics& S = F.getSemantics(); 52760b57cec5SDimitry Andric new (&Double) 52770b57cec5SDimitry Andric DoubleAPFloat(Semantics, APFloat(std::move(F), S), 52780b57cec5SDimitry Andric APFloat(semIEEEdouble)); 52790b57cec5SDimitry Andric return; 52800b57cec5SDimitry Andric } 52810b57cec5SDimitry Andric llvm_unreachable("Unexpected semantics"); 52820b57cec5SDimitry Andric } 52830b57cec5SDimitry Andric 5284480093f4SDimitry Andric Expected<APFloat::opStatus> APFloat::convertFromString(StringRef Str, 5285480093f4SDimitry Andric roundingMode RM) { 52860b57cec5SDimitry Andric APFLOAT_DISPATCH_ON_SEMANTICS(convertFromString(Str, RM)); 52870b57cec5SDimitry Andric } 52880b57cec5SDimitry Andric 52890b57cec5SDimitry Andric hash_code hash_value(const APFloat &Arg) { 52900b57cec5SDimitry Andric if (APFloat::usesLayout<detail::IEEEFloat>(Arg.getSemantics())) 52910b57cec5SDimitry Andric return hash_value(Arg.U.IEEE); 52920b57cec5SDimitry Andric if (APFloat::usesLayout<detail::DoubleAPFloat>(Arg.getSemantics())) 52930b57cec5SDimitry Andric return hash_value(Arg.U.Double); 52940b57cec5SDimitry Andric llvm_unreachable("Unexpected semantics"); 52950b57cec5SDimitry Andric } 52960b57cec5SDimitry Andric 52970b57cec5SDimitry Andric APFloat::APFloat(const fltSemantics &Semantics, StringRef S) 52980b57cec5SDimitry Andric : APFloat(Semantics) { 5299480093f4SDimitry Andric auto StatusOrErr = convertFromString(S, rmNearestTiesToEven); 5300480093f4SDimitry Andric assert(StatusOrErr && "Invalid floating point representation"); 5301480093f4SDimitry Andric consumeError(StatusOrErr.takeError()); 53020b57cec5SDimitry Andric } 53030b57cec5SDimitry Andric 530406c3fb27SDimitry Andric FPClassTest APFloat::classify() const { 530506c3fb27SDimitry Andric if (isZero()) 530606c3fb27SDimitry Andric return isNegative() ? fcNegZero : fcPosZero; 530706c3fb27SDimitry Andric if (isNormal()) 530806c3fb27SDimitry Andric return isNegative() ? fcNegNormal : fcPosNormal; 530906c3fb27SDimitry Andric if (isDenormal()) 531006c3fb27SDimitry Andric return isNegative() ? fcNegSubnormal : fcPosSubnormal; 531106c3fb27SDimitry Andric if (isInfinity()) 531206c3fb27SDimitry Andric return isNegative() ? fcNegInf : fcPosInf; 531306c3fb27SDimitry Andric assert(isNaN() && "Other class of FP constant"); 531406c3fb27SDimitry Andric return isSignaling() ? fcSNan : fcQNan; 531506c3fb27SDimitry Andric } 531606c3fb27SDimitry Andric 53170b57cec5SDimitry Andric APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics, 53180b57cec5SDimitry Andric roundingMode RM, bool *losesInfo) { 53190b57cec5SDimitry Andric if (&getSemantics() == &ToSemantics) { 53200b57cec5SDimitry Andric *losesInfo = false; 53210b57cec5SDimitry Andric return opOK; 53220b57cec5SDimitry Andric } 53230b57cec5SDimitry Andric if (usesLayout<IEEEFloat>(getSemantics()) && 53240b57cec5SDimitry Andric usesLayout<IEEEFloat>(ToSemantics)) 53250b57cec5SDimitry Andric return U.IEEE.convert(ToSemantics, RM, losesInfo); 53260b57cec5SDimitry Andric if (usesLayout<IEEEFloat>(getSemantics()) && 53270b57cec5SDimitry Andric usesLayout<DoubleAPFloat>(ToSemantics)) { 53280b57cec5SDimitry Andric assert(&ToSemantics == &semPPCDoubleDouble); 53290b57cec5SDimitry Andric auto Ret = U.IEEE.convert(semPPCDoubleDoubleLegacy, RM, losesInfo); 53300b57cec5SDimitry Andric *this = APFloat(ToSemantics, U.IEEE.bitcastToAPInt()); 53310b57cec5SDimitry Andric return Ret; 53320b57cec5SDimitry Andric } 53330b57cec5SDimitry Andric if (usesLayout<DoubleAPFloat>(getSemantics()) && 53340b57cec5SDimitry Andric usesLayout<IEEEFloat>(ToSemantics)) { 53350b57cec5SDimitry Andric auto Ret = getIEEE().convert(ToSemantics, RM, losesInfo); 53360b57cec5SDimitry Andric *this = APFloat(std::move(getIEEE()), ToSemantics); 53370b57cec5SDimitry Andric return Ret; 53380b57cec5SDimitry Andric } 53390b57cec5SDimitry Andric llvm_unreachable("Unexpected semantics"); 53400b57cec5SDimitry Andric } 53410b57cec5SDimitry Andric 5342349cc55cSDimitry Andric APFloat APFloat::getAllOnesValue(const fltSemantics &Semantics) { 5343349cc55cSDimitry Andric return APFloat(Semantics, APInt::getAllOnes(Semantics.sizeInBits)); 53440b57cec5SDimitry Andric } 53450b57cec5SDimitry Andric 53460b57cec5SDimitry Andric void APFloat::print(raw_ostream &OS) const { 53470b57cec5SDimitry Andric SmallVector<char, 16> Buffer; 53480b57cec5SDimitry Andric toString(Buffer); 53490b57cec5SDimitry Andric OS << Buffer << "\n"; 53500b57cec5SDimitry Andric } 53510b57cec5SDimitry Andric 53520b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 53530b57cec5SDimitry Andric LLVM_DUMP_METHOD void APFloat::dump() const { print(dbgs()); } 53540b57cec5SDimitry Andric #endif 53550b57cec5SDimitry Andric 53560b57cec5SDimitry Andric void APFloat::Profile(FoldingSetNodeID &NID) const { 53570b57cec5SDimitry Andric NID.Add(bitcastToAPInt()); 53580b57cec5SDimitry Andric } 53590b57cec5SDimitry Andric 53600b57cec5SDimitry Andric /* Same as convertToInteger(integerPart*, ...), except the result is returned in 53610b57cec5SDimitry Andric an APSInt, whose initial bit-width and signed-ness are used to determine the 53620b57cec5SDimitry Andric precision of the conversion. 53630b57cec5SDimitry Andric */ 53640b57cec5SDimitry Andric APFloat::opStatus APFloat::convertToInteger(APSInt &result, 53650b57cec5SDimitry Andric roundingMode rounding_mode, 53660b57cec5SDimitry Andric bool *isExact) const { 53670b57cec5SDimitry Andric unsigned bitWidth = result.getBitWidth(); 53680b57cec5SDimitry Andric SmallVector<uint64_t, 4> parts(result.getNumWords()); 53690b57cec5SDimitry Andric opStatus status = convertToInteger(parts, bitWidth, result.isSigned(), 53700b57cec5SDimitry Andric rounding_mode, isExact); 53710b57cec5SDimitry Andric // Keeps the original signed-ness. 53720b57cec5SDimitry Andric result = APInt(bitWidth, parts); 53730b57cec5SDimitry Andric return status; 53740b57cec5SDimitry Andric } 53750b57cec5SDimitry Andric 5376fe6060f1SDimitry Andric double APFloat::convertToDouble() const { 5377fe6060f1SDimitry Andric if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEdouble) 5378fe6060f1SDimitry Andric return getIEEE().convertToDouble(); 5379fe6060f1SDimitry Andric assert(getSemantics().isRepresentableBy(semIEEEdouble) && 5380fe6060f1SDimitry Andric "Float semantics is not representable by IEEEdouble"); 5381fe6060f1SDimitry Andric APFloat Temp = *this; 5382fe6060f1SDimitry Andric bool LosesInfo; 5383fe6060f1SDimitry Andric opStatus St = Temp.convert(semIEEEdouble, rmNearestTiesToEven, &LosesInfo); 5384fe6060f1SDimitry Andric assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision"); 5385fe6060f1SDimitry Andric (void)St; 5386fe6060f1SDimitry Andric return Temp.getIEEE().convertToDouble(); 5387fe6060f1SDimitry Andric } 5388fe6060f1SDimitry Andric 5389*0fca6ea1SDimitry Andric #ifdef HAS_IEE754_FLOAT128 5390*0fca6ea1SDimitry Andric float128 APFloat::convertToQuad() const { 5391*0fca6ea1SDimitry Andric if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEquad) 5392*0fca6ea1SDimitry Andric return getIEEE().convertToQuad(); 5393*0fca6ea1SDimitry Andric assert(getSemantics().isRepresentableBy(semIEEEquad) && 5394*0fca6ea1SDimitry Andric "Float semantics is not representable by IEEEquad"); 5395*0fca6ea1SDimitry Andric APFloat Temp = *this; 5396*0fca6ea1SDimitry Andric bool LosesInfo; 5397*0fca6ea1SDimitry Andric opStatus St = Temp.convert(semIEEEquad, rmNearestTiesToEven, &LosesInfo); 5398*0fca6ea1SDimitry Andric assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision"); 5399*0fca6ea1SDimitry Andric (void)St; 5400*0fca6ea1SDimitry Andric return Temp.getIEEE().convertToQuad(); 5401*0fca6ea1SDimitry Andric } 5402*0fca6ea1SDimitry Andric #endif 5403*0fca6ea1SDimitry Andric 5404fe6060f1SDimitry Andric float APFloat::convertToFloat() const { 5405fe6060f1SDimitry Andric if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) 5406fe6060f1SDimitry Andric return getIEEE().convertToFloat(); 5407fe6060f1SDimitry Andric assert(getSemantics().isRepresentableBy(semIEEEsingle) && 5408fe6060f1SDimitry Andric "Float semantics is not representable by IEEEsingle"); 5409fe6060f1SDimitry Andric APFloat Temp = *this; 5410fe6060f1SDimitry Andric bool LosesInfo; 5411fe6060f1SDimitry Andric opStatus St = Temp.convert(semIEEEsingle, rmNearestTiesToEven, &LosesInfo); 5412fe6060f1SDimitry Andric assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision"); 5413fe6060f1SDimitry Andric (void)St; 5414fe6060f1SDimitry Andric return Temp.getIEEE().convertToFloat(); 5415fe6060f1SDimitry Andric } 5416fe6060f1SDimitry Andric 5417e8d8bef9SDimitry Andric } // namespace llvm 54180b57cec5SDimitry Andric 54190b57cec5SDimitry Andric #undef APFLOAT_DISPATCH_ON_SEMANTICS 5420