diff options
author | Tim Northover <tnorthover@apple.com> | 2014-03-29 15:09:45 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-03-29 15:09:45 +0000 |
commit | a2ee433c8d99632419d4a13a66cc4d06eada4014 (patch) | |
tree | e6ab2db8facbc4c5ed2fb11df260db8138572ace /clang/lib/Sema | |
parent | af3698066a1ea2e5ab4cc08ae9a59620cf18adb7 (diff) | |
download | bcm5719-llvm-a2ee433c8d99632419d4a13a66cc4d06eada4014.tar.gz bcm5719-llvm-a2ee433c8d99632419d4a13a66cc4d06eada4014.zip |
ARM64: initial clang support commit.
This adds Clang support for the ARM64 backend. There are definitely
still some rough edges, so please bring up any issues you see with
this patch.
As with the LLVM commit though, we think it'll be more useful for
merging with AArch64 from within the tree.
llvm-svn: 205100
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 52 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 24 |
2 files changed, 55 insertions, 21 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 32bf6e01c9f..41c7613c74a 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -309,6 +309,10 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (CheckARMBuiltinFunctionCall(BuiltinID, TheCall)) return ExprError(); break; + case llvm::Triple::arm64: + if (CheckARM64BuiltinFunctionCall(BuiltinID, TheCall)) + return ExprError(); + break; case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: if (CheckAArch64BuiltinFunctionCall(BuiltinID, TheCall)) @@ -369,7 +373,7 @@ static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) { /// the vector type specified by the NeonTypeFlags. This is used to check /// the pointer arguments for Neon load/store intrinsics. static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, - bool IsAArch64) { + bool IsPolyUnsigned, bool IsInt64Long) { switch (Flags.getEltType()) { case NeonTypeFlags::Int8: return Flags.isUnsigned() ? Context.UnsignedCharTy : Context.SignedCharTy; @@ -378,15 +382,15 @@ static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, case NeonTypeFlags::Int32: return Flags.isUnsigned() ? Context.UnsignedIntTy : Context.IntTy; case NeonTypeFlags::Int64: - if (IsAArch64) + if (IsInt64Long) return Flags.isUnsigned() ? Context.UnsignedLongTy : Context.LongTy; else return Flags.isUnsigned() ? Context.UnsignedLongLongTy : Context.LongLongTy; case NeonTypeFlags::Poly8: - return IsAArch64 ? Context.UnsignedCharTy : Context.SignedCharTy; + return IsPolyUnsigned ? Context.UnsignedCharTy : Context.SignedCharTy; case NeonTypeFlags::Poly16: - return IsAArch64 ? Context.UnsignedShortTy : Context.ShortTy; + return IsPolyUnsigned ? Context.UnsignedShortTy : Context.ShortTy; case NeonTypeFlags::Poly64: return Context.UnsignedLongTy; case NeonTypeFlags::Poly128: @@ -434,9 +438,13 @@ bool Sema::CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg); QualType RHSTy = RHS.get()->getType(); - bool IsAArch64 = - Context.getTargetInfo().getTriple().getArch() == llvm::Triple::aarch64; - QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context, IsAArch64); + llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch(); + bool IsPolyUnsigned = + Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::arm64; + bool IsInt64Long = + Context.getTargetInfo().getInt64Type() == TargetInfo::SignedLong; + QualType EltTy = + getNeonEltType(NeonTypeFlags(TV), Context, IsPolyUnsigned, IsInt64Long); if (HasConstPtr) EltTy = EltTy.withConst(); QualType LHSTy = Context.getPointerType(EltTy); @@ -487,11 +495,15 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, return false; } -bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall) { +bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, + unsigned MaxWidth) { assert((BuiltinID == ARM::BI__builtin_arm_ldrex || - BuiltinID == ARM::BI__builtin_arm_strex) && + BuiltinID == ARM::BI__builtin_arm_strex || + BuiltinID == ARM64::BI__builtin_arm_ldrex || + BuiltinID == ARM64::BI__builtin_arm_strex) && "unexpected ARM builtin"); - bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex; + bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex || + BuiltinID == ARM64::BI__builtin_arm_ldrex; DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); @@ -552,7 +564,8 @@ bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall) { } // But ARM doesn't have instructions to deal with 128-bit versions. - if (Context.getTypeSize(ValType) > 64) { + if (Context.getTypeSize(ValType) > MaxWidth) { + assert(MaxWidth == 64 && "Diagnostic unexpectedly inaccurate"); Diag(DRE->getLocStart(), diag::err_atomic_exclusive_builtin_pointer_size) << PointerArg->getType() << PointerArg->getSourceRange(); return true; @@ -598,7 +611,7 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (BuiltinID == ARM::BI__builtin_arm_ldrex || BuiltinID == ARM::BI__builtin_arm_strex) { - return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall); + return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 64); } if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall)) @@ -636,6 +649,21 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return false; } +bool Sema::CheckARM64BuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + llvm::APSInt Result; + + if (BuiltinID == ARM64::BI__builtin_arm_ldrex || + BuiltinID == ARM64::BI__builtin_arm_strex) { + return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128); + } + + if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall)) + return true; + + return false; +} + bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { unsigned i = 0, l = 0, u = 0; switch (BuiltinID) { diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 035778bbc1d..e273cb6e364 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -4720,14 +4720,20 @@ static void HandleExtVectorTypeAttr(QualType &CurType, } static bool isPermittedNeonBaseType(QualType &Ty, - VectorType::VectorKind VecKind, - bool IsAArch64) { + VectorType::VectorKind VecKind, Sema &S) { const BuiltinType *BTy = Ty->getAs<BuiltinType>(); if (!BTy) return false; + llvm::Triple Triple = S.Context.getTargetInfo().getTriple(); + + // Signed poly is mathematically wrong, but has been baked into some ABIs by + // now. + bool IsPolyUnsigned = Triple.getArch() == llvm::Triple::aarch64 || + Triple.getArch() == llvm::Triple::aarch64_be || + Triple.getArch() == llvm::Triple::arm64; if (VecKind == VectorType::NeonPolyVector) { - if (IsAArch64) { + if (IsPolyUnsigned) { // AArch64 polynomial vectors are unsigned and support poly64. return BTy->getKind() == BuiltinType::UChar || BTy->getKind() == BuiltinType::UShort || @@ -4742,7 +4748,11 @@ static bool isPermittedNeonBaseType(QualType &Ty, // Non-polynomial vector types: the usual suspects are allowed, as well as // float64_t on AArch64. - if (IsAArch64 && BTy->getKind() == BuiltinType::Double) + bool Is64Bit = Triple.getArch() == llvm::Triple::aarch64 || + Triple.getArch() == llvm::Triple::aarch64_be || + Triple.getArch() == llvm::Triple::arm64; + + if (Is64Bit && BTy->getKind() == BuiltinType::Double) return true; return BTy->getKind() == BuiltinType::SChar || @@ -4794,11 +4804,7 @@ static void HandleNeonVectorTypeAttr(QualType& CurType, return; } // Only certain element types are supported for Neon vectors. - llvm::Triple::ArchType Arch = - S.Context.getTargetInfo().getTriple().getArch(); - if (!isPermittedNeonBaseType(CurType, VecKind, - (Arch == llvm::Triple::aarch64) || - (Arch == llvm::Triple::aarch64_be))) { + if (!isPermittedNeonBaseType(CurType, VecKind, S)) { S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; Attr.setInvalid(); return; |