aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-02-22 04:16:10 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-02-22 04:16:10 +0000
commit0af9929e1ba8e5b9ae0a8999439736d249599bbe (patch)
treec3ffd396b5b72e5c3ec3e93aee5e68d925aff786 /lib/CodeGen/CGCall.cpp
parent4bdf08770e75a068de2430e21a43b381aeb13b95 (diff)
x86_64 ABI: Classify <1 x i64> as INTEGER (match gcc not llvm-gcc).
Also, make sure to pass <1 x i64> as i64 (not <1 x i64>, which doesn't quite work yet in the backend). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65262 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r--lib/CodeGen/CGCall.cpp18
1 files changed, 12 insertions, 6 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 02e00558d8..0e2bd606eb 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -524,11 +524,15 @@ void X86_64ABIInfo::classify(QualType Ty,
} else if (const VectorType *VT = Ty->getAsVectorType()) {
uint64_t Size = Context.getTypeSize(VT);
if (Size == 64) {
- // gcc passes <1 x double> in memory.
- if (VT->getElementType() == Context.DoubleTy)
+ // gcc passes <1 x double> in memory. :(
+ if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::Double))
return;
-
- Current = SSE;
+
+ // gcc passes <1 x long long> as INTEGER.
+ if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::LongLong))
+ Current = Integer;
+ else
+ Current = SSE;
// If this type crosses an eightbyte boundary, it should be
// split.
@@ -542,7 +546,7 @@ void X86_64ABIInfo::classify(QualType Ty,
QualType ET = Context.getCanonicalType(CT->getElementType());
uint64_t Size = Context.getTypeSize(Ty);
- if (ET->isIntegerType()) {
+ if (ET->isIntegralType()) {
if (Size <= 64)
Current = Integer;
else if (Size <= 128)
@@ -688,8 +692,9 @@ ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty,
if (CoerceTo == llvm::Type::Int64Ty) {
// Integer and pointer types will end up in a general purpose
// register.
- if (Ty->isIntegerType() || Ty->isPointerType())
+ if (Ty->isIntegralType() || Ty->isPointerType())
return ABIArgInfo::getDirect();
+
} else if (CoerceTo == llvm::Type::DoubleTy) {
// FIXME: It would probably be better to make CGFunctionInfo only
// map using canonical types than to canonize here.
@@ -698,6 +703,7 @@ ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty,
// Float and double end up in a single SSE reg.
if (CTy == Context.FloatTy || CTy == Context.DoubleTy)
return ABIArgInfo::getDirect();
+
}
return ABIArgInfo::getCoerce(CoerceTo);