diff options
author | Christian Pirker <cpirker@a-bix.com> | 2014-03-14 11:51:06 +0000 |
---|---|---|
committer | Christian Pirker <cpirker@a-bix.com> | 2014-03-14 11:51:06 +0000 |
commit | f5164229f32a8bc6d720ed54e06425c9ef99d540 (patch) | |
tree | ea6e358d97d5f8f61647ed68b46dc45b18de099d /clang/lib/CodeGen | |
parent | b76ea32834762d0042c4b27b9394e91ed8c8c5ff (diff) | |
download | bcm5719-llvm-f5164229f32a8bc6d720ed54e06425c9ef99d540.tar.gz bcm5719-llvm-f5164229f32a8bc6d720ed54e06425c9ef99d540.zip |
AArch64_be varargs processing for ARM ABI
llvm-svn: 203917
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index f013fcfb211..93b869bfda8 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -4186,9 +4186,6 @@ llvm::Value *AArch64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, // int __vr_offs; // }; - assert(!CGF.CGM.getDataLayout().isBigEndian() - && "va_arg not implemented for big-endian AArch64"); - int FreeIntRegs = 8, FreeVFPRegs = 8; Ty = CGF.getContext().getCanonicalType(Ty); ABIArgInfo AI = classifyGenericType(Ty, FreeIntRegs, FreeVFPRegs); @@ -4298,9 +4295,14 @@ llvm::Value *AArch64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, llvm::Type *BaseTy = CGF.ConvertType(QualType(Base, 0)); llvm::Type *HFATy = llvm::ArrayType::get(BaseTy, NumMembers); llvm::Value *Tmp = CGF.CreateTempAlloca(HFATy); + int Offset = 0; + if (CGF.CGM.getDataLayout().isBigEndian() && + getContext().getTypeSize(Base) < 128) + Offset = 16 - getContext().getTypeSize(Base)/8; for (unsigned i = 0; i < NumMembers; ++i) { - llvm::Value *BaseOffset = llvm::ConstantInt::get(CGF.Int32Ty, 16 * i); + llvm::Value *BaseOffset = llvm::ConstantInt::get(CGF.Int32Ty, + 16 * i + Offset); llvm::Value *LoadAddr = CGF.Builder.CreateGEP(BaseAddr, BaseOffset); LoadAddr = CGF.Builder.CreateBitCast(LoadAddr, llvm::PointerType::getUnqual(BaseTy)); @@ -4313,6 +4315,20 @@ llvm::Value *AArch64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, RegAddr = CGF.Builder.CreateBitCast(Tmp, MemTy); } else { // Otherwise the object is contiguous in memory + unsigned BeAlign = reg_top_index == 2 ? 16 : 8; + if (CGF.CGM.getDataLayout().isBigEndian() && !isAggregateTypeForABI(Ty) && + getContext().getTypeSize(Ty) < (BeAlign * 8)) { + int Offset = BeAlign - getContext().getTypeSize(Ty)/8; + BaseAddr = CGF.Builder.CreatePtrToInt(BaseAddr, CGF.Int64Ty); + + BaseAddr = CGF.Builder.CreateAdd(BaseAddr, + llvm::ConstantInt::get(CGF.Int64Ty, + Offset), + "align_be"); + + BaseAddr = CGF.Builder.CreateIntToPtr(BaseAddr, CGF.Int8PtrTy); + } + RegAddr = CGF.Builder.CreateBitCast(BaseAddr, MemTy); } @@ -4360,6 +4376,19 @@ llvm::Value *AArch64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, // Write the new value of __stack for the next call to va_arg CGF.Builder.CreateStore(NewStack, stack_p); + if (CGF.CGM.getDataLayout().isBigEndian() && !isAggregateTypeForABI(Ty) && + getContext().getTypeSize(Ty) < 64 ) { + int Offset = 8 - getContext().getTypeSize(Ty)/8; + OnStackAddr = CGF.Builder.CreatePtrToInt(OnStackAddr, CGF.Int64Ty); + + OnStackAddr = CGF.Builder.CreateAdd(OnStackAddr, + llvm::ConstantInt::get(CGF.Int64Ty, + Offset), + "align_be"); + + OnStackAddr = CGF.Builder.CreateIntToPtr(OnStackAddr, CGF.Int8PtrTy); + } + OnStackAddr = CGF.Builder.CreateBitCast(OnStackAddr, MemTy); CGF.EmitBranch(ContBlock); |