diff options
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 85 | ||||
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 13 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 25 |
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; } } |