diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-11-18 02:12:09 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-11-18 02:12:09 +0000 |
commit | 7b1fb81a512def2a20e2834b4598a7b3a740dc7f (patch) | |
tree | 276a52d287050a636616cde00756e0cca9a7a803 /lib/CodeGen | |
parent | 506d4e375a6a36a49eb70578983dc4acaf2f15ae (diff) |
A bunch of fixes to argument passing and va_arg on Darwin x86-32 for structures containing an SSE vector.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144963 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 5be38978f2..88f8579b9a 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -620,7 +620,7 @@ static bool isRecordWithSSEVectorType(ASTContext &Context, QualType Ty) { i != e; ++i) { QualType FT = i->getType(); - if (FT->getAs<VectorType>() && Context.getTypeSize(Ty) == 128) + if (FT->getAs<VectorType>() && Context.getTypeSize(FT) == 128) return true; if (isRecordWithSSEVectorType(Context, FT)) @@ -644,7 +644,7 @@ unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty, } // Otherwise, if the type contains an SSE vector type, the alignment is 16. - if (isRecordWithSSEVectorType(getContext(), Ty)) + if (Align >= 16 && isRecordWithSSEVectorType(getContext(), Ty)) return 16; return MinABIStackAlignInBytes; @@ -739,12 +739,30 @@ llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); + + // Compute if the address needs to be aligned + unsigned Align = CGF.getContext().getTypeAlignInChars(Ty).getQuantity(); + Align = getTypeStackAlignInBytes(Ty, Align); + Align = std::max(Align, 4U); + if (Align > 4) { + // addr = (addr + align - 1) & -align; + llvm::Value *Offset = + llvm::ConstantInt::get(CGF.Int32Ty, Align - 1); + Addr = CGF.Builder.CreateGEP(Addr, Offset); + llvm::Value *AsInt = CGF.Builder.CreatePtrToInt(Addr, + CGF.Int32Ty); + llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, -Align); + Addr = CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask), + Addr->getType(), + "ap.cur.aligned"); + } + llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy); uint64_t Offset = - llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 4); + llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, Align); llvm::Value *NextAddr = Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset), "ap.next"); |