aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-04-01 06:13:08 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-04-01 06:13:08 +0000
commit360431660b2245a109f5c6870729126dbcdea254 (patch)
treede9276d26d1d6fb654f3834083304a31144519f6 /lib/CodeGen/CGCall.cpp
parenta56478910f397fae5990af3ce96646054e68e194 (diff)
x86-32 Darwin ABI: Handle direct return of vectors.
- Current return-arguments-32 status is: 8 out of 1000 failures (-7) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68192 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r--lib/CodeGen/CGCall.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 291e476f0b..58e448949e 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -278,6 +278,28 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
ASTContext &Context) const {
if (RetTy->isVoidType()) {
return ABIArgInfo::getIgnore();
+ } else if (const VectorType *VT = RetTy->getAsVectorType()) {
+ // On Darwin, some vectors are returned in registers.
+ if (IsDarwin) {
+ uint64_t Size = Context.getTypeSize(RetTy);
+
+ // 128-bit vectors are a special case; they are returned in
+ // registers and we need to make sure to pick a type the LLVM
+ // backend will like.
+ if (Size == 128)
+ return ABIArgInfo::getCoerce(llvm::VectorType::get(llvm::Type::Int64Ty,
+ 2));
+
+ // Always return in register if it fits in a general purpose
+ // register, or if it is 64 bits and has a single element.
+ if ((Size == 8 || Size == 16 || Size == 32) ||
+ (Size == 64 && VT->getNumElements() == 1))
+ return ABIArgInfo::getCoerce(llvm::IntegerType::get(Size));
+
+ return ABIArgInfo::getIndirect(0);
+ }
+
+ return ABIArgInfo::getDirect();
} else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
// Outside of Darwin, structs and unions are always indirect.
if (!IsDarwin && !RetTy->isAnyComplexType())