diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 875bd27e13206..f785d220b0c78 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -10,6 +10,9 @@ endif() # Must go below project(..) include(GNUInstallDirs) +list(APPEND CMAKE_REQUIRED_INCLUDES "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src") +list(APPEND CMAKE_REQUIRED_LIBRARIES "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/libbid.a") + if(CLANG_BUILT_STANDALONE) set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") set(CMAKE_CXX_STANDARD_REQUIRED YES) @@ -998,6 +1001,8 @@ endif() set(CLANG_INSTALL_LIBDIR_BASENAME "lib${CLANG_LIBDIR_SUFFIX}") + configure_file( ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake ${CLANG_BINARY_DIR}/include/clang/Config/config.h) + diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 4e6fe060f2518..2e839b667522c 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -1531,7 +1531,12 @@ enum CXCursorKind { */ CXCursor_RequiresExpr = 154, - CXCursor_LastExpr = CXCursor_RequiresExpr, + /** + * Decimal Float literal + */ + CXCursor_DecimalFloatLiteral = 155, + + CXCursor_LastExpr = CXCursor_DecimalFloatLiteral, /* Statements */ CXCursor_FirstStmt = 200, diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 5f4ac02f53c9a..12397d775ffda 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_AST_APVALUE_H #include "clang/Basic/LLVM.h" +#include "llvm/ADT/APDecimalFloat.h" #include "llvm/ADT/APFixedPoint.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" @@ -123,6 +124,7 @@ class APValue { typedef llvm::APFixedPoint APFixedPoint; typedef llvm::APSInt APSInt; typedef llvm::APFloat APFloat; + typedef llvm::APDecimalFloat APDecimalFloat; public: enum ValueKind { /// There is no such object (it's outside its lifetime). @@ -140,7 +142,8 @@ class APValue { Struct, Union, MemberPointer, - AddrLabelDiff + AddrLabelDiff, + DecimalFloat }; class LValueBase { @@ -316,6 +319,9 @@ class APValue { explicit APValue(APFixedPoint FX) : Kind(None) { MakeFixedPoint(std::move(FX)); } + explicit APValue(APDecimalFloat DF) : Kind(None) { + MakeDecimalFloat(std::move(DF)); + } explicit APValue(const APValue *E, unsigned N) : Kind(None) { MakeVector(); setVector(E, N); } @@ -402,6 +408,7 @@ class APValue { bool isUnion() const { return Kind == Union; } bool isMemberPointer() const { return Kind == MemberPointer; } bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } + bool isDecimalFloat() const { return Kind == DecimalFloat; } void dump() const; void dump(raw_ostream &OS, const ASTContext &Context) const; @@ -442,6 +449,14 @@ class APValue { return const_cast(this)->getFixedPoint(); } + APDecimalFloat &getDecimalFloat() { + assert(isDecimalFloat() && "Invalid accessor"); + return *(APDecimalFloat *)(char *)&Data; + } + const APDecimalFloat &getDecimalFloat() const { + return const_cast(this)->getDecimalFloat(); + } + APSInt &getComplexIntReal() { assert(isComplexInt() && "Invalid accessor"); return ((ComplexAPSInt *)(char *)&Data)->Real; @@ -589,6 +604,10 @@ class APValue { assert(isFixedPoint() && "Invalid accessor"); *(APFixedPoint *)(char *)&Data = std::move(FX); } + void setDecimalFloat(APDecimalFloat FX) { + assert(isDecimalFloat() && "Invalid accessor"); + *(APDecimalFloat *)(char *)&Data = std::move(FX); + } void setVector(const APValue *E, unsigned N) { MutableArrayRef InternalElts = setVectorUninit(N); for (unsigned i = 0; i != N; ++i) @@ -637,6 +656,11 @@ class APValue { new ((void *)(char *)&Data) APFixedPoint(std::move(FX)); Kind = FixedPoint; } + void MakeDecimalFloat(APDecimalFloat &&DF) { + assert(isAbsent() && "Bad state change"); + new ((void *)(char *)&Data) APDecimalFloat(std::move(DF)); + Kind = DecimalFloat; + } void MakeVector() { assert(isAbsent() && "Bad state change"); new ((void *)(char *)&Data) Vec(); diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index c4954f0d11a3d..d3b72c964b2f0 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -77,8 +77,10 @@ namespace llvm { class APFixedPoint; +class APDecimalFloat; class FixedPointSemantics; struct fltSemantics; +struct decFltSemantics; template class SmallPtrSet; } // namespace llvm @@ -1117,6 +1119,8 @@ class ASTContext : public RefCountedBase { CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy; CanQualType UnsignedLongLongTy, UnsignedInt128Ty; CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty, Ibm128Ty; + CanQualType DecimalFloat32Ty, DecimalFloat64Ty, DecimalFloat128Ty; // ISO/IEC TS 18661-2:2015 C23 conditionally supported + // ISO/IEC TR 24733:2011 C++ support CanQualType ShortAccumTy, AccumTy, LongAccumTy; // ISO/IEC JTC1 SC22 WG14 N1169 Extension CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy; @@ -2187,6 +2191,10 @@ class ASTContext : public RefCountedBase { llvm::APFixedPoint getFixedPointMax(QualType Ty) const; llvm::APFixedPoint getFixedPointMin(QualType Ty) const; + llvm::decFltSemantics getDecimalFloatSemantics(QualType Ty) const; + llvm::APDecimalFloat getDecimalFloatMax(QualType Ty) const; + llvm::APDecimalFloat getDecimalFloatMin(QualType Ty) const; + DeclarationNameInfo getNameForTemplate(TemplateName Name, SourceLocation NameLoc) const; diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h index 3394c68f54ebe..5969dfa482b5a 100644 --- a/clang/include/clang/AST/AbstractBasicReader.h +++ b/clang/include/clang/AST/AbstractBasicReader.h @@ -188,6 +188,16 @@ class DataStreamBasicReader : public BasicReaderBase { hasUnsignedPadding); } + llvm::decFltSemantics readdecFltSemantics() { + unsigned width = asImpl().readUInt32(); + unsigned scale = asImpl().readUInt32(); + unsigned isSigned = asImpl().readBool(); + unsigned isSat = asImpl().readBool(); + unsigned HasPadding = asImpl().readBool(); + + return llvm::decFltSemantics(width, scale, isSigned, isSat, HasPadding); + } + APValue::LValuePathSerializationHelper readLValuePathSerializationHelper( SmallVectorImpl &path) { auto elemTy = asImpl().readQualType(); diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h index 41772ba0f63cd..f7b247579162e 100644 --- a/clang/include/clang/AST/AbstractBasicWriter.h +++ b/clang/include/clang/AST/AbstractBasicWriter.h @@ -172,6 +172,14 @@ class DataStreamBasicWriter : public BasicWriterBase { sema.hasUnsignedPadding() << 2); } + void writedecFltSemantics(const llvm::decFltSemantics &sema) { + asImpl().writeUInt32(sema.getWidth()); + asImpl().writeUInt32(sema.getScale()); + asImpl().writeBool(sema.isSigned()); + asImpl().writeBool(sema.isSaturated()); + asImpl().writeBool(sema.hasUnsignedPadding()); + } + void writeLValuePathSerializationHelper( APValue::LValuePathSerializationHelper lvaluePath) { ArrayRef path = lvaluePath.Path; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f12719..f71054ae9b0c8 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -221,6 +221,18 @@ FLOATING_TYPE(Float128, Float128Ty) // '__ibm128' FLOATING_TYPE(Ibm128, Ibm128Ty) +// Putting Decimal Float types below IBM128Ty so that BuiltinType::isFloatingPoint() does +// not return true +// +// '_Decimal32' +SIGNED_TYPE(DecimalFloat32, DecimalFloat32Ty) + +// '_Decimal64' +SIGNED_TYPE(DecimalFloat64, DecimalFloat64Ty) + +// '_Decimal128' +SIGNED_TYPE(DecimalFloat128, DecimalFloat128Ty) + //===- Language-specific types --------------------------------------------===// // This is the type of C++0x 'nullptr'. diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index a65e06205fa6b..fa541a6c66dee 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1500,6 +1500,28 @@ class APFloatStorage : private APNumericStorage { } }; +class APDecimalFloatStorage : private APNumericStorage { +public: + // llvm::APDecimalFloat + llvm::APInt getValue(const llvm::decFltSemantics &Semantics) const { + // return llvm::APDecimalFloat(getIntValue(),Semantics); + return getIntValue(); + } + + llvm::APInt getValue() const { + // return llvm::APDecimalFloat(getIntValue(),Semantics); + return getIntValue(); + } + + void setValue(const ASTContext &C, const llvm::APDecimalFloat &Val) { + setIntValue(C, Val.bitcastToAPInt()); + } + void setValue(const ASTContext &C, const llvm::APInt &Val) { + setIntValue(C, Val); + } +}; + + class IntegerLiteral : public Expr, public APIntStorage { SourceLocation Loc; @@ -1590,6 +1612,61 @@ class FixedPointLiteral : public Expr, public APIntStorage { } }; +class DecimalFloatLiteral : public Expr, public APDecimalFloatStorage { + SourceLocation Loc; + unsigned width = 32; + unsigned scale = 1; + bool isSigned = false; + + /// \brief Construct an empty fixed-point literal. + explicit DecimalFloatLiteral(EmptyShell Empty) + : Expr(DecimalFloatLiteralClass, Empty) {} + + public: + DecimalFloatLiteral(const ASTContext &C, const llvm::APDecimalFloat &V, QualType type, + SourceLocation l, unsigned width = 32 ); + + + /// Returns an empty fixed-point literal. + static DecimalFloatLiteral *Create(const ASTContext &C, EmptyShell Empty); + static DecimalFloatLiteral * + CreateFromAPDecimalFloat(const ASTContext &C, llvm::APDecimalFloat Val, + QualType type, SourceLocation l, unsigned width); + + SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } + SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } + + /// \brief Retrieve the location of the literal. + SourceLocation getLocation() const { return Loc; } + + void setLocation(SourceLocation Location) { Loc = Location; } + + llvm::decFltSemantics getSemantics() const { + return {width, scale, isSigned, false, false}; + } + + // llvm::APDecimalFloat getValue() const { + // return APDecimalFloatStorage::getValue(getSemantics()); + // } + + void setWidth(unsigned Width) { width = Width;} + unsigned getWidth() { return width; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == DecimalFloatLiteralClass; + } + + std::string getValueAsString() const; + + // Iterators + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + class CharacterLiteral : public Expr { public: enum CharacterKind { diff --git a/clang/include/clang/AST/OperationKinds.def b/clang/include/clang/AST/OperationKinds.def index b05b9d81569eb..d4499d65edc39 100644 --- a/clang/include/clang/AST/OperationKinds.def +++ b/clang/include/clang/AST/OperationKinds.def @@ -225,10 +225,35 @@ CAST_OPERATION(FixedPointToIntegral) /// (_Accum) 2 CAST_OPERATION(IntegralToFixedPoint) -/// CK_FixedPointToBoolean - Fixed point to boolean. +/// CK_FixedPointToBoolean - Decimal Float to boolean. /// (bool) 0.5r CAST_OPERATION(FixedPointToBoolean) +/// CK_FloatingToDecimalFloat - Floating to Decimal Float. +/// _Accum a = f; +CAST_OPERATION(FloatingToDecimalFloat) + +/// CK_DecimalFloatToFloating - Decimal Float to floating. +/// (float) 2.5k +CAST_OPERATION(DecimalFloatToFloating) + +/// CK_DecimalFloatCast - Decimal Float to Decimal Float. +/// (_Accum) 0.5r +CAST_OPERATION(DecimalFloatCast) + +/// CK_DecimalFloatToIntegral - Decimal Float to integral. +/// (int) 2.0k +CAST_OPERATION(DecimalFloatToIntegral) + +/// CK_IntegralToDecimalFloat - Integral to a Decimal Float. +/// (_Accum) 2 +CAST_OPERATION(IntegralToDecimalFloat) + +/// CK_DecimalFloatToBoolean - Decimal Float to boolean. +/// (bool) 0.5r +CAST_OPERATION(DecimalFloatToBoolean) + + /// CK_FloatingToIntegral - Floating point to integral. Rounds /// towards zero, discarding any fractional component. /// (int) f diff --git a/clang/include/clang/AST/OptionalDiagnostic.h b/clang/include/clang/AST/OptionalDiagnostic.h index c9a2d19f4ebce..18fda5ee0bb62 100644 --- a/clang/include/clang/AST/OptionalDiagnostic.h +++ b/clang/include/clang/AST/OptionalDiagnostic.h @@ -16,6 +16,7 @@ #include "clang/AST/APValue.h" #include "clang/Basic/PartialDiagnostic.h" +#include "llvm/ADT/APDecimalFloat.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallVector.h" @@ -71,6 +72,15 @@ class OptionalDiagnostic { } return *this; } + + OptionalDiagnostic &operator<<(const llvm::APDecimalFloat &DF) { + if (Diag) { + SmallVector Buffer; + DF.toString(Buffer); + *Diag << StringRef(Buffer.data(), Buffer.size()); + } + return *this; + } }; } // namespace clang diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td index a61f0770adbd3..e4f2161a9ad42 100644 --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -117,6 +117,9 @@ def ExtParameterInfo : PropertyType<"FunctionProtoType::ExtParameterInfo">; def FixedPointSemantics : PropertyType<"llvm::FixedPointSemantics"> { let PassByReference = 1; } +def decFltSemantics : PropertyType<"llvm::decFltSemantics"> { + let PassByReference = 1; +} def Identifier : RefPropertyType<"IdentifierInfo"> { let ConstWhenWriting = 1; } def LValuePathEntry : PropertyType<"APValue::LValuePathEntry">; def LValuePathSerializationHelper : @@ -293,6 +296,17 @@ let Class = PropertyTypeCase in { return APValue(llvm::APFixedPoint(std::move(value), semantics)); }]>; } +let Class = PropertyTypeCase in { + def : Property<"semantics", decFltSemantics> { + let Read = [{ node.getDecimalFloat().getSemantics() }]; + } + def : Property<"value", APInt> { + let Read = [{ node.getDecimalFloat().bitcastToAPInt() }]; + } + def : Creator<[{ + return APValue(llvm::APDecimalFloat(std::move(value), semantics)); + }]>; +} let Class = PropertyTypeCase in { def : Property<"real", APSInt> { let Read = [{ node.getComplexIntReal() }]; diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 9f5d1be1174cb..78cc069a38cf7 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2905,6 +2905,7 @@ DEF_TRAVERSE_STMT(RequiresExpr, { // These literals (all of them) do not need any action. DEF_TRAVERSE_STMT(IntegerLiteral, {}) DEF_TRAVERSE_STMT(FixedPointLiteral, {}) +DEF_TRAVERSE_STMT(DecimalFloatLiteral, {}) DEF_TRAVERSE_STMT(CharacterLiteral, {}) DEF_TRAVERSE_STMT(FloatingLiteral, {}) DEF_TRAVERSE_STMT(ImaginaryLiteral, {}) diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index c7d9dce9c6b2d..5bf5b28bf4d26 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -258,6 +258,7 @@ class TextNodeDumper void VisitCharacterLiteral(const CharacterLiteral *Node); void VisitIntegerLiteral(const IntegerLiteral *Node); void VisitFixedPointLiteral(const FixedPointLiteral *Node); + void VisitDecimalFloatLiteral(const DecimalFloatLiteral *Node); void VisitFloatingLiteral(const FloatingLiteral *Node); void VisitStringLiteral(const StringLiteral *Str); void VisitInitListExpr(const InitListExpr *ILE); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index fbf65e588fb51..ad86539ffe1fb 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -30,6 +30,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/Visibility.h" +#include "llvm/ADT/APDecimalFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" @@ -2492,9 +2493,16 @@ class alignas(8) Type : public ExtQualsTypeCommonBase { /// ISO/IEC JTC1 SC22 WG14 N1169. bool isFixedPointType() const; + /// Return true if this is a decimal float type according to + /// ISO/IEC TS 18661-2:2015 + bool isDecimalFloatType() const; + /// Return true if this is a fixed point or integer type. bool isFixedPointOrIntegerType() const; + /// Return true if this is a decinal float or integer type. + bool isDecimalFloatOrIntegerType() const; + /// Return true if this is a saturated fixed point type according to /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. bool isSaturatedFixedPointType() const; @@ -7275,10 +7283,23 @@ inline bool Type::isFixedPointType() const { return false; } +inline bool Type::isDecimalFloatType() const { + if (const auto *BT = dyn_cast(CanonicalType)) { + return BT->getKind() >= BuiltinType::DecimalFloat32 && + BT->getKind() <= BuiltinType::DecimalFloat128 ; + } + return false; +} + + inline bool Type::isFixedPointOrIntegerType() const { return isFixedPointType() || isIntegerType(); } +inline bool Type::isDecimalFloatOrIntegerType() const { + return isDecimalFloatType() || isIntegerType(); +} + inline bool Type::isSaturatedFixedPointType() const { if (const auto *BT = dyn_cast(CanonicalType)) { return BT->getKind() >= BuiltinType::SatShortAccum && @@ -7533,6 +7554,8 @@ QualType DecayedType::getPointeeType() const { void FixedPointValueToString(SmallVectorImpl &Str, llvm::APSInt Val, unsigned Scale); +void DecimalFloatValueToString(SmallVectorImpl &Str, llvm::APDecimalFloat Val); + } // namespace clang #endif // LLVM_CLANG_AST_TYPE_H diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index ebbd8db313428..8342da55fc5f3 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -61,6 +61,7 @@ def SYCLUniqueStableNameExpr : StmtNode; def DeclRefExpr : StmtNode; def IntegerLiteral : StmtNode; def FixedPointLiteral : StmtNode; +def DecimalFloatLiteral : StmtNode; def FloatingLiteral : StmtNode; def ImaginaryLiteral : StmtNode; def StringLiteral : StmtNode; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 9b9439e2c34f6..1070da18ce220 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -89,6 +89,9 @@ struct TransferrableTargetInfo { unsigned char FloatWidth, FloatAlign; unsigned char DoubleWidth, DoubleAlign; unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align, Ibm128Align; + unsigned char DecimalFloat32Width, DecimalFloat32Align; + unsigned char DecimalFloat64Width, DecimalFloat64Align; + unsigned char DecimalFloat128Width, DecimalFloat128Align; unsigned char LargeArrayMinWidth, LargeArrayAlign; unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; @@ -742,6 +745,21 @@ class TargetInfo : public virtual TransferrableTargetInfo, unsigned getIbm128Align() const { return Ibm128Align; } const llvm::fltSemantics &getIbm128Format() const { return *Ibm128Format; } + /// DecimalFloat32Width/Align/Format - Return the size/align/format of + /// '_Decimal32'. + unsigned getDecimalFloat32Width() const { return DecimalFloat32Width; } + unsigned getDecimalFloat32Align() const { return DecimalFloat32Align; } + + /// DecimalFloat64Width/Align/Format - Return the size/align/format of + /// '_Decimal64'. + unsigned getDecimalFloat64Width() const { return DecimalFloat64Width; } + unsigned getDecimalFloat64Align() const { return DecimalFloat64Align; } + + /// DecimalFloat128Width/Align/Format - Return the size/align/format of + /// '_Decimal128'. + unsigned getDecimalFloat128Width() const { return DecimalFloat128Width; } + unsigned getDecimalFloat128Align() const { return DecimalFloat128Align; } + /// Return the mangled code of long double. virtual const char *getLongDoubleMangling() const { return "e"; } diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index fd237c2c9cd87..e6f9eff26d655 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -17,6 +17,7 @@ #include "clang/Basic/CharInfo.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/TokenKinds.h" +#include "llvm/ADT/APDecimalFloat.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" @@ -51,7 +52,8 @@ class NumericLiteralParser { unsigned radix; - bool saw_exponent, saw_period, saw_ud_suffix, saw_fixed_point_suffix; + bool saw_exponent, saw_period, saw_ud_suffix, saw_fixed_point_suffix, + saw_decimal_float_suffix; SmallString<32> UDSuffixBuf; @@ -72,6 +74,11 @@ class NumericLiteralParser { bool isFract : 1; // 1.0hr/r/lr/uhr/ur/ulr bool isAccum : 1; // 1.0hk/k/lk/uhk/uk/ulk bool isBitInt : 1; // 1wb, 1uwb (C2x) + bool isDecimalFloat : 1; // df/DF for _Decimal32 dd/DD for _Decimal64 dl/DL + // for _Decimal128 + bool isDecimal32 : 1; // 6543.0DF + bool isDecimal64 : 1; // 9.99DD + bool isDecimal128 : 1; // 9.99DL uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. @@ -79,6 +86,10 @@ class NumericLiteralParser { return (saw_period || saw_exponent) && saw_fixed_point_suffix; } + bool isDecimalFloatLiteral() const { + return (saw_period || saw_exponent) && saw_decimal_float_suffix; + } + bool isIntegerLiteral() const { return !saw_period && !saw_exponent && !isFixedPointLiteral(); } @@ -121,6 +132,8 @@ class NumericLiteralParser { /// calculating the digit sequence of the exponent. bool GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale); + bool GetDecimalFloatValue(llvm::APDecimalFloat &Result); + /// Get the digits that comprise the literal. This excludes any prefix or /// suffix associated with the literal. StringRef getLiteralDigits() const { diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 3bbd2723be676..abed0b7abd8b6 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1077,6 +1077,16 @@ enum PredefinedTypeIDs { /// \brief The '__ibm128' type PREDEF_TYPE_IBM128_ID = 74, + /// \brief The '_Decimal32' type + PREDEF_TYPE_DECIMAL_FLOAT32_ID = 75, + + /// \brief The '_Decimal64' type + PREDEF_TYPE_DECIMAL_FLOAT64_ID = 76, + + /// \brief The '_Decimal128' type + PREDEF_TYPE_DECIMAL_FLOAT128_ID = 77, + + /// OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, @@ -1998,6 +2008,9 @@ enum StmtCode { // FixedPointLiteral EXPR_FIXEDPOINT_LITERAL, + // DecimalFloatLiteral + EXPR_DECIMALFLOAT_LITERAL, + // SYCLUniqueStableNameExpr EXPR_SYCL_UNIQUE_STABLE_NAME, }; diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 634423008c2ed..f13e3b7dbafa4 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -327,6 +327,11 @@ APValue::APValue(const APValue &RHS) : Kind(None) { MakeFixedPoint(std::move(FXCopy)); break; } + case DecimalFloat: { + APDecimalFloat DFCopy = RHS.getDecimalFloat(); + MakeDecimalFloat(std::move(DFCopy)); + break; + } case Vector: MakeVector(); setVector(((const Vec *)(const char *)&RHS.Data)->Elts, @@ -405,6 +410,8 @@ void APValue::DestroyDataAndMakeUninit() { ((APFloat *)(char *)&Data)->~APFloat(); else if (Kind == FixedPoint) ((APFixedPoint *)(char *)&Data)->~APFixedPoint(); + else if (Kind == DecimalFloat) + ((APDecimalFloat *)(char *)&Data)->~APDecimalFloat(); else if (Kind == Vector) ((Vec *)(char *)&Data)->~Vec(); else if (Kind == ComplexInt) @@ -443,6 +450,8 @@ bool APValue::needsCleanup() const { return getFloat().needsCleanup(); case FixedPoint: return getFixedPoint().getValue().needsCleanup(); + case DecimalFloat: + return getDecimalFloat().needsCleanup(); case ComplexFloat: assert(getComplexFloatImag().needsCleanup() == getComplexFloatReal().needsCleanup() && @@ -580,6 +589,10 @@ void APValue::Profile(llvm::FoldingSetNodeID &ID) const { profileIntValue(ID, getFixedPoint().getValue()); return; + case DecimalFloat: + profileIntValue(ID, getDecimalFloat().bitcastToAPInt()); + return; + case ComplexFloat: profileIntValue(ID, getComplexFloatReal().bitcastToAPInt()); profileIntValue(ID, getComplexFloatImag().bitcastToAPInt()); @@ -721,6 +734,9 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy, case APValue::FixedPoint: Out << getFixedPoint(); return; + case APValue::DecimalFloat: + Out << getDecimalFloat(); + return; case APValue::Vector: { Out << '{'; QualType ElemTy = Ty->castAs()->getElementType(); @@ -1121,6 +1137,7 @@ LinkageInfo LinkageComputer::getLVForValue(const APValue &V, case APValue::Int: case APValue::Float: case APValue::FixedPoint: + case APValue::DecimalFloat: case APValue::ComplexInt: case APValue::ComplexFloat: case APValue::Vector: diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b9d12e203feef..1edc1442db08f 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -64,6 +64,7 @@ #include "clang/Basic/TargetCXXABI.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/XRayLists.h" +#include "llvm/ADT/APDecimalFloat.h" #include "llvm/ADT/APFixedPoint.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" @@ -1325,6 +1326,10 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, // __ibm128 for IBM extended precision InitBuiltinType(Ibm128Ty, BuiltinType::Ibm128); + InitBuiltinType(DecimalFloat32Ty, BuiltinType::DecimalFloat32); + InitBuiltinType(DecimalFloat64Ty, BuiltinType::DecimalFloat64); + InitBuiltinType(DecimalFloat128Ty, BuiltinType::DecimalFloat128); + // C11 extension ISO/IEC TS 18661-3 InitBuiltinType(Float16Ty, BuiltinType::Float16); @@ -1734,6 +1739,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { } } + CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { unsigned Align = Target->getCharWidth(); @@ -2158,6 +2164,18 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Width = Target->getIbm128Width(); Align = Target->getIbm128Align(); break; + case BuiltinType::DecimalFloat32: + Width = Target->getDecimalFloat32Width(); + Align = Target->getDecimalFloat32Align(); + break; + case BuiltinType::DecimalFloat64: + Width = Target->getDecimalFloat64Width(); + Align = Target->getDecimalFloat64Align(); + break; + case BuiltinType::DecimalFloat128: + Width = Target->getDecimalFloat128Width(); + Align = Target->getDecimalFloat128Align(); + break; case BuiltinType::LongDouble: if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && (Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() || @@ -8004,6 +8022,9 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C, case BuiltinType::SatUShortFract: case BuiltinType::SatUFract: case BuiltinType::SatULongFract: + case BuiltinType::DecimalFloat32: + case BuiltinType::DecimalFloat64: + case BuiltinType::DecimalFloat128: // FIXME: potentially need @encodes for these! return ' '; @@ -13249,6 +13270,24 @@ llvm::APFixedPoint ASTContext::getFixedPointMin(QualType Ty) const { return llvm::APFixedPoint::getMin(getFixedPointSemantics(Ty)); } +llvm::decFltSemantics ASTContext::getDecimalFloatSemantics(QualType Ty) const{ + assert(Ty->isDecimalFloatType()); + + return llvm::decFltSemantics( + static_cast(getTypeSize(Ty)), /*Scale=*/1u, /*IsSigned=*/0u, + /*IsSaturated=*/false, /*HasUnsignedPadding=*/false); +} + +llvm::APDecimalFloat ASTContext::getDecimalFloatMax(QualType Ty) const { + assert(Ty->isDecimalFloatType()); + return llvm::APDecimalFloat::getMax(getDecimalFloatSemantics(Ty)); +} + +llvm::APDecimalFloat ASTContext::getDecimalFloatMin(QualType Ty) const { + assert(Ty->isDecimalFloatType()); + return llvm::APDecimalFloat::getMin(getDecimalFloatSemantics(Ty)); +} + QualType ASTContext::getCorrespondingSignedFixedPointType(QualType Ty) const { assert(Ty->isUnsignedFixedPointType() && "Expected unsigned fixed point type"); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 65aff71bf691d..0e57e3bb38f61 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -9783,6 +9783,7 @@ ASTNodeImporter::ImportAPValue(const APValue &FromValue) { case APValue::Int: case APValue::Float: case APValue::FixedPoint: + case APValue::DecimalFloat: case APValue::ComplexInt: case APValue::ComplexFloat: Result = FromValue; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 08b5e8d45c95a..3a81ec68b96df 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1015,6 +1015,33 @@ std::string FixedPointLiteral::getValueAsString(unsigned Radix) const { return std::string(S.str()); } +DecimalFloatLiteral::DecimalFloatLiteral(const ASTContext &C, const llvm::APDecimalFloat &V, + QualType type, SourceLocation l, unsigned width) + : Expr(DecimalFloatLiteralClass, type, VK_PRValue, OK_Ordinary), Loc(l), width(width) { + assert(type->isDecimalFloatType() && "Illegal type in DecimalFloatLiterals"); + + setValue(C,V); + setDependence(ExprDependence::None); +} + +DecimalFloatLiteral *DecimalFloatLiteral::Create(const ASTContext &C, + EmptyShell Empty) { + return new (C) DecimalFloatLiteral(Empty); +} + +DecimalFloatLiteral *DecimalFloatLiteral::CreateFromAPDecimalFloat( + const ASTContext &C, llvm::APDecimalFloat Val, QualType type, + SourceLocation l, unsigned width) { + return new (C) DecimalFloatLiteral(C, Val, type, l, width); +} + +std::string DecimalFloatLiteral::getValueAsString() const { + SmallString<64> S; + DecimalFloatValueToString(S, + llvm::APDecimalFloat(getValue(), getSemantics())); + return std::string(S.str()); +} + void CharacterLiteral::print(unsigned Val, CharacterKind Kind, raw_ostream &OS) { switch (Kind) { @@ -1905,6 +1932,11 @@ bool CastExpr::CastConsistency() const { case CK_FixedPointCast: case CK_FixedPointToIntegral: case CK_IntegralToFixedPoint: + case CK_FloatingToDecimalFloat: + case CK_DecimalFloatToFloating: + case CK_DecimalFloatCast: + case CK_DecimalFloatToIntegral: + case CK_IntegralToDecimalFloat: case CK_MatrixCast: assert(!getType()->isBooleanType() && "unheralded conversion to bool"); goto CheckNoBasePath; @@ -1919,6 +1951,7 @@ bool CastExpr::CastConsistency() const { case CK_FloatingToBoolean: case CK_MemberPointerToBoolean: case CK_FloatingComplexToBoolean: + case CK_DecimalFloatToBoolean: case CK_IntegralComplexToBoolean: case CK_LValueBitCast: // -> bool& case CK_LValueToRValueBitCast: @@ -3526,6 +3559,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case PredefinedExprClass: case IntegerLiteralClass: case FixedPointLiteralClass: + case DecimalFloatLiteralClass: case FloatingLiteralClass: case ImaginaryLiteralClass: case StringLiteralClass: diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 6c122cac2c60b..f7f6b26ca58ba 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -170,6 +170,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::ConvertVectorExprClass: case Expr::IntegerLiteralClass: case Expr::FixedPointLiteralClass: + case Expr::DecimalFloatLiteralClass: case Expr::CharacterLiteralClass: case Expr::AddrLabelExprClass: case Expr::CXXDeleteExprClass: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 64c50c8b82e5a..d3b19534327ce 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -51,6 +51,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/APDecimalFloat.h" #include "llvm/ADT/APFixedPoint.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallBitVector.h" @@ -63,6 +64,7 @@ #define DEBUG_TYPE "exprconstant" using namespace clang; +using llvm::APDecimalFloat; using llvm::APFixedPoint; using llvm::APInt; using llvm::APSInt; @@ -1833,6 +1835,11 @@ static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info); +/// Evaluate only a decimal float expression into an APResult. +static bool EvaluateDecimalFloat(const Expr *E, APDecimalFloat &Result, + EvalInfo &Info); + + //===----------------------------------------------------------------------===// // Misc utilities //===----------------------------------------------------------------------===// @@ -2490,6 +2497,9 @@ static bool HandleConversionToBool(const APValue &Val, bool &Result) { case APValue::FixedPoint: Result = Val.getFixedPoint().getBoolValue(); return true; + case APValue::DecimalFloat: + Result = Val.getDecimalFloat().getBoolValue(); + return true; case APValue::Float: Result = !Val.getFloat().isZero(); return true; @@ -6898,6 +6908,8 @@ class APValueToBufferConverter { return visitInt(Val.getInt(), Ty, Offset); case APValue::Float: return visitFloat(Val.getFloat(), Ty, Offset); + case APValue::DecimalFloat: + return visitDecimalFloat(Val.getDecimalFloat(), Ty, Offset); case APValue::Array: return visitArray(Val, Ty, Offset); case APValue::Struct: @@ -7011,6 +7023,12 @@ class APValueToBufferConverter { return visitInt(AsInt, Ty, Offset); } + bool visitDecimalFloat(const APDecimalFloat &Val, QualType Ty, + CharUnits Offset) { + APSInt AsInt(Val.bitcastToAPInt()); + return visitInt(AsInt, Ty, Offset); + } + public: static Optional convert(EvalInfo &Info, const APValue &Src, const CastExpr *BCE) { @@ -11091,6 +11109,46 @@ class FixedPointExprEvaluator bool VisitUnaryOperator(const UnaryOperator *E); bool VisitBinaryOperator(const BinaryOperator *E); }; + + +class DecimalFloatExprEvaluator + : public ExprEvaluatorBase { + APValue &Result; + + public: + DecimalFloatExprEvaluator(EvalInfo &info, APValue &result) + : ExprEvaluatorBaseTy(info), Result(result) {} + + bool Success(const APValue &V, const Expr *E) { + return Success(V.getDecimalFloat(), E); + } + + bool Success(const APInt &V, const Expr *E) { + return Success( + APDecimalFloat(V, Info.Ctx.getDecimalFloatSemantics(E->getType())), E); + } + + bool Success(const APDecimalFloat &V, const Expr *E) { + assert(E->getType()->isDecimalFloatType() && "Invalid evaluation result."); + assert(V.getWidth() == Info.Ctx.getIntWidth(E->getType()) && + "Invalid evaluation result."); + Result = APValue(V); + return true; + } + + //===--------------------------------------------------------------------===// + // Visitor Methods + //===--------------------------------------------------------------------===// + + bool VisitDecimalFloatLiteral(const DecimalFloatLiteral *E) { + return Success(E->getValue(), E); + } + + bool VisitCastExpr(const CastExpr *E); + bool VisitUnaryOperator(const UnaryOperator *E); + bool VisitBinaryOperator(const BinaryOperator *E); +}; + } // end anonymous namespace /// EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and @@ -11145,6 +11203,22 @@ static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, return false; } +static bool EvaluateDecimalFloat(const Expr *E, APDecimalFloat &Result, + EvalInfo &Info) { + assert(!E->isValueDependent()); + if (E->getType()->isDecimalFloatType()) { + APValue Val; + if (!DecimalFloatExprEvaluator(Info, Val).Visit(E)) + return false; + if (!Val.isDecimalFloat()) + return false; + + Result = Val.getDecimalFloat(); + return true; + } + return false; +} + static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info) { assert(!E->isValueDependent()); @@ -13866,6 +13940,157 @@ bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { return Success(Result, E); } +bool DecimalFloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { + switch (E->getOpcode()) { + default: + // Invalid unary operators + return Error(E); + case UO_Plus: + // The result is just the value. + return Visit(E->getSubExpr()); + case UO_Minus: { + if (!Visit(E->getSubExpr())) return false; + if (!Result.isDecimalFloat()) + return Error(E); + bool Overflowed; + APDecimalFloat Negated = Result.getDecimalFloat().negate(&Overflowed); + if (Overflowed && !HandleOverflow(Info, E, Negated, E->getType())) + return false; + return Success(Negated, E); + } + } +} + +bool DecimalFloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { + if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma) + return ExprEvaluatorBaseTy::VisitBinaryOperator(E); + + const Expr *LHS = E->getLHS(); + const Expr *RHS = E->getRHS(); + llvm::decFltSemantics ResultFXSema = + Info.Ctx.getDecimalFloatSemantics(E->getType()); + + APDecimalFloat LHSFX(Info.Ctx.getDecimalFloatSemantics(LHS->getType())); + if (!EvaluateDecimalFloat(LHS, LHSFX, Info)) + return false; + APDecimalFloat RHSFX(Info.Ctx.getDecimalFloatSemantics(RHS->getType())); + if (!EvaluateDecimalFloat(RHS, RHSFX, Info)) + return false; + + bool OpOverflow = false, ConversionOverflow = false; + APDecimalFloat Result(LHSFX.getSemantics()); + switch (E->getOpcode()) { + case BO_Add: { + Result = LHSFX.add(RHSFX, &OpOverflow) + .convert(ResultFXSema, &ConversionOverflow); + break; + } + case BO_Sub: { + Result = LHSFX.sub(RHSFX, &OpOverflow) + .convert(ResultFXSema, &ConversionOverflow); + break; + } + case BO_Mul: { + Result = LHSFX.mul(RHSFX, &OpOverflow) + .convert(ResultFXSema, &ConversionOverflow); + break; + } + case BO_Div: { + if (RHSFX.isZero()) { + Info.FFDiag(E, diag::note_expr_divide_by_zero); + return false; + } + Result = LHSFX.div(RHSFX, &OpOverflow) + .convert(ResultFXSema, &ConversionOverflow); + break; + } + + default: + return false; + } + if (OpOverflow || ConversionOverflow) { + if (Info.checkingForUndefinedBehavior()) + Info.Ctx.getDiagnostics().Report(E->getExprLoc(), + diag::warn_fixedpoint_constant_overflow) + << Result.toString() << E->getType(); + if (!HandleOverflow(Info, E, Result, E->getType())) + return false; + } + return Success(Result, E); +} + +bool DecimalFloatExprEvaluator::VisitCastExpr(const CastExpr *E) { + const Expr *SubExpr = E->getSubExpr(); + QualType DestType = E->getType(); + assert(DestType->isDecimalFloatType() && + "Expected destination type to be a decimal float type"); + auto DestFXSema = Info.Ctx.getDecimalFloatSemantics(DestType); + + switch (E->getCastKind()) { + case CK_DecimalFloatCast: { + APDecimalFloat Src(Info.Ctx.getDecimalFloatSemantics(SubExpr->getType())); + if (!EvaluateDecimalFloat(SubExpr, Src, Info)) + return false; + bool Overflowed; + APDecimalFloat Result = Src.convert(DestFXSema, &Overflowed); + if (Overflowed) { + if (Info.checkingForUndefinedBehavior()) + Info.Ctx.getDiagnostics().Report(E->getExprLoc(), + diag::warn_fixedpoint_constant_overflow) + << Result.toString() << E->getType(); + if (!HandleOverflow(Info, E, Result, E->getType())) + return false; + } + return Success(Result, E); + } + case CK_IntegralToDecimalFloat: { + APSInt Src; + if (!EvaluateInteger(SubExpr, Src, Info)) + return false; + + bool Overflowed; + APDecimalFloat IntResult = APDecimalFloat::getFromIntValue( + Src, Info.Ctx.getDecimalFloatSemantics(DestType), &Overflowed); + + if (Overflowed) { + if (Info.checkingForUndefinedBehavior()) + Info.Ctx.getDiagnostics().Report(E->getExprLoc(), + diag::warn_fixedpoint_constant_overflow) + << IntResult.toString() << E->getType(); + if (!HandleOverflow(Info, E, IntResult, E->getType())) + return false; + } + + return Success(IntResult, E); + } + case CK_FloatingToDecimalFloat: { + APFloat Src(0.0); + if (!EvaluateFloat(SubExpr, Src, Info)) + return false; + + bool Overflowed; + APDecimalFloat Result = APDecimalFloat::getFromFloatValue( + Src, Info.Ctx.getDecimalFloatSemantics(DestType), &Overflowed); + + if (Overflowed) { + if (Info.checkingForUndefinedBehavior()) + Info.Ctx.getDiagnostics().Report(E->getExprLoc(), + diag::warn_fixedpoint_constant_overflow) + << Result.toString() << E->getType(); + if (!HandleOverflow(Info, E, Result, E->getType())) + return false; + } + + return Success(Result, E); + } + case CK_NoOp: + case CK_LValueToRValue: + return ExprEvaluatorBaseTy::VisitCastExpr(E); + default: + return Error(E); + } +} + //===----------------------------------------------------------------------===// // Float Evaluation //===----------------------------------------------------------------------===// @@ -14894,6 +15119,8 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) { C.moveInto(Result); } else if (T->isFixedPointType()) { if (!FixedPointExprEvaluator(Info, Result).Visit(E)) return false; + } else if (T->isDecimalFloatType()) { + if (!DecimalFloatExprEvaluator(Info, Result).Visit(E)) return false; } else if (T->isMemberPointerType()) { MemberPtr P; if (!EvaluateMemberPointer(E, P, Info)) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 46229a0843ef1..0fc1daf6c3f71 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3031,6 +3031,15 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { case BuiltinType::Half: Out << "Dh"; break; + case BuiltinType::DecimalFloat64: + Out << "Dd"; + break; + case BuiltinType::DecimalFloat128: + Out << "De"; + break; + case BuiltinType::DecimalFloat32: + Out << "Df"; + break; case BuiltinType::Float: Out << 'f'; break; @@ -4951,6 +4960,10 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, mangleFixedPointLiteral(); break; + case Expr::DecimalFloatLiteralClass: + mangleType(E->getType()); + break; + case Expr::CharacterLiteralClass: // Out << 'L'; @@ -5544,6 +5557,9 @@ static bool isZeroInitialized(QualType T, const APValue &V) { case APValue::Float: return V.getFloat().isPosZero(); + case APValue::DecimalFloat: + return V.getDecimalFloat().isZero(); + case APValue::FixedPoint: return !V.getFixedPoint().getValue(); @@ -5760,6 +5776,10 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V, mangleFloatLiteral(T, V.getFloat()); break; + case APValue::DecimalFloat: + mangleType(T); + break; + case APValue::FixedPoint: mangleFixedPointLiteral(); break; diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp index db7878e18c42d..e4446f1670f02 100644 --- a/clang/lib/AST/NSAPI.cpp +++ b/clang/lib/AST/NSAPI.cpp @@ -493,6 +493,9 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const { case BuiltinType::OMPArrayShaping: case BuiltinType::OMPIterator: case BuiltinType::BFloat16: + case BuiltinType::DecimalFloat32: + case BuiltinType::DecimalFloat64: + case BuiltinType::DecimalFloat128: break; } diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp index 96079c235c5eb..676e7fde01ac1 100644 --- a/clang/lib/AST/PrintfFormatString.cpp +++ b/clang/lib/AST/PrintfFormatString.cpp @@ -783,6 +783,9 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, case BuiltinType::SatUShortFract: case BuiltinType::SatUFract: case BuiltinType::SatULongFract: + case BuiltinType::DecimalFloat32: + case BuiltinType::DecimalFloat64: + case BuiltinType::DecimalFloat128: // Various types which are non-trivial to correct. return false; diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index a29f762e10c14..f9882742010a6 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1321,6 +1321,19 @@ void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) { } } +void StmtPrinter::VisitDecimalFloatLiteral(DecimalFloatLiteral *Node) { + if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) + return; + OS << Node->getValueAsString(); + + switch (Node->getType()->castAs()->getKind()) { + default: llvm_unreachable("Unexpected type for decimal float literal!"); + case BuiltinType::DecimalFloat32: OS << "DF"; break; + case BuiltinType::DecimalFloat64: OS << "DD"; break; + case BuiltinType::DecimalFloat128: OS << "DL"; break; + } +} + static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, bool PrintSuffix) { SmallString<16> Str; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 6af2beefc7926..622c6e679621c 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1299,6 +1299,13 @@ void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral *S) { ID.AddInteger(S->getType()->castAs()->getKind()); } +void StmtProfiler::VisitDecimalFloatLiteral(const DecimalFloatLiteral *S) { + VisitExpr(S); + S->getValue().Profile(ID); + ID.AddInteger(S->getType()->castAs()->getKind()); +} + + void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) { VisitExpr(S); ID.AddInteger(S->getKind()); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 890f877ca4e19..fe9089540d3c4 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -414,6 +414,7 @@ static bool isSimpleAPValue(const APValue &Value) { case APValue::Int: case APValue::Float: case APValue::FixedPoint: + case APValue::DecimalFloat: case APValue::ComplexInt: case APValue::ComplexFloat: case APValue::LValue: @@ -506,6 +507,13 @@ void TextNodeDumper::Visit(const APValue &Value, QualType Ty) { OS << Value.getFixedPoint(); } return; + case APValue::DecimalFloat: + OS << "DecimalFloat "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << Value.getDecimalFloat(); + } + return; case APValue::Vector: { unsigned VectorLength = Value.getVectorLength(); OS << "Vector length=" << VectorLength; @@ -1099,6 +1107,11 @@ void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) { OS << " " << Node->getValueAsString(/*Radix=*/10); } +void TextNodeDumper::VisitDecimalFloatLiteral(const DecimalFloatLiteral *Node) { + ColorScope Color(OS, ShowColors, ValueColor); + OS << " " << Node->getValueAsString(); +} + void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { ColorScope Color(OS, ShowColors, ValueColor); OS << " " << Node->getValueAsApproximateDouble(); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index bd5fe3dda304d..89ccde535f7b6 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2151,9 +2151,11 @@ bool Type::isRealType() const { bool Type::isArithmeticType() const { if (const auto *BT = dyn_cast(CanonicalType)) - return BT->getKind() >= BuiltinType::Bool && - BT->getKind() <= BuiltinType::Ibm128 && - BT->getKind() != BuiltinType::BFloat16; + return (BT->getKind() >= BuiltinType::Bool && + BT->getKind() <= BuiltinType::Ibm128 && + BT->getKind() != BuiltinType::BFloat16) || + (BT->getKind() >= BuiltinType::DecimalFloat32 && + BT->getKind() <= BuiltinType::DecimalFloat128); if (const auto *ET = dyn_cast(CanonicalType)) // GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2). // If a body isn't seen by the time we get here, return false. @@ -2611,7 +2613,7 @@ bool Type::isLiteralType(const ASTContext &Ctx) const { // As an extension, Clang treats vector types and complex types as // literal types. if (BaseTy->isScalarType() || BaseTy->isVectorType() || - BaseTy->isAnyComplexType()) + BaseTy->isAnyComplexType() || BaseTy->isDecimalFloatType()) return true; // -- a reference type; or if (BaseTy->isReferenceType()) @@ -3074,6 +3076,12 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { return "__float128"; case Ibm128: return "__ibm128"; + case DecimalFloat32: + return "_Decimal32"; + case DecimalFloat64: + return "_Decimal64"; + case DecimalFloat128: + return "_Decimal128"; case WChar_S: case WChar_U: return Policy.MSWChar ? "__wchar_t" : "wchar_t"; @@ -4482,6 +4490,10 @@ void clang::FixedPointValueToString(SmallVectorImpl &Str, llvm::APFixedPoint(Val, FXSema).toString(Str); } +void clang::DecimalFloatValueToString(SmallVectorImpl &Str, llvm::APDecimalFloat Val) { + Val.toString(Str); +} + AutoType::AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, TypeDependence ExtraDependence, QualType Canon, ConceptDecl *TypeConstraintConcept, diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 99566b4ce68b0..ce83bd44fe620 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -348,6 +348,12 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { case BuiltinType::WChar_S: case BuiltinType::WChar_U: return TST_wchar; + case BuiltinType::DecimalFloat32: + return TST_decimal32; + case BuiltinType::DecimalFloat64: + return TST_decimal64; + case BuiltinType::DecimalFloat128: + return TST_decimal128; case BuiltinType::UChar: case BuiltinType::UShort: case BuiltinType::UInt: diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 833e37b325e69..b7b489ead66a8 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -90,6 +90,12 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { LongDoubleAlign = 64; Float128Align = 128; Ibm128Align = 128; + DecimalFloat32Width = 32; + DecimalFloat32Align = 32; + DecimalFloat64Width = 64; + DecimalFloat64Align = 64; + DecimalFloat128Width = 128; + DecimalFloat128Align = 128; LargeArrayMinWidth = 0; LargeArrayAlign = 0; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index aa02821aa971b..7180cbc9b3946 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -887,6 +887,11 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { case BuiltinType::SatULongFract: Encoding = llvm::dwarf::DW_ATE_unsigned_fixed; break; + case BuiltinType::DecimalFloat32: + case BuiltinType::DecimalFloat64: + case BuiltinType::DecimalFloat128: + Encoding = llvm::dwarf::DW_ATE_unsigned; + break; } BTName = BT->getName(CGM.getLangOpts()); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index af753767f0328..80057fbd431cf 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -4764,6 +4764,12 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: case CK_IntegralToFixedPoint: + case CK_FloatingToDecimalFloat: + case CK_DecimalFloatToFloating: + case CK_DecimalFloatCast: + case CK_DecimalFloatToBoolean: + case CK_DecimalFloatToIntegral: + case CK_IntegralToDecimalFloat: case CK_MatrixCast: return EmitUnsupportedLValue(E, "unexpected cast lvalue"); diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 443ce7bbc16e7..e163f25789993 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -917,6 +917,12 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: case CK_IntegralToFixedPoint: + case CK_FloatingToDecimalFloat: + case CK_DecimalFloatToFloating: + case CK_DecimalFloatCast: + case CK_DecimalFloatToBoolean: + case CK_DecimalFloatToIntegral: + case CK_IntegralToDecimalFloat: llvm_unreachable("cast kind invalid for aggregate types"); } } @@ -1459,6 +1465,13 @@ static bool castPreservesZero(const CastExpr *CE) { case CK_FloatingToFixedPoint: case CK_IntegralToFixedPoint: // FIXME: Do all fixed-point types represent zero as all 0 bits? + case CK_FloatingToDecimalFloat: + case CK_DecimalFloatToFloating: + case CK_DecimalFloatCast: + case CK_DecimalFloatToBoolean: + case CK_DecimalFloatToIntegral: + case CK_IntegralToDecimalFloat: + // FIXME: confirm this is correct return false; case CK_AddressSpaceConversion: diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index a31685ddf38a4..4079871576d59 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -556,6 +556,12 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op, case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: case CK_IntegralToFixedPoint: + case CK_FloatingToDecimalFloat: + case CK_DecimalFloatToFloating: + case CK_DecimalFloatCast: + case CK_DecimalFloatToBoolean: + case CK_DecimalFloatToIntegral: + case CK_IntegralToDecimalFloat: case CK_MatrixCast: llvm_unreachable("invalid cast kind for complex value"); diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index db6341e87933a..c03b6162c5455 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1197,6 +1197,12 @@ class ConstExprEmitter : case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: case CK_IntegralToFixedPoint: + case CK_FloatingToDecimalFloat: + case CK_DecimalFloatToFloating: + case CK_DecimalFloatCast: + case CK_DecimalFloatToBoolean: + case CK_DecimalFloatToIntegral: + case CK_IntegralToDecimalFloat: case CK_ZeroToOCLOpaqueType: case CK_MatrixCast: return nullptr; @@ -2080,6 +2086,9 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value, case APValue::FixedPoint: return llvm::ConstantInt::get(CGM.getLLVMContext(), Value.getFixedPoint().getValue()); + case APValue::DecimalFloat: + return llvm::ConstantInt::get(CGM.getLLVMContext(), + Value.getDecimalFloat().getValue()); case APValue::ComplexInt: { llvm::Constant *Complex[2]; diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index a724f8b6afd76..d219691bb1feb 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -32,6 +32,7 @@ #include "llvm/IR/CFG.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DecimalFloatBuilder.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/FixedPointBuilder.h" #include "llvm/IR/Function.h" @@ -142,6 +143,22 @@ struct BinOpInfo { return UnOp->getSubExpr()->getType()->isFixedPointType(); return false; } + + /// Check if at least one operand is a decimal float type. In such cases, this + /// operation did not follow usual arithmetic conversion and both operands + /// might not be of the same type. + bool isDecimalFloatOp() const { + // We cannot simply check the result type since comparison operations return + // an int. + if (const auto *BinOp = dyn_cast(E)) { + QualType LHSType = BinOp->getLHS()->getType(); + QualType RHSType = BinOp->getRHS()->getType(); + return LHSType->isDecimalFloatType() || RHSType->isDecimalFloatType(); + } + if (const auto *UnOp = dyn_cast(E)) + return UnOp->getSubExpr()->getType()->isDecimalFloatType(); + return false; + } }; static bool MustVisitNullValue(const Expr *E) { @@ -454,6 +471,11 @@ class ScalarExprEmitter Value *VisitFixedPointLiteral(const FixedPointLiteral *E) { return Builder.getInt(E->getValue()); } + + Value *VisitDecimalFloatLiteral(const DecimalFloatLiteral *E) { + return Builder.getInt(E->getValue()); + } + Value *VisitFloatingLiteral(const FloatingLiteral *E) { return llvm::ConstantFP::get(VMContext, E->getValue()); } @@ -761,6 +783,10 @@ class ScalarExprEmitter } if (Ops.isFixedPointOp()) return EmitFixedPointBinOp(Ops); + + if (Ops.isDecimalFloatOp()) + return EmitDecimalFloatBinOp(Ops); + return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); } /// Create a binary op that checks for overflow. @@ -796,6 +822,9 @@ class ScalarExprEmitter // Helper functions for fixed point binary operations. Value *EmitFixedPointBinOp(const BinOpInfo &Ops); + // Helper functions for decimal float binary operations. + Value *EmitDecimalFloatBinOp(const BinOpInfo &Ops); + BinOpInfo EmitBinOps(const BinaryOperator *E, QualType PromotionTy = QualType()); @@ -3480,6 +3509,8 @@ Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { } else if (Ops.isFixedPointOp()) return EmitFixedPointBinOp(Ops); + else if (Ops.isDecimalFloatOp()) + return EmitDecimalFloatBinOp(Ops); else if (Ops.Ty->hasUnsignedIntegerRepresentation()) return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div"); else @@ -3858,6 +3889,9 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) { if (op.isFixedPointOp()) return EmitFixedPointBinOp(op); + if (op.isDecimalFloatOp()) + return EmitDecimalFloatBinOp(op); + return Builder.CreateAdd(op.LHS, op.RHS, "add"); } @@ -3967,6 +4001,110 @@ Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) { ResultFixedSema); } +Value *ScalarExprEmitter::EmitDecimalFloatBinOp(const BinOpInfo &op) { + using llvm::APSInt; + using llvm::ConstantInt; + + // This is either a binary operation where at least one of the operands is + // a fixed-point type, or a unary operation where the operand is a fixed-point + // type. The result type of a binary operation is determined by + // Sema::handleFixedPointConversions(). + QualType ResultTy = op.Ty; + QualType LHSTy, RHSTy; + if (const auto *BinOp = dyn_cast(op.E)) { + RHSTy = BinOp->getRHS()->getType(); + if (const auto *CAO = dyn_cast(BinOp)) { + // For compound assignment, the effective type of the LHS at this point + // is the computation LHS type, not the actual LHS type, and the final + // result type is not the type of the expression but rather the + // computation result type. + LHSTy = CAO->getComputationLHSType(); + ResultTy = CAO->getComputationResultType(); + } else + LHSTy = BinOp->getLHS()->getType(); + } else if (const auto *UnOp = dyn_cast(op.E)) { + LHSTy = UnOp->getSubExpr()->getType(); + RHSTy = UnOp->getSubExpr()->getType(); + } + ASTContext &Ctx = CGF.getContext(); + Value *LHS = op.LHS; + Value *RHS = op.RHS; + + auto LHSFixedSema = Ctx.getDecimalFloatSemantics(LHSTy); + auto RHSFixedSema = Ctx.getDecimalFloatSemantics(RHSTy); + auto ResultFixedSema = Ctx.getDecimalFloatSemantics(ResultTy); + auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema); + + // Perform the actual operation. + Value *Result; + llvm::DecimalFloatBuilder FPBuilder(Builder); + switch (op.Opcode) { + case BO_AddAssign: + case BO_Add: + Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema); + break; + case BO_SubAssign: + case BO_Sub: + Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema); + break; + case BO_MulAssign: + case BO_Mul: + Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema); + break; + case BO_DivAssign: + case BO_Div: + Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema); + break; + case BO_ShlAssign: + case BO_Shl: + Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS); + break; + case BO_ShrAssign: + case BO_Shr: + Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS); + break; + case BO_LT: + return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema); + case BO_GT: + return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema); + case BO_LE: + return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema); + case BO_GE: + return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema); + case BO_EQ: + // For equality operations, we assume any padding bits on unsigned types are + // zero'd out. They could be overwritten through non-saturating operations + // that cause overflow, but this leads to undefined behavior. + return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema); + case BO_NE: + return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema); + case BO_Cmp: + case BO_LAnd: + case BO_LOr: + llvm_unreachable("Found unimplemented fixed point binary operation"); + case BO_PtrMemD: + case BO_PtrMemI: + case BO_Rem: + case BO_Xor: + case BO_And: + case BO_Or: + case BO_Assign: + case BO_RemAssign: + case BO_AndAssign: + case BO_XorAssign: + case BO_OrAssign: + case BO_Comma: + llvm_unreachable( + "Found unsupported binary operation for fixed point types."); + } + + bool IsShift = BinaryOperator::isShiftOp(op.Opcode) || + BinaryOperator::isShiftAssignOp(op.Opcode); + // Convert to the result type. + return FPBuilder.CreateFixedToFixed( + Result, IsShift ? LHSFixedSema : CommonFixedSema, ResultFixedSema); +} + Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) { // The LHS is always a pointer if either side is. if (!op.LHS->getType()->isPointerTy()) { @@ -4007,6 +4145,9 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) { if (op.isFixedPointOp()) return EmitFixedPointBinOp(op); + if (op.isDecimalFloatOp()) + return EmitDecimalFloatBinOp(op); + return Builder.CreateSub(op.LHS, op.RHS, "sub"); } @@ -4096,6 +4237,9 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { if (Ops.isFixedPointOp()) return EmitFixedPointBinOp(Ops); + if (Ops.isDecimalFloatOp()) + return EmitDecimalFloatBinOp(Ops); + // LLVM requires the LHS and RHS to be the same type: promote or truncate the // RHS to the same size as the LHS. Value *RHS = Ops.RHS; @@ -4174,6 +4318,9 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) { if (Ops.isFixedPointOp()) return EmitFixedPointBinOp(Ops); + if (Ops.isDecimalFloatOp()) + return EmitDecimalFloatBinOp(Ops); + // LLVM requires the LHS and RHS to be the same type: promote or truncate the // RHS to the same size as the LHS. Value *RHS = Ops.RHS; @@ -4343,6 +4490,8 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E, if (BOInfo.isFixedPointOp()) { Result = EmitFixedPointBinOp(BOInfo); + } else if (BOInfo.isDecimalFloatOp()) { + Result = EmitDecimalFloatBinOp(BOInfo); } else if (LHS->getType()->isFPOrFPVectorTy()) { CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures); if (!IsSignaling) diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index fcce424747f1c..b8905f98e367f 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -540,6 +540,18 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { /* UseNativeHalf = */ false); break; + case BuiltinType::DecimalFloat32: + // ResultType = llvm::Type::getDecimalFloat32Ty(getLLVMContext()); + ResultType = llvm::IntegerType::get(getLLVMContext(), 32); + break; + case BuiltinType::DecimalFloat64: + // ResultType = llvm::Type::getDecimalFloat64Ty(getLLVMContext()); + ResultType = llvm::IntegerType::get(getLLVMContext(), 64); + break; + case BuiltinType::DecimalFloat128: + // ResultType = llvm::Type::getDecimalFloat128Ty(getLLVMContext()); + ResultType = llvm::IntegerType::get(getLLVMContext(), 128); + break; case BuiltinType::NullPtr: // Model std::nullptr_t as i8* ResultType = llvm::Type::getInt8PtrTy(getLLVMContext()); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index c84faf468ea22..50deb78d3dddd 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3235,6 +3235,9 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) { case BuiltinType::Char32: case BuiltinType::Int128: case BuiltinType::UInt128: + case BuiltinType::DecimalFloat32: + case BuiltinType::DecimalFloat64: + case BuiltinType::DecimalFloat128: return true; #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ @@ -4166,7 +4169,8 @@ void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(const CXXRecordDecl *RD) { getContext().FloatTy, getContext().DoubleTy, getContext().LongDoubleTy, getContext().Float128Ty, getContext().Char8Ty, getContext().Char16Ty, - getContext().Char32Ty + getContext().Char32Ty, getContext().DecimalFloat32Ty, + getContext().DecimalFloat64Ty, getContext().DecimalFloat128Ty }; llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass = RD->hasAttr() || CGM.shouldMapVisibilityToDLLExport(RD) diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp index e804abe2de50f..9995c679d221e 100644 --- a/clang/lib/Index/USRGeneration.cpp +++ b/clang/lib/Index/USRGeneration.cpp @@ -711,7 +711,8 @@ void USRGenerator::VisitType(QualType T) { case BuiltinType::LongDouble: c = 'D'; break; case BuiltinType::Float128: - c = 'Q'; break; + c = 'Q'; + break; case BuiltinType::NullPtr: c = 'n'; break; #define BUILTIN_TYPE(Id, SingletonId) @@ -762,6 +763,9 @@ void USRGenerator::VisitType(QualType T) { case BuiltinType::SatUFract: case BuiltinType::SatULongFract: case BuiltinType::BFloat16: + case BuiltinType::DecimalFloat32: + case BuiltinType::DecimalFloat64: + case BuiltinType::DecimalFloat128: IgnoreResults = true; return; case BuiltinType::ObjCId: diff --git a/clang/lib/Lex/CMakeLists.txt b/clang/lib/Lex/CMakeLists.txt index 7694eaba6cf10..312286141291c 100644 --- a/clang/lib/Lex/CMakeLists.txt +++ b/clang/lib/Lex/CMakeLists.txt @@ -28,5 +28,6 @@ add_clang_library(clangLex TokenLexer.cpp LINK_LIBS + "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/libbid.a" clangBasic ) diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 160240e49dd70..a37e4c1d0f40c 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -11,6 +11,10 @@ // //===----------------------------------------------------------------------===// +#include "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src/bid_conf.h" +#include "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src/bid_functions.h" +#include "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src/bid_internal.h" + #include "clang/Lex/LiteralSupport.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/LangOptions.h" @@ -844,6 +848,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, saw_period = false; saw_ud_suffix = false; saw_fixed_point_suffix = false; + saw_decimal_float_suffix = false; isLong = false; isUnsigned = false; isLongLong = false; @@ -853,6 +858,10 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, isImaginary = false; isFloat16 = false; isFloat128 = false; + isDecimalFloat = false; + isDecimal32 = false; + isDecimal64 = false; + isDecimal128 = false; MicrosoftInteger = 0; isFract = false; isAccum = false; @@ -908,6 +917,26 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, // we break out of the loop. for (; s != ThisTokEnd; ++s) { switch (*s) { + case 'd': + case 'D': + switch (s[1]) { + case 'f': + case 'F': + isDecimal32 = true; + saw_decimal_float_suffix = true; + break; + case 'd': + case 'D': + isDecimal64 = true; + saw_decimal_float_suffix = true; + break; + case 'l': + case 'L': + isDecimal128 = true; + saw_decimal_float_suffix = true; + break; + } + continue; case 'R': case 'r': if (!LangOpts.FixedPoint) @@ -1084,6 +1113,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, isBitInt = false; MicrosoftInteger = 0; saw_fixed_point_suffix = false; + saw_decimal_float_suffix = false; isFract = false; isAccum = false; } @@ -1432,6 +1462,42 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { : APFloat::opInvalidOp; } +bool NumericLiteralParser::GetDecimalFloatValue(llvm::APDecimalFloat &Result) { + using llvm::APFloat; + + unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin); + + llvm::SmallString<16> Buffer; + StringRef Str(ThisTokBegin, n); + // if (Str.contains('\'')) { + Buffer.reserve(n); + std::remove_copy_if(Str.begin(), Str.end(), std::back_inserter(Buffer), + &isDigitSeparator); + Str = Buffer; + //} + + BID_UINT32 result; + BID_UINT32 result2; + unsigned int x = 0; + printf("%s\n", Buffer.c_str()); + result2 = bid32_from_string((char *)Buffer.c_str(), x, &result); + printf("%08x\n", result2); + + llvm::APInt store(32u, result2, false); + + Result = llvm::APDecimalFloat( + store, llvm::decFltSemantics(32u, /*Scale=*/1u, /*IsSigned=*/0u, + /*IsSaturated=*/false, + /*HasUnsignedPadding=*/false)); + + // auto StatusOrErr = + // Result.convertFromString(Str, APFloat::rmNearestTiesToEven); + // assert(StatusOrErr && "Invalid floating point representation"); + // return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr + // : APFloat::opInvalidOp; + return true; +} + static inline bool IsExponentPart(char c) { return c == 'p' || c == 'P' || c == 'e' || c == 'E'; } diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index c8eac7b06b652..24dde63740fac 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1748,9 +1748,9 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, // GNU keywords if (LangOpts.GNUKeywords) { // FIXME: Enable when we actually support decimal floating point. - // Results.AddResult(Result("_Decimal32")); - // Results.AddResult(Result("_Decimal64")); - // Results.AddResult(Result("_Decimal128")); + Results.AddResult(Result("_Decimal32")); + Results.AddResult(Result("_Decimal64")); + Results.AddResult(Result("_Decimal128")); Builder.AddTypedTextChunk("typeof"); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index d8344cfd01f95..7139bd81b232d 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1392,6 +1392,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Expr::ImplicitValueInitExprClass: case Expr::IntegerLiteralClass: case Expr::FixedPointLiteralClass: + case Expr::DecimalFloatLiteralClass: case Expr::ArrayInitIndexExprClass: case Expr::NoInitExprClass: case Expr::ObjCEncodeExprClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 474f86cffd169..c7feac0852058 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3907,6 +3907,24 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { Res = FixedPointLiteral::CreateFromRawInt(Context, Val, Ty, Tok.getLocation(), scale); + } else if (Literal.isDecimalFloatLiteral()) { + QualType Ty; + + if (Literal.isDecimal32) + Ty = Context.DecimalFloat32Ty; + else if (Literal.isDecimal64) + Ty = Context.DecimalFloat64Ty; + else if (Literal.isDecimal128) + Ty = Context.DecimalFloat128Ty; + + unsigned bit_width = Context.getTypeInfo(Ty).Width; + + llvm::APDecimalFloat Val(llvm::decFltSemantics( + 32u, /*Scale=*/1u, /*IsSigned=*/0u, /*IsSaturated=*/false, + /*HasUnsignedPadding=*/false)); + bool Overflowed = Literal.GetDecimalFloatValue(Val); + Res = DecimalFloatLiteral::CreateFromAPDecimalFloat( + Context, Val, Ty, Tok.getLocation(), bit_width); } else if (Literal.isFloatingLiteral()) { QualType Ty; if (Literal.isHalf){ diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c7e66d1e1d2ab..b7f72ca461b7b 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -8451,6 +8451,12 @@ class BuiltinOperatorOverloadBuilder { ArithmeticTypes.push_back(S.Context.ShortTy); ArithmeticTypes.push_back(S.Context.UnsignedCharTy); ArithmeticTypes.push_back(S.Context.UnsignedShortTy); + + // Decimal Floating Point types + ArithmeticTypes.push_back(S.Context.DecimalFloat32Ty); + ArithmeticTypes.push_back(S.Context.DecimalFloat64Ty); + ArithmeticTypes.push_back(S.Context.DecimalFloat128Ty); + LastIntegralType = ArithmeticTypes.size(); NumArithmeticTypes = ArithmeticTypes.size(); // End of integral types. diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 9fa821ea6bdef..a08d348464656 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -7267,6 +7267,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, case APValue::AddrLabelDiff: return Diag(StartLoc, diag::err_non_type_template_arg_addr_label_diff); case APValue::FixedPoint: + case APValue::DecimalFloat: case APValue::Float: case APValue::ComplexInt: case APValue::ComplexFloat: diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index f49deaf80fbce..7b83d25efb454 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1560,11 +1560,16 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { Result = Context.BoolTy; // _Bool or bool break; case DeclSpec::TST_decimal32: // _Decimal32 + Result = Context.DecimalFloat32Ty; + break; case DeclSpec::TST_decimal64: // _Decimal64 + Result = Context.DecimalFloat64Ty; + break; case DeclSpec::TST_decimal128: // _Decimal128 - S.Diag(DS.getTypeSpecTypeLoc(), diag::err_decimal_unsupported); - Result = Context.IntTy; - declarator.setInvalidType(true); + Result = Context.DecimalFloat128Ty; + // S.Diag(DS.getTypeSpecTypeLoc(), diag::err_decimal_unsupported); + // Result = Context.IntTy; + // declarator.setInvalidType(true); break; case DeclSpec::TST_class: case DeclSpec::TST_enum: diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 82b6cfacf46b6..02dacf45a6d4d 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -10629,6 +10629,14 @@ ExprResult TreeTransform::TransformFixedPointLiteral( return E; } +template +ExprResult TreeTransform::TransformDecimalFloatLiteral( + DecimalFloatLiteral *E) { + return E; +} + + + template ExprResult TreeTransform::TransformFloatingLiteral(FloatingLiteral *E) { diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index 53e4c889f5298..f9b83d57b8f5e 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -171,6 +171,15 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::Ibm128: ID = PREDEF_TYPE_IBM128_ID; break; + case BuiltinType::DecimalFloat32: + ID = PREDEF_TYPE_DECIMAL_FLOAT32_ID; + break; + case BuiltinType::DecimalFloat64: + ID = PREDEF_TYPE_DECIMAL_FLOAT64_ID; + break; + case BuiltinType::DecimalFloat128: + ID = PREDEF_TYPE_DECIMAL_FLOAT128_ID; + break; case BuiltinType::NullPtr: ID = PREDEF_TYPE_NULLPTR_ID; break; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 45a6a474f1d93..4f1c01f054b1d 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -7004,6 +7004,15 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_IBM128_ID: T = Context.Ibm128Ty; break; + case PREDEF_TYPE_DECIMAL_FLOAT32_ID: + T = Context.DecimalFloat32Ty; + break; + case PREDEF_TYPE_DECIMAL_FLOAT64_ID: + T = Context.DecimalFloat64Ty; + break; + case PREDEF_TYPE_DECIMAL_FLOAT128_ID: + T = Context.DecimalFloat128Ty; + break; case PREDEF_TYPE_OVERLOAD_ID: T = Context.OverloadTy; break; diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 3f5a85786da4c..e7a5e6b009dc4 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -629,6 +629,14 @@ void ASTStmtReader::VisitFixedPointLiteral(FixedPointLiteral *E) { E->setValue(Record.getContext(), Record.readAPInt()); } +void ASTStmtReader::VisitDecimalFloatLiteral(DecimalFloatLiteral *E) { + VisitExpr(E); + E->setLocation(readSourceLocation()); + E->setWidth(Record.readInt()); + E->setValue(Record.getContext(), Record.readAPInt()); +} + + void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) { VisitExpr(E); E->setRawSemantics( @@ -2899,6 +2907,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = FixedPointLiteral::Create(Context, Empty); break; + case EXPR_DECIMALFLOAT_LITERAL: + S = DecimalFloatLiteral::Create(Context, Empty); + break; + case EXPR_FLOATING_LITERAL: S = FloatingLiteral::Create(Context, Empty); break; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index aec3b7240ae99..502ccc55cede0 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -662,6 +662,16 @@ void ASTStmtWriter::VisitFixedPointLiteral(FixedPointLiteral *E) { Code = serialization::EXPR_FIXEDPOINT_LITERAL; } +void ASTStmtWriter::VisitDecimalFloatLiteral(DecimalFloatLiteral *E) { + VisitExpr(E); + Record.AddSourceLocation(E->getLocation()); + Record.push_back(E->getWidth()); + // Record.AddAPInt(E->getValue().bitcastToAPInt()); + Record.AddAPInt(E->getValue()); + Code = serialization::EXPR_DECIMALFLOAT_LITERAL; +} + + void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) { VisitExpr(E); Record.push_back(E->getRawSemantics()); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index f6b6de73796e2..9ae216644a54f 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1906,6 +1906,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::AttributedStmtClass: case Stmt::IntegerLiteralClass: case Stmt::FixedPointLiteralClass: + case Stmt::DecimalFloatLiteralClass: case Stmt::CharacterLiteralClass: case Stmt::CXXScalarValueInitExprClass: case Stmt::CXXBoolLiteralExprClass: diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 10b70222af24b..7d740c7b3ee8b 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -408,7 +408,13 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, case CK_FixedPointCast: case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: - case CK_IntegralToFixedPoint: { + case CK_IntegralToFixedPoint: + case CK_FloatingToDecimalFloat: + case CK_DecimalFloatToFloating: + case CK_DecimalFloatCast: + case CK_DecimalFloatToBoolean: + case CK_DecimalFloatToIntegral: + case CK_IntegralToDecimalFloat: { state = handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); continue; diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index a90f414663ffe..8e2d6c5c5bd9d 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -380,6 +380,10 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, K = CXCursor_FixedPointLiteral; break; + case Stmt::DecimalFloatLiteralClass: + K = CXCursor_DecimalFloatLiteral; + break; + case Stmt::FloatingLiteralClass: K = CXCursor_FloatingLiteral; break; diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 4db8c458f923a..fce19ad46438b 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -15,6 +15,9 @@ endif() set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON) +list(APPEND CMAKE_REQUIRED_INCLUDES "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src") +list(APPEND CMAKE_REQUIRED_LIBRARIES "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/libbid.a") + if(NOT DEFINED LLVM_VERSION_MAJOR) set(LLVM_VERSION_MAJOR 16) endif() @@ -1077,11 +1080,11 @@ set_target_properties(srpm PROPERTIES FOLDER "Misc") if(APPLE AND DARWIN_LTO_LIBRARY) set(CMAKE_EXE_LINKER_FLAGS - "${CMAKE_EXE_LINKER_FLAGS} -Wl,-lto_library -Wl,${DARWIN_LTO_LIBRARY}") + "${CMAKE_EXE_LINKER_FLAGS} -lbid -Wl,-lto_library -Wl,${DARWIN_LTO_LIBRARY}") set(CMAKE_SHARED_LINKER_FLAGS - "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-lto_library -Wl,${DARWIN_LTO_LIBRARY}") + "${CMAKE_SHARED_LINKER_FLAGS} -lbid -Wl,-lto_library -Wl,${DARWIN_LTO_LIBRARY}") set(CMAKE_MODULE_LINKER_FLAGS - "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-lto_library -Wl,${DARWIN_LTO_LIBRARY}") + "${CMAKE_MODULE_LINKER_FLAGS} -lbid -Wl,-lto_library -Wl,${DARWIN_LTO_LIBRARY}") endif() # Build with _XOPEN_SOURCE on AIX, as stray macros in _ALL_SOURCE mode tend to diff --git a/llvm/include/llvm/ADT/APDecimalFloat.h b/llvm/include/llvm/ADT/APDecimalFloat.h new file mode 100644 index 0000000000000..2537f3a2f7680 --- /dev/null +++ b/llvm/include/llvm/ADT/APDecimalFloat.h @@ -0,0 +1,260 @@ +//===- APDecimalFloat.h - Decimal Float constant handling -----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Defines the decimal float number interface. +/// This is a class for abstracting various operations performed on decimal float +/// types. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_APDECIMALFLOAT_H +#define LLVM_ADT_APDECIMALFLOAT_H + +#include "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src/bid_conf.h" +#include "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src/bid_functions.h" +#include "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src/bid_internal.h" + +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +class APFloat; +class APDecimalFloat; +struct fltSemantics; + +struct decFltSemantics { +public: + decFltSemantics(unsigned Width, unsigned Scale, bool IsSigned, + bool IsSaturated, bool HasUnsignedPadding) + : Width(Width), LsbWeight(-static_cast(Scale)), IsSigned(IsSigned), + IsSaturated(IsSaturated), HasUnsignedPadding(HasUnsignedPadding) {} + + unsigned getWidth() const { return Width; } + unsigned getScale() const { return -LsbWeight; } + int getLsbWeight() const { return LsbWeight; } + int getMsbWeight() const { + return LsbWeight + Width - 1 /*Both lsb and msb are both part of width*/; + } + bool isSigned() const { return IsSigned; } + bool isSaturated() const { return IsSaturated; } + bool hasUnsignedPadding() const { return HasUnsignedPadding; } + + void setSaturated(bool Saturated) { IsSaturated = Saturated; } + + bool hasSignOrPaddingBit() const { return IsSigned || HasUnsignedPadding; } + + unsigned getIntegralBits() const { + return std::max(getMsbWeight() + 1 - hasSignOrPaddingBit(), 0); + } + + bool fitsInFloatSemantics(const fltSemantics &FloatSema) const; + + decFltSemantics getCommonSemantics(const decFltSemantics &Other) const { + int CommonLsb = std::min(getLsbWeight(), Other.getLsbWeight()); + int CommonMSb = + std::max(getMsbWeight() - hasSignOrPaddingBit(), + Other.getMsbWeight() - Other.hasSignOrPaddingBit()); + unsigned CommonWidth = CommonMSb - CommonLsb + 1; + + bool ResultIsSigned = isSigned() || Other.isSigned(); + bool ResultIsSaturated = isSaturated() || Other.isSaturated(); + bool ResultHasUnsignedPadding = false; + if (!ResultIsSigned) { + // Both are unsigned. + ResultHasUnsignedPadding = hasUnsignedPadding() && + Other.hasUnsignedPadding() && + !ResultIsSaturated; + } + + // If the result is signed, add an extra bit for the sign. Otherwise, if it + // is unsigned and has unsigned padding, we only need to add the extra + // padding bit back if we are not saturating. + if (ResultIsSigned || ResultHasUnsignedPadding) + CommonWidth++; + + return decFltSemantics(CommonWidth, CommonLsb, ResultIsSigned, + ResultIsSaturated, ResultHasUnsignedPadding); + } + + /// Return the DecimalFloatemantics for an integer type. + static decFltSemantics GetIntegerSemantics(unsigned Width, bool IsSigned) { + return decFltSemantics(Width, /*Scale=*/0, IsSigned, /*IsSaturated=*/false, + /*HasUnsignedPadding=*/false); + } + +private: + unsigned Width : 16; + signed int LsbWeight : 13; + unsigned IsSigned : 1; + unsigned IsSaturated : 1; + unsigned HasUnsignedPadding : 1; +}; + +/// The APDecimalFloat class +class APDecimalFloat { +public: + APDecimalFloat(const decFltSemantics &Sema) : + Sema(Sema) { + } + + APDecimalFloat(APDecimalFloat Val, const decFltSemantics &Sema) + : Val(Val.getValue(), !Sema.isSigned()), Sema(Sema) { + assert(Val.getWidth() == Sema.getWidth() && + "The value should have a bit width that matches the Sema width"); + } + + APDecimalFloat(const APInt &Val, const decFltSemantics &Sema) + : Val(Val, !Sema.isSigned()), Sema(Sema) { + assert(Val.getBitWidth() == Sema.getWidth() && + "The value should have a bit width that matches the Sema width"); + } + + inline unsigned getWidth() const { return Sema.getWidth(); } + decFltSemantics getSemantics() const { return Sema; } + APSInt getValue() const { return APSInt(Val, !Sema.isSigned()); } + + const static fltSemantics *promoteFloatSemantics(const fltSemantics *S) { + if (S == &APFloat::BFloat()) + return &APFloat::IEEEdouble(); + else if (S == &APFloat::IEEEhalf()) + return &APFloat::IEEEsingle(); + else if (S == &APFloat::IEEEsingle()) + return &APFloat::IEEEdouble(); + else if (S == &APFloat::IEEEdouble()) + return &APFloat::IEEEquad(); + llvm_unreachable("Could not promote float type!"); + } + + bool needsCleanup() const { return false; } + + APDecimalFloat add(const APDecimalFloat &Other, bool *Overflow = nullptr) const { + unsigned int x = 0; + BID_UINT32 Tmp; + BID_UINT32 RHSVal = Val.getZExtValue(); + BID_UINT32 LHSVal = Other.getValue().getZExtValue(); + BID_UINT32 ResultVal = bid32_add(RHSVal, LHSVal, x, &Tmp); + + printf("Add: %08x\n", ResultVal); + llvm::APInt store(32u, ResultVal, false); + + APDecimalFloat Result = llvm::APDecimalFloat( + store, llvm::decFltSemantics(32u, /*Scale=*/1u, /*IsSigned=*/0u, + /*IsSaturated=*/false, + /*HasUnsignedPadding=*/false)); + + return Result; + } + + APDecimalFloat sub(const APDecimalFloat &Other, bool *Overflow = nullptr) const { + unsigned int x = 0; + BID_UINT32 Tmp; + BID_UINT32 RHSVal = Val.getZExtValue(); + BID_UINT32 LHSVal = Other.getValue().getZExtValue(); + BID_UINT32 ResultVal = bid32_sub(RHSVal, LHSVal, x, &Tmp); + + printf("Sub: %08x\n", ResultVal); + llvm::APInt store(32u, ResultVal, false); + + APDecimalFloat Result = llvm::APDecimalFloat( + store, llvm::decFltSemantics(32u, /*Scale=*/1u, /*IsSigned=*/0u, + /*IsSaturated=*/false, + /*HasUnsignedPadding=*/false)); + + return Result; + } + + APDecimalFloat mul(const APDecimalFloat &Other, bool *Overflow = nullptr) const { + APDecimalFloat Result(*this); + + return Result; + } + + APDecimalFloat div(const APDecimalFloat &Other, bool *Overflow = nullptr) const { + APDecimalFloat Result(*this); + + return Result; + } + + static APDecimalFloat getMax(const decFltSemantics &Sema); + static APDecimalFloat getMin(const decFltSemantics &Sema); + + static APDecimalFloat getFromIntValue(const APInt &Value, + const decFltSemantics &DstFXSema, + bool *Overflow) { + APDecimalFloat Result(DstFXSema); + + return Result; + } + + + static APDecimalFloat getFromFloatValue(const APFloat &Value, + const decFltSemantics &DstFXSema, + bool *Overflow) { + APDecimalFloat Result(DstFXSema); + + return Result; + } + + APDecimalFloat convert(const decFltSemantics &DstFXSema, + bool *Overflow) { + APDecimalFloat Result(*this); + + return Result; + } + + APDecimalFloat& operator++() { return *this; } + APDecimalFloat operator++(int) { + APDecimalFloat APDF(*this); + ++(*this); + return APDF; + } + + bool isZero() const { return false; } + + bool getBoolValue() const { return !isZero(); } + + void flipAllBits(){} + + APDecimalFloat negate(bool *Overflow = nullptr) { + flipAllBits(); + ++(*this); + + return *this; + } + + APInt bitcastToAPInt() const { return APInt{getWidth(), Val.getZExtValue()}; } + + void Profile(FoldingSetNodeID& ID) const { + ID.AddInteger(getWidth()); + } + + void toString(SmallVectorImpl &Str) const; + std::string toString() const { + SmallString<40> S; + toString(S); + return std::string(S.str()); + } + +private: + APSInt Val; + decFltSemantics Sema; +}; + +inline raw_ostream &operator<<(raw_ostream &OS, const APDecimalFloat &FX) { + OS << FX.toString(); + return OS; +} + +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index d26507a720491..0822b031fca3f 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -175,6 +175,9 @@ enum TypeCodes { TYPE_CODE_X86_AMX = 24, // X86 AMX TYPE_CODE_OPAQUE_POINTER = 25, // OPAQUE_POINTER: [addrspace] + TYPE_CODE_DECIMAL_FLOAT32 = 26, + TYPE_CODE_DECIMAL_FLOAT64 = 27, + TYPE_CODE_DECIMAL_FLOAT128 = 28, }; enum OperandBundleTagCode { diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h index e4ddbbe6f3e90..2fc8b83bd3d33 100644 --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -20,6 +20,7 @@ #ifndef LLVM_IR_CONSTANTS_H #define LLVM_IR_CONSTANTS_H +#include "llvm/ADT/APDecimalFloat.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" @@ -127,6 +128,8 @@ class ConstantInt final : public ConstantData { /// value. Otherwise return a ConstantInt for the given value. static Constant *get(Type *Ty, const APInt &V); + static ConstantInt *DecimalFloatGet(Type *Ty); + /// Return the constant as an APInt value reference. This allows clients to /// obtain a full-precision copy of the value. /// Return the constant's value. diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h index a6621c963d851..fc9c9952aab73 100644 --- a/llvm/include/llvm/IR/DataLayout.h +++ b/llvm/include/llvm/IR/DataLayout.h @@ -696,6 +696,12 @@ inline TypeSize DataLayout::getTypeSizeInBits(Type *Ty) const { case Type::DoubleTyID: case Type::X86_MMXTyID: return TypeSize::Fixed(64); + case Type::DecimalFloat32TyID: + return TypeSize::Fixed(32); + case Type::DecimalFloat64TyID: + return TypeSize::Fixed(64); + case Type::DecimalFloat128TyID: + return TypeSize::Fixed(128); case Type::PPC_FP128TyID: case Type::FP128TyID: return TypeSize::Fixed(128); diff --git a/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h index e6d351babb563..e1f244d7e6854 100644 --- a/llvm/include/llvm/IR/Type.h +++ b/llvm/include/llvm/IR/Type.h @@ -57,6 +57,9 @@ class Type { BFloatTyID, ///< 16-bit floating point type (7-bit significand) FloatTyID, ///< 32-bit floating point type DoubleTyID, ///< 64-bit floating point type + DecimalFloat32TyID, + DecimalFloat64TyID, + DecimalFloat128TyID, X86_FP80TyID, ///< 80-bit floating point type (X87) FP128TyID, ///< 128-bit floating point type (112-bit significand) PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, PowerPC) @@ -270,7 +273,7 @@ class Type { // If it's a primitive, it is always sized. if (getTypeID() == IntegerTyID || isFloatingPointTy() || getTypeID() == PointerTyID || getTypeID() == X86_MMXTyID || - getTypeID() == X86_AMXTyID) + getTypeID() == X86_AMXTyID || getTypeID() == DecimalFloat32TyID || getTypeID() == DecimalFloat64TyID || getTypeID() == DecimalFloat128TyID) return true; // If it is not something that can have a size (e.g. a function or label), // it doesn't have a size. @@ -424,6 +427,9 @@ class Type { static Type *getBFloatTy(LLVMContext &C); static Type *getFloatTy(LLVMContext &C); static Type *getDoubleTy(LLVMContext &C); + static Type *getDecimalFloat32Ty(LLVMContext &C); + static Type *getDecimalFloat64Ty(LLVMContext &C); + static Type *getDecimalFloat128Ty(LLVMContext &C); static Type *getMetadataTy(LLVMContext &C); static Type *getX86_FP80Ty(LLVMContext &C); static Type *getFP128Ty(LLVMContext &C); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index f66bc2d1dcc35..fc6714c5b74df 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -941,6 +941,9 @@ void ModuleBitcodeWriter::writeTypeTable() { case Type::BFloatTyID: Code = bitc::TYPE_CODE_BFLOAT; break; case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; + case Type::DecimalFloat32TyID: Code = bitc::TYPE_CODE_DECIMAL_FLOAT32; break; + case Type::DecimalFloat64TyID: Code = bitc::TYPE_CODE_DECIMAL_FLOAT64; break; + case Type::DecimalFloat128TyID: Code = bitc::TYPE_CODE_DECIMAL_FLOAT128; break; case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break; diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp index 1bc03f0dfd833..66285a59b7e86 100644 --- a/llvm/lib/CodeGen/ValueTypes.cpp +++ b/llvm/lib/CodeGen/ValueTypes.cpp @@ -551,6 +551,8 @@ MVT MVT::getVT(Type *Ty, bool HandleUnknown){ return MVT::isVoid; case Type::IntegerTyID: return getIntegerVT(cast(Ty)->getBitWidth()); + case Type::DecimalFloat32TyID: + return getIntegerVT(32); case Type::HalfTyID: return MVT(MVT::f16); case Type::BFloatTyID: return MVT(MVT::bf16); case Type::FloatTyID: return MVT(MVT::f32); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index d9443f43ae14f..188a0e56a9f82 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -541,6 +541,9 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { case Type::BFloatTyID: OS << "bfloat"; return; case Type::FloatTyID: OS << "float"; return; case Type::DoubleTyID: OS << "double"; return; + case Type::DecimalFloat32TyID: OS << "_Decimal32"; return; + case Type::DecimalFloat64TyID: OS << "_Decimal64"; return; + case Type::DecimalFloat128TyID: OS << "_Decimal128"; return; case Type::X86_FP80TyID: OS << "x86_fp80"; return; case Type::FP128TyID: OS << "fp128"; return; case Type::PPC_FP128TyID: OS << "ppc_fp128"; return; diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index d6a87c868b847..88182af26a6ab 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -351,6 +351,8 @@ Constant *Constant::getNullValue(Type *Ty) { switch (Ty->getTypeID()) { case Type::IntegerTyID: return ConstantInt::get(Ty, 0); + case Type::DecimalFloat32TyID: + return ConstantInt::DecimalFloatGet(Ty); case Type::HalfTyID: case Type::BFloatTyID: case Type::FloatTyID: @@ -919,6 +921,14 @@ void ConstantInt::destroyConstantImpl() { llvm_unreachable("You can't ConstantInt->destroyConstantImpl()!"); } +// +// Decimal Float +// + +ConstantInt *ConstantInt::DecimalFloatGet(Type *Ty) { + return get(Ty->getContext(), APInt(32, 0, /*isSigned=*/false)); +} + //===----------------------------------------------------------------------===// // ConstantFP //===----------------------------------------------------------------------===// diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp index 96f55cf14de8f..7e18c4b301666 100644 --- a/llvm/lib/IR/DataLayout.cpp +++ b/llvm/lib/IR/DataLayout.cpp @@ -816,6 +816,12 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const { } case Type::X86_AMXTyID: return Align(64); + case Type::DecimalFloat32TyID: + return Align(32); + case Type::DecimalFloat64TyID: + return Align(64); + case Type::DecimalFloat128TyID: + return Align(128); default: llvm_unreachable("Bad type for getAlignment!!!"); } diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp index d7aaf00085649..07c2e833d9ddb 100644 --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -45,7 +45,9 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) MetadataTy(C, Type::MetadataTyID), TokenTy(C, Type::TokenTyID), X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID), PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_MMXTy(C, Type::X86_MMXTyID), - X86_AMXTy(C, Type::X86_AMXTyID), Int1Ty(C, 1), Int8Ty(C, 8), + X86_AMXTy(C, Type::X86_AMXTyID), + DecimalFloat32Ty(C, Type::DecimalFloat32TyID), DecimalFloat64Ty(C, Type::DecimalFloat64TyID), DecimalFloat128Ty(C, Type::DecimalFloat128TyID), + Int1Ty(C, 1), Int8Ty(C, 8), Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) { if (OpaquePointersCL.getNumOccurrences()) { OpaquePointers = OpaquePointersCL; diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 0b1e5194222fc..c49180448fbc3 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1465,6 +1465,7 @@ class LLVMContextImpl { Type VoidTy, LabelTy, HalfTy, BFloatTy, FloatTy, DoubleTy, MetadataTy, TokenTy; Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy, X86_AMXTy; + Type DecimalFloat32Ty, DecimalFloat64Ty, DecimalFloat128Ty; IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty; std::unique_ptr TheNoneToken; diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp index 85b658c8a52ff..1adbaf2a7e154 100644 --- a/llvm/lib/IR/Type.cpp +++ b/llvm/lib/IR/Type.cpp @@ -225,6 +225,9 @@ Type *Type::getHalfTy(LLVMContext &C) { return &C.pImpl->HalfTy; } Type *Type::getBFloatTy(LLVMContext &C) { return &C.pImpl->BFloatTy; } Type *Type::getFloatTy(LLVMContext &C) { return &C.pImpl->FloatTy; } Type *Type::getDoubleTy(LLVMContext &C) { return &C.pImpl->DoubleTy; } +Type *Type::getDecimalFloat32Ty(LLVMContext &C) { return &C.pImpl->DecimalFloat32Ty; } +Type *Type::getDecimalFloat64Ty(LLVMContext &C) { return &C.pImpl->DecimalFloat64Ty; } +Type *Type::getDecimalFloat128Ty(LLVMContext &C) { return &C.pImpl->DecimalFloat128Ty; } Type *Type::getMetadataTy(LLVMContext &C) { return &C.pImpl->MetadataTy; } Type *Type::getTokenTy(LLVMContext &C) { return &C.pImpl->TokenTy; } Type *Type::getX86_FP80Ty(LLVMContext &C) { return &C.pImpl->X86_FP80Ty; } @@ -233,6 +236,7 @@ Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; } Type *Type::getX86_MMXTy(LLVMContext &C) { return &C.pImpl->X86_MMXTy; } Type *Type::getX86_AMXTy(LLVMContext &C) { return &C.pImpl->X86_AMXTy; } + IntegerType *Type::getInt1Ty(LLVMContext &C) { return &C.pImpl->Int1Ty; } IntegerType *Type::getInt8Ty(LLVMContext &C) { return &C.pImpl->Int8Ty; } IntegerType *Type::getInt16Ty(LLVMContext &C) { return &C.pImpl->Int16Ty; } diff --git a/llvm/lib/Support/APDecimalFloat.cpp b/llvm/lib/Support/APDecimalFloat.cpp new file mode 100644 index 0000000000000..fbc005292cf74 --- /dev/null +++ b/llvm/lib/Support/APDecimalFloat.cpp @@ -0,0 +1,71 @@ +//===- APDecimalFloat.cpp - Decimal float constant handling ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file +/// Defines the implementation for the decimal float number interface. +// +//===----------------------------------------------------------------------===// + +#include "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src/bid_conf.h" +#include "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src/bid_functions.h" +#include "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/src/bid_internal.h" + +#include "llvm/ADT/APDecimalFloat.h" +#include "llvm/ADT/APFloat.h" + +namespace llvm { + +APDecimalFloat APDecimalFloat::getMax(const decFltSemantics &Sema) { + return APDecimalFloat(Sema); +} + +APDecimalFloat APDecimalFloat::getMin(const decFltSemantics &Sema) { + return APDecimalFloat(Sema); +} + +bool decFltSemantics::fitsInFloatSemantics( + const fltSemantics &FloatSema) const { + // A fixed point semantic fits in a floating point semantic if the maximum + // and minimum values as integers of the fixed point semantic can fit in the + // floating point semantic. + + // If these values do not fit, then a floating point rescaling of the true + // maximum/minimum value will not fit either, so the floating point semantic + // cannot be used to perform such a rescaling. + + APSInt MaxInt = APDecimalFloat::getMax(*this).getValue(); + APFloat F(FloatSema); + APFloat::opStatus Status = F.convertFromAPInt(MaxInt, MaxInt.isSigned(), + APFloat::rmNearestTiesToAway); + if ((Status & APFloat::opOverflow) || !isSigned()) + return !(Status & APFloat::opOverflow); + + APSInt MinInt = APDecimalFloat::getMin(*this).getValue(); + Status = F.convertFromAPInt(MinInt, MinInt.isSigned(), + APFloat::rmNearestTiesToAway); + return !(Status & APFloat::opOverflow); +} + +void APDecimalFloat::toString(SmallVectorImpl &Str) const { + char output[100]{0}; + BID_UINT32 result2 = Val.getZExtValue(); + unsigned int x; + + bid32_to_string(output, result2, &x); + + char *p = output; + + while (*p) { + Str.push_back(*p); + ++p; + } + + // Str.push_back('0'); +} + +} // namespace llvm diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index c6a04fdb66599..48035db61830a 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -124,6 +124,7 @@ add_llvm_component_library(LLVMSupport ABIBreak.cpp ARMTargetParser.cpp AMDGPUMetadata.cpp + APDecimalFloat.cpp APFixedPoint.cpp APFloat.cpp APInt.cpp @@ -283,6 +284,7 @@ add_llvm_component_library(LLVMSupport LINK_LIBS ${system_libs} ${imported_libs} ${delayload_flags} + "/Users/shafik/Downloads/IntelRDFPMathLib20U2/LIBRARY/libbid.a" LINK_COMPONENTS Demangle