//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Neil Booth and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
if the requested precision is less than the natural precision the
output is correctly rounded for the specified rounding mode.
- Conversion to and from decimal text is not currently implemented.
+ It also reads decimal floating point numbers and correctly rounds
+ according to the specified rounding mode.
+
+ Conversion to decimal text is not currently implemented.
Non-zero finite numbers are represented internally as a sign bit,
a 16-bit signed exponent, and the significand as an array of
Some features that may or may not be worth adding:
- Conversions to and from decimal strings (hard).
+ Binary to decimal conversion (hard).
Optional ability to detect underflow tininess before rounding.
New formats: x87 in single and double precision mode (IEEE apart
- from extended exponent range) and IBM two-double extended
- precision (hard).
+ from extended exponent range) (hard).
New operations: sqrt, IEEE remainder, C90 fmod, nextafter,
nexttoward.
// APInt contains static functions implementing bignum arithmetic.
#include "llvm/ADT/APInt.h"
-#include "llvm/CodeGen/ValueTypes.h"
namespace llvm {
typedef signed short exponent_t;
struct fltSemantics;
+ class StringRef;
/* When bits of a floating point number are truncated, this enum is
used to indicate what fraction of the LSB those bits represented.
It essentially combines the roles of guard and sticky bits. */
- enum lostFraction { // Example of truncated bits:
- lfExactlyZero, // 000000
- lfLessThanHalf, // 0xxxxx x's not all zero
- lfExactlyHalf, // 100000
- lfMoreThanHalf // 1xxxxx x's not all zero
+ enum lostFraction { // Example of truncated bits:
+ lfExactlyZero, // 000000
+ lfLessThanHalf, // 0xxxxx x's not all zero
+ lfExactlyHalf, // 100000
+ lfMoreThanHalf // 1xxxxx x's not all zero
};
class APFloat {
static const fltSemantics IEEEquad;
static const fltSemantics PPCDoubleDouble;
static const fltSemantics x87DoubleExtended;
- /* And this psuedo, used to construct APFloats that cannot
+ /* And this pseudo, used to construct APFloats that cannot
conflict with anything real. */
static const fltSemantics Bogus;
rmNearestTiesToAway
};
- /* Operation status. opUnderflow or opOverflow are always returned
- or-ed with opInexact. */
+ // Operation status. opUnderflow or opOverflow are always returned
+ // or-ed with opInexact.
enum opStatus {
opOK = 0x00,
opInvalidOp = 0x01,
opInexact = 0x10
};
- /* Category of internally-represented number. */
+ // Category of internally-represented number.
enum fltCategory {
fcInfinity,
fcNaN,
fcZero
};
- /* Constructors. */
- APFloat(const fltSemantics &, const char *);
+ // Constructors.
+ APFloat(const fltSemantics &, const StringRef &);
APFloat(const fltSemantics &, integerPart);
- APFloat(const fltSemantics &, fltCategory, bool negative);
+ APFloat(const fltSemantics &, fltCategory, bool negative, unsigned type=0);
explicit APFloat(double d);
explicit APFloat(float f);
explicit APFloat(const APInt &, bool isIEEE = false);
APFloat(const APFloat &);
~APFloat();
+ // Convenience "constructors"
+ static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
+ return APFloat(Sem, fcZero, Negative);
+ }
+ static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
+ return APFloat(Sem, fcInfinity, Negative);
+ }
+ /// getNaN - Factory for QNaN values.
+ ///
+ /// \param Negative - True iff the NaN generated should be negative.
+ /// \param type - The unspecified fill bits for creating the NaN, 0 by
+ /// default. The value is truncated as necessary.
+ static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
+ unsigned type = 0) {
+ return APFloat(Sem, fcNaN, Negative, type);
+ }
+
+ /// Profile - Used to insert APFloat objects, or objects that contain
+ /// APFloat objects, into FoldingSets.
+ void Profile(FoldingSetNodeID& NID) const;
+
+ /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
+ void Emit(Serializer& S) const;
+
+ /// @brief Used by the Bitcode deserializer to deserialize APInts.
+ static APFloat ReadVal(Deserializer& D);
+
/* Arithmetic. */
opStatus add(const APFloat &, roundingMode);
opStatus subtract(const APFloat &, roundingMode);
opStatus multiply(const APFloat &, roundingMode);
opStatus divide(const APFloat &, roundingMode);
+ /* IEEE remainder. */
+ opStatus remainder(const APFloat &);
+ /* C fmod, or llvm frem. */
opStatus mod(const APFloat &, roundingMode);
- void copySign(const APFloat &);
opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
- void changeSign(); // neg
- void clearSign(); // abs
+
+ /* Sign operations. */
+ void changeSign();
+ void clearSign();
+ void copySign(const APFloat &);
/* Conversions. */
- opStatus convert(const fltSemantics &, roundingMode);
+ opStatus convert(const fltSemantics &, roundingMode, bool *);
opStatus convertToInteger(integerPart *, unsigned int, bool,
- roundingMode) const;
+ roundingMode, bool *) const;
+ opStatus convertFromAPInt(const APInt &,
+ bool, roundingMode);
opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
bool, roundingMode);
opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
bool, roundingMode);
- opStatus convertFromString(const char *, roundingMode);
- APInt convertToAPInt() const;
+ opStatus convertFromString(const StringRef&, roundingMode);
+ APInt bitcastToAPInt() const;
double convertToDouble() const;
float convertToFloat() const;
compare unordered, 0==-0). */
cmpResult compare(const APFloat &) const;
+ /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */
+ bool bitwiseIsEqual(const APFloat &) const;
+
/* Write out a hexadecimal representation of the floating point
value to DST, which must be of sufficient size, in the C99 form
[-]0xh.hhhhp[+-]d. Return the number of characters written,
unsigned int convertToHexString(char *dst, unsigned int hexDigits,
bool upperCase, roundingMode) const;
- /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */
- bool bitwiseIsEqual(const APFloat &) const;
-
/* Simple queries. */
fltCategory getCategory() const { return category; }
const fltSemantics &getSemantics() const { return *semantics; }
bool isZero() const { return category == fcZero; }
bool isNonZero() const { return category != fcZero; }
+ bool isNaN() const { return category == fcNaN; }
+ bool isInfinity() const { return category == fcInfinity; }
bool isNegative() const { return sign; }
bool isPosZero() const { return isZero() && !isNegative(); }
bool isNegZero() const { return isZero() && isNegative(); }
opStatus addOrSubtractSpecials(const APFloat &, bool subtract);
opStatus divideSpecials(const APFloat &);
opStatus multiplySpecials(const APFloat &);
+ opStatus modSpecials(const APFloat &);
/* Miscellany. */
+ void makeNaN(unsigned = 0);
opStatus normalize(roundingMode, lostFraction);
opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
cmpResult compareAbsoluteValue(const APFloat &) const;
opStatus handleOverflow(roundingMode);
bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
+ opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
+ roundingMode, bool *) const;
opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
roundingMode);
- opStatus convertFromHexadecimalString(const char *, roundingMode);
+ opStatus convertFromHexadecimalString(const StringRef&, roundingMode);
+ opStatus convertFromDecimalString (const StringRef&, roundingMode);
char *convertNormalToHexString(char *, unsigned int, bool,
roundingMode) const;
+ opStatus roundSignificandWithExponent(const integerPart *, unsigned int,
+ int, roundingMode);
+
APInt convertFloatAPFloatToAPInt() const;
APInt convertDoubleAPFloatToAPInt() const;
+ APInt convertQuadrupleAPFloatToAPInt() const;
APInt convertF80LongDoubleAPFloatToAPInt() const;
APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
void initFromAPInt(const APInt& api, bool isIEEE = false);
void initFromFloatAPInt(const APInt& api);
void initFromDoubleAPInt(const APInt& api);
+ void initFromQuadrupleAPInt(const APInt &api);
void initFromF80LongDoubleAPInt(const APInt& api);
void initFromPPCDoubleDoubleAPInt(const APInt& api);