summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorChristian Pirker <cpirker@a-bix.com>2014-03-14 11:51:06 +0000
committerChristian Pirker <cpirker@a-bix.com>2014-03-14 11:51:06 +0000
commitf5164229f32a8bc6d720ed54e06425c9ef99d540 (patch)
treeea6e358d97d5f8f61647ed68b46dc45b18de099d /clang/lib/CodeGen
parentb76ea32834762d0042c4b27b9394e91ed8c8c5ff (diff)
downloadbcm5719-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.cpp37
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);
OpenPOWER on IntegriCloud