mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 13:50:11 +00:00
[Clang] Add __ibm128 type to represent ppc_fp128
Currently, we have no front-end type for ppc_fp128 type in IR. PowerPC target generates ppc_fp128 type from long double now, but there's option (-mabi=(ieee|ibm)longdouble) to control it and we're going to do transition from IBM extended double-double ppc_fp128 to IEEE fp128 in the future. This patch adds type __ibm128 which always represents ppc_fp128 in IR, as what GCC did for that type. Without this type in Clang, compilation will fail if compiling against future version of libstdcxx (which uses __ibm128 in headers). Although all operations in backend for __ibm128 is done by software, only PowerPC enables support for it. There's something not implemented in this commit, which can be done in future ones: - Literal suffix for __ibm128 type. w/W is suitable as GCC documented. - __attribute__((mode(IF))) should be for __ibm128. - Complex __ibm128 type. Reviewed By: rjmccall Differential Revision: https://reviews.llvm.org/D93377
This commit is contained in:
parent
96f6785bc9
commit
fae0dfa642
@ -2059,6 +2059,7 @@ TypeKind.OBJCCLASS = TypeKind(28)
|
|||||||
TypeKind.OBJCSEL = TypeKind(29)
|
TypeKind.OBJCSEL = TypeKind(29)
|
||||||
TypeKind.FLOAT128 = TypeKind(30)
|
TypeKind.FLOAT128 = TypeKind(30)
|
||||||
TypeKind.HALF = TypeKind(31)
|
TypeKind.HALF = TypeKind(31)
|
||||||
|
TypeKind.IBM128 = TypeKind(40)
|
||||||
TypeKind.COMPLEX = TypeKind(100)
|
TypeKind.COMPLEX = TypeKind(100)
|
||||||
TypeKind.POINTER = TypeKind(101)
|
TypeKind.POINTER = TypeKind(101)
|
||||||
TypeKind.BLOCKPOINTER = TypeKind(102)
|
TypeKind.BLOCKPOINTER = TypeKind(102)
|
||||||
|
@ -3298,8 +3298,9 @@ enum CXTypeKind {
|
|||||||
CXType_UAccum = 37,
|
CXType_UAccum = 37,
|
||||||
CXType_ULongAccum = 38,
|
CXType_ULongAccum = 38,
|
||||||
CXType_BFloat16 = 39,
|
CXType_BFloat16 = 39,
|
||||||
|
CXType_Ibm128 = 40,
|
||||||
CXType_FirstBuiltin = CXType_Void,
|
CXType_FirstBuiltin = CXType_Void,
|
||||||
CXType_LastBuiltin = CXType_BFloat16,
|
CXType_LastBuiltin = CXType_Ibm128,
|
||||||
|
|
||||||
CXType_Complex = 100,
|
CXType_Complex = 100,
|
||||||
CXType_Pointer = 101,
|
CXType_Pointer = 101,
|
||||||
|
@ -1076,7 +1076,7 @@ public:
|
|||||||
CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
|
CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
|
||||||
CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
|
CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
|
||||||
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
|
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
|
||||||
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
|
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty, Ibm128Ty;
|
||||||
CanQualType ShortAccumTy, AccumTy,
|
CanQualType ShortAccumTy, AccumTy,
|
||||||
LongAccumTy; // ISO/IEC JTC1 SC22 WG14 N1169 Extension
|
LongAccumTy; // ISO/IEC JTC1 SC22 WG14 N1169 Extension
|
||||||
CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy;
|
CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy;
|
||||||
|
@ -218,6 +218,9 @@ FLOATING_TYPE(BFloat16, BFloat16Ty)
|
|||||||
// '__float128'
|
// '__float128'
|
||||||
FLOATING_TYPE(Float128, Float128Ty)
|
FLOATING_TYPE(Float128, Float128Ty)
|
||||||
|
|
||||||
|
// '__ibm128'
|
||||||
|
FLOATING_TYPE(Ibm128, Ibm128Ty)
|
||||||
|
|
||||||
//===- Language-specific types --------------------------------------------===//
|
//===- Language-specific types --------------------------------------------===//
|
||||||
|
|
||||||
// This is the type of C++0x 'nullptr'.
|
// This is the type of C++0x 'nullptr'.
|
||||||
|
@ -2003,6 +2003,7 @@ public:
|
|||||||
bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661
|
bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661
|
||||||
bool isBFloat16Type() const;
|
bool isBFloat16Type() const;
|
||||||
bool isFloat128Type() const;
|
bool isFloat128Type() const;
|
||||||
|
bool isIbm128Type() const;
|
||||||
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
|
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
|
||||||
bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
|
bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
|
||||||
bool isVoidType() const; // C99 6.2.5p19
|
bool isVoidType() const; // C99 6.2.5p19
|
||||||
@ -2550,7 +2551,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isFloatingPoint() const {
|
bool isFloatingPoint() const {
|
||||||
return getKind() >= Half && getKind() <= Float128;
|
return getKind() >= Half && getKind() <= Ibm128;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether the given kind corresponds to a placeholder type.
|
/// Determines whether the given kind corresponds to a placeholder type.
|
||||||
@ -6973,6 +6974,10 @@ inline bool Type::isFloat128Type() const {
|
|||||||
return isSpecificBuiltinType(BuiltinType::Float128);
|
return isSpecificBuiltinType(BuiltinType::Float128);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Type::isIbm128Type() const {
|
||||||
|
return isSpecificBuiltinType(BuiltinType::Ibm128);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool Type::isNullPtrType() const {
|
inline bool Type::isNullPtrType() const {
|
||||||
return isSpecificBuiltinType(BuiltinType::NullPtr);
|
return isSpecificBuiltinType(BuiltinType::NullPtr);
|
||||||
}
|
}
|
||||||
|
@ -581,10 +581,9 @@ public:
|
|||||||
|
|
||||||
bool needsExtraLocalData() const {
|
bool needsExtraLocalData() const {
|
||||||
BuiltinType::Kind bk = getTypePtr()->getKind();
|
BuiltinType::Kind bk = getTypePtr()->getKind();
|
||||||
return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
|
return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) ||
|
||||||
|| (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
|
(bk >= BuiltinType::Short && bk <= BuiltinType::Ibm128) ||
|
||||||
|| bk == BuiltinType::UChar
|
bk == BuiltinType::UChar || bk == BuiltinType::SChar;
|
||||||
|| bk == BuiltinType::SChar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned getExtraLocalDataSize() const {
|
unsigned getExtraLocalDataSize() const {
|
||||||
|
@ -59,6 +59,7 @@ namespace clang {
|
|||||||
TST_float,
|
TST_float,
|
||||||
TST_double,
|
TST_double,
|
||||||
TST_float128,
|
TST_float128,
|
||||||
|
TST_ibm128,
|
||||||
TST_bool, // _Bool
|
TST_bool, // _Bool
|
||||||
TST_decimal32, // _Decimal32
|
TST_decimal32, // _Decimal32
|
||||||
TST_decimal64, // _Decimal64
|
TST_decimal64, // _Decimal64
|
||||||
|
@ -64,7 +64,7 @@ struct TransferrableTargetInfo {
|
|||||||
unsigned char BFloat16Width, BFloat16Align;
|
unsigned char BFloat16Width, BFloat16Align;
|
||||||
unsigned char FloatWidth, FloatAlign;
|
unsigned char FloatWidth, FloatAlign;
|
||||||
unsigned char DoubleWidth, DoubleAlign;
|
unsigned char DoubleWidth, DoubleAlign;
|
||||||
unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align;
|
unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align, Ibm128Align;
|
||||||
unsigned char LargeArrayMinWidth, LargeArrayAlign;
|
unsigned char LargeArrayMinWidth, LargeArrayAlign;
|
||||||
unsigned char LongWidth, LongAlign;
|
unsigned char LongWidth, LongAlign;
|
||||||
unsigned char LongLongWidth, LongLongAlign;
|
unsigned char LongLongWidth, LongLongAlign;
|
||||||
@ -104,7 +104,7 @@ struct TransferrableTargetInfo {
|
|||||||
unsigned MaxTLSAlign;
|
unsigned MaxTLSAlign;
|
||||||
|
|
||||||
const llvm::fltSemantics *HalfFormat, *BFloat16Format, *FloatFormat,
|
const llvm::fltSemantics *HalfFormat, *BFloat16Format, *FloatFormat,
|
||||||
*DoubleFormat, *LongDoubleFormat, *Float128Format;
|
*DoubleFormat, *LongDoubleFormat, *Float128Format, *Ibm128Format;
|
||||||
|
|
||||||
///===---- Target Data Type Query Methods -------------------------------===//
|
///===---- Target Data Type Query Methods -------------------------------===//
|
||||||
enum IntType {
|
enum IntType {
|
||||||
@ -126,8 +126,10 @@ struct TransferrableTargetInfo {
|
|||||||
Float = 0,
|
Float = 0,
|
||||||
Double,
|
Double,
|
||||||
LongDouble,
|
LongDouble,
|
||||||
Float128
|
Float128,
|
||||||
|
Ibm128
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType, WIntType,
|
IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType, WIntType,
|
||||||
Char16Type, Char32Type, Int64Type, Int16Type, SigAtomicType,
|
Char16Type, Char32Type, Int64Type, Int16Type, SigAtomicType,
|
||||||
@ -200,6 +202,7 @@ protected:
|
|||||||
bool HasFloat128;
|
bool HasFloat128;
|
||||||
bool HasFloat16;
|
bool HasFloat16;
|
||||||
bool HasBFloat16;
|
bool HasBFloat16;
|
||||||
|
bool HasIbm128;
|
||||||
bool HasStrictFP;
|
bool HasStrictFP;
|
||||||
|
|
||||||
unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
|
unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
|
||||||
@ -594,6 +597,9 @@ public:
|
|||||||
/// Determine whether the _BFloat16 type is supported on this target.
|
/// Determine whether the _BFloat16 type is supported on this target.
|
||||||
virtual bool hasBFloat16Type() const { return HasBFloat16; }
|
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.
|
/// Determine whether constrained floating point is supported on this target.
|
||||||
virtual bool hasStrictFP() const { return HasStrictFP; }
|
virtual bool hasStrictFP() const { return HasStrictFP; }
|
||||||
|
|
||||||
@ -672,12 +678,23 @@ public:
|
|||||||
return *Float128Format;
|
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.
|
/// Return the mangled code of long double.
|
||||||
virtual const char *getLongDoubleMangling() const { return "e"; }
|
virtual const char *getLongDoubleMangling() const { return "e"; }
|
||||||
|
|
||||||
/// Return the mangled code of __float128.
|
/// Return the mangled code of __float128.
|
||||||
virtual const char *getFloat128Mangling() const { return "g"; }
|
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.
|
/// Return the mangled code of bfloat.
|
||||||
virtual const char *getBFloat16Mangling() const {
|
virtual const char *getBFloat16Mangling() const {
|
||||||
llvm_unreachable("bfloat not implemented on this target");
|
llvm_unreachable("bfloat not implemented on this target");
|
||||||
|
@ -438,6 +438,7 @@ TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
|
|||||||
KEYWORD(__builtin_va_arg , KEYALL)
|
KEYWORD(__builtin_va_arg , KEYALL)
|
||||||
KEYWORD(__extension__ , KEYALL)
|
KEYWORD(__extension__ , KEYALL)
|
||||||
KEYWORD(__float128 , KEYALL)
|
KEYWORD(__float128 , KEYALL)
|
||||||
|
KEYWORD(__ibm128 , KEYALL)
|
||||||
KEYWORD(__imag , KEYALL)
|
KEYWORD(__imag , KEYALL)
|
||||||
KEYWORD(__int128 , KEYALL)
|
KEYWORD(__int128 , KEYALL)
|
||||||
KEYWORD(__label__ , KEYALL)
|
KEYWORD(__label__ , KEYALL)
|
||||||
|
@ -275,6 +275,7 @@ public:
|
|||||||
static const TST TST_accum = clang::TST_Accum;
|
static const TST TST_accum = clang::TST_Accum;
|
||||||
static const TST TST_fract = clang::TST_Fract;
|
static const TST TST_fract = clang::TST_Fract;
|
||||||
static const TST TST_float128 = clang::TST_float128;
|
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_bool = clang::TST_bool;
|
||||||
static const TST TST_decimal32 = clang::TST_decimal32;
|
static const TST TST_decimal32 = clang::TST_decimal32;
|
||||||
static const TST TST_decimal64 = clang::TST_decimal64;
|
static const TST TST_decimal64 = clang::TST_decimal64;
|
||||||
|
@ -1064,6 +1064,9 @@ enum PredefinedTypeIDs {
|
|||||||
/// \brief The '__bf16' type
|
/// \brief The '__bf16' type
|
||||||
PREDEF_TYPE_BFLOAT16_ID = 73,
|
PREDEF_TYPE_BFLOAT16_ID = 73,
|
||||||
|
|
||||||
|
/// \brief The '__ibm128' type
|
||||||
|
PREDEF_TYPE_IBM128_ID = 74,
|
||||||
|
|
||||||
/// OpenCL image types with auto numeration
|
/// OpenCL image types with auto numeration
|
||||||
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
|
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
|
||||||
PREDEF_TYPE_##Id##_ID,
|
PREDEF_TYPE_##Id##_ID,
|
||||||
|
@ -101,7 +101,14 @@
|
|||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
enum FloatingRank {
|
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
|
/// \returns location that is relevant when searching for Doc comments related
|
||||||
@ -1307,6 +1314,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
|
|||||||
// GNU extension, __float128 for IEEE quadruple precision
|
// GNU extension, __float128 for IEEE quadruple precision
|
||||||
InitBuiltinType(Float128Ty, BuiltinType::Float128);
|
InitBuiltinType(Float128Ty, BuiltinType::Float128);
|
||||||
|
|
||||||
|
// __ibm128 for IBM extended precision
|
||||||
|
InitBuiltinType(Ibm128Ty, BuiltinType::Ibm128);
|
||||||
|
|
||||||
// C11 extension ISO/IEC TS 18661-3
|
// C11 extension ISO/IEC TS 18661-3
|
||||||
InitBuiltinType(Float16Ty, BuiltinType::Float16);
|
InitBuiltinType(Float16Ty, BuiltinType::Float16);
|
||||||
|
|
||||||
@ -1703,6 +1713,8 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
|
|||||||
return Target->getHalfFormat();
|
return Target->getHalfFormat();
|
||||||
case BuiltinType::Float: return Target->getFloatFormat();
|
case BuiltinType::Float: return Target->getFloatFormat();
|
||||||
case BuiltinType::Double: return Target->getDoubleFormat();
|
case BuiltinType::Double: return Target->getDoubleFormat();
|
||||||
|
case BuiltinType::Ibm128:
|
||||||
|
return Target->getIbm128Format();
|
||||||
case BuiltinType::LongDouble:
|
case BuiltinType::LongDouble:
|
||||||
if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice)
|
if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice)
|
||||||
return AuxTarget->getLongDoubleFormat();
|
return AuxTarget->getLongDoubleFormat();
|
||||||
@ -2129,6 +2141,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
|
|||||||
Width = Target->getDoubleWidth();
|
Width = Target->getDoubleWidth();
|
||||||
Align = Target->getDoubleAlign();
|
Align = Target->getDoubleAlign();
|
||||||
break;
|
break;
|
||||||
|
case BuiltinType::Ibm128:
|
||||||
|
Width = Target->getIbm128Width();
|
||||||
|
Align = Target->getIbm128Align();
|
||||||
|
break;
|
||||||
case BuiltinType::LongDouble:
|
case BuiltinType::LongDouble:
|
||||||
if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
|
if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
|
||||||
(Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() ||
|
(Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() ||
|
||||||
@ -6309,6 +6325,7 @@ static FloatingRank getFloatingRank(QualType T) {
|
|||||||
case BuiltinType::LongDouble: return LongDoubleRank;
|
case BuiltinType::LongDouble: return LongDoubleRank;
|
||||||
case BuiltinType::Float128: return Float128Rank;
|
case BuiltinType::Float128: return Float128Rank;
|
||||||
case BuiltinType::BFloat16: return BFloat16Rank;
|
case BuiltinType::BFloat16: return BFloat16Rank;
|
||||||
|
case BuiltinType::Ibm128: return Ibm128Rank;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6324,6 +6341,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
|
|||||||
case BFloat16Rank: llvm_unreachable("Complex bfloat16 is not supported");
|
case BFloat16Rank: llvm_unreachable("Complex bfloat16 is not supported");
|
||||||
case Float16Rank:
|
case Float16Rank:
|
||||||
case HalfRank: llvm_unreachable("Complex half is not supported");
|
case HalfRank: llvm_unreachable("Complex half is not supported");
|
||||||
|
case Ibm128Rank: llvm_unreachable("Complex __ibm128 is not supported");
|
||||||
case FloatRank: return FloatComplexTy;
|
case FloatRank: return FloatComplexTy;
|
||||||
case DoubleRank: return DoubleComplexTy;
|
case DoubleRank: return DoubleComplexTy;
|
||||||
case LongDoubleRank: return LongDoubleComplexTy;
|
case LongDoubleRank: return LongDoubleComplexTy;
|
||||||
@ -6340,6 +6358,8 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
|
|||||||
case DoubleRank: return DoubleTy;
|
case DoubleRank: return DoubleTy;
|
||||||
case LongDoubleRank: return LongDoubleTy;
|
case LongDoubleRank: return LongDoubleTy;
|
||||||
case Float128Rank: return Float128Ty;
|
case Float128Rank: return Float128Ty;
|
||||||
|
case Ibm128Rank:
|
||||||
|
return Ibm128Ty;
|
||||||
}
|
}
|
||||||
llvm_unreachable("getFloatingRank(): illegal value for rank");
|
llvm_unreachable("getFloatingRank(): illegal value for rank");
|
||||||
}
|
}
|
||||||
@ -7315,6 +7335,7 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C,
|
|||||||
case BuiltinType::BFloat16:
|
case BuiltinType::BFloat16:
|
||||||
case BuiltinType::Float16:
|
case BuiltinType::Float16:
|
||||||
case BuiltinType::Float128:
|
case BuiltinType::Float128:
|
||||||
|
case BuiltinType::Ibm128:
|
||||||
case BuiltinType::Half:
|
case BuiltinType::Half:
|
||||||
case BuiltinType::ShortAccum:
|
case BuiltinType::ShortAccum:
|
||||||
case BuiltinType::Accum:
|
case BuiltinType::Accum:
|
||||||
@ -11250,6 +11271,8 @@ QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth,
|
|||||||
return LongDoubleTy;
|
return LongDoubleTy;
|
||||||
case TargetInfo::Float128:
|
case TargetInfo::Float128:
|
||||||
return Float128Ty;
|
return Float128Ty;
|
||||||
|
case TargetInfo::Ibm128:
|
||||||
|
return Ibm128Ty;
|
||||||
case TargetInfo::NoFloat:
|
case TargetInfo::NoFloat:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -2860,6 +2860,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
|
|||||||
// ::= d # double
|
// ::= d # double
|
||||||
// ::= e # long double, __float80
|
// ::= e # long double, __float80
|
||||||
// ::= g # __float128
|
// ::= g # __float128
|
||||||
|
// ::= g # __ibm128
|
||||||
// UNSUPPORTED: ::= Dd # IEEE 754r decimal floating point (64 bits)
|
// UNSUPPORTED: ::= Dd # IEEE 754r decimal floating point (64 bits)
|
||||||
// UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits)
|
// UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits)
|
||||||
// UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits)
|
// UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits)
|
||||||
@ -2988,6 +2989,11 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
|
|||||||
Out << TI->getBFloat16Mangling();
|
Out << TI->getBFloat16Mangling();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case BuiltinType::Ibm128: {
|
||||||
|
const TargetInfo *TI = &getASTContext().getTargetInfo();
|
||||||
|
Out << TI->getIbm128Mangling();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case BuiltinType::NullPtr:
|
case BuiltinType::NullPtr:
|
||||||
Out << "Dn";
|
Out << "Dn";
|
||||||
break;
|
break;
|
||||||
|
@ -2466,6 +2466,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
|
|||||||
case BuiltinType::SatUFract:
|
case BuiltinType::SatUFract:
|
||||||
case BuiltinType::SatULongFract:
|
case BuiltinType::SatULongFract:
|
||||||
case BuiltinType::BFloat16:
|
case BuiltinType::BFloat16:
|
||||||
|
case BuiltinType::Ibm128:
|
||||||
case BuiltinType::Float128: {
|
case BuiltinType::Float128: {
|
||||||
DiagnosticsEngine &Diags = Context.getDiags();
|
DiagnosticsEngine &Diags = Context.getDiags();
|
||||||
unsigned DiagID = Diags.getCustomDiagID(
|
unsigned DiagID = Diags.getCustomDiagID(
|
||||||
|
@ -456,6 +456,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
|
|||||||
case BuiltinType::UInt128:
|
case BuiltinType::UInt128:
|
||||||
case BuiltinType::Float16:
|
case BuiltinType::Float16:
|
||||||
case BuiltinType::Float128:
|
case BuiltinType::Float128:
|
||||||
|
case BuiltinType::Ibm128:
|
||||||
case BuiltinType::NullPtr:
|
case BuiltinType::NullPtr:
|
||||||
case BuiltinType::ObjCClass:
|
case BuiltinType::ObjCClass:
|
||||||
case BuiltinType::ObjCId:
|
case BuiltinType::ObjCId:
|
||||||
|
@ -755,6 +755,7 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
|
|||||||
case BuiltinType::BFloat16:
|
case BuiltinType::BFloat16:
|
||||||
case BuiltinType::Float16:
|
case BuiltinType::Float16:
|
||||||
case BuiltinType::Float128:
|
case BuiltinType::Float128:
|
||||||
|
case BuiltinType::Ibm128:
|
||||||
case BuiltinType::ShortAccum:
|
case BuiltinType::ShortAccum:
|
||||||
case BuiltinType::Accum:
|
case BuiltinType::Accum:
|
||||||
case BuiltinType::LongAccum:
|
case BuiltinType::LongAccum:
|
||||||
|
@ -1183,6 +1183,7 @@ static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
|
|||||||
switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
|
switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
|
||||||
default: llvm_unreachable("Unexpected type for float literal!");
|
default: llvm_unreachable("Unexpected type for float literal!");
|
||||||
case BuiltinType::Half: break; // FIXME: suffix?
|
case BuiltinType::Half: break; // FIXME: suffix?
|
||||||
|
case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal
|
||||||
case BuiltinType::Double: break; // no suffix.
|
case BuiltinType::Double: break; // no suffix.
|
||||||
case BuiltinType::Float16: OS << "F16"; break;
|
case BuiltinType::Float16: OS << "F16"; break;
|
||||||
case BuiltinType::Float: OS << 'F'; break;
|
case BuiltinType::Float: OS << 'F'; break;
|
||||||
|
@ -2097,7 +2097,7 @@ bool Type::hasUnsignedIntegerRepresentation() const {
|
|||||||
bool Type::isFloatingType() const {
|
bool Type::isFloatingType() const {
|
||||||
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
|
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||||
return BT->getKind() >= BuiltinType::Half &&
|
return BT->getKind() >= BuiltinType::Half &&
|
||||||
BT->getKind() <= BuiltinType::Float128;
|
BT->getKind() <= BuiltinType::Ibm128;
|
||||||
if (const auto *CT = dyn_cast<ComplexType>(CanonicalType))
|
if (const auto *CT = dyn_cast<ComplexType>(CanonicalType))
|
||||||
return CT->getElementType()->isFloatingType();
|
return CT->getElementType()->isFloatingType();
|
||||||
return false;
|
return false;
|
||||||
@ -2119,7 +2119,7 @@ bool Type::isRealFloatingType() const {
|
|||||||
bool Type::isRealType() const {
|
bool Type::isRealType() const {
|
||||||
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
|
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||||
return BT->getKind() >= BuiltinType::Bool &&
|
return BT->getKind() >= BuiltinType::Bool &&
|
||||||
BT->getKind() <= BuiltinType::Float128;
|
BT->getKind() <= BuiltinType::Ibm128;
|
||||||
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
|
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
|
||||||
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
|
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
|
||||||
return isExtIntType();
|
return isExtIntType();
|
||||||
@ -2128,7 +2128,7 @@ bool Type::isRealType() const {
|
|||||||
bool Type::isArithmeticType() const {
|
bool Type::isArithmeticType() const {
|
||||||
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
|
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||||
return BT->getKind() >= BuiltinType::Bool &&
|
return BT->getKind() >= BuiltinType::Bool &&
|
||||||
BT->getKind() <= BuiltinType::Float128 &&
|
BT->getKind() <= BuiltinType::Ibm128 &&
|
||||||
BT->getKind() != BuiltinType::BFloat16;
|
BT->getKind() != BuiltinType::BFloat16;
|
||||||
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
|
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
|
||||||
// GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
|
// GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
|
||||||
@ -3030,6 +3030,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
|
|||||||
return "_Float16";
|
return "_Float16";
|
||||||
case Float128:
|
case Float128:
|
||||||
return "__float128";
|
return "__float128";
|
||||||
|
case Ibm128:
|
||||||
|
return "__ibm128";
|
||||||
case WChar_S:
|
case WChar_S:
|
||||||
case WChar_U:
|
case WChar_U:
|
||||||
return Policy.MSWChar ? "__wchar_t" : "wchar_t";
|
return Policy.MSWChar ? "__wchar_t" : "wchar_t";
|
||||||
|
@ -351,6 +351,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
|
|||||||
case BuiltinType::LongDouble:
|
case BuiltinType::LongDouble:
|
||||||
case BuiltinType::Float16:
|
case BuiltinType::Float16:
|
||||||
case BuiltinType::Float128:
|
case BuiltinType::Float128:
|
||||||
|
case BuiltinType::Ibm128:
|
||||||
case BuiltinType::ShortAccum:
|
case BuiltinType::ShortAccum:
|
||||||
case BuiltinType::Accum:
|
case BuiltinType::Accum:
|
||||||
case BuiltinType::LongAccum:
|
case BuiltinType::LongAccum:
|
||||||
|
@ -34,6 +34,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
|
|||||||
NoAsmVariants = false;
|
NoAsmVariants = false;
|
||||||
HasLegalHalfType = false;
|
HasLegalHalfType = false;
|
||||||
HasFloat128 = false;
|
HasFloat128 = false;
|
||||||
|
HasIbm128 = false;
|
||||||
HasFloat16 = false;
|
HasFloat16 = false;
|
||||||
HasBFloat16 = false;
|
HasBFloat16 = false;
|
||||||
HasStrictFP = false;
|
HasStrictFP = false;
|
||||||
@ -83,6 +84,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
|
|||||||
LongDoubleWidth = 64;
|
LongDoubleWidth = 64;
|
||||||
LongDoubleAlign = 64;
|
LongDoubleAlign = 64;
|
||||||
Float128Align = 128;
|
Float128Align = 128;
|
||||||
|
Ibm128Align = 128;
|
||||||
LargeArrayMinWidth = 0;
|
LargeArrayMinWidth = 0;
|
||||||
LargeArrayAlign = 0;
|
LargeArrayAlign = 0;
|
||||||
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
|
||||||
@ -113,6 +115,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
|
|||||||
DoubleFormat = &llvm::APFloat::IEEEdouble();
|
DoubleFormat = &llvm::APFloat::IEEEdouble();
|
||||||
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
|
||||||
Float128Format = &llvm::APFloat::IEEEquad();
|
Float128Format = &llvm::APFloat::IEEEquad();
|
||||||
|
Ibm128Format = &llvm::APFloat::PPCDoubleDouble();
|
||||||
MCountName = "mcount";
|
MCountName = "mcount";
|
||||||
UserLabelPrefix = "_";
|
UserLabelPrefix = "_";
|
||||||
RegParmMax = 0;
|
RegParmMax = 0;
|
||||||
|
@ -89,6 +89,7 @@ public:
|
|||||||
LongDoubleWidth = LongDoubleAlign = 128;
|
LongDoubleWidth = LongDoubleAlign = 128;
|
||||||
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble();
|
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble();
|
||||||
HasStrictFP = true;
|
HasStrictFP = true;
|
||||||
|
HasIbm128 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the language option for altivec based on our value.
|
// Set the language option for altivec based on our value.
|
||||||
@ -347,6 +348,7 @@ public:
|
|||||||
: "u9__ieee128";
|
: "u9__ieee128";
|
||||||
}
|
}
|
||||||
const char *getFloat128Mangling() const override { return "u9__ieee128"; }
|
const char *getFloat128Mangling() const override { return "u9__ieee128"; }
|
||||||
|
const char *getIbm128Mangling() const override { return "g"; }
|
||||||
|
|
||||||
bool hasExtIntType() const override { return true; }
|
bool hasExtIntType() const override { return true; }
|
||||||
|
|
||||||
|
@ -830,11 +830,12 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
|
|||||||
case BuiltinType::BFloat16:
|
case BuiltinType::BFloat16:
|
||||||
case BuiltinType::Float128:
|
case BuiltinType::Float128:
|
||||||
case BuiltinType::Double:
|
case BuiltinType::Double:
|
||||||
// FIXME: For targets where long double and __float128 have the same size,
|
case BuiltinType::Ibm128:
|
||||||
// they are currently indistinguishable in the debugger without some
|
// FIXME: For targets where long double, __ibm128 and __float128 have the
|
||||||
// special treatment. However, there is currently no consensus on encoding
|
// same size, they are currently indistinguishable in the debugger without
|
||||||
// and this should be updated once a DWARF encoding exists for distinct
|
// some special treatment. However, there is currently no consensus on
|
||||||
// floating point types of the same size.
|
// 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;
|
Encoding = llvm::dwarf::DW_ATE_float;
|
||||||
break;
|
break;
|
||||||
case BuiltinType::ShortAccum:
|
case BuiltinType::ShortAccum:
|
||||||
|
@ -2680,7 +2680,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
|
|||||||
amt = llvm::ConstantFP::get(VMContext,
|
amt = llvm::ConstantFP::get(VMContext,
|
||||||
llvm::APFloat(static_cast<double>(amount)));
|
llvm::APFloat(static_cast<double>(amount)));
|
||||||
else {
|
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<float>(amount));
|
llvm::APFloat F(static_cast<float>(amount));
|
||||||
bool ignored;
|
bool ignored;
|
||||||
const llvm::fltSemantics *FS;
|
const llvm::fltSemantics *FS;
|
||||||
@ -2690,6 +2691,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
|
|||||||
FS = &CGF.getTarget().getFloat128Format();
|
FS = &CGF.getTarget().getFloat128Format();
|
||||||
else if (value->getType()->isHalfTy())
|
else if (value->getType()->isHalfTy())
|
||||||
FS = &CGF.getTarget().getHalfFormat();
|
FS = &CGF.getTarget().getHalfFormat();
|
||||||
|
else if (value->getType()->isPPC_FP128Ty())
|
||||||
|
FS = &CGF.getTarget().getIbm128Format();
|
||||||
else
|
else
|
||||||
FS = &CGF.getTarget().getLongDoubleFormat();
|
FS = &CGF.getTarget().getLongDoubleFormat();
|
||||||
F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
|
F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
|
||||||
|
@ -512,6 +512,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
|||||||
case BuiltinType::Double:
|
case BuiltinType::Double:
|
||||||
case BuiltinType::LongDouble:
|
case BuiltinType::LongDouble:
|
||||||
case BuiltinType::Float128:
|
case BuiltinType::Float128:
|
||||||
|
case BuiltinType::Ibm128:
|
||||||
ResultType = getTypeForFormat(getLLVMContext(),
|
ResultType = getTypeForFormat(getLLVMContext(),
|
||||||
Context.getFloatTypeSemantics(T),
|
Context.getFloatTypeSemantics(T),
|
||||||
/* UseNativeHalf = */ false);
|
/* UseNativeHalf = */ false);
|
||||||
|
@ -3269,6 +3269,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
|
|||||||
case BuiltinType::LongDouble:
|
case BuiltinType::LongDouble:
|
||||||
case BuiltinType::Float16:
|
case BuiltinType::Float16:
|
||||||
case BuiltinType::Float128:
|
case BuiltinType::Float128:
|
||||||
|
case BuiltinType::Ibm128:
|
||||||
case BuiltinType::Char8:
|
case BuiltinType::Char8:
|
||||||
case BuiltinType::Char16:
|
case BuiltinType::Char16:
|
||||||
case BuiltinType::Char32:
|
case BuiltinType::Char32:
|
||||||
|
@ -5226,8 +5226,9 @@ bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
|
|||||||
if (BT->getKind() == BuiltinType::Float ||
|
if (BT->getKind() == BuiltinType::Float ||
|
||||||
BT->getKind() == BuiltinType::Double ||
|
BT->getKind() == BuiltinType::Double ||
|
||||||
BT->getKind() == BuiltinType::LongDouble ||
|
BT->getKind() == BuiltinType::LongDouble ||
|
||||||
|
BT->getKind() == BuiltinType::Ibm128 ||
|
||||||
(getContext().getTargetInfo().hasFloat128Type() &&
|
(getContext().getTargetInfo().hasFloat128Type() &&
|
||||||
(BT->getKind() == BuiltinType::Float128))) {
|
(BT->getKind() == BuiltinType::Float128))) {
|
||||||
if (IsSoftFloatABI)
|
if (IsSoftFloatABI)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -53,6 +53,7 @@ bool FormatToken::isSimpleTypeSpecifier() const {
|
|||||||
case tok::kw___bf16:
|
case tok::kw___bf16:
|
||||||
case tok::kw__Float16:
|
case tok::kw__Float16:
|
||||||
case tok::kw___float128:
|
case tok::kw___float128:
|
||||||
|
case tok::kw___ibm128:
|
||||||
case tok::kw_wchar_t:
|
case tok::kw_wchar_t:
|
||||||
case tok::kw_bool:
|
case tok::kw_bool:
|
||||||
case tok::kw___underlying_type:
|
case tok::kw___underlying_type:
|
||||||
|
@ -705,6 +705,7 @@ void USRGenerator::VisitType(QualType T) {
|
|||||||
c = 'f'; break;
|
c = 'f'; break;
|
||||||
case BuiltinType::Double:
|
case BuiltinType::Double:
|
||||||
c = 'd'; break;
|
c = 'd'; break;
|
||||||
|
case BuiltinType::Ibm128: // FIXME: Need separate tag
|
||||||
case BuiltinType::LongDouble:
|
case BuiltinType::LongDouble:
|
||||||
c = 'D'; break;
|
c = 'D'; break;
|
||||||
case BuiltinType::Float128:
|
case BuiltinType::Float128:
|
||||||
|
@ -3929,6 +3929,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||||||
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec,
|
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec,
|
||||||
DiagID, Policy);
|
DiagID, Policy);
|
||||||
break;
|
break;
|
||||||
|
case tok::kw___ibm128:
|
||||||
|
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_ibm128, Loc, PrevSpec,
|
||||||
|
DiagID, Policy);
|
||||||
|
break;
|
||||||
case tok::kw_wchar_t:
|
case tok::kw_wchar_t:
|
||||||
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
|
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
|
||||||
DiagID, Policy);
|
DiagID, Policy);
|
||||||
@ -5007,6 +5011,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
|
|||||||
case tok::kw__Fract:
|
case tok::kw__Fract:
|
||||||
case tok::kw__Float16:
|
case tok::kw__Float16:
|
||||||
case tok::kw___float128:
|
case tok::kw___float128:
|
||||||
|
case tok::kw___ibm128:
|
||||||
case tok::kw_bool:
|
case tok::kw_bool:
|
||||||
case tok::kw__Bool:
|
case tok::kw__Bool:
|
||||||
case tok::kw__Decimal32:
|
case tok::kw__Decimal32:
|
||||||
@ -5088,6 +5093,7 @@ bool Parser::isTypeSpecifierQualifier() {
|
|||||||
case tok::kw__Fract:
|
case tok::kw__Fract:
|
||||||
case tok::kw__Float16:
|
case tok::kw__Float16:
|
||||||
case tok::kw___float128:
|
case tok::kw___float128:
|
||||||
|
case tok::kw___ibm128:
|
||||||
case tok::kw_bool:
|
case tok::kw_bool:
|
||||||
case tok::kw__Bool:
|
case tok::kw__Bool:
|
||||||
case tok::kw__Decimal32:
|
case tok::kw__Decimal32:
|
||||||
@ -5258,6 +5264,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
|
|||||||
case tok::kw__Fract:
|
case tok::kw__Fract:
|
||||||
case tok::kw__Float16:
|
case tok::kw__Float16:
|
||||||
case tok::kw___float128:
|
case tok::kw___float128:
|
||||||
|
case tok::kw___ibm128:
|
||||||
case tok::kw_bool:
|
case tok::kw_bool:
|
||||||
case tok::kw__Bool:
|
case tok::kw__Bool:
|
||||||
case tok::kw__Decimal32:
|
case tok::kw__Decimal32:
|
||||||
|
@ -1521,6 +1521,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
|
|||||||
case tok::kw___bf16:
|
case tok::kw___bf16:
|
||||||
case tok::kw__Float16:
|
case tok::kw__Float16:
|
||||||
case tok::kw___float128:
|
case tok::kw___float128:
|
||||||
|
case tok::kw___ibm128:
|
||||||
case tok::kw_void:
|
case tok::kw_void:
|
||||||
case tok::kw_typename:
|
case tok::kw_typename:
|
||||||
case tok::kw_typeof:
|
case tok::kw_typeof:
|
||||||
|
@ -2226,6 +2226,9 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
|
|||||||
case tok::kw___float128:
|
case tok::kw___float128:
|
||||||
DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy);
|
DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy);
|
||||||
break;
|
break;
|
||||||
|
case tok::kw___ibm128:
|
||||||
|
DS.SetTypeSpecType(DeclSpec::TST_ibm128, Loc, PrevSpec, DiagID, Policy);
|
||||||
|
break;
|
||||||
case tok::kw_wchar_t:
|
case tok::kw_wchar_t:
|
||||||
DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy);
|
DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy);
|
||||||
break;
|
break;
|
||||||
|
@ -1637,6 +1637,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
|||||||
case tok::kw___bf16:
|
case tok::kw___bf16:
|
||||||
case tok::kw__Float16:
|
case tok::kw__Float16:
|
||||||
case tok::kw___float128:
|
case tok::kw___float128:
|
||||||
|
case tok::kw___ibm128:
|
||||||
case tok::kw_void:
|
case tok::kw_void:
|
||||||
case tok::annot_decltype:
|
case tok::annot_decltype:
|
||||||
#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
|
#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
|
||||||
@ -1751,6 +1752,7 @@ bool Parser::isCXXDeclarationSpecifierAType() {
|
|||||||
case tok::kw___bf16:
|
case tok::kw___bf16:
|
||||||
case tok::kw__Float16:
|
case tok::kw__Float16:
|
||||||
case tok::kw___float128:
|
case tok::kw___float128:
|
||||||
|
case tok::kw___ibm128:
|
||||||
case tok::kw_void:
|
case tok::kw_void:
|
||||||
case tok::kw___unknown_anytype:
|
case tok::kw___unknown_anytype:
|
||||||
case tok::kw___auto_type:
|
case tok::kw___auto_type:
|
||||||
|
@ -358,6 +358,7 @@ bool Declarator::isDeclarationOfFunction() const {
|
|||||||
case TST_Fract:
|
case TST_Fract:
|
||||||
case TST_Float16:
|
case TST_Float16:
|
||||||
case TST_float128:
|
case TST_float128:
|
||||||
|
case TST_ibm128:
|
||||||
case TST_enum:
|
case TST_enum:
|
||||||
case TST_error:
|
case TST_error:
|
||||||
case TST_float:
|
case TST_float:
|
||||||
@ -558,6 +559,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
|
|||||||
case DeclSpec::TST_fract: return "_Fract";
|
case DeclSpec::TST_fract: return "_Fract";
|
||||||
case DeclSpec::TST_float16: return "_Float16";
|
case DeclSpec::TST_float16: return "_Float16";
|
||||||
case DeclSpec::TST_float128: return "__float128";
|
case DeclSpec::TST_float128: return "__float128";
|
||||||
|
case DeclSpec::TST_ibm128: return "__ibm128";
|
||||||
case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool";
|
case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool";
|
||||||
case DeclSpec::TST_decimal32: return "_Decimal32";
|
case DeclSpec::TST_decimal32: return "_Decimal32";
|
||||||
case DeclSpec::TST_decimal64: return "_Decimal64";
|
case DeclSpec::TST_decimal64: return "_Decimal64";
|
||||||
|
@ -1887,12 +1887,22 @@ void Sema::checkDeviceDecl(ValueDecl *D, SourceLocation Loc) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if we are dealing with two 'long double' but with different
|
||||||
|
// semantics.
|
||||||
|
bool LongDoubleMismatched = false;
|
||||||
|
if (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128) {
|
||||||
|
const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(Ty);
|
||||||
|
if (!Ty->isIbm128Type() && !Ty->isFloat128Type() &&
|
||||||
|
&Sem != &Context.getTargetInfo().getLongDoubleFormat())
|
||||||
|
LongDoubleMismatched = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
|
if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
|
||||||
((Ty->isFloat128Type() ||
|
(Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) ||
|
||||||
(Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) &&
|
(Ty->isIbm128Type() && !Context.getTargetInfo().hasIbm128Type()) ||
|
||||||
!Context.getTargetInfo().hasFloat128Type()) ||
|
|
||||||
(Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
|
(Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
|
||||||
!Context.getTargetInfo().hasInt128Type())) {
|
!Context.getTargetInfo().hasInt128Type()) ||
|
||||||
|
LongDoubleMismatched) {
|
||||||
if (targetDiag(Loc, diag::err_device_unsupported_type, FD)
|
if (targetDiag(Loc, diag::err_device_unsupported_type, FD)
|
||||||
<< D << true /*show bit size*/
|
<< D << true /*show bit size*/
|
||||||
<< static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty
|
<< static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty
|
||||||
|
@ -141,6 +141,7 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
|
|||||||
case tok::kw___bf16:
|
case tok::kw___bf16:
|
||||||
case tok::kw__Float16:
|
case tok::kw__Float16:
|
||||||
case tok::kw___float128:
|
case tok::kw___float128:
|
||||||
|
case tok::kw___ibm128:
|
||||||
case tok::kw_wchar_t:
|
case tok::kw_wchar_t:
|
||||||
case tok::kw_bool:
|
case tok::kw_bool:
|
||||||
case tok::kw___underlying_type:
|
case tok::kw___underlying_type:
|
||||||
|
@ -1197,45 +1197,32 @@ static QualType handleFloatConversion(Sema &S, ExprResult &LHS,
|
|||||||
/*ConvertInt=*/!IsCompAssign);
|
/*ConvertInt=*/!IsCompAssign);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Diagnose attempts to convert between __float128 and long double if
|
/// Diagnose attempts to convert between __float128, __ibm128 and
|
||||||
/// there is no support for such conversion. Helper function of
|
/// long double if there is no support for such conversion.
|
||||||
/// UsualArithmeticConversions().
|
/// Helper function of UsualArithmeticConversions().
|
||||||
static bool unsupportedTypeConversion(const Sema &S, QualType LHSType,
|
static bool unsupportedTypeConversion(const Sema &S, QualType LHSType,
|
||||||
QualType RHSType) {
|
QualType RHSType) {
|
||||||
/* No issue converting if at least one of the types is not a floating point
|
// No issue if either is not a floating point type.
|
||||||
type or the two types have the same rank.
|
if (!LHSType->isFloatingType() || !RHSType->isFloatingType())
|
||||||
*/
|
|
||||||
if (!LHSType->isFloatingType() || !RHSType->isFloatingType() ||
|
|
||||||
S.Context.getFloatingTypeOrder(LHSType, RHSType) == 0)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
assert(LHSType->isFloatingType() && RHSType->isFloatingType() &&
|
// No issue if both have the same 128-bit float semantics.
|
||||||
"The remaining types must be floating point types.");
|
|
||||||
|
|
||||||
auto *LHSComplex = LHSType->getAs<ComplexType>();
|
auto *LHSComplex = LHSType->getAs<ComplexType>();
|
||||||
auto *RHSComplex = RHSType->getAs<ComplexType>();
|
auto *RHSComplex = RHSType->getAs<ComplexType>();
|
||||||
|
|
||||||
QualType LHSElemType = LHSComplex ?
|
QualType LHSElem = LHSComplex ? LHSComplex->getElementType() : LHSType;
|
||||||
LHSComplex->getElementType() : LHSType;
|
QualType RHSElem = RHSComplex ? RHSComplex->getElementType() : RHSType;
|
||||||
QualType RHSElemType = RHSComplex ?
|
|
||||||
RHSComplex->getElementType() : RHSType;
|
|
||||||
|
|
||||||
// No issue if the two types have the same representation
|
const llvm::fltSemantics &LHSSem = S.Context.getFloatTypeSemantics(LHSElem);
|
||||||
if (&S.Context.getFloatTypeSemantics(LHSElemType) ==
|
const llvm::fltSemantics &RHSSem = S.Context.getFloatTypeSemantics(RHSElem);
|
||||||
&S.Context.getFloatTypeSemantics(RHSElemType))
|
|
||||||
|
if ((&LHSSem != &llvm::APFloat::PPCDoubleDouble() ||
|
||||||
|
&RHSSem != &llvm::APFloat::IEEEquad()) &&
|
||||||
|
(&LHSSem != &llvm::APFloat::IEEEquad() ||
|
||||||
|
&RHSSem != &llvm::APFloat::PPCDoubleDouble()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool Float128AndLongDouble = (LHSElemType == S.Context.Float128Ty &&
|
return true;
|
||||||
RHSElemType == S.Context.LongDoubleTy);
|
|
||||||
Float128AndLongDouble |= (LHSElemType == S.Context.LongDoubleTy &&
|
|
||||||
RHSElemType == S.Context.Float128Ty);
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef ExprResult PerformCastFn(Sema &S, Expr *operand, QualType toType);
|
typedef ExprResult PerformCastFn(Sema &S, Expr *operand, QualType toType);
|
||||||
@ -1547,8 +1534,8 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
|
|||||||
|
|
||||||
// At this point, we have two different arithmetic types.
|
// At this point, we have two different arithmetic types.
|
||||||
|
|
||||||
// Diagnose attempts to convert between __float128 and long double where
|
// Diagnose attempts to convert between __ibm128, __float128 and long double
|
||||||
// such conversions currently can't be handled.
|
// where such conversions currently can't be handled.
|
||||||
if (unsupportedTypeConversion(*this, LHSType, RHSType))
|
if (unsupportedTypeConversion(*this, LHSType, RHSType))
|
||||||
return QualType();
|
return QualType();
|
||||||
|
|
||||||
@ -8375,8 +8362,8 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
|
|||||||
QualType LHSTy = LHS.get()->getType();
|
QualType LHSTy = LHS.get()->getType();
|
||||||
QualType RHSTy = RHS.get()->getType();
|
QualType RHSTy = RHS.get()->getType();
|
||||||
|
|
||||||
// Diagnose attempts to convert between __float128 and long double where
|
// Diagnose attempts to convert between __ibm128, __float128 and long double
|
||||||
// such conversions currently can't be handled.
|
// where such conversions currently can't be handled.
|
||||||
if (unsupportedTypeConversion(*this, LHSTy, RHSTy)) {
|
if (unsupportedTypeConversion(*this, LHSTy, RHSTy)) {
|
||||||
Diag(QuestionLoc,
|
Diag(QuestionLoc,
|
||||||
diag::err_typecheck_cond_incompatible_operands) << LHSTy << RHSTy
|
diag::err_typecheck_cond_incompatible_operands) << LHSTy << RHSTy
|
||||||
@ -9310,8 +9297,8 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
|
|||||||
return Incompatible;
|
return Incompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diagnose attempts to convert between __float128 and long double where
|
// Diagnose attempts to convert between __ibm128, __float128 and long double
|
||||||
// such conversions currently can't be handled.
|
// where such conversions currently can't be handled.
|
||||||
if (unsupportedTypeConversion(*this, LHSType, RHSType))
|
if (unsupportedTypeConversion(*this, LHSType, RHSType))
|
||||||
return Incompatible;
|
return Incompatible;
|
||||||
|
|
||||||
|
@ -1869,24 +1869,25 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
|
|||||||
SCS.Second = ICK_Complex_Real;
|
SCS.Second = ICK_Complex_Real;
|
||||||
FromType = ToType.getUnqualifiedType();
|
FromType = ToType.getUnqualifiedType();
|
||||||
} else if (FromType->isRealFloatingType() && ToType->isRealFloatingType()) {
|
} else if (FromType->isRealFloatingType() && ToType->isRealFloatingType()) {
|
||||||
// FIXME: disable conversions between long double and __float128 if
|
// FIXME: disable conversions between long double, __ibm128 and __float128
|
||||||
// their representation is different until there is back end support
|
// if their representation is different until there is back end support
|
||||||
// We of course allow this conversion if long double is really double.
|
// We of course allow this conversion if long double is really double.
|
||||||
|
|
||||||
// Conversions between bfloat and other floats are not permitted.
|
// Conversions between bfloat and other floats are not permitted.
|
||||||
if (FromType == S.Context.BFloat16Ty || ToType == S.Context.BFloat16Ty)
|
if (FromType == S.Context.BFloat16Ty || ToType == S.Context.BFloat16Ty)
|
||||||
return false;
|
return false;
|
||||||
if (&S.Context.getFloatTypeSemantics(FromType) !=
|
|
||||||
&S.Context.getFloatTypeSemantics(ToType)) {
|
// Conversions between IEEE-quad and IBM-extended semantics are not
|
||||||
bool Float128AndLongDouble = ((FromType == S.Context.Float128Ty &&
|
// permitted.
|
||||||
ToType == S.Context.LongDoubleTy) ||
|
const llvm::fltSemantics &FromSem =
|
||||||
(FromType == S.Context.LongDoubleTy &&
|
S.Context.getFloatTypeSemantics(FromType);
|
||||||
ToType == S.Context.Float128Ty));
|
const llvm::fltSemantics &ToSem = S.Context.getFloatTypeSemantics(ToType);
|
||||||
if (Float128AndLongDouble &&
|
if ((&FromSem == &llvm::APFloat::PPCDoubleDouble() &&
|
||||||
(&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) ==
|
&ToSem == &llvm::APFloat::IEEEquad()) ||
|
||||||
&llvm::APFloat::PPCDoubleDouble()))
|
(&FromSem == &llvm::APFloat::IEEEquad() &&
|
||||||
return false;
|
&ToSem == &llvm::APFloat::PPCDoubleDouble()))
|
||||||
}
|
return false;
|
||||||
|
|
||||||
// Floating point conversions (C++ 4.8).
|
// Floating point conversions (C++ 4.8).
|
||||||
SCS.Second = ICK_Floating_Conversion;
|
SCS.Second = ICK_Floating_Conversion;
|
||||||
FromType = ToType.getUnqualifiedType();
|
FromType = ToType.getUnqualifiedType();
|
||||||
@ -2237,7 +2238,8 @@ bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType) {
|
|||||||
(FromBuiltin->getKind() == BuiltinType::Float ||
|
(FromBuiltin->getKind() == BuiltinType::Float ||
|
||||||
FromBuiltin->getKind() == BuiltinType::Double) &&
|
FromBuiltin->getKind() == BuiltinType::Double) &&
|
||||||
(ToBuiltin->getKind() == BuiltinType::LongDouble ||
|
(ToBuiltin->getKind() == BuiltinType::LongDouble ||
|
||||||
ToBuiltin->getKind() == BuiltinType::Float128))
|
ToBuiltin->getKind() == BuiltinType::Float128 ||
|
||||||
|
ToBuiltin->getKind() == BuiltinType::Ibm128))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Half can be promoted to float.
|
// Half can be promoted to float.
|
||||||
@ -8173,6 +8175,8 @@ class BuiltinOperatorOverloadBuilder {
|
|||||||
ArithmeticTypes.push_back(S.Context.LongDoubleTy);
|
ArithmeticTypes.push_back(S.Context.LongDoubleTy);
|
||||||
if (S.Context.getTargetInfo().hasFloat128Type())
|
if (S.Context.getTargetInfo().hasFloat128Type())
|
||||||
ArithmeticTypes.push_back(S.Context.Float128Ty);
|
ArithmeticTypes.push_back(S.Context.Float128Ty);
|
||||||
|
if (S.Context.getTargetInfo().hasIbm128Type())
|
||||||
|
ArithmeticTypes.push_back(S.Context.Ibm128Ty);
|
||||||
|
|
||||||
// Start of integral types.
|
// Start of integral types.
|
||||||
FirstIntegralType = ArithmeticTypes.size();
|
FirstIntegralType = ArithmeticTypes.size();
|
||||||
|
@ -893,6 +893,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
|
|||||||
case TST_Fract:
|
case TST_Fract:
|
||||||
case TST_Float16:
|
case TST_Float16:
|
||||||
case TST_float128:
|
case TST_float128:
|
||||||
|
case TST_ibm128:
|
||||||
case TST_bool:
|
case TST_bool:
|
||||||
case TST_decimal32:
|
case TST_decimal32:
|
||||||
case TST_decimal64:
|
case TST_decimal64:
|
||||||
|
@ -1547,6 +1547,13 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
|
|||||||
<< "__float128";
|
<< "__float128";
|
||||||
Result = Context.Float128Ty;
|
Result = Context.Float128Ty;
|
||||||
break;
|
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:
|
case DeclSpec::TST_bool:
|
||||||
Result = Context.BoolTy; // _Bool or bool
|
Result = Context.BoolTy; // _Bool or bool
|
||||||
break;
|
break;
|
||||||
|
@ -168,6 +168,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
|
|||||||
case BuiltinType::Float128:
|
case BuiltinType::Float128:
|
||||||
ID = PREDEF_TYPE_FLOAT128_ID;
|
ID = PREDEF_TYPE_FLOAT128_ID;
|
||||||
break;
|
break;
|
||||||
|
case BuiltinType::Ibm128:
|
||||||
|
ID = PREDEF_TYPE_IBM128_ID;
|
||||||
|
break;
|
||||||
case BuiltinType::NullPtr:
|
case BuiltinType::NullPtr:
|
||||||
ID = PREDEF_TYPE_NULLPTR_ID;
|
ID = PREDEF_TYPE_NULLPTR_ID;
|
||||||
break;
|
break;
|
||||||
|
@ -6940,6 +6940,9 @@ QualType ASTReader::GetType(TypeID ID) {
|
|||||||
case PREDEF_TYPE_FLOAT128_ID:
|
case PREDEF_TYPE_FLOAT128_ID:
|
||||||
T = Context.Float128Ty;
|
T = Context.Float128Ty;
|
||||||
break;
|
break;
|
||||||
|
case PREDEF_TYPE_IBM128_ID:
|
||||||
|
T = Context.Ibm128Ty;
|
||||||
|
break;
|
||||||
case PREDEF_TYPE_OVERLOAD_ID:
|
case PREDEF_TYPE_OVERLOAD_ID:
|
||||||
T = Context.OverloadTy;
|
T = Context.OverloadTy;
|
||||||
break;
|
break;
|
||||||
|
61
clang/test/CodeGen/ibm128-cast.c
Normal file
61
clang/test/CodeGen/ibm128-cast.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown -verify \
|
||||||
|
// RUN: -target-feature +float128 -mabi=ieeelongdouble -fsyntax-only -Wno-unused %s
|
||||||
|
// RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown -verify \
|
||||||
|
// RUN: -target-feature +float128 -fsyntax-only -Wno-unused %s
|
||||||
|
|
||||||
|
__float128 cast1(__ibm128 x) { return x; } // expected-error {{returning '__ibm128' from a function with incompatible result type '__float128'}}
|
||||||
|
|
||||||
|
__ibm128 cast2(__float128 x) { return x; } // expected-error {{returning '__float128' from a function with incompatible result type '__ibm128'}}
|
||||||
|
|
||||||
|
__ibm128 gf;
|
||||||
|
|
||||||
|
void narrow(double *d, float *f) {
|
||||||
|
__ibm128 v = gf;
|
||||||
|
gf = *d; // expected-no-error {{assigning to '__ibm128' from incompatible type 'double'}}
|
||||||
|
*f = v; // expected-no-error {{assigning to 'float' from incompatible type '__ibm128'}}
|
||||||
|
*d = gf + *f; // expected-no-error {{invalid operands to binary expression ('__ibm128' and 'float')}}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __LONG_DOUBLE_IEEE128__
|
||||||
|
long double cast3(__ibm128 x) { return x; } // expected-error {{returning '__ibm128' from a function with incompatible result type 'long double'}}
|
||||||
|
|
||||||
|
__ibm128 cast4(long double x) { return x; } // expected-error {{returning 'long double' from a function with incompatible result type '__ibm128'}}
|
||||||
|
|
||||||
|
void imp_cast(__ibm128 w, __float128 q, long double l, _Bool b) {
|
||||||
|
w + q; // expected-error {{invalid operands to binary expression ('__ibm128' and '__float128')}}
|
||||||
|
l + w; // expected-error {{invalid operands to binary expression ('long double' and '__ibm128')}}
|
||||||
|
q - w; // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
|
||||||
|
w - l; // expected-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
|
||||||
|
w *l; // expected-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
|
||||||
|
q *w; // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
|
||||||
|
q / w; // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
|
||||||
|
w / l; // expected-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
|
||||||
|
w = q; // expected-error {{assigning to '__ibm128' from incompatible type '__float128'}}
|
||||||
|
q = w; // expected-error {{assigning to '__float128' from incompatible type '__ibm128'}}
|
||||||
|
l = w; // expected-error {{assigning to 'long double' from incompatible type '__ibm128'}}
|
||||||
|
w = l; // expected-error {{assigning to '__ibm128' from incompatible type 'long double'}}
|
||||||
|
b ? q : w; // expected-error {{incompatible operand types ('__float128' and '__ibm128')}}
|
||||||
|
!b ? w : l; // expected-error {{incompatible operand types ('__ibm128' and 'long double')}}
|
||||||
|
}
|
||||||
|
#elif __LONG_DOUBLE_IBM128__
|
||||||
|
long double cast3(__ibm128 x) { return x; } // expected-no-error {{returning '__ibm128' from a function with incompatible result type 'long double'}}
|
||||||
|
|
||||||
|
__ibm128 cast4(long double x) { return x; } // expected-no-error {{returning 'long double' from a function with incompatible result type '__ibm128'}}
|
||||||
|
|
||||||
|
void imp_cast(__ibm128 w, __float128 q, long double l, _Bool b) {
|
||||||
|
w + q; // expected-error {{invalid operands to binary expression ('__ibm128' and '__float128')}}
|
||||||
|
l + w; // expected-no-error {{invalid operands to binary expression ('long double' and '__ibm128')}}
|
||||||
|
q - w; // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
|
||||||
|
w - l; // expected-no-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
|
||||||
|
w *l; // expected-no-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
|
||||||
|
q *w; // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
|
||||||
|
q / w; // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
|
||||||
|
w / l; // expected-no-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
|
||||||
|
w = q; // expected-error {{assigning to '__ibm128' from incompatible type '__float128'}}
|
||||||
|
q = w; // expected-error {{assigning to '__float128' from incompatible type '__ibm128'}}
|
||||||
|
l = w; // expected-no-error {{assigning to 'long double' from incompatible type '__ibm128'}}
|
||||||
|
w = l; // expected-no-error {{assigning to '__ibm128' from incompatible type 'long double'}}
|
||||||
|
b ? q : w; // expected-error {{incompatible operand types ('__float128' and '__ibm128')}}
|
||||||
|
!b ? w : l; // expected-no-error {{incompatible operand types ('__ibm128' and 'long double')}}
|
||||||
|
}
|
||||||
|
#endif
|
15
clang/test/CodeGen/ibm128-unsupported.c
Normal file
15
clang/test/CodeGen/ibm128-unsupported.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// RUN: %clang_cc1 -triple powerpc64le -emit-llvm-bc -fopenmp %s \
|
||||||
|
// RUN: -fopenmp-targets=powerpc64le,x86_64 -o %t-ppc-host.bc
|
||||||
|
// RUN: %clang_cc1 -verify -triple x86_64 -aux-triple powerpc64le -fopenmp \
|
||||||
|
// RUN: -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc %s \
|
||||||
|
// RUN: -fsyntax-only
|
||||||
|
|
||||||
|
void foo(__ibm128 x); // expected-note {{'foo' defined here}}
|
||||||
|
|
||||||
|
void loop(int n, __ibm128 *arr) {
|
||||||
|
#pragma omp target parallel
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
// expected-error@+1 {{'foo' requires 128 bit size '__ibm128' type support, but device 'x86_64' does not support it}}
|
||||||
|
foo(arr[i]);
|
||||||
|
}
|
||||||
|
}
|
169
clang/test/CodeGenCXX/ibm128-declarations.cpp
Normal file
169
clang/test/CodeGenCXX/ibm128-declarations.cpp
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
|
||||||
|
// RUN: %clang_cc1 -emit-llvm -triple powerpc64-unknown-unknown \
|
||||||
|
// RUN: -std=c++20 %s -o - -debug-info-kind=limited | FileCheck %s
|
||||||
|
// RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown \
|
||||||
|
// RUN: -std=c++20 %s -o - -debug-info-kind=limited | FileCheck %s
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr __ibm128 func_add(__ibm128 a, __ibm128 b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
constinit const __ibm128 ci = func_add(1.0, 2.0);
|
||||||
|
__ibm128 gf = ci;
|
||||||
|
|
||||||
|
__ibm128 func_arith(__ibm128 a, __ibm128 b, __ibm128 c) {
|
||||||
|
__ibm128 v1 = a + b;
|
||||||
|
__ibm128 v2 = a - c;
|
||||||
|
__ibm128 v3 = v1 * c;
|
||||||
|
__ibm128 v4 = v2 / v3;
|
||||||
|
return v4;
|
||||||
|
}
|
||||||
|
|
||||||
|
__ibm128 func_vaarg(int n, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, n);
|
||||||
|
__ibm128 r = va_arg(ap, __ibm128);
|
||||||
|
va_end(ap);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> struct T1 {
|
||||||
|
T mem1;
|
||||||
|
};
|
||||||
|
template <> struct T1<__ibm128> {
|
||||||
|
__ibm128 mem2;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <__ibm128 Q> struct T2 {
|
||||||
|
constexpr static __ibm128 mem = Q;
|
||||||
|
};
|
||||||
|
|
||||||
|
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: @arrgf = global [10 x ppc_fp128] zeroinitializer, align 16
|
||||||
|
// CHECK: @gf = global ppc_fp128 0xM40080000000000000000000000000000, align 16
|
||||||
|
// CHECK: @_ZN5CTest3scfE = external constant ppc_fp128, align 16
|
||||||
|
|
||||||
|
// CHECK: define dso_local ppc_fp128 @_Z10func_arithggg(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c)
|
||||||
|
// CHECK: entry:
|
||||||
|
// CHECK: store ppc_fp128 %a, ppc_fp128* %a.addr, align 16
|
||||||
|
// CHECK: store ppc_fp128 %b, ppc_fp128* %b.addr, align 16
|
||||||
|
// CHECK: store ppc_fp128 %c, ppc_fp128* %c.addr, align 16
|
||||||
|
// CHECK: %0 = load ppc_fp128, ppc_fp128* %a.addr, align 16
|
||||||
|
// CHECK: %1 = load ppc_fp128, ppc_fp128* %b.addr, align 16
|
||||||
|
// CHECK: %add = fadd ppc_fp128 %0, %1
|
||||||
|
// CHECK: store ppc_fp128 %add, ppc_fp128* %v1, align 16
|
||||||
|
// CHECK: %2 = load ppc_fp128, ppc_fp128* %a.addr, align 16
|
||||||
|
// CHECK: %3 = load ppc_fp128, ppc_fp128* %c.addr, align 16
|
||||||
|
// CHECK: %sub = fsub ppc_fp128 %2, %3
|
||||||
|
// CHECK: store ppc_fp128 %sub, ppc_fp128* %v2, align 16
|
||||||
|
// CHECK: %4 = load ppc_fp128, ppc_fp128* %v1, align 16
|
||||||
|
// CHECK: %5 = load ppc_fp128, ppc_fp128* %c.addr, align 16
|
||||||
|
// CHECK: %mul = fmul ppc_fp128 %4, %5
|
||||||
|
// CHECK: store ppc_fp128 %mul, ppc_fp128* %v3, align 16
|
||||||
|
// CHECK: %6 = load ppc_fp128, ppc_fp128* %v2, align 16
|
||||||
|
// CHECK: %7 = load ppc_fp128, ppc_fp128* %v3, align 16
|
||||||
|
// CHECK: %div = fdiv ppc_fp128 %6, %7
|
||||||
|
// CHECK: store ppc_fp128 %div, ppc_fp128* %v4, align 16
|
||||||
|
// CHECK: %8 = load ppc_fp128, ppc_fp128* %v4, align 16
|
||||||
|
// CHECK: ret ppc_fp128 %8
|
||||||
|
// CHECK: }
|
||||||
|
|
||||||
|
// CHECK: define dso_local ppc_fp128 @_Z10func_vaargiz(i32 signext %n, ...)
|
||||||
|
// CHECK: entry:
|
||||||
|
// CHECK: store i32 %n, i32* %n.addr, align 4
|
||||||
|
// CHECK: %ap1 = bitcast i8** %ap to i8*
|
||||||
|
// CHECK: call void @llvm.va_start(i8* %ap1)
|
||||||
|
// CHECK: %argp.cur = load i8*, i8** %ap, align 8
|
||||||
|
// CHECK: %argp.next = getelementptr inbounds i8, i8* %argp.cur, i64 16
|
||||||
|
// CHECK: store i8* %argp.next, i8** %ap, align 8
|
||||||
|
// CHECK: %0 = bitcast i8* %argp.cur to ppc_fp128*
|
||||||
|
// CHECK: %1 = load ppc_fp128, ppc_fp128* %0, align 8
|
||||||
|
// CHECK: store ppc_fp128 %1, ppc_fp128* %r, align 16
|
||||||
|
// CHECK: %ap2 = bitcast i8** %ap to i8*
|
||||||
|
// CHECK: call void @llvm.va_end(i8* %ap2)
|
||||||
|
// CHECK: %2 = load ppc_fp128, ppc_fp128* %r, align 16
|
||||||
|
// CHECK: ret ppc_fp128 %2
|
||||||
|
// CHECK: }
|
||||||
|
|
||||||
|
// CHECK: define dso_local signext i32 @main()
|
||||||
|
// CHECK: entry:
|
||||||
|
// CHECK: %0 = load ppc_fp128, ppc_fp128* %lf, align 16
|
||||||
|
// CHECK: call void @_ZN5CTestC1Eg(%class.CTest* nonnull align 16 dereferenceable(32) %ct, ppc_fp128 %0)
|
||||||
|
// CHECK: %mem2 = getelementptr inbounds %struct.T1, %struct.T1* %tf, i32 0, i32 0
|
||||||
|
// CHECK: %1 = load ppc_fp128, ppc_fp128* %mem2, align 16
|
||||||
|
// CHECK: %2 = load ppc_fp128, ppc_fp128* %lf, align 16
|
||||||
|
// CHECK: %call = call ppc_fp128 @_Z5func1g(ppc_fp128 %2)
|
||||||
|
// CHECK: %add = fadd ppc_fp128 %1, %call
|
||||||
|
// CHECK: %3 = load ppc_fp128, ppc_fp128* %lf, align 16
|
||||||
|
// CHECK: %call1 = call ppc_fp128 @_ZN5CTest5func3Eg(ppc_fp128 %3)
|
||||||
|
// CHECK: %sub = fsub ppc_fp128 %add, %call1
|
||||||
|
// CHECK: store ppc_fp128 %sub, ppc_fp128* %lfi, align 16
|
||||||
|
// CHECK: ret i32 0
|
||||||
|
// CHECK: }
|
||||||
|
|
||||||
|
// CHECK: define linkonce_odr void @_ZN5CTestC1Eg(%class.CTest* nonnull align 16 dereferenceable(32) %this, ppc_fp128 %arg)
|
||||||
|
// CHECK: entry:
|
||||||
|
// CHECK: store %class.CTest* %this, %class.CTest** %this.addr, align 8
|
||||||
|
// CHECK: store ppc_fp128 %arg, ppc_fp128* %arg.addr, align 16
|
||||||
|
// CHECK: %this1 = load %class.CTest*, %class.CTest** %this.addr, align 8
|
||||||
|
// CHECK: %0 = load ppc_fp128, ppc_fp128* %arg.addr, align 16
|
||||||
|
// CHECK: call void @_ZN5CTestC2Eg(%class.CTest* nonnull align 16 dereferenceable(32) %this1, ppc_fp128 %0)
|
||||||
|
// CHECK: ret void
|
||||||
|
// CHECK: }
|
||||||
|
|
||||||
|
// CHECK: define linkonce_odr ppc_fp128 @_ZN5CTest5func3Eg(ppc_fp128 %arg)
|
||||||
|
// CHECK: entry:
|
||||||
|
// CHECK: %arg.addr = alloca ppc_fp128, align 16
|
||||||
|
// CHECK: store ppc_fp128 %arg, ppc_fp128* %arg.addr, align 16
|
||||||
|
// CHECK: %0 = load ppc_fp128, ppc_fp128* %arg.addr, align 16
|
||||||
|
// CHECK: %1 = load ppc_fp128, ppc_fp128* @_ZN5CTest3scfE, align 16
|
||||||
|
// CHECK: %mul = fmul ppc_fp128 %0, %1
|
||||||
|
// CHECK: ret ppc_fp128 %mul
|
||||||
|
// CHECK: }
|
||||||
|
|
||||||
|
// CHECK: define linkonce_odr void @_ZN5CTestC2Eg(%class.CTest* nonnull align 16 dereferenceable(32) %this, ppc_fp128 %arg)
|
||||||
|
// CHECK: entry:
|
||||||
|
// CHECK: store %class.CTest* %this, %class.CTest** %this.addr, align 8
|
||||||
|
// CHECK: store ppc_fp128 %arg, ppc_fp128* %arg.addr, align 16
|
||||||
|
// CHECK: %this1 = load %class.CTest*, %class.CTest** %this.addr, align 8
|
||||||
|
// CHECK: %pf = getelementptr inbounds %class.CTest, %class.CTest* %this1, i32 0, i32 0
|
||||||
|
// CHECK: %0 = load ppc_fp128, ppc_fp128* %arg.addr, align 16
|
||||||
|
// CHECK: store ppc_fp128 %0, ppc_fp128* %pf, align 16
|
||||||
|
// CHECK: %vf = getelementptr inbounds %class.CTest, %class.CTest* %this1, i32 0, i32 1
|
||||||
|
// CHECK: %1 = load ppc_fp128, ppc_fp128* %arg.addr, align 16
|
||||||
|
// CHECK: store volatile ppc_fp128 %1, ppc_fp128* %vf, align 16
|
||||||
|
// CHECK: ret void
|
||||||
|
// CHECK: }
|
||||||
|
|
||||||
|
// CHECK: !6 = distinct !DIGlobalVariable(name: "gf", scope: !2, file: !7, line: {{[0-9]+}}, type: !8, isLocal: false, isDefinition: true)
|
||||||
|
// CHECK: !8 = !DIBasicType(name: "__ibm128", size: 128, encoding: DW_ATE_float)
|
@ -20,7 +20,7 @@ int g(int x, __float128 *y) {
|
|||||||
return x + *y;
|
return x + *y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// expected-no-diagnostics
|
// expected-no-error {{__float128 is not supported on this target}}
|
||||||
#else
|
#else
|
||||||
#if !defined(__STRICT_ANSI__)
|
#if !defined(__STRICT_ANSI__)
|
||||||
__float128 f; // expected-error {{__float128 is not supported on this target}}
|
__float128 f; // expected-error {{__float128 is not supported on this target}}
|
||||||
@ -44,3 +44,18 @@ int g(int x, __float128 *y) { // expected-error {{__float128 is not supported o
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
#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
|
||||||
|
@ -60,6 +60,7 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
|
|||||||
BTCASE(ULongAccum);
|
BTCASE(ULongAccum);
|
||||||
BTCASE(Float16);
|
BTCASE(Float16);
|
||||||
BTCASE(Float128);
|
BTCASE(Float128);
|
||||||
|
BTCASE(Ibm128);
|
||||||
BTCASE(NullPtr);
|
BTCASE(NullPtr);
|
||||||
BTCASE(Overload);
|
BTCASE(Overload);
|
||||||
BTCASE(Dependent);
|
BTCASE(Dependent);
|
||||||
@ -577,6 +578,7 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
|
|||||||
TKIND(ULongAccum);
|
TKIND(ULongAccum);
|
||||||
TKIND(Float16);
|
TKIND(Float16);
|
||||||
TKIND(Float128);
|
TKIND(Float128);
|
||||||
|
TKIND(Ibm128);
|
||||||
TKIND(NullPtr);
|
TKIND(NullPtr);
|
||||||
TKIND(Overload);
|
TKIND(Overload);
|
||||||
TKIND(Dependent);
|
TKIND(Dependent);
|
||||||
|
Loading…
Reference in New Issue
Block a user