aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/AsmWriter.cpp85
-rw-r--r--lib/VMCore/ConstantFold.cpp13
-rw-r--r--lib/VMCore/Constants.cpp25
3 files changed, 83 insertions, 40 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index a7b1239..b96fbff 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -481,35 +481,64 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
else
Out << CI->getValue().toStringSigned(10);
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- // We would like to output the FP constant value in exponential notation,
- // but we cannot do this if doing so will lose precision. Check here to
- // make sure that we only output it in exponential format if we can parse
- // the value back and get the same value.
- //
- bool isDouble = &CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble;
- double Val = (isDouble) ? CFP->getValueAPF().convertToDouble() :
- CFP->getValueAPF().convertToFloat();
- std::string StrVal = ftostr(CFP->getValueAPF());
-
- // Check to make sure that the stringized number is not some string like
- // "Inf" or NaN, that atof will accept, but the lexer will not. Check that
- // the string matches the "[-+]?[0-9]" regex.
- //
- if ((StrVal[0] >= '0' && StrVal[0] <= '9') ||
- ((StrVal[0] == '-' || StrVal[0] == '+') &&
- (StrVal[1] >= '0' && StrVal[1] <= '9')))
- // Reparse stringized version!
- if (atof(StrVal.c_str()) == Val) {
- Out << StrVal;
- return;
+ if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble ||
+ &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) {
+ // We would like to output the FP constant value in exponential notation,
+ // but we cannot do this if doing so will lose precision. Check here to
+ // make sure that we only output it in exponential format if we can parse
+ // the value back and get the same value.
+ //
+ bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble;
+ double Val = (isDouble) ? CFP->getValueAPF().convertToDouble() :
+ CFP->getValueAPF().convertToFloat();
+ std::string StrVal = ftostr(CFP->getValueAPF());
+
+ // Check to make sure that the stringized number is not some string like
+ // "Inf" or NaN, that atof will accept, but the lexer will not. Check
+ // that the string matches the "[-+]?[0-9]" regex.
+ //
+ if ((StrVal[0] >= '0' && StrVal[0] <= '9') ||
+ ((StrVal[0] == '-' || StrVal[0] == '+') &&
+ (StrVal[1] >= '0' && StrVal[1] <= '9'))) {
+ // Reparse stringized version!
+ if (atof(StrVal.c_str()) == Val) {
+ Out << StrVal;
+ return;
+ }
}
-
- // Otherwise we could not reparse it to exactly the same value, so we must
- // output the string in hexadecimal format!
- assert(sizeof(double) == sizeof(uint64_t) &&
- "assuming that double is 64 bits!");
- Out << "0x" << utohexstr(DoubleToBits(Val));
-
+ // Otherwise we could not reparse it to exactly the same value, so we must
+ // output the string in hexadecimal format!
+ assert(sizeof(double) == sizeof(uint64_t) &&
+ "assuming that double is 64 bits!");
+ Out << "0x" << utohexstr(DoubleToBits(Val));
+ } else {
+ // Some form of long double. These appear as a magic letter identifying
+ // the type, then a fixed number of hex digits.
+ Out << "0x";
+ if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended)
+ Out << 'K';
+ else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad)
+ Out << 'L';
+ else
+ assert(0 && "Unsupported floating point type");
+ const uint64_t* p = CFP->getValueAPF().convertToAPInt().getRawData();
+ uint64_t word = *p;
+ int shiftcount=60;
+ int width = CFP->getValueAPF().convertToAPInt().getBitWidth();
+ for (int j=0; j<width; j+=4, shiftcount-=4) {
+ unsigned int nibble = (word>>shiftcount) & 15;
+ if (nibble < 10)
+ Out << (unsigned char)(nibble + '0');
+ else
+ Out << (unsigned char)(nibble - 10 + 'A');
+ if (shiftcount == 0) {
+ word = *(++p);
+ shiftcount = 60;
+ if (width-j-4 < 64)
+ shiftcount = width-j-4;
+ }
+ }
+ }
} else if (isa<ConstantAggregateZero>(CV)) {
Out << "zeroinitializer";
} else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index e11b749..5c80a37 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -87,8 +87,8 @@ static Constant *CastConstantVector(ConstantVector *CV,
if (SrcEltTy->getTypeID() == Type::DoubleTyID) {
for (unsigned i = 0; i != SrcNumElts; ++i) {
- uint64_t V = *cast<ConstantFP>(CV->getOperand(i))->
- getValueAPF().convertToAPInt().getRawData();
+ uint64_t V = cast<ConstantFP>(CV->getOperand(i))->
+ getValueAPF().convertToAPInt().getZExtValue();
Constant *C = ConstantInt::get(Type::Int64Ty, V);
Result.push_back(ConstantExpr::getBitCast(C, DstEltTy ));
}
@@ -97,8 +97,8 @@ static Constant *CastConstantVector(ConstantVector *CV,
assert(SrcEltTy->getTypeID() == Type::FloatTyID);
for (unsigned i = 0; i != SrcNumElts; ++i) {
- uint32_t V = (uint32_t)*cast<ConstantFP>(CV->getOperand(i))->
- getValueAPF().convertToAPInt().getRawData();
+ uint32_t V = (uint32_t)cast<ConstantFP>(CV->getOperand(i))->
+ getValueAPF().convertToAPInt().getZExtValue();
Constant *C = ConstantInt::get(Type::Int32Ty, V);
Result.push_back(ConstantExpr::getBitCast(C, DstEltTy));
}
@@ -331,9 +331,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
return const_cast<Constant*>(V);
if (DestTy->isFloatingPoint()) {
- if (DestTy == Type::FloatTy)
- return ConstantFP::get(DestTy, APFloat(CI->getValue()));
- assert(DestTy == Type::DoubleTy && "Unknown FP type!");
+ assert((DestTy == Type::DoubleTy || DestTy == Type::FloatTy) &&
+ "Unknown FP type!");
return ConstantFP::get(DestTy, APFloat(CI->getValue()));
}
// Otherwise, can't fold this (vector?)
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 1708e46..c546045 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -245,8 +245,14 @@ ConstantFP::ConstantFP(const Type *Ty, const APFloat& V)
// temporary
if (Ty==Type::FloatTy)
assert(&V.getSemantics()==&APFloat::IEEEsingle);
- else
+ else if (Ty==Type::DoubleTy)
assert(&V.getSemantics()==&APFloat::IEEEdouble);
+ else if (Ty==Type::X86_FP80Ty)
+ assert(&V.getSemantics()==&APFloat::x87DoubleExtended);
+ else if (Ty==Type::FP128Ty)
+ assert(&V.getSemantics()==&APFloat::IEEEquad);
+ else
+ assert(0);
}
bool ConstantFP::isNullValue() const {
@@ -294,8 +300,14 @@ ConstantFP *ConstantFP::get(const Type *Ty, const APFloat& V) {
// temporary
if (Ty==Type::FloatTy)
assert(&V.getSemantics()==&APFloat::IEEEsingle);
- else
+ else if (Ty==Type::DoubleTy)
assert(&V.getSemantics()==&APFloat::IEEEdouble);
+ else if (Ty==Type::X86_FP80Ty)
+ assert(&V.getSemantics()==&APFloat::x87DoubleExtended);
+ else if (Ty==Type::FP128Ty)
+ assert(&V.getSemantics()==&APFloat::IEEEquad);
+ else
+ assert(0);
DenseMapAPFloatKeyInfo::KeyTy Key(V);
ConstantFP *&Slot = (*FPConstants)[Key];
@@ -713,11 +725,14 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
&Val2.getSemantics() == &APFloat::IEEEdouble ||
Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven) ==
APFloat::opOK;
- // TODO: Figure out how to test if we can use a shorter type instead!
case Type::X86_FP80TyID:
- case Type::PPC_FP128TyID:
+ return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+ &Val2.getSemantics() == &APFloat::IEEEdouble ||
+ &Val2.getSemantics() == &APFloat::x87DoubleExtended;
case Type::FP128TyID:
- return true;
+ return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+ &Val2.getSemantics() == &APFloat::IEEEdouble ||
+ &Val2.getSemantics() == &APFloat::IEEEquad;
}
}