]> granicus.if.org Git - clang/commitdiff
x86_64 ABI: Pass 32-bit vectors as Integer to match gcc. We don't care
authorDaniel Dunbar <daniel@zuster.org>
Sun, 22 Feb 2009 04:48:22 +0000 (04:48 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sun, 22 Feb 2009 04:48:22 +0000 (04:48 +0000)
about these much but <2 x i16> shows up in the gcc test suite.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65264 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCall.cpp

index 0e2bd606ebff11d1df4cf2d5fbffca28eaafb084..71ef679f18e579a66f9cc53b6c737cbe87742822 100644 (file)
@@ -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;