diff options
author | Robert Lytton <robert@xmos.com> | 2013-08-19 09:46:39 +0000 |
---|---|---|
committer | Robert Lytton <robert@xmos.com> | 2013-08-19 09:46:39 +0000 |
commit | 7d1db15ae14f093216b17877127016db9b04b5c0 (patch) | |
tree | 39bc8de345ffefb2622b0a65740bcb0124ad9be8 /clang/lib/CodeGen/TargetInfo.cpp | |
parent | a7d1d865e50a76ebabb3bab61f48b91350470d32 (diff) | |
download | bcm5719-llvm-7d1db15ae14f093216b17877127016db9b04b5c0.tar.gz bcm5719-llvm-7d1db15ae14f093216b17877127016db9b04b5c0.zip |
XCore target: Add target specific EmitVAArg
This is so aggregates can be passed as var args too.
llvm-svn: 188664
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index bab77e6a45b..4b1c56599f4 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5370,13 +5370,53 @@ public: // Xcore ABI Implementation //===----------------------------------------------------------------------===// namespace { +class XCoreABIInfo : public DefaultABIInfo { +public: + XCoreABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const; +}; + class XcoreTargetCodeGenInfo : public TargetCodeGenInfo { public: XcoreTargetCodeGenInfo(CodeGenTypes &CGT) - :TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} + :TargetCodeGenInfo(new XCoreABIInfo(CGT)) {} }; } // 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 + 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 + llvm::Type *ArgPtrTy = llvm::PointerType::getUnqual(ArgTy); + switch (AI.getKind()) { + default: + case ABIArgInfo::Expand: + llvm_unreachable("Unsupported ABI kind for va_arg"); + case ABIArgInfo::Ignore: + return llvm::UndefValue::get(ArgPtrTy); + case ABIArgInfo::Extend: + case ABIArgInfo::Direct: + return Builder.CreatePointerCast(AP, ArgPtrTy); + case ABIArgInfo::Indirect: + llvm::Value *ArgAddr; + ArgAddr = Builder.CreateBitCast(AP, llvm::PointerType::getUnqual(ArgPtrTy)); + ArgAddr = Builder.CreateLoad(ArgAddr); + return Builder.CreatePointerCast(ArgAddr, ArgPtrTy); + } +} //===----------------------------------------------------------------------===// // Driver code |