summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-02-22 04:48:22 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-02-22 04:48:22 +0000
commitc64c481d18826a0925c1b34f6877d0811236e849 (patch)
tree9f53bd22253d9e8637780ff667d9ced215baad28
parent3ebd531b2c0fa992f5c1f93e8033999f1e0ff203 (diff)
downloadbcm5719-llvm-c64c481d18826a0925c1b34f6877d0811236e849.tar.gz
bcm5719-llvm-c64c481d18826a0925c1b34f6877d0811236e849.zip
x86_64 ABI: Pass 32-bit vectors as Integer to match gcc. We don't care
about these much but <2 x i16> shows up in the gcc test suite. llvm-svn: 65264
-rw-r--r--clang/lib/CodeGen/CGCall.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 0e2bd606ebf..71ef679f18e 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -497,6 +497,10 @@ void X86_64ABIInfo::classify(QualType Ty,
// class for Class pairs with appropriate constructor methods for
// the various situations.
+ // FIXME: Some of the split computations are wrong; unaligned
+ // vectors shouldn't be passed in registers for example, so there is
+ // no chance they can straddle an eightbyte. Verify & simplify.
+
Lo = Hi = NoClass;
Class &Current = OffsetBase < 64 ? Lo : Hi;
@@ -523,7 +527,18 @@ void X86_64ABIInfo::classify(QualType Ty,
Current = Integer;
} else if (const VectorType *VT = Ty->getAsVectorType()) {
uint64_t Size = Context.getTypeSize(VT);
- if (Size == 64) {
+ if (Size == 32) {
+ // gcc passes all <4 x char>, <2 x short>, <1 x int>, <1 x
+ // float> as integer.
+ Current = Integer;
+
+ // If this type crosses an eightbyte boundary, it should be
+ // split.
+ uint64_t EB_Real = (OffsetBase) / 64;
+ uint64_t EB_Imag = (OffsetBase + Size - 1) / 64;
+ if (EB_Real != EB_Imag)
+ Hi = Lo;
+ } else if (Size == 64) {
// gcc passes <1 x double> in memory. :(
if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::Double))
return;
OpenPOWER on IntegriCloud