summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
authorRobert Lytton <robert@xmos.com>2013-10-11 10:29:34 +0000
committerRobert Lytton <robert@xmos.com>2013-10-11 10:29:34 +0000
commit2d1969584a85772e5e91c57339f1b9a87b8b5234 (patch)
tree4a3f3d378f118ac7c5bbfc95930959186d0369d7 /clang/lib/CodeGen/TargetInfo.cpp
parente67bd87c4818061db57fba085bb61e406f62948a (diff)
downloadbcm5719-llvm-2d1969584a85772e5e91c57339f1b9a87b8b5234.tar.gz
bcm5719-llvm-2d1969584a85772e5e91c57339f1b9a87b8b5234.zip
XCore : Fix bug in XCoreABIInfo::EmitVAArg()
Incorrect handling of 'double' and 'long long int' llvm-svn: 192436
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp40
1 files changed, 27 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 9ad17a454ef..8b8c90b3efc 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -5426,40 +5426,54 @@ public:
XcoreTargetCodeGenInfo(CodeGenTypes &CGT)
:TargetCodeGenInfo(new XCoreABIInfo(CGT)) {}
};
-} // end anonymous namespace
+} // End anonymous namespace.
llvm::Value *XCoreABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
CodeGenFunction &CGF) const {
- ABIArgInfo AI = classifyArgumentType(Ty);
CGBuilderTy &Builder = CGF.Builder;
- llvm::Type *ArgTy = CGT.ConvertType(Ty);
- if (AI.canHaveCoerceToType() && !AI.getCoerceToType())
- AI.setCoerceToType(ArgTy);
- // handle the VAList
+ // Get the VAList.
llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr,
CGF.Int8PtrPtrTy);
llvm::Value *AP = Builder.CreateLoad(VAListAddrAsBPP);
- llvm::Value *APN = Builder.CreateConstGEP1_32(AP, 4);
- Builder.CreateStore(APN, VAListAddrAsBPP);
- // handle the argument
+ // Handle the argument.
+ ABIArgInfo AI = classifyArgumentType(Ty);
+ llvm::Type *ArgTy = CGT.ConvertType(Ty);
+ if (AI.canHaveCoerceToType() && !AI.getCoerceToType())
+ AI.setCoerceToType(ArgTy);
llvm::Type *ArgPtrTy = llvm::PointerType::getUnqual(ArgTy);
+ llvm::Value *Val;
+ uint64_t ArgSize;
switch (AI.getKind()) {
case ABIArgInfo::Expand:
llvm_unreachable("Unsupported ABI kind for va_arg");
case ABIArgInfo::Ignore:
- return llvm::UndefValue::get(ArgPtrTy);
+ Val = llvm::UndefValue::get(ArgPtrTy);
+ ArgSize = 0;
+ break;
case ABIArgInfo::Extend:
case ABIArgInfo::Direct:
- return Builder.CreatePointerCast(AP, ArgPtrTy);
+ Val = Builder.CreatePointerCast(AP, ArgPtrTy);
+ ArgSize = getDataLayout().getTypeAllocSize(AI.getCoerceToType());
+ if (ArgSize < 4)
+ ArgSize = 4;
+ break;
case ABIArgInfo::Indirect:
llvm::Value *ArgAddr;
ArgAddr = Builder.CreateBitCast(AP, llvm::PointerType::getUnqual(ArgPtrTy));
ArgAddr = Builder.CreateLoad(ArgAddr);
- return Builder.CreatePointerCast(ArgAddr, ArgPtrTy);
+ Val = Builder.CreatePointerCast(ArgAddr, ArgPtrTy);
+ ArgSize = 4;
+ break;
+ }
+
+ // Increment the VAList.
+ if (ArgSize) {
+ llvm::Value *APN = Builder.CreateConstGEP1_32(AP, ArgSize);
+ Builder.CreateStore(APN, VAListAddrAsBPP);
}
- llvm_unreachable("Unknown ABI kind");
+ return Val;
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud