diff options
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 43 | ||||
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 3 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 27 | ||||
-rw-r--r-- | lib/VMCore/Core.cpp | 8 | ||||
-rw-r--r-- | lib/VMCore/LLVMContextImpl.cpp | 1 | ||||
-rw-r--r-- | lib/VMCore/LLVMContextImpl.h | 2 | ||||
-rw-r--r-- | lib/VMCore/Type.cpp | 10 |
7 files changed, 67 insertions, 27 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 4fb5fd3cb7..3da4774451 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -189,6 +189,7 @@ void TypePrinting::incorporateTypes(const Module &M) { void TypePrinting::print(Type *Ty, raw_ostream &OS) { switch (Ty->getTypeID()) { case Type::VoidTyID: OS << "void"; break; + case Type::HalfTyID: OS << "half"; break; case Type::FloatTyID: OS << "float"; break; case Type::DoubleTyID: OS << "double"; break; case Type::X86_FP80TyID: OS << "x86_fp80"; break; @@ -708,31 +709,35 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, } if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { - if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble || - &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) { + if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEhalf || + &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle || + &CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble) { // 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 ignored; + bool isHalf = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEhalf; bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble; - double Val = isDouble ? CFP->getValueAPF().convertToDouble() : - CFP->getValueAPF().convertToFloat(); - SmallString<128> StrVal; - raw_svector_ostream(StrVal) << Val; - - // 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.str(); - return; + if (!isHalf) { + double Val = isDouble ? CFP->getValueAPF().convertToDouble() : + CFP->getValueAPF().convertToFloat(); + SmallString<128> StrVal; + raw_svector_ostream(StrVal) << Val; + + // 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.str(); + return; + } } } // Otherwise we could not reparse it to exactly the same value, so we must @@ -743,7 +748,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, "assuming that double is 64 bits!"); char Buffer[40]; APFloat apf = CFP->getValueAPF(); - // Floats are represented in ASCII IR as double, convert. + // Halves and floats are represented in ASCII IR as double, convert. if (!isDouble) apf.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored); diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index d1a9e7a70f..4d7a857de5 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -571,7 +571,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, if (ConstantFP *FPC = dyn_cast<ConstantFP>(V)) { bool ignored; APFloat Val = FPC->getValueAPF(); - Val.convert(DestTy->isFloatTy() ? APFloat::IEEEsingle : + Val.convert(DestTy->isHalfTy() ? APFloat::IEEEhalf : + DestTy->isFloatTy() ? APFloat::IEEEsingle : DestTy->isDoubleTy() ? APFloat::IEEEdouble : DestTy->isX86_FP80Ty() ? APFloat::x87DoubleExtended : DestTy->isFP128Ty() ? APFloat::IEEEquad : diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index a1489123ca..f17f9a26ca 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -84,6 +84,9 @@ Constant *Constant::getNullValue(Type *Ty) { switch (Ty->getTypeID()) { case Type::IntegerTyID: return ConstantInt::get(Ty, 0); + case Type::HalfTyID: + return ConstantFP::get(Ty->getContext(), + APFloat::getZero(APFloat::IEEEhalf)); case Type::FloatTyID: return ConstantFP::get(Ty->getContext(), APFloat::getZero(APFloat::IEEEsingle)); @@ -468,6 +471,8 @@ ConstantInt* ConstantInt::get(IntegerType* Ty, StringRef Str, //===----------------------------------------------------------------------===// static const fltSemantics *TypeToFloatSemantics(Type *Ty) { + if (Ty->isHalfTy()) + return &APFloat::IEEEhalf; if (Ty->isFloatTy()) return &APFloat::IEEEsingle; if (Ty->isDoubleTy()) @@ -550,7 +555,9 @@ ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) { if (!Slot) { Type *Ty; - if (&V.getSemantics() == &APFloat::IEEEsingle) + if (&V.getSemantics() == &APFloat::IEEEhalf) + Ty = Type::getHalfTy(Context); + else if (&V.getSemantics() == &APFloat::IEEEsingle) Ty = Type::getFloatTy(Context); else if (&V.getSemantics() == &APFloat::IEEEdouble) Ty = Type::getDoubleTy(Context); @@ -939,6 +946,12 @@ bool ConstantFP::isValueValidForType(Type *Ty, const APFloat& Val) { return false; // These can't be represented as floating point! // FIXME rounding mode needs to be more flexible + case Type::HalfTyID: { + if (&Val2.getSemantics() == &APFloat::IEEEhalf) + return true; + Val2.convert(APFloat::IEEEhalf, APFloat::rmNearestTiesToEven, &losesInfo); + return !losesInfo; + } case Type::FloatTyID: { if (&Val2.getSemantics() == &APFloat::IEEEsingle) return true; @@ -946,22 +959,26 @@ bool ConstantFP::isValueValidForType(Type *Ty, const APFloat& Val) { return !losesInfo; } case Type::DoubleTyID: { - if (&Val2.getSemantics() == &APFloat::IEEEsingle || + if (&Val2.getSemantics() == &APFloat::IEEEhalf || + &Val2.getSemantics() == &APFloat::IEEEsingle || &Val2.getSemantics() == &APFloat::IEEEdouble) return true; Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo); return !losesInfo; } case Type::X86_FP80TyID: - return &Val2.getSemantics() == &APFloat::IEEEsingle || + return &Val2.getSemantics() == &APFloat::IEEEhalf || + &Val2.getSemantics() == &APFloat::IEEEsingle || &Val2.getSemantics() == &APFloat::IEEEdouble || &Val2.getSemantics() == &APFloat::x87DoubleExtended; case Type::FP128TyID: - return &Val2.getSemantics() == &APFloat::IEEEsingle || + return &Val2.getSemantics() == &APFloat::IEEEhalf || + &Val2.getSemantics() == &APFloat::IEEEsingle || &Val2.getSemantics() == &APFloat::IEEEdouble || &Val2.getSemantics() == &APFloat::IEEEquad; case Type::PPC_FP128TyID: - return &Val2.getSemantics() == &APFloat::IEEEsingle || + return &Val2.getSemantics() == &APFloat::IEEEhalf || + &Val2.getSemantics() == &APFloat::IEEEsingle || &Val2.getSemantics() == &APFloat::IEEEdouble || &Val2.getSemantics() == &APFloat::PPCDoubleDouble; } diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index a505e4b4f5..612d5fa2b9 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -136,6 +136,8 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { assert(false && "Unhandled TypeID."); case Type::VoidTyID: return LLVMVoidTypeKind; + case Type::HalfTyID: + return LLVMHalfTypeKind; case Type::FloatTyID: return LLVMFloatTypeKind; case Type::DoubleTyID: @@ -222,6 +224,9 @@ unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy) { /*--.. Operations on real types ............................................--*/ +LLVMTypeRef LLVMHalfTypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getHalfTy(*unwrap(C)); +} LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getFloatTy(*unwrap(C)); } @@ -241,6 +246,9 @@ LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getX86_MMXTy(*unwrap(C)); } +LLVMTypeRef LLVMHalfType(void) { + return LLVMHalfTypeInContext(LLVMGetGlobalContext()); +} LLVMTypeRef LLVMFloatType(void) { return LLVMFloatTypeInContext(LLVMGetGlobalContext()); } diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index 504b37267f..252b34033b 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -21,6 +21,7 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) : TheTrueVal(0), TheFalseVal(0), VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID), + HalfTy(C, Type::HalfTyID), FloatTy(C, Type::FloatTyID), DoubleTy(C, Type::DoubleTyID), MetadataTy(C, Type::MetadataTyID), diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index a3f68fecbb..30f9d46987 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -169,7 +169,7 @@ public: LeakDetectorImpl<Value> LLVMObjects; // Basic type instances. - Type VoidTy, LabelTy, FloatTy, DoubleTy, MetadataTy; + Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy; Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy; IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty; diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index 469defdb85..f4fad667a1 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -25,6 +25,7 @@ using namespace llvm; Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) { switch (IDNumber) { case VoidTyID : return getVoidTy(C); + case HalfTyID : return getHalfTy(C); case FloatTyID : return getFloatTy(C); case DoubleTyID : return getDoubleTy(C); case X86_FP80TyID : return getX86_FP80Ty(C); @@ -73,7 +74,7 @@ bool Type::isIntOrIntVectorTy() const { /// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP types. /// bool Type::isFPOrFPVectorTy() const { - if (ID == Type::FloatTyID || ID == Type::DoubleTyID || + if (ID == Type::HalfTyID || ID == Type::FloatTyID || ID == Type::DoubleTyID || ID == Type::FP128TyID || ID == Type::X86_FP80TyID || ID == Type::PPC_FP128TyID) return true; @@ -139,6 +140,7 @@ bool Type::isEmptyTy() const { unsigned Type::getPrimitiveSizeInBits() const { switch (getTypeID()) { + case Type::HalfTyID: return 16; case Type::FloatTyID: return 32; case Type::DoubleTyID: return 64; case Type::X86_FP80TyID: return 80; @@ -165,6 +167,7 @@ int Type::getFPMantissaWidth() const { if (const VectorType *VTy = dyn_cast<VectorType>(this)) return VTy->getElementType()->getFPMantissaWidth(); assert(isFloatingPointTy() && "Not a floating point type!"); + if (ID == HalfTyID) return 11; if (ID == FloatTyID) return 24; if (ID == DoubleTyID) return 53; if (ID == X86_FP80TyID) return 64; @@ -207,6 +210,7 @@ bool Type::isSizedDerivedType() const { Type *Type::getVoidTy(LLVMContext &C) { return &C.pImpl->VoidTy; } Type *Type::getLabelTy(LLVMContext &C) { return &C.pImpl->LabelTy; } +Type *Type::getHalfTy(LLVMContext &C) { return &C.pImpl->HalfTy; } Type *Type::getFloatTy(LLVMContext &C) { return &C.pImpl->FloatTy; } Type *Type::getDoubleTy(LLVMContext &C) { return &C.pImpl->DoubleTy; } Type *Type::getMetadataTy(LLVMContext &C) { return &C.pImpl->MetadataTy; } @@ -225,6 +229,10 @@ IntegerType *Type::getIntNTy(LLVMContext &C, unsigned N) { return IntegerType::get(C, N); } +PointerType *Type::getHalfPtrTy(LLVMContext &C, unsigned AS) { + return getHalfTy(C)->getPointerTo(AS); +} + PointerType *Type::getFloatPtrTy(LLVMContext &C, unsigned AS) { return getFloatTy(C)->getPointerTo(AS); } |