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/SemaChecking.cpp | |
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/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 52 |
1 files changed, 40 insertions, 12 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) { |