diff options
author | Akira Hatanaka <ahatanak@gmail.com> | 2011-08-01 20:48:01 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanak@gmail.com> | 2011-08-01 20:48:01 +0000 |
commit | fb1d9f325c25cbce5e8ad73119209810cb9816ae (patch) | |
tree | 075b0097e84e3df060071b4bdfa6cd88f7db676f /clang/lib/CodeGen/TargetInfo.cpp | |
parent | 2fbb48ae20b724e6bdf9f3e6c165e5f0baf0807e (diff) | |
download | bcm5719-llvm-fb1d9f325c25cbce5e8ad73119209810cb9816ae.tar.gz bcm5719-llvm-fb1d9f325c25cbce5e8ad73119209810cb9816ae.zip |
Implement MipsABIInfo::EmitVAArg. This fix enables clang to complete compilation
without bailing out when va_arg is an aggregate expression. However,
alignment checking needs to be added in isSafeToEliminateVarargsCast in
InstCombineCalls.cpp in order to produce correct mips code (see link below).
http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-July/042047.html
llvm-svn: 136647
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 3866c2b2e50..167a0b12b88 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -2904,6 +2904,7 @@ void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D, namespace { class MipsABIInfo : public ABIInfo { + static const unsigned MinABIStackAlignInBytes = 4; public: MipsABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} @@ -2978,7 +2979,36 @@ void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const { llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { - return 0; + llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); + llvm::Type *BPP = llvm::PointerType::getUnqual(BP); + + CGBuilderTy &Builder = CGF.Builder; + llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); + llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); + unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8; + llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); + llvm::Value *AddrTyped; + + if (TypeAlign > MinABIStackAlignInBytes) { + llvm::Value *AddrAsInt32 = CGF.Builder.CreatePtrToInt(Addr, CGF.Int32Ty); + llvm::Value *Inc = llvm::ConstantInt::get(CGF.Int32Ty, TypeAlign - 1); + llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, -TypeAlign); + llvm::Value *Add = CGF.Builder.CreateAdd(AddrAsInt32, Inc); + llvm::Value *And = CGF.Builder.CreateAnd(Add, Mask); + AddrTyped = CGF.Builder.CreateIntToPtr(And, PTy); + } + else + AddrTyped = Builder.CreateBitCast(Addr, PTy); + + llvm::Value *AlignedAddr = Builder.CreateBitCast(AddrTyped, BP); + uint64_t Offset = + llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, TypeAlign); + llvm::Value *NextAddr = + Builder.CreateGEP(AlignedAddr, llvm::ConstantInt::get(CGF.Int32Ty, Offset), + "ap.next"); + Builder.CreateStore(NextAddr, VAListAddrAsBPP); + + return AddrTyped; } bool |