diff options
author | Robert Lytton <robert@xmos.com> | 2013-10-11 10:29:34 +0000 |
---|---|---|
committer | Robert Lytton <robert@xmos.com> | 2013-10-11 10:29:34 +0000 |
commit | 2d1969584a85772e5e91c57339f1b9a87b8b5234 (patch) | |
tree | 4a3f3d378f118ac7c5bbfc95930959186d0369d7 /clang/lib/CodeGen/TargetInfo.cpp | |
parent | e67bd87c4818061db57fba085bb61e406f62948a (diff) | |
download | bcm5719-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.cpp | 40 |
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; } //===----------------------------------------------------------------------===// |