Index: clang/bindings/python/clang/cindex.py =================================================================== --- clang/bindings/python/clang/cindex.py +++ 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) Index: clang/include/clang-c/Index.h =================================================================== --- clang/include/clang-c/Index.h +++ 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, Index: clang/include/clang/AST/ASTContext.h =================================================================== --- clang/include/clang/AST/ASTContext.h +++ 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; Index: clang/include/clang/AST/BuiltinTypes.def =================================================================== --- clang/include/clang/AST/BuiltinTypes.def +++ 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'. Index: clang/include/clang/AST/Type.h =================================================================== --- clang/include/clang/AST/Type.h +++ 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. @@ -6958,6 +6959,10 @@ return isSpecificBuiltinType(BuiltinType::Float128); } +inline bool Type::isIbm128Type() const { + return isSpecificBuiltinType(BuiltinType::Ibm128); +} + inline bool Type::isNullPtrType() const { return isSpecificBuiltinType(BuiltinType::NullPtr); } Index: clang/include/clang/AST/TypeLoc.h =================================================================== --- clang/include/clang/AST/TypeLoc.h +++ 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 { Index: clang/include/clang/Basic/Specifiers.h =================================================================== --- clang/include/clang/Basic/Specifiers.h +++ 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 Index: clang/include/clang/Basic/TargetInfo.h =================================================================== --- clang/include/clang/Basic/TargetInfo.h +++ 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,23 @@ 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 { + llvm_unreachable("ibm128 not implemented on this target"); + } + /// Return the mangled code of bfloat. virtual const char *getBFloat16Mangling() const { llvm_unreachable("bfloat not implemented on this target"); Index: clang/include/clang/Basic/TokenKinds.def =================================================================== --- clang/include/clang/Basic/TokenKinds.def +++ 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) Index: clang/include/clang/Sema/DeclSpec.h =================================================================== --- clang/include/clang/Sema/DeclSpec.h +++ 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; Index: clang/include/clang/Serialization/ASTBitCodes.h =================================================================== --- clang/include/clang/Serialization/ASTBitCodes.h +++ 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, Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ 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,7 @@ case BuiltinType::LongDouble: return LongDoubleRank; case BuiltinType::Float128: return Float128Rank; case BuiltinType::BFloat16: return BFloat16Rank; + case BuiltinType::Ibm128: return Ibm128Rank; } } @@ -6190,6 +6200,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 +6217,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 +7193,7 @@ case BuiltinType::BFloat16: case BuiltinType::Float16: case BuiltinType::Float128: + case BuiltinType::Ibm128: case BuiltinType::Half: case BuiltinType::ShortAccum: case BuiltinType::Accum: @@ -10935,6 +10948,8 @@ return LongDoubleTy; case TargetInfo::Float128: return Float128Ty; + case TargetInfo::Ibm128: + return Ibm128Ty; case TargetInfo::NoFloat: return {}; } Index: clang/lib/AST/ItaniumMangle.cpp =================================================================== --- clang/lib/AST/ItaniumMangle.cpp +++ 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; Index: clang/lib/AST/MicrosoftMangle.cpp =================================================================== --- clang/lib/AST/MicrosoftMangle.cpp +++ 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( Index: clang/lib/AST/NSAPI.cpp =================================================================== --- clang/lib/AST/NSAPI.cpp +++ 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: Index: clang/lib/AST/PrintfFormatString.cpp =================================================================== --- clang/lib/AST/PrintfFormatString.cpp +++ 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: Index: clang/lib/AST/StmtPrinter.cpp =================================================================== --- clang/lib/AST/StmtPrinter.cpp +++ 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; Index: clang/lib/AST/Type.cpp =================================================================== --- clang/lib/AST/Type.cpp +++ 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"; Index: clang/lib/AST/TypeLoc.cpp =================================================================== --- clang/lib/AST/TypeLoc.cpp +++ 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: Index: clang/lib/Basic/TargetInfo.cpp =================================================================== --- clang/lib/Basic/TargetInfo.cpp +++ 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; Index: clang/lib/Basic/Targets/PPC.h =================================================================== --- clang/lib/Basic/Targets/PPC.h +++ 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. @@ -341,6 +342,7 @@ : "u9__ieee128"; } const char *getFloat128Mangling() const override { return "u9__ieee128"; } + const char *getIbm128Mangling() const override { return "g"; } bool hasExtIntType() const override { return true; } Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -799,11 +799,12 @@ case BuiltinType::BFloat16: case BuiltinType::Float128: case BuiltinType::Double: - // 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 - // and this should be updated once a DWARF encoding exists for distinct - // floating point types of the same size. + case BuiltinType::Ibm128: + // FIXME: For targets where long double, __ibm128 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 and this should be updated once a DWARF encoding exists for + // distinct floating point types of the same size. Encoding = llvm::dwarf::DW_ATE_float; break; case BuiltinType::ShortAccum: Index: clang/lib/CodeGen/CGExprScalar.cpp =================================================================== --- clang/lib/CodeGen/CGExprScalar.cpp +++ clang/lib/CodeGen/CGExprScalar.cpp @@ -2603,7 +2603,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; @@ -2613,6 +2614,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); Index: clang/lib/CodeGen/CodeGenTypes.cpp =================================================================== --- clang/lib/CodeGen/CodeGenTypes.cpp +++ 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); Index: clang/lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- clang/lib/CodeGen/ItaniumCXXABI.cpp +++ 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: Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ 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) Index: clang/lib/Format/FormatToken.cpp =================================================================== --- clang/lib/Format/FormatToken.cpp +++ 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: Index: clang/lib/Index/USRGeneration.cpp =================================================================== --- clang/lib/Index/USRGeneration.cpp +++ clang/lib/Index/USRGeneration.cpp @@ -705,6 +705,7 @@ c = 'f'; break; case BuiltinType::Double: c = 'd'; break; + case BuiltinType::Ibm128: // FIXME: Need separate tag case BuiltinType::LongDouble: c = 'D'; break; case BuiltinType::Float128: Index: clang/lib/Parse/ParseDecl.cpp =================================================================== --- clang/lib/Parse/ParseDecl.cpp +++ 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: Index: clang/lib/Parse/ParseExpr.cpp =================================================================== --- clang/lib/Parse/ParseExpr.cpp +++ 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: Index: clang/lib/Parse/ParseExprCXX.cpp =================================================================== --- clang/lib/Parse/ParseExprCXX.cpp +++ 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; Index: clang/lib/Parse/ParseTentative.cpp =================================================================== --- clang/lib/Parse/ParseTentative.cpp +++ 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: Index: clang/lib/Sema/DeclSpec.cpp =================================================================== --- clang/lib/Sema/DeclSpec.cpp +++ 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"; Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ 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: Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -1185,9 +1185,9 @@ /*ConvertInt=*/!IsCompAssign); } -/// Diagnose attempts to convert between __float128 and long double if -/// there is no support for such conversion. Helper function of -/// UsualArithmeticConversions(). +/// Diagnose attempts to convert between __float128, __ibm128 and +/// long double if there is no support for such conversion. +/// Helper function of UsualArithmeticConversions(). static bool unsupportedTypeConversion(const Sema &S, QualType LHSType, QualType RHSType) { /* No issue converting if at least one of the types is not a floating point @@ -1208,22 +1208,23 @@ QualType RHSElemType = RHSComplex ? RHSComplex->getElementType() : RHSType; + const llvm::fltSemantics &LHSSem = + S.Context.getFloatTypeSemantics(LHSElemType); + const llvm::fltSemantics &RHSSem = + S.Context.getFloatTypeSemantics(RHSElemType); + // No issue if the two types have the same representation - if (&S.Context.getFloatTypeSemantics(LHSElemType) == - &S.Context.getFloatTypeSemantics(RHSElemType)) + if (&LHSSem == &RHSSem) return false; - bool Float128AndLongDouble = (LHSElemType == S.Context.Float128Ty && - RHSElemType == S.Context.LongDoubleTy); - Float128AndLongDouble |= (LHSElemType == S.Context.LongDoubleTy && - RHSElemType == S.Context.Float128Ty); + if ((&LHSSem != &llvm::APFloat::PPCDoubleDouble() || + &RHSSem != &llvm::APFloat::IEEEquad()) && + (&LHSSem != &llvm::APFloat::IEEEquad() || + &RHSSem != &llvm::APFloat::PPCDoubleDouble())) + return false; - // 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()); + // Assume IEEE-quad and IBM-extended are not convertable + return true; } typedef ExprResult PerformCastFn(Sema &S, Expr *operand, QualType toType); @@ -1540,8 +1541,8 @@ // At this point, we have two different arithmetic types. - // Diagnose attempts to convert between __float128 and long double where - // such conversions currently can't be handled. + // Diagnose attempts to convert between __ibm128, __float128 and long double + // where such conversions currently can't be handled. if (unsupportedTypeConversion(*this, LHSType, RHSType)) return QualType(); @@ -8176,8 +8177,8 @@ QualType LHSTy = LHS.get()->getType(); QualType RHSTy = RHS.get()->getType(); - // Diagnose attempts to convert between __float128 and long double where - // such conversions currently can't be handled. + // Diagnose attempts to convert between __ibm128, __float128 and long double + // where such conversions currently can't be handled. if (unsupportedTypeConversion(*this, LHSTy, RHSTy)) { Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) << LHSTy << RHSTy @@ -9111,8 +9112,8 @@ return Incompatible; } - // Diagnose attempts to convert between __float128 and long double where - // such conversions currently can't be handled. + // Diagnose attempts to convert between __ibm128, __float128 and long double + // where such conversions currently can't be handled. if (unsupportedTypeConversion(*this, LHSType, RHSType)) return Incompatible; Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -1869,24 +1869,25 @@ SCS.Second = ICK_Complex_Real; FromType = ToType.getUnqualifiedType(); } else if (FromType->isRealFloatingType() && ToType->isRealFloatingType()) { - // FIXME: disable conversions between long double and __float128 if - // their representation is different until there is back end support + // FIXME: disable conversions between long double, __ibm128 and __float128 + // if their representation is different until there is back end support // We of course allow this conversion if long double is really double. // Conversions between bfloat and other floats are not permitted. if (FromType == S.Context.BFloat16Ty || ToType == S.Context.BFloat16Ty) return false; - if (&S.Context.getFloatTypeSemantics(FromType) != - &S.Context.getFloatTypeSemantics(ToType)) { - bool Float128AndLongDouble = ((FromType == S.Context.Float128Ty && - ToType == S.Context.LongDoubleTy) || - (FromType == S.Context.LongDoubleTy && - ToType == S.Context.Float128Ty)); - if (Float128AndLongDouble && - (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) == - &llvm::APFloat::PPCDoubleDouble())) - return false; - } + + // Conversions between IEEE-quad and IBM-extended semantics are not + // permitted. + const llvm::fltSemantics &FromSem = + S.Context.getFloatTypeSemantics(FromType); + const llvm::fltSemantics &ToSem = S.Context.getFloatTypeSemantics(ToType); + if ((&FromSem == &llvm::APFloat::PPCDoubleDouble() && + &ToSem == &llvm::APFloat::IEEEquad()) || + (&FromSem == &llvm::APFloat::IEEEquad() && + &ToSem == &llvm::APFloat::PPCDoubleDouble())) + return false; + // Floating point conversions (C++ 4.8). SCS.Second = ICK_Floating_Conversion; FromType = ToType.getUnqualifiedType(); @@ -2237,7 +2238,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 +8182,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(); Index: clang/lib/Sema/SemaTemplateVariadic.cpp =================================================================== --- clang/lib/Sema/SemaTemplateVariadic.cpp +++ 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: Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ 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; Index: clang/lib/Serialization/ASTCommon.cpp =================================================================== --- clang/lib/Serialization/ASTCommon.cpp +++ 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; Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ 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; Index: clang/test/Sema/128bitfloat.cpp =================================================================== --- clang/test/Sema/128bitfloat.cpp +++ 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 Index: clang/tools/libclang/CXType.cpp =================================================================== --- clang/tools/libclang/CXType.cpp +++ 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);