X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FAPFloat.h;h=29a89dd06c2d53acc14b42ec1e950f1acef7701a;hb=6de603071879bdc5d7d663826354c24a9d176469;hp=d62b5c20c6548920eb761ad1a71e5d37419445fd;hpb=33d4c92e78a32a8e07ab3ebc1487b07304875ddd;p=oota-llvm.git diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index d62b5c20c65..29a89dd06c2 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -2,8 +2,8 @@ // // 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. // //===----------------------------------------------------------------------===// // @@ -60,7 +60,10 @@ 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 @@ -83,13 +86,12 @@ 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. @@ -100,7 +102,6 @@ // APInt contains static functions implementing bignum arithmetic. #include "llvm/ADT/APInt.h" -#include "llvm/CodeGen/ValueTypes.h" namespace llvm { @@ -112,11 +113,11 @@ namespace llvm { /* 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 { @@ -126,8 +127,9 @@ namespace llvm { static const fltSemantics IEEEsingle; static const fltSemantics IEEEdouble; 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; @@ -150,8 +152,8 @@ namespace llvm { 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, @@ -161,7 +163,7 @@ namespace llvm { opInexact = 0x10 }; - /* Category of internally-represented number. */ + // Category of internally-represented number. enum fltCategory { fcInfinity, fcNaN, @@ -169,35 +171,65 @@ namespace llvm { fcZero }; - /* Constructors. */ + // Constructors. APFloat(const fltSemantics &, const char *); APFloat(const fltSemantics &, integerPart); APFloat(const fltSemantics &, fltCategory, bool negative); explicit APFloat(double d); explicit APFloat(float f); - explicit APFloat(const APInt &); + 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); + } + static APFloat getNaN(const fltSemantics &Sem, bool Negative = false) { + return APFloat(Sem, fcNaN, Negative); + } + + /// 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; - opStatus convertFromInteger(const integerPart *, unsigned int, bool, - roundingMode); + 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; + APInt bitcastToAPInt() const; double convertToDouble() const; float convertToFloat() const; @@ -210,6 +242,9 @@ namespace llvm { 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, @@ -217,14 +252,13 @@ namespace llvm { 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(); } @@ -259,25 +293,35 @@ namespace llvm { opStatus addOrSubtractSpecials(const APFloat &, bool subtract); opStatus divideSpecials(const APFloat &); opStatus multiplySpecials(const APFloat &); + opStatus modSpecials(const APFloat &); /* Miscellany. */ + void makeNaN(void); 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 convertFromUnsignedInteger(integerPart *, unsigned int, - roundingMode); + opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool, + roundingMode, bool *) const; + opStatus convertFromUnsignedParts(const integerPart *, unsigned int, + roundingMode); opStatus convertFromHexadecimalString(const char *, roundingMode); + opStatus convertFromDecimalString (const char *, roundingMode); char *convertNormalToHexString(char *, unsigned int, bool, roundingMode) const; + opStatus roundSignificandWithExponent(const integerPart *, unsigned int, + int, roundingMode); + APInt convertFloatAPFloatToAPInt() const; APInt convertDoubleAPFloatToAPInt() const; APInt convertF80LongDoubleAPFloatToAPInt() const; - void initFromAPInt(const APInt& api); + APInt convertPPCDoubleDoubleAPFloatToAPInt() const; + void initFromAPInt(const APInt& api, bool isIEEE = false); void initFromFloatAPInt(const APInt& api); void initFromDoubleAPInt(const APInt& api); void initFromF80LongDoubleAPInt(const APInt& api); + void initFromPPCDoubleDoubleAPInt(const APInt& api); void assign(const APFloat &); void copySignificand(const APFloat &); @@ -304,6 +348,13 @@ namespace llvm { /* The sign bit of this number. */ unsigned int sign: 1; + + /* For PPCDoubleDouble, we have a second exponent and sign (the second + significand is appended to the first one, although it would be wrong to + regard these as a single number for arithmetic purposes). These fields + are not meaningful for any other type. */ + exponent_t exponent2 : 11; + unsigned int sign2: 1; }; } /* namespace llvm */