mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-17 08:36:52 +00:00
Enhance APFloat to retain bits of NaNs (fixes oggenc).
Use APFloat interfaces for more references, mostly of ConstantFPSDNode. llvm-svn: 41632
This commit is contained in:
parent
ffa8296e3f
commit
81d6ecb886
@ -64,8 +64,11 @@
|
||||
so that the smallest denormal has just the least significant bit
|
||||
of the significand set. The sign of zeroes and infinities is
|
||||
significant; the exponent and significand of such numbers is
|
||||
indeterminate and meaningless. For QNaNs the sign bit, as well as
|
||||
the exponent and significand are indeterminate and meaningless.
|
||||
not stored, but has a known implicit (deterministic) value:
|
||||
0 for the significands, 0 for zero exponent, all 1 bits for
|
||||
infinity exponent. For NaNs the sign and significand are
|
||||
deterministic, although not really meaningful; the exponent is
|
||||
implicitly all 1 bits.
|
||||
|
||||
TODO
|
||||
====
|
||||
@ -155,7 +158,7 @@ namespace llvm {
|
||||
/* Category of internally-represented number. */
|
||||
enum fltCategory {
|
||||
fcInfinity,
|
||||
fcQNaN,
|
||||
fcNaN,
|
||||
fcNormal,
|
||||
fcZero
|
||||
};
|
||||
@ -192,7 +195,7 @@ namespace llvm {
|
||||
whatever it is you really mean. */
|
||||
// bool operator==(const APFloat &) const; // DO NOT IMPLEMENT
|
||||
|
||||
/* IEEE comparison with another floating point number (QNaNs
|
||||
/* IEEE comparison with another floating point number (NaNs
|
||||
compare unordered, 0==-0). */
|
||||
cmpResult compare(const APFloat &) const;
|
||||
|
||||
@ -205,6 +208,8 @@ namespace llvm {
|
||||
bool isZero() const { return category == fcZero; }
|
||||
bool isNonZero() const { return category != fcZero; }
|
||||
bool isNegative() const { return sign; }
|
||||
bool isPosZero() const { return isZero() && !isNegative(); }
|
||||
bool isNegZero() const { return isZero() && isNegative(); }
|
||||
|
||||
APFloat& operator=(const APFloat &);
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define LLVM_ADT_STRINGEXTRAS_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
@ -92,6 +93,14 @@ static inline std::string ftostr(double V) {
|
||||
return B;
|
||||
}
|
||||
|
||||
static inline std::string ftostr(APFloat V) {
|
||||
if (&V.getSemantics() == &APFloat::IEEEsingle)
|
||||
return ftostr(V.convertToDouble());
|
||||
else if (&V.getSemantics() == &APFloat::IEEEdouble)
|
||||
return ftostr((double)V.convertToFloat());
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
static inline std::string LowercaseString(const std::string &S) {
|
||||
std::string result(S);
|
||||
for (unsigned i = 0; i < S.length(); ++i)
|
||||
|
@ -109,11 +109,13 @@ bool ISD::isBuildVectorAllOnes(const SDNode *N) {
|
||||
} else if (isa<ConstantFPSDNode>(NotZero)) {
|
||||
MVT::ValueType VT = NotZero.getValueType();
|
||||
if (VT== MVT::f64) {
|
||||
if (DoubleToBits(cast<ConstantFPSDNode>(NotZero)->getValue()) !=
|
||||
if (DoubleToBits(cast<ConstantFPSDNode>(NotZero)->
|
||||
getValueAPF().convertToDouble()) !=
|
||||
(uint64_t)-1)
|
||||
return false;
|
||||
} else {
|
||||
if (FloatToBits(cast<ConstantFPSDNode>(NotZero)->getValue()) !=
|
||||
if (FloatToBits(cast<ConstantFPSDNode>(NotZero)->
|
||||
getValueAPF().convertToFloat()) !=
|
||||
(uint32_t)-1)
|
||||
return false;
|
||||
}
|
||||
@ -155,7 +157,7 @@ bool ISD::isBuildVectorAllZeros(const SDNode *N) {
|
||||
if (!cast<ConstantSDNode>(Zero)->isNullValue())
|
||||
return false;
|
||||
} else if (isa<ConstantFPSDNode>(Zero)) {
|
||||
if (!cast<ConstantFPSDNode>(Zero)->isExactlyValue(0.0))
|
||||
if (!cast<ConstantFPSDNode>(Zero)->getValueAPF().isPosZero())
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
@ -320,9 +322,16 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, SDNode *N) {
|
||||
ID.AddInteger(cast<ConstantSDNode>(N)->getValue());
|
||||
break;
|
||||
case ISD::TargetConstantFP:
|
||||
case ISD::ConstantFP:
|
||||
ID.AddDouble(cast<ConstantFPSDNode>(N)->getValue());
|
||||
case ISD::ConstantFP: {
|
||||
APFloat V = cast<ConstantFPSDNode>(N)->getValueAPF();
|
||||
if (&V.getSemantics() == &APFloat::IEEEdouble)
|
||||
ID.AddDouble(V.convertToDouble());
|
||||
else if (&V.getSemantics() == &APFloat::IEEEsingle)
|
||||
ID.AddDouble((double)V.convertToFloat());
|
||||
else
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
case ISD::TargetGlobalAddress:
|
||||
case ISD::GlobalAddress:
|
||||
case ISD::TargetGlobalTLSAddress:
|
||||
@ -966,16 +975,36 @@ SDOperand SelectionDAG::FoldSetCC(MVT::ValueType VT, SDOperand N1,
|
||||
}
|
||||
if (ConstantFPSDNode *N1C = dyn_cast<ConstantFPSDNode>(N1.Val))
|
||||
if (ConstantFPSDNode *N2C = dyn_cast<ConstantFPSDNode>(N2.Val)) {
|
||||
double C1 = N1C->getValue(), C2 = N2C->getValue();
|
||||
|
||||
|
||||
APFloat::cmpResult R = N1C->getValueAPF().compare(N2C->getValueAPF());
|
||||
switch (Cond) {
|
||||
default: break; // FIXME: Implement the rest of these!
|
||||
case ISD::SETEQ: return getConstant(C1 == C2, VT);
|
||||
case ISD::SETNE: return getConstant(C1 != C2, VT);
|
||||
case ISD::SETLT: return getConstant(C1 < C2, VT);
|
||||
case ISD::SETGT: return getConstant(C1 > C2, VT);
|
||||
case ISD::SETLE: return getConstant(C1 <= C2, VT);
|
||||
case ISD::SETGE: return getConstant(C1 >= C2, VT);
|
||||
default: break;
|
||||
case ISD::SETOEQ:
|
||||
case ISD::SETEQ: return getConstant(R==APFloat::cmpEqual, VT);
|
||||
case ISD::SETONE:
|
||||
case ISD::SETNE: return getConstant(R==APFloat::cmpGreaterThan ||
|
||||
R==APFloat::cmpLessThan, VT);
|
||||
case ISD::SETOLT:
|
||||
case ISD::SETLT: return getConstant(R==APFloat::cmpLessThan, VT);
|
||||
case ISD::SETOGT:
|
||||
case ISD::SETGT: return getConstant(R==APFloat::cmpGreaterThan, VT);
|
||||
case ISD::SETOLE:
|
||||
case ISD::SETLE: return getConstant(R==APFloat::cmpLessThan ||
|
||||
R==APFloat::cmpEqual, VT);
|
||||
case ISD::SETOGE:
|
||||
case ISD::SETGE: return getConstant(R==APFloat::cmpGreaterThan ||
|
||||
R==APFloat::cmpEqual, VT);
|
||||
case ISD::SETO: return getConstant(R!=APFloat::cmpUnordered, VT);
|
||||
case ISD::SETUO: return getConstant(R==APFloat::cmpUnordered, VT);
|
||||
case ISD::SETUEQ: return getConstant(R==APFloat::cmpUnordered ||
|
||||
R==APFloat::cmpEqual, VT);
|
||||
case ISD::SETUNE: return getConstant(R!=APFloat::cmpEqual, VT);
|
||||
case ISD::SETULT: return getConstant(R==APFloat::cmpUnordered ||
|
||||
R==APFloat::cmpLessThan, VT);
|
||||
case ISD::SETUGT: return getConstant(R==APFloat::cmpGreaterThan ||
|
||||
R==APFloat::cmpUnordered, VT);
|
||||
case ISD::SETULE: return getConstant(R!=APFloat::cmpGreaterThan, VT);
|
||||
case ISD::SETUGE: return getConstant(R!=APFloat::cmpLessThan, VT);
|
||||
}
|
||||
} else {
|
||||
// Ensure that the constant occurs on the RHS.
|
||||
|
@ -95,7 +95,7 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
|
||||
if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Node)) {
|
||||
Op += ": " + utostr(CSDN->getValue());
|
||||
} else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(Node)) {
|
||||
Op += ": " + ftostr(CSDN->getValue());
|
||||
Op += ": " + ftostr(CSDN->getValueAPF());
|
||||
} else if (const GlobalAddressSDNode *GADN =
|
||||
dyn_cast<GlobalAddressSDNode>(Node)) {
|
||||
int offset = GADN->getOffset();
|
||||
@ -115,7 +115,7 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
|
||||
Op += "<" + SS.str() + ">";
|
||||
} else {
|
||||
if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
|
||||
Op += "<" + ftostr(CFP->getValue()) + ">";
|
||||
Op += "<" + ftostr(CFP->getValueAPF()) + ">";
|
||||
else if (ConstantInt *CI = dyn_cast<ConstantInt>(CP->getConstVal()))
|
||||
Op += "<" + utostr(CI->getZExtValue()) + ">";
|
||||
else {
|
||||
|
@ -247,14 +247,14 @@ APFloat::assign(const APFloat &rhs)
|
||||
sign = rhs.sign;
|
||||
category = rhs.category;
|
||||
exponent = rhs.exponent;
|
||||
if(category == fcNormal)
|
||||
if(category == fcNormal || category == fcNaN)
|
||||
copySignificand(rhs);
|
||||
}
|
||||
|
||||
void
|
||||
APFloat::copySignificand(const APFloat &rhs)
|
||||
{
|
||||
assert(category == fcNormal);
|
||||
assert(category == fcNormal || category == fcNaN);
|
||||
assert(rhs.partCount() >= partCount());
|
||||
|
||||
APInt::tcAssign(significandParts(), rhs.significandParts(),
|
||||
@ -280,15 +280,14 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
|
||||
if (this == &rhs)
|
||||
return true;
|
||||
if (semantics != rhs.semantics ||
|
||||
category != rhs.category)
|
||||
category != rhs.category ||
|
||||
sign != rhs.sign)
|
||||
return false;
|
||||
if (category==fcQNaN)
|
||||
if (category==fcZero || category==fcInfinity)
|
||||
return true;
|
||||
else if (category==fcZero || category==fcInfinity)
|
||||
return sign==rhs.sign;
|
||||
else if (category==fcNormal && exponent!=rhs.exponent)
|
||||
return false;
|
||||
else {
|
||||
if (sign!=rhs.sign || exponent!=rhs.exponent)
|
||||
return false;
|
||||
int i= partCount();
|
||||
const integerPart* p=significandParts();
|
||||
const integerPart* q=rhs.significandParts();
|
||||
@ -358,7 +357,7 @@ APFloat::significandParts() const
|
||||
integerPart *
|
||||
APFloat::significandParts()
|
||||
{
|
||||
assert(category == fcNormal);
|
||||
assert(category == fcNormal || category == fcNaN);
|
||||
|
||||
if(partCount() > 1)
|
||||
return significand.parts;
|
||||
@ -701,7 +700,7 @@ bool
|
||||
APFloat::roundAwayFromZero(roundingMode rounding_mode,
|
||||
lostFraction lost_fraction)
|
||||
{
|
||||
/* QNaNs and infinities should not have lost fractions. */
|
||||
/* NaNs and infinities should not have lost fractions. */
|
||||
assert(category == fcNormal || category == fcZero);
|
||||
|
||||
/* Our caller has already handled this case. */
|
||||
@ -851,19 +850,20 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
|
||||
default:
|
||||
assert(0);
|
||||
|
||||
case convolve(fcQNaN, fcZero):
|
||||
case convolve(fcQNaN, fcNormal):
|
||||
case convolve(fcQNaN, fcInfinity):
|
||||
case convolve(fcQNaN, fcQNaN):
|
||||
case convolve(fcNaN, fcZero):
|
||||
case convolve(fcNaN, fcNormal):
|
||||
case convolve(fcNaN, fcInfinity):
|
||||
case convolve(fcNaN, fcNaN):
|
||||
case convolve(fcNormal, fcZero):
|
||||
case convolve(fcInfinity, fcNormal):
|
||||
case convolve(fcInfinity, fcZero):
|
||||
return opOK;
|
||||
|
||||
case convolve(fcZero, fcQNaN):
|
||||
case convolve(fcNormal, fcQNaN):
|
||||
case convolve(fcInfinity, fcQNaN):
|
||||
category = fcQNaN;
|
||||
case convolve(fcZero, fcNaN):
|
||||
case convolve(fcNormal, fcNaN):
|
||||
case convolve(fcInfinity, fcNaN):
|
||||
category = fcNaN;
|
||||
copySignificand(rhs);
|
||||
return opOK;
|
||||
|
||||
case convolve(fcNormal, fcInfinity):
|
||||
@ -885,7 +885,9 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
|
||||
/* Differently signed infinities can only be validly
|
||||
subtracted. */
|
||||
if(sign ^ rhs.sign != subtract) {
|
||||
category = fcQNaN;
|
||||
category = fcNaN;
|
||||
// Arbitrary but deterministic value for significand
|
||||
APInt::tcSet(significandParts(), ~0U, partCount());
|
||||
return opInvalidOp;
|
||||
}
|
||||
|
||||
@ -974,14 +976,17 @@ APFloat::multiplySpecials(const APFloat &rhs)
|
||||
default:
|
||||
assert(0);
|
||||
|
||||
case convolve(fcQNaN, fcZero):
|
||||
case convolve(fcQNaN, fcNormal):
|
||||
case convolve(fcQNaN, fcInfinity):
|
||||
case convolve(fcQNaN, fcQNaN):
|
||||
case convolve(fcZero, fcQNaN):
|
||||
case convolve(fcNormal, fcQNaN):
|
||||
case convolve(fcInfinity, fcQNaN):
|
||||
category = fcQNaN;
|
||||
case convolve(fcNaN, fcZero):
|
||||
case convolve(fcNaN, fcNormal):
|
||||
case convolve(fcNaN, fcInfinity):
|
||||
case convolve(fcNaN, fcNaN):
|
||||
return opOK;
|
||||
|
||||
case convolve(fcZero, fcNaN):
|
||||
case convolve(fcNormal, fcNaN):
|
||||
case convolve(fcInfinity, fcNaN):
|
||||
category = fcNaN;
|
||||
copySignificand(rhs);
|
||||
return opOK;
|
||||
|
||||
case convolve(fcNormal, fcInfinity):
|
||||
@ -998,7 +1003,9 @@ APFloat::multiplySpecials(const APFloat &rhs)
|
||||
|
||||
case convolve(fcZero, fcInfinity):
|
||||
case convolve(fcInfinity, fcZero):
|
||||
category = fcQNaN;
|
||||
category = fcNaN;
|
||||
// Arbitrary but deterministic value for significand
|
||||
APInt::tcSet(significandParts(), ~0U, partCount());
|
||||
return opInvalidOp;
|
||||
|
||||
case convolve(fcNormal, fcNormal):
|
||||
@ -1013,20 +1020,21 @@ APFloat::divideSpecials(const APFloat &rhs)
|
||||
default:
|
||||
assert(0);
|
||||
|
||||
case convolve(fcQNaN, fcZero):
|
||||
case convolve(fcQNaN, fcNormal):
|
||||
case convolve(fcQNaN, fcInfinity):
|
||||
case convolve(fcQNaN, fcQNaN):
|
||||
case convolve(fcNaN, fcZero):
|
||||
case convolve(fcNaN, fcNormal):
|
||||
case convolve(fcNaN, fcInfinity):
|
||||
case convolve(fcNaN, fcNaN):
|
||||
case convolve(fcInfinity, fcZero):
|
||||
case convolve(fcInfinity, fcNormal):
|
||||
case convolve(fcZero, fcInfinity):
|
||||
case convolve(fcZero, fcNormal):
|
||||
return opOK;
|
||||
|
||||
case convolve(fcZero, fcQNaN):
|
||||
case convolve(fcNormal, fcQNaN):
|
||||
case convolve(fcInfinity, fcQNaN):
|
||||
category = fcQNaN;
|
||||
case convolve(fcZero, fcNaN):
|
||||
case convolve(fcNormal, fcNaN):
|
||||
case convolve(fcInfinity, fcNaN):
|
||||
category = fcNaN;
|
||||
copySignificand(rhs);
|
||||
return opOK;
|
||||
|
||||
case convolve(fcNormal, fcInfinity):
|
||||
@ -1039,7 +1047,9 @@ APFloat::divideSpecials(const APFloat &rhs)
|
||||
|
||||
case convolve(fcInfinity, fcInfinity):
|
||||
case convolve(fcZero, fcZero):
|
||||
category = fcQNaN;
|
||||
category = fcNaN;
|
||||
// Arbitrary but deterministic value for significand
|
||||
APInt::tcSet(significandParts(), ~0U, partCount());
|
||||
return opInvalidOp;
|
||||
|
||||
case convolve(fcNormal, fcNormal):
|
||||
@ -1172,7 +1182,7 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
|
||||
/* FS can only be opOK or opInvalidOp. There is no more work
|
||||
to do in the latter case. The IEEE-754R standard says it is
|
||||
implementation-defined in this case whether, if ADDEND is a
|
||||
quiet QNaN, we raise invalid op; this implementation does so.
|
||||
quiet NaN, we raise invalid op; this implementation does so.
|
||||
|
||||
If we need to do the addition we can do so with normal
|
||||
precision. */
|
||||
@ -1195,13 +1205,13 @@ APFloat::compare(const APFloat &rhs) const
|
||||
default:
|
||||
assert(0);
|
||||
|
||||
case convolve(fcQNaN, fcZero):
|
||||
case convolve(fcQNaN, fcNormal):
|
||||
case convolve(fcQNaN, fcInfinity):
|
||||
case convolve(fcQNaN, fcQNaN):
|
||||
case convolve(fcZero, fcQNaN):
|
||||
case convolve(fcNormal, fcQNaN):
|
||||
case convolve(fcInfinity, fcQNaN):
|
||||
case convolve(fcNaN, fcZero):
|
||||
case convolve(fcNaN, fcNormal):
|
||||
case convolve(fcNaN, fcInfinity):
|
||||
case convolve(fcNaN, fcNaN):
|
||||
case convolve(fcZero, fcNaN):
|
||||
case convolve(fcNormal, fcNaN):
|
||||
case convolve(fcInfinity, fcNaN):
|
||||
return cmpUnordered;
|
||||
|
||||
case convolve(fcInfinity, fcNormal):
|
||||
@ -1309,7 +1319,7 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width,
|
||||
int bits;
|
||||
|
||||
/* Handle the three special cases first. */
|
||||
if(category == fcInfinity || category == fcQNaN)
|
||||
if(category == fcInfinity || category == fcNaN)
|
||||
return opInvalidOp;
|
||||
|
||||
partsCount = partCountForBits(width);
|
||||
@ -1517,7 +1527,7 @@ uint32_t
|
||||
APFloat::getHashValue() const {
|
||||
if (category==fcZero) return sign<<8 | semantics->precision ;
|
||||
else if (category==fcInfinity) return sign<<9 | semantics->precision;
|
||||
else if (category==fcQNaN) return 1<<10 | semantics->precision;
|
||||
else if (category==fcNaN) return 1<<10 | semantics->precision;
|
||||
else {
|
||||
uint32_t hash = sign<<11 | semantics->precision | exponent<<12;
|
||||
const integerPart* p = significandParts();
|
||||
@ -1538,28 +1548,25 @@ APFloat::convertToDouble() const {
|
||||
assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble);
|
||||
assert (partCount()==1);
|
||||
|
||||
uint64_t myexponent, mysign, mysignificand;
|
||||
uint64_t myexponent, mysignificand;
|
||||
|
||||
if (category==fcNormal) {
|
||||
mysign = sign;
|
||||
mysignificand = *significandParts();
|
||||
myexponent = exponent+1023; //bias
|
||||
} else if (category==fcZero) {
|
||||
mysign = sign;
|
||||
myexponent = 0;
|
||||
mysignificand = 0;
|
||||
} else if (category==fcInfinity) {
|
||||
mysign = sign;
|
||||
myexponent = 0x7ff;
|
||||
mysignificand = 0;
|
||||
} else if (category==fcQNaN) {
|
||||
mysign = 0;
|
||||
} else if (category==fcNaN) {
|
||||
myexponent = 0x7ff;
|
||||
mysignificand = 0xfffffffffffffLL;
|
||||
mysignificand = *significandParts();
|
||||
} else
|
||||
assert(0);
|
||||
|
||||
return BitsToDouble(((mysign & 1) << 63) | ((myexponent & 0x7ff) << 52) |
|
||||
return BitsToDouble((((uint64_t)sign & 1) << 63) |
|
||||
((myexponent & 0x7ff) << 52) |
|
||||
(mysignificand & 0xfffffffffffffLL));
|
||||
}
|
||||
|
||||
@ -1568,82 +1575,74 @@ APFloat::convertToFloat() const {
|
||||
assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle);
|
||||
assert (partCount()==1);
|
||||
|
||||
uint32_t mysign, myexponent, mysignificand;
|
||||
uint32_t myexponent, mysignificand;
|
||||
|
||||
if (category==fcNormal) {
|
||||
mysign = sign;
|
||||
myexponent = exponent+127; //bias
|
||||
mysignificand = *significandParts();
|
||||
} else if (category==fcZero) {
|
||||
mysign = sign;
|
||||
myexponent = 0;
|
||||
mysignificand = 0;
|
||||
} else if (category==fcInfinity) {
|
||||
mysign = sign;
|
||||
myexponent = 0xff;
|
||||
mysignificand = 0;
|
||||
} else if (category==fcQNaN) {
|
||||
mysign = sign;
|
||||
} else if (category==fcNaN) {
|
||||
myexponent = 0x7ff;
|
||||
mysignificand = 0x7fffff;
|
||||
mysignificand = *significandParts();
|
||||
} else
|
||||
assert(0);
|
||||
|
||||
return BitsToFloat(((mysign&1) << 31) | ((myexponent&0xff) << 23) |
|
||||
return BitsToFloat(((sign&1) << 31) | ((myexponent&0xff) << 23) |
|
||||
(mysignificand & 0x7fffff));
|
||||
}
|
||||
|
||||
APFloat::APFloat(double d) {
|
||||
uint64_t i = DoubleToBits(d);
|
||||
uint64_t mysign = i >> 63;
|
||||
uint64_t myexponent = (i >> 52) & 0x7ff;
|
||||
uint64_t mysignificand = i & 0xfffffffffffffLL;
|
||||
|
||||
initialize(&APFloat::IEEEdouble);
|
||||
assert(partCount()==1);
|
||||
|
||||
sign = i>>63;
|
||||
if (myexponent==0 && mysignificand==0) {
|
||||
// exponent, significand meaningless
|
||||
category = fcZero;
|
||||
sign = mysign;
|
||||
} else if (myexponent==0x7ff && mysignificand==0) {
|
||||
// exponent, significand meaningless
|
||||
category = fcInfinity;
|
||||
sign = mysign;
|
||||
} else if (myexponent==0x7ff && (mysignificand & 0x8000000000000LL)) {
|
||||
// sign, exponent, significand meaningless
|
||||
category = fcQNaN;
|
||||
} else if (myexponent==0x7ff && mysignificand!=0) {
|
||||
// exponent meaningless
|
||||
category = fcNaN;
|
||||
*significandParts() = mysignificand;
|
||||
} else {
|
||||
sign = mysign;
|
||||
category = fcNormal;
|
||||
exponent = myexponent - 1023;
|
||||
*significandParts() = mysignificand | 0x10000000000000LL;
|
||||
}
|
||||
*significandParts() = mysignificand | 0x10000000000000LL;
|
||||
}
|
||||
}
|
||||
|
||||
APFloat::APFloat(float f) {
|
||||
uint32_t i = FloatToBits(f);
|
||||
uint32_t mysign = i >> 31;
|
||||
uint32_t myexponent = (i >> 23) & 0xff;
|
||||
uint32_t mysignificand = i & 0x7fffff;
|
||||
|
||||
initialize(&APFloat::IEEEsingle);
|
||||
assert(partCount()==1);
|
||||
|
||||
sign = i >> 31;
|
||||
if (myexponent==0 && mysignificand==0) {
|
||||
// exponent, significand meaningless
|
||||
category = fcZero;
|
||||
sign = mysign;
|
||||
} else if (myexponent==0xff && mysignificand==0) {
|
||||
// exponent, significand meaningless
|
||||
category = fcInfinity;
|
||||
sign = mysign;
|
||||
} else if (myexponent==0xff && (mysignificand & 0x400000)) {
|
||||
// sign, exponent, significand meaningless
|
||||
category = fcQNaN;
|
||||
category = fcNaN;
|
||||
*significandParts() = mysignificand;
|
||||
} else {
|
||||
category = fcNormal;
|
||||
sign = mysign;
|
||||
exponent = myexponent - 127; //bias
|
||||
*significandParts() = mysignificand | 0x800000; // integer bit
|
||||
}
|
||||
|
@ -1033,14 +1033,14 @@ ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
|
||||
/// isFloatingPointZero - Return true if this is +0.0.
|
||||
static bool isFloatingPointZero(SDOperand Op) {
|
||||
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op))
|
||||
return CFP->isExactlyValue(0.0);
|
||||
return CFP->getValueAPF().isPosZero();
|
||||
else if (ISD::isEXTLoad(Op.Val) || ISD::isNON_EXTLoad(Op.Val)) {
|
||||
// Maybe this has already been legalized into the constant pool?
|
||||
if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) {
|
||||
SDOperand WrapperOp = Op.getOperand(1).getOperand(0);
|
||||
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(WrapperOp))
|
||||
if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
|
||||
return CFP->isExactlyValue(0.0);
|
||||
return CFP->getValueAPF().isPosZero();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -131,15 +131,15 @@ namespace {
|
||||
|
||||
static bool isFPZ(SDOperand N) {
|
||||
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
|
||||
return (CN && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)));
|
||||
return (CN && (CN->getValueAPF().isZero()));
|
||||
}
|
||||
static bool isFPZn(SDOperand N) {
|
||||
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
|
||||
return (CN && CN->isExactlyValue(-0.0));
|
||||
return (CN && CN->getValueAPF().isNegZero());
|
||||
}
|
||||
static bool isFPZp(SDOperand N) {
|
||||
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
|
||||
return (CN && CN->isExactlyValue(+0.0));
|
||||
return (CN && CN->getValueAPF().isPosZero());
|
||||
}
|
||||
|
||||
public:
|
||||
@ -334,11 +334,11 @@ SDNode *AlphaDAGToDAGISel::Select(SDOperand Op) {
|
||||
ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
|
||||
bool isDouble = N->getValueType(0) == MVT::f64;
|
||||
MVT::ValueType T = isDouble ? MVT::f64 : MVT::f32;
|
||||
if (CN->isExactlyValue(+0.0)) {
|
||||
if (CN->getValueAPF().isPosZero()) {
|
||||
return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYST : Alpha::CPYSS,
|
||||
T, CurDAG->getRegister(Alpha::F31, T),
|
||||
CurDAG->getRegister(Alpha::F31, T));
|
||||
} else if ( CN->isExactlyValue(-0.0)) {
|
||||
} else if (CN->getValueAPF().isNegZero()) {
|
||||
return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYSNT : Alpha::CPYSNS,
|
||||
T, CurDAG->getRegister(Alpha::F31, T),
|
||||
CurDAG->getRegister(Alpha::F31, T));
|
||||
|
@ -404,9 +404,9 @@ SDNode *IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
SDOperand Chain = CurDAG->getEntryNode(); // this is a constant, so..
|
||||
|
||||
SDOperand V;
|
||||
if (cast<ConstantFPSDNode>(N)->isExactlyValue(+0.0)) {
|
||||
if (cast<ConstantFPSDNode>(N)->getValueAPF().isPosZero()) {
|
||||
V = CurDAG->getCopyFromReg(Chain, IA64::F0, MVT::f64);
|
||||
} else if (cast<ConstantFPSDNode>(N)->isExactlyValue(+1.0)) {
|
||||
} else if (cast<ConstantFPSDNode>(N)->isExactlyValue(APFloat(+1.0))) {
|
||||
V = CurDAG->getCopyFromReg(Chain, IA64::F1, MVT::f64);
|
||||
} else
|
||||
assert(0 && "Unexpected FP constant!");
|
||||
|
@ -362,12 +362,12 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
/// isFloatingPointZero - Return true if this is 0.0 or -0.0.
|
||||
static bool isFloatingPointZero(SDOperand Op) {
|
||||
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op))
|
||||
return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0);
|
||||
return CFP->getValueAPF().isZero();
|
||||
else if (ISD::isEXTLoad(Op.Val) || ISD::isNON_EXTLoad(Op.Val)) {
|
||||
// Maybe this has already been legalized into the constant pool?
|
||||
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op.getOperand(1)))
|
||||
if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
|
||||
return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0);
|
||||
return CFP->getValueAPF().isZero();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -530,7 +530,7 @@ bool PPC::isAllNegativeZeroVector(SDNode *N) {
|
||||
assert(N->getOpcode() == ISD::BUILD_VECTOR);
|
||||
if (PPC::isSplatShuffleMask(N, N->getNumOperands()))
|
||||
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N))
|
||||
return CFP->isExactlyValue(-0.0);
|
||||
return CFP->getValueAPF().isNegZero();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -622,7 +622,7 @@ SDOperand PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
|
||||
ValSizeInBytes = MVT::getSizeInBits(CN->getValueType(0))/8;
|
||||
} else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
|
||||
assert(CN->getValueType(0) == MVT::f32 && "Only one legal FP vector type!");
|
||||
Value = FloatToBits(CN->getValue());
|
||||
Value = FloatToBits(CN->getValueAPF().convertToFloat());
|
||||
ValSizeInBytes = 4;
|
||||
}
|
||||
|
||||
@ -2194,7 +2194,7 @@ static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
|
||||
} else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
|
||||
assert(CN->getValueType(0) == MVT::f32 &&
|
||||
"Only one legal FP vector type!");
|
||||
EltBits = FloatToBits(CN->getValue());
|
||||
EltBits = FloatToBits(CN->getValueAPF().convertToFloat());
|
||||
} else {
|
||||
// Nonconstant element.
|
||||
return true;
|
||||
|
@ -817,7 +817,7 @@ static inline bool isZeroNode(SDOperand Elt) {
|
||||
return ((isa<ConstantSDNode>(Elt) &&
|
||||
cast<ConstantSDNode>(Elt)->getValue() == 0) ||
|
||||
(isa<ConstantFPSDNode>(Elt) &&
|
||||
cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
|
||||
cast<ConstantFPSDNode>(Elt)->getValueAPF().isPosZero()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -2303,7 +2303,7 @@ static inline bool isZeroNode(SDOperand Elt) {
|
||||
return ((isa<ConstantSDNode>(Elt) &&
|
||||
cast<ConstantSDNode>(Elt)->getValue() == 0) ||
|
||||
(isa<ConstantFPSDNode>(Elt) &&
|
||||
cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
|
||||
cast<ConstantFPSDNode>(Elt)->getValueAPF().isPosZero()));
|
||||
}
|
||||
|
||||
/// isZeroShuffle - Returns true if N is a VECTOR_SHUFFLE that can be resolved
|
||||
|
Loading…
Reference in New Issue
Block a user