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