diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -2059,6 +2059,7 @@ TypeKind.OBJCSEL = TypeKind(29) TypeKind.FLOAT128 = TypeKind(30) TypeKind.HALF = TypeKind(31) +TypeKind.IBM128 = TypeKind(32) TypeKind.COMPLEX = TypeKind(100) TypeKind.POINTER = TypeKind(101) TypeKind.BLOCKPOINTER = TypeKind(102) diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -3274,6 +3274,7 @@ CXType_UAccum = 37, CXType_ULongAccum = 38, CXType_BFloat16 = 39, + CXType_Ibm128 = 40, CXType_FirstBuiltin = CXType_Void, CXType_LastBuiltin = CXType_BFloat16, diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -971,7 +971,7 @@ CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty; CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy; CanQualType UnsignedLongLongTy, UnsignedInt128Ty; - CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty; + CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty, Ibm128Ty; CanQualType ShortAccumTy, AccumTy, LongAccumTy; // ISO/IEC JTC1 SC22 WG14 N1169 Extension CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -218,6 +218,9 @@ // '__float128' FLOATING_TYPE(Float128, Float128Ty) +// '__ibm128' +FLOATING_TYPE(Ibm128, Ibm128Ty) + //===- Language-specific types --------------------------------------------===// // This is the type of C++0x 'nullptr'. diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1991,6 +1991,7 @@ bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 bool isBFloat16Type() const; bool isFloat128Type() const; + bool isIbm128Type() const; bool isRealType() const; // C99 6.2.5p17 (real floating + integer) bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) bool isVoidType() const; // C99 6.2.5p19 @@ -2534,7 +2535,7 @@ } bool isFloatingPoint() const { - return getKind() >= Half && getKind() <= Float128; + return getKind() >= Half && getKind() <= Ibm128; } /// Determines whether the given kind corresponds to a placeholder type. @@ -6945,6 +6946,10 @@ return isSpecificBuiltinType(BuiltinType::Float128); } +inline bool Type::isIbm128Type() const { + return isSpecificBuiltinType(BuiltinType::Ibm128); +} + inline bool Type::isNullPtrType() const { return isSpecificBuiltinType(BuiltinType::NullPtr); } diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -581,10 +581,9 @@ bool needsExtraLocalData() const { BuiltinType::Kind bk = getTypePtr()->getKind(); - return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) - || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128) - || bk == BuiltinType::UChar - || bk == BuiltinType::SChar; + return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) || + (bk >= BuiltinType::Short && bk <= BuiltinType::Ibm128) || + bk == BuiltinType::UChar || bk == BuiltinType::SChar; } unsigned getExtraLocalDataSize() const { diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -59,6 +59,7 @@ TST_float, TST_double, TST_float128, + TST_ibm128, TST_bool, // _Bool TST_decimal32, // _Decimal32 TST_decimal64, // _Decimal64 diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -64,7 +64,7 @@ unsigned char BFloat16Width, BFloat16Align; unsigned char FloatWidth, FloatAlign; unsigned char DoubleWidth, DoubleAlign; - unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align; + unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align, Ibm128Align; unsigned char LargeArrayMinWidth, LargeArrayAlign; unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; @@ -104,7 +104,7 @@ unsigned MaxTLSAlign; const llvm::fltSemantics *HalfFormat, *BFloat16Format, *FloatFormat, - *DoubleFormat, *LongDoubleFormat, *Float128Format; + *DoubleFormat, *LongDoubleFormat, *Float128Format, *Ibm128Format; ///===---- Target Data Type Query Methods -------------------------------===// enum IntType { @@ -126,8 +126,10 @@ Float = 0, Double, LongDouble, - Float128 + Float128, + Ibm128 }; + protected: IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType, WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType, @@ -192,6 +194,7 @@ bool HasFloat128; bool HasFloat16; bool HasBFloat16; + bool HasIbm128; bool HasStrictFP; unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; @@ -580,6 +583,9 @@ /// Determine whether the _BFloat16 type is supported on this target. virtual bool hasBFloat16Type() const { return HasBFloat16; } + /// Determine whether the __ibm128 type is supported on this target. + virtual bool hasIbm128Type() const { return HasIbm128; } + /// Determine whether constrained floating point is supported on this target. virtual bool hasStrictFP() const { return HasStrictFP; } @@ -658,12 +664,21 @@ return *Float128Format; } + /// getIbm128Width/Align/Format - Return the size/align/format of + /// '__ibm128'. + unsigned getIbm128Width() const { return 128; } + unsigned getIbm128Align() const { return Ibm128Align; } + const llvm::fltSemantics &getIbm128Format() const { return *Ibm128Format; } + /// Return the mangled code of long double. virtual const char *getLongDoubleMangling() const { return "e"; } /// Return the mangled code of __float128. virtual const char *getFloat128Mangling() const { return "g"; } + /// Return the mangled code of __ibm128. + virtual const char *getIbm128Mangling() const { return "g"; } + /// Return the mangled code of bfloat. virtual const char *getBFloat16Mangling() const { llvm_unreachable("bfloat not implemented on this target"); diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -436,6 +436,7 @@ KEYWORD(__builtin_va_arg , KEYALL) KEYWORD(__extension__ , KEYALL) KEYWORD(__float128 , KEYALL) +KEYWORD(__ibm128 , KEYALL) KEYWORD(__imag , KEYALL) KEYWORD(__int128 , KEYALL) KEYWORD(__label__ , KEYALL) diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -275,6 +275,7 @@ static const TST TST_accum = clang::TST_Accum; static const TST TST_fract = clang::TST_Fract; static const TST TST_float128 = clang::TST_float128; + static const TST TST_ibm128 = clang::TST_ibm128; static const TST TST_bool = clang::TST_bool; static const TST TST_decimal32 = clang::TST_decimal32; static const TST TST_decimal64 = clang::TST_decimal64; diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1069,6 +1069,9 @@ /// \brief The '__bf16' type PREDEF_TYPE_BFLOAT16_ID = 73, + /// \brief The '__ibm128' type + PREDEF_TYPE_IBM128_ID = 74, + /// OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -100,7 +100,8 @@ using namespace clang; enum FloatingRank { - BFloat16Rank, Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank + BFloat16Rank, Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, + Float128Rank, Ibm128Rank }; /// \returns location that is relevant when searching for Doc comments related @@ -1296,6 +1297,9 @@ // GNU extension, __float128 for IEEE quadruple precision InitBuiltinType(Float128Ty, BuiltinType::Float128); + // __ibm128 for IBM extended precision + InitBuiltinType(Ibm128Ty, BuiltinType::Ibm128); + // C11 extension ISO/IEC TS 18661-3 InitBuiltinType(Float16Ty, BuiltinType::Float16); @@ -1671,6 +1675,7 @@ return Target->getHalfFormat(); case BuiltinType::Float: return Target->getFloatFormat(); case BuiltinType::Double: return Target->getDoubleFormat(); + case BuiltinType::Ibm128: return Target->getIbm128Format(); case BuiltinType::LongDouble: if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice) return AuxTarget->getLongDoubleFormat(); @@ -2091,6 +2096,10 @@ Width = Target->getDoubleWidth(); Align = Target->getDoubleAlign(); break; + case BuiltinType::Ibm128: + Width = Target->getIbm128Width(); + Align = Target->getIbm128Align(); + break; case BuiltinType::LongDouble: if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && (Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() || @@ -6175,6 +6184,8 @@ case BuiltinType::LongDouble: return LongDoubleRank; case BuiltinType::Float128: return Float128Rank; case BuiltinType::BFloat16: return BFloat16Rank; + case BuiltinType::Ibm128: + return Ibm128Rank; } } @@ -6190,6 +6201,7 @@ case BFloat16Rank: llvm_unreachable("Complex bfloat16 is not supported"); case Float16Rank: case HalfRank: llvm_unreachable("Complex half is not supported"); + case Ibm128Rank: llvm_unreachable("Complex __ibm128 is not supported"); case FloatRank: return FloatComplexTy; case DoubleRank: return DoubleComplexTy; case LongDoubleRank: return LongDoubleComplexTy; @@ -6206,6 +6218,7 @@ case DoubleRank: return DoubleTy; case LongDoubleRank: return LongDoubleTy; case Float128Rank: return Float128Ty; + case Ibm128Rank: return Ibm128Ty; } llvm_unreachable("getFloatingRank(): illegal value for rank"); } @@ -7181,6 +7194,7 @@ case BuiltinType::BFloat16: case BuiltinType::Float16: case BuiltinType::Float128: + case BuiltinType::Ibm128: case BuiltinType::Half: case BuiltinType::ShortAccum: case BuiltinType::Accum: @@ -10935,6 +10949,8 @@ return LongDoubleTy; case TargetInfo::Float128: return Float128Ty; + case TargetInfo::Ibm128: + return Ibm128Ty; case TargetInfo::NoFloat: return {}; } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2665,6 +2665,7 @@ // ::= d # double // ::= e # long double, __float80 // ::= g # __float128 + // ::= g # __ibm128 // UNSUPPORTED: ::= Dd # IEEE 754r decimal floating point (64 bits) // UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits) // UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits) @@ -2793,6 +2794,11 @@ Out << TI->getBFloat16Mangling(); break; } + case BuiltinType::Ibm128: { + const TargetInfo *TI = &getASTContext().getTargetInfo(); + Out << TI->getIbm128Mangling(); + break; + } case BuiltinType::NullPtr: Out << "Dn"; break; diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -2423,6 +2423,7 @@ case BuiltinType::SatUFract: case BuiltinType::SatULongFract: case BuiltinType::BFloat16: + case BuiltinType::Ibm128: case BuiltinType::Float128: { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID( diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp --- a/clang/lib/AST/NSAPI.cpp +++ b/clang/lib/AST/NSAPI.cpp @@ -456,6 +456,7 @@ case BuiltinType::UInt128: case BuiltinType::Float16: case BuiltinType::Float128: + case BuiltinType::Ibm128: case BuiltinType::NullPtr: case BuiltinType::ObjCClass: case BuiltinType::ObjCId: diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp --- a/clang/lib/AST/PrintfFormatString.cpp +++ b/clang/lib/AST/PrintfFormatString.cpp @@ -755,6 +755,7 @@ case BuiltinType::BFloat16: case BuiltinType::Float16: case BuiltinType::Float128: + case BuiltinType::Ibm128: case BuiltinType::ShortAccum: case BuiltinType::Accum: case BuiltinType::LongAccum: diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1196,6 +1196,7 @@ switch (Node->getType()->castAs()->getKind()) { default: llvm_unreachable("Unexpected type for float literal!"); case BuiltinType::Half: break; // FIXME: suffix? + case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal case BuiltinType::Double: break; // no suffix. case BuiltinType::Float16: OS << "F16"; break; case BuiltinType::Float: OS << 'F'; break; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2093,7 +2093,7 @@ bool Type::isFloatingType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->getKind() >= BuiltinType::Half && - BT->getKind() <= BuiltinType::Float128; + BT->getKind() <= BuiltinType::Ibm128; if (const auto *CT = dyn_cast(CanonicalType)) return CT->getElementType()->isFloatingType(); return false; @@ -2115,7 +2115,7 @@ bool Type::isRealType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && - BT->getKind() <= BuiltinType::Float128; + BT->getKind() <= BuiltinType::Ibm128; if (const auto *ET = dyn_cast(CanonicalType)) return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped(); return isExtIntType(); @@ -2124,7 +2124,7 @@ bool Type::isArithmeticType() const { if (const auto *BT = dyn_cast(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && - BT->getKind() <= BuiltinType::Float128 && + BT->getKind() <= BuiltinType::Ibm128 && BT->getKind() != BuiltinType::BFloat16; if (const auto *ET = dyn_cast(CanonicalType)) // GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2). @@ -3023,6 +3023,8 @@ return "_Float16"; case Float128: return "__float128"; + case Ibm128: + return "__ibm128"; case WChar_S: case WChar_U: return Policy.MSWChar ? "__wchar_t" : "wchar_t"; diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -351,6 +351,7 @@ case BuiltinType::LongDouble: case BuiltinType::Float16: case BuiltinType::Float128: + case BuiltinType::Ibm128: case BuiltinType::ShortAccum: case BuiltinType::Accum: case BuiltinType::LongAccum: diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -35,6 +35,7 @@ NoAsmVariants = false; HasLegalHalfType = false; HasFloat128 = false; + HasIbm128 = false; HasFloat16 = false; HasBFloat16 = false; HasStrictFP = false; @@ -81,6 +82,7 @@ LongDoubleWidth = 64; LongDoubleAlign = 64; Float128Align = 128; + Ibm128Align = 128; LargeArrayMinWidth = 0; LargeArrayAlign = 0; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; @@ -108,6 +110,7 @@ DoubleFormat = &llvm::APFloat::IEEEdouble(); LongDoubleFormat = &llvm::APFloat::IEEEdouble(); Float128Format = &llvm::APFloat::IEEEquad(); + Ibm128Format = &llvm::APFloat::PPCDoubleDouble(); MCountName = "mcount"; RegParmMax = 0; SSERegParmMax = 0; diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -83,6 +83,7 @@ LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); HasStrictFP = true; + HasIbm128 = true; } // Set the language option for altivec based on our value. diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -799,6 +799,7 @@ case BuiltinType::BFloat16: case BuiltinType::Float128: case BuiltinType::Double: + case BuiltinType::Ibm128: // FIXME: For targets where long double and __float128 have the same size, // they are currently indistinguishable in the debugger without some // special treatment. However, there is currently no consensus on encoding diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2571,7 +2571,8 @@ amt = llvm::ConstantFP::get(VMContext, llvm::APFloat(static_cast(amount))); else { - // Remaining types are Half, LongDouble or __float128. Convert from float. + // Remaining types are Half, LongDouble, __ibm128 or __float128. Convert + // from float. llvm::APFloat F(static_cast(amount)); bool ignored; const llvm::fltSemantics *FS; @@ -2581,6 +2582,8 @@ FS = &CGF.getTarget().getFloat128Format(); else if (value->getType()->isHalfTy()) FS = &CGF.getTarget().getHalfFormat(); + else if (value->getType()->isPPC_FP128Ty()) + FS = &CGF.getTarget().getIbm128Format(); else FS = &CGF.getTarget().getLongDoubleFormat(); F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored); diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -512,6 +512,7 @@ case BuiltinType::Double: case BuiltinType::LongDouble: case BuiltinType::Float128: + case BuiltinType::Ibm128: ResultType = getTypeForFormat(getLLVMContext(), Context.getFloatTypeSemantics(T), /* UseNativeHalf = */ false); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3157,6 +3157,7 @@ case BuiltinType::LongDouble: case BuiltinType::Float16: case BuiltinType::Float128: + case BuiltinType::Ibm128: case BuiltinType::Char8: case BuiltinType::Char16: case BuiltinType::Char32: @@ -4071,8 +4072,8 @@ getContext().UnsignedInt128Ty, getContext().HalfTy, getContext().FloatTy, getContext().DoubleTy, getContext().LongDoubleTy, getContext().Float128Ty, - getContext().Char8Ty, getContext().Char16Ty, - getContext().Char32Ty + getContext().Ibm128Ty, getContext().Char8Ty, + getContext().Char16Ty, getContext().Char32Ty }; llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass = RD->hasAttr() diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5177,6 +5177,7 @@ if (BT->getKind() == BuiltinType::Float || BT->getKind() == BuiltinType::Double || BT->getKind() == BuiltinType::LongDouble || + BT->getKind() == BuiltinType::Ibm128 || (getContext().getTargetInfo().hasFloat128Type() && (BT->getKind() == BuiltinType::Float128))) { if (IsSoftFloatABI) diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp --- a/clang/lib/Format/FormatToken.cpp +++ b/clang/lib/Format/FormatToken.cpp @@ -53,6 +53,7 @@ case tok::kw___bf16: case tok::kw__Float16: case tok::kw___float128: + case tok::kw___ibm128: case tok::kw_wchar_t: case tok::kw_bool: case tok::kw___underlying_type: diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3822,6 +3822,10 @@ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy); break; + case tok::kw___ibm128: + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_ibm128, Loc, PrevSpec, + DiagID, Policy); + break; case tok::kw_wchar_t: isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy); @@ -4895,6 +4899,7 @@ case tok::kw__Fract: case tok::kw__Float16: case tok::kw___float128: + case tok::kw___ibm128: case tok::kw_bool: case tok::kw__Bool: case tok::kw__Decimal32: @@ -4976,6 +4981,7 @@ case tok::kw__Fract: case tok::kw__Float16: case tok::kw___float128: + case tok::kw___ibm128: case tok::kw_bool: case tok::kw__Bool: case tok::kw__Decimal32: @@ -5145,6 +5151,7 @@ case tok::kw__Fract: case tok::kw__Float16: case tok::kw___float128: + case tok::kw___ibm128: case tok::kw_bool: case tok::kw__Bool: case tok::kw__Decimal32: diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1518,6 +1518,7 @@ case tok::kw___bf16: case tok::kw__Float16: case tok::kw___float128: + case tok::kw___ibm128: case tok::kw_void: case tok::kw_typename: case tok::kw_typeof: diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -2241,6 +2241,9 @@ case tok::kw___float128: DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy); break; + case tok::kw___ibm128: + DS.SetTypeSpecType(DeclSpec::TST_ibm128, Loc, PrevSpec, DiagID, Policy); + break; case tok::kw_wchar_t: DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy); break; diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -1637,6 +1637,7 @@ case tok::kw___bf16: case tok::kw__Float16: case tok::kw___float128: + case tok::kw___ibm128: case tok::kw_void: case tok::annot_decltype: #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: @@ -1751,6 +1752,7 @@ case tok::kw___bf16: case tok::kw__Float16: case tok::kw___float128: + case tok::kw___ibm128: case tok::kw_void: case tok::kw___unknown_anytype: case tok::kw___auto_type: diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -357,6 +357,7 @@ case TST_Fract: case TST_Float16: case TST_float128: + case TST_ibm128: case TST_enum: case TST_error: case TST_float: @@ -557,6 +558,7 @@ case DeclSpec::TST_fract: return "_Fract"; case DeclSpec::TST_float16: return "_Float16"; case DeclSpec::TST_float128: return "__float128"; + case DeclSpec::TST_ibm128: return "__ibm128"; case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool"; case DeclSpec::TST_decimal32: return "_Decimal32"; case DeclSpec::TST_decimal64: return "_Decimal64"; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -141,6 +141,7 @@ case tok::kw___bf16: case tok::kw__Float16: case tok::kw___float128: + case tok::kw___ibm128: case tok::kw_wchar_t: case tok::kw_bool: case tok::kw___underlying_type: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1213,6 +1213,8 @@ &S.Context.getFloatTypeSemantics(RHSElemType)) return false; + bool EitherIbm128 = + LHSElemType == S.Context.Ibm128Ty || RHSElemType == S.Context.Ibm128Ty; bool Float128AndLongDouble = (LHSElemType == S.Context.Float128Ty && RHSElemType == S.Context.LongDoubleTy); Float128AndLongDouble |= (LHSElemType == S.Context.LongDoubleTy && @@ -1221,9 +1223,10 @@ // We've handled the situation where __float128 and long double have the same // representation. We allow all conversions for all possible long double types // except PPC's double double. - return Float128AndLongDouble && - (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) == - &llvm::APFloat::PPCDoubleDouble()); + return (Float128AndLongDouble && + (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) == + &llvm::APFloat::PPCDoubleDouble())) || + EitherIbm128; } typedef ExprResult PerformCastFn(Sema &S, Expr *operand, QualType toType); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1882,9 +1882,12 @@ ToType == S.Context.LongDoubleTy) || (FromType == S.Context.LongDoubleTy && ToType == S.Context.Float128Ty)); - if (Float128AndLongDouble && - (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) == - &llvm::APFloat::PPCDoubleDouble())) + bool EitherIbm128 = + FromType == S.Context.Ibm128Ty || ToType == S.Context.Ibm128Ty; + if ((Float128AndLongDouble && + (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) == + &llvm::APFloat::PPCDoubleDouble())) || + EitherIbm128) return false; } // Floating point conversions (C++ 4.8). @@ -2237,7 +2240,8 @@ (FromBuiltin->getKind() == BuiltinType::Float || FromBuiltin->getKind() == BuiltinType::Double) && (ToBuiltin->getKind() == BuiltinType::LongDouble || - ToBuiltin->getKind() == BuiltinType::Float128)) + ToBuiltin->getKind() == BuiltinType::Float128 || + ToBuiltin->getKind() == BuiltinType::Ibm128)) return true; // Half can be promoted to float. @@ -8180,6 +8184,8 @@ ArithmeticTypes.push_back(S.Context.LongDoubleTy); if (S.Context.getTargetInfo().hasFloat128Type()) ArithmeticTypes.push_back(S.Context.Float128Ty); + if (S.Context.getTargetInfo().hasIbm128Type()) + ArithmeticTypes.push_back(S.Context.Ibm128Ty); // Start of integral types. FirstIntegralType = ArithmeticTypes.size(); diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -893,6 +893,7 @@ case TST_Fract: case TST_Float16: case TST_float128: + case TST_ibm128: case TST_bool: case TST_decimal32: case TST_decimal64: diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1557,6 +1557,13 @@ << "__float128"; Result = Context.Float128Ty; break; + case DeclSpec::TST_ibm128: + if (!S.Context.getTargetInfo().hasIbm128Type() && + !S.getLangOpts().SYCLIsDevice && + !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice)) + S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) << "__ibm128"; + Result = Context.Ibm128Ty; + break; case DeclSpec::TST_bool: Result = Context.BoolTy; // _Bool or bool break; diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -168,6 +168,9 @@ case BuiltinType::Float128: ID = PREDEF_TYPE_FLOAT128_ID; break; + case BuiltinType::Ibm128: + ID = PREDEF_TYPE_IBM128_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 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6935,6 +6935,9 @@ case PREDEF_TYPE_FLOAT128_ID: T = Context.Float128Ty; break; + case PREDEF_TYPE_IBM128_ID: + T = Context.Ibm128Ty; + break; case PREDEF_TYPE_OVERLOAD_ID: T = Context.OverloadTy; break; diff --git a/clang/test/CodeGenCXX/ibm128-declarations.cpp b/clang/test/CodeGenCXX/ibm128-declarations.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/ibm128-declarations.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -emit-llvm -triple powerpc64-unknown-unknown \ +// RUN: -std=c++11 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown \ +// RUN: -std=c++11 %s -o - | FileCheck %s + +__ibm128 gf; +static __ibm128 sgf; +__ibm128 arrgf[10]; +__ibm128 func1(__ibm128 arg); + +class CTest { + __ibm128 pf; + static const __ibm128 scf; + volatile __ibm128 vf; +public: + CTest(__ibm128 arg) : pf(arg), vf(arg) {} + __ibm128 func2(__ibm128 arg) { + return pf + arg; + } + static __ibm128 func3(__ibm128 arg) { + return arg * CTest::scf; + } +}; + +__ibm128 func4(__ibm128 a, __ibm128 b) { + return a + b; +} + +template struct T1 { + T mem1; +}; +template <> struct T1<__ibm128> { + __ibm128 mem2; +}; + +int main(void) { + __ibm128 lf; + CTest ct(lf); + T1<__ibm128> tf; + __ibm128 lfi = tf.mem2 + func1(lf) - CTest::func3(lf); +} + +// CHECK: %class.CTest = type { ppc_fp128, ppc_fp128 } +// CHECK: %struct.T1 = type { ppc_fp128 } + +// CHECK: @gf = global ppc_fp128 0xM00000000000000000000000000000000, align 16 +// CHECK: @arrgf = global [10 x ppc_fp128] zeroinitializer, align 16 +// CHECK: @_ZN5CTest3scfE = external constant ppc_fp128, align 16 + +// CHECK-LABEL: define ppc_fp128 @_Z5func4gg(ppc_fp128 %a, ppc_fp128 %b) +// CHECK: store ppc_fp128 %a, ppc_fp128* %a.addr, align 16 +// CHECK-NEXT: store ppc_fp128 %b, ppc_fp128* %b.addr, align 16 +// CHECK-NEXT: %0 = load ppc_fp128, ppc_fp128* %a.addr, align 16 +// CHECK-NEXT: %1 = load ppc_fp128, ppc_fp128* %b.addr, align 16 +// CHECK-NEXT: %add = fadd ppc_fp128 %0, %1 +// CHECK-NEXT: ret ppc_fp128 %add + +// CHECK-LABEL: define signext i32 @main() +// CHECK: %0 = load ppc_fp128, ppc_fp128* %lf, align 16 +// CHECK-NEXT: call void @_ZN5CTestC1Eg(%class.CTest* nonnull dereferenceable(32) %ct, ppc_fp128 %0) +// CHECK: %1 = load ppc_fp128, ppc_fp128* %mem2, align 16 +// CHECK-NEXT: %2 = load ppc_fp128, ppc_fp128* %lf, align 16 +// CHECK-NEXT: %call = call ppc_fp128 @_Z5func1g(ppc_fp128 %2) +// CHECK-NEXT: %add = fadd ppc_fp128 %1, %call +// CHECK-NEXT: %3 = load ppc_fp128, ppc_fp128* %lf, align 16 +// CHECK-NEXT: %call1 = call ppc_fp128 @_ZN5CTest5func3Eg(ppc_fp128 %3) +// CHECK-NEXT: %sub = fsub ppc_fp128 %add, %call1 +// CHECK-NEXT: store ppc_fp128 %sub, ppc_fp128* %lfi, align 16 + +// CHECK-LABEL: define linkonce_odr void @_ZN5CTestC1Eg(%class.CTest* nonnull dereferenceable(32) %this, ppc_fp128 %arg) +// CHECK: store ppc_fp128 %arg, ppc_fp128* %arg.addr, align 16 +// CHECK: %0 = load ppc_fp128, ppc_fp128* %arg.addr, align 16 +// CHECK-NEXT: call void @_ZN5CTestC2Eg(%class.CTest* nonnull dereferenceable(32) %this1, ppc_fp128 %0) + +// CHECK: declare ppc_fp128 @_Z5func1g(ppc_fp128) + +// CHECK-LABEL: define linkonce_odr ppc_fp128 @_ZN5CTest5func3Eg(ppc_fp128 %arg) +// CHECK: store ppc_fp128 %arg, ppc_fp128* %arg.addr, align 16 +// CHECK-NEXT: %0 = load ppc_fp128, ppc_fp128* %arg.addr, align 16 +// CHECK-NEXT: %1 = load ppc_fp128, ppc_fp128* @_ZN5CTest3scfE, align 16 +// CHECK-NEXT: %mul = fmul ppc_fp128 %0, %1 +// CHECK-NEXT: ret ppc_fp128 %mul + +// CHECK-LABEL: define linkonce_odr void @_ZN5CTestC2Eg(%class.CTest* nonnull dereferenceable(32) %this, ppc_fp128 %arg) +// CHECK: store ppc_fp128 %arg, ppc_fp128* %arg.addr, align 16 +// CHECK: %0 = load ppc_fp128, ppc_fp128* %arg.addr, align 16 +// CHECK-NEXT: store ppc_fp128 %0, ppc_fp128* %pf, align 16 +// CHECK: %1 = load ppc_fp128, ppc_fp128* %arg.addr, align 16 +// CHECK-NEXT: store volatile ppc_fp128 %1, ppc_fp128* %vf, align 16 diff --git a/clang/test/Sema/128bitfloat.cpp b/clang/test/Sema/128bitfloat.cpp --- a/clang/test/Sema/128bitfloat.cpp +++ b/clang/test/Sema/128bitfloat.cpp @@ -13,7 +13,7 @@ return x + *y; } -// expected-no-diagnostics +// expected-no-error {{__float128 is not supported on this target}} #else #if !defined(__STRICT_ANSI__) __float128 f; // expected-error {{__float128 is not supported on this target}} @@ -37,3 +37,18 @@ #endif #endif + +#ifdef __ppc__ +__ibm128 i; +template<> struct __is_floating_point_helper<__ibm128> {}; +int w(int x, __ibm128 *y) { + return x + *y; +} +// expected-no-error {{__ibm128 is not supported on this target}} +#else +__ibm128 i; // expected-error {{__ibm128 is not supported on this target}} +template<> struct __is_floating_point_helper<__ibm128> {}; // expected-error {{__ibm128 is not supported on this target}} +int w(int x, __ibm128 *y) { // expected-error {{__ibm128 is not supported on this target}} + return x + *y; +} +#endif diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -60,6 +60,7 @@ BTCASE(ULongAccum); BTCASE(Float16); BTCASE(Float128); + BTCASE(Ibm128); BTCASE(NullPtr); BTCASE(Overload); BTCASE(Dependent); @@ -577,6 +578,7 @@ TKIND(ULongAccum); TKIND(Float16); TKIND(Float128); + TKIND(Ibm128); TKIND(NullPtr); TKIND(Overload); TKIND(Dependent);