]> granicus.if.org Git - clang/commitdiff
start setting up infrastructure for passing multi-floats
authorChris Lattner <sabre@nondot.org>
Thu, 29 Jul 2010 17:49:08 +0000 (17:49 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 29 Jul 2010 17:49:08 +0000 (17:49 +0000)
as <2 x float> instead of as double.  The backend isn't ready
yet, but infrastructure in the frontend can come up.

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

lib/CodeGen/TargetInfo.cpp

index 27884e6d28160b367430365c483fb5b645df7128..1e66f046b0cd10f5b517ae0e97824a98ee4353f3 100644 (file)
@@ -718,7 +718,8 @@ class X86_64ABIInfo : public ABIInfo {
   void classify(QualType T, uint64_t OffsetBase, Class &Lo, Class &Hi) const;
 
   const llvm::Type *Get16ByteVectorType(QualType Ty) const;
-
+  const llvm::Type *GetSSETypeAtOffset(const llvm::Type *IRType,
+                                       unsigned IROffset) const;
   const llvm::Type *GetINTEGERTypeAtOffset(const llvm::Type *IRType,
                                            unsigned IROffset, QualType SourceTy,
                                            unsigned SourceOffset) const;
@@ -1211,6 +1212,20 @@ const llvm::Type *X86_64ABIInfo::Get16ByteVectorType(QualType Ty) const {
 }
 
 
+/// GetSSETypeAtOffset - Return a type that will be passed by the backend in the
+/// low 8 bytes of an XMM register, corresponding to the SSE class.
+const llvm::Type *X86_64ABIInfo::GetSSETypeAtOffset(const llvm::Type *IRType,
+                                                    unsigned IROffset) const {
+  // The only two choices we have are either double or <2 x float>.
+  
+  // FIXME: <2 x float> doesn't pass as one XMM register yet.  Don't enable this
+  // code until it does.
+  
+  return llvm::Type::getDoubleTy(getVMContext());
+}
+
+
+
 /// BitsContainNoUserData - Return true if the specified [start,end) bit range
 /// is known to either be off the end of the specified type or being in
 /// alignment padding.  The user type specified is known to be at most 128 bits
@@ -1405,7 +1420,7 @@ classifyReturnType(QualType RetTy) const {
     // AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next
     // available SSE register of the sequence %xmm0, %xmm1 is used.
   case SSE:
-    ResType = llvm::Type::getDoubleTy(getVMContext());
+    ResType = GetSSETypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 0);
     break;
 
     // AMD64-ABI 3.2.3p4: Rule 6. If the class is X87, the value is
@@ -1443,11 +1458,12 @@ classifyReturnType(QualType RetTy) const {
     ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
     break;
   }
-  case SSE:
-    ResType = llvm::StructType::get(getVMContext(), ResType,
-                                    llvm::Type::getDoubleTy(getVMContext()),
-                                    NULL);
+  case SSE: {
+    const llvm::Type *HiType =
+      GetSSETypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 8);
+    ResType = llvm::StructType::get(getVMContext(), ResType, HiType,NULL);
     break;
+  }
 
     // AMD64-ABI 3.2.3p4: Rule 5. If the class is SSEUP, the eightbyte
     // is passed in the upper half of the last used SSE register.
@@ -1465,10 +1481,11 @@ classifyReturnType(QualType RetTy) const {
     // anything. However, in some cases with unions it may not be
     // preceeded by X87. In such situations we follow gcc and pass the
     // extra bits in an SSE reg.
-    if (Lo != X87)
-      ResType = llvm::StructType::get(getVMContext(), ResType,
-                                      llvm::Type::getDoubleTy(getVMContext()),
-                                      NULL);
+    if (Lo != X87) {
+      const llvm::Type *HiType =
+        GetSSETypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 8);
+      ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
+    }
     break;
   }
 
@@ -1522,7 +1539,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
     // order from %xmm0 to %xmm7.
   case SSE:
     ++neededSSE;
-    ResType = llvm::Type::getDoubleTy(getVMContext());
+    ResType = GetSSETypeAtOffset(CGT.ConvertTypeRecursive(Ty), 0);
     break;
   }
 
@@ -1550,12 +1567,13 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
     // X87Up generally doesn't occur here (long double is passed in
     // memory), except in situations involving unions.
   case X87Up:
-  case SSE:
-    ResType = llvm::StructType::get(getVMContext(), ResType,
-                                    llvm::Type::getDoubleTy(getVMContext()),
-                                    NULL);
+  case SSE: {
+    const llvm::Type *HiType =
+      GetSSETypeAtOffset(CGT.ConvertTypeRecursive(Ty), 8);
+    ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
     ++neededSSE;
     break;
+  }
 
     // AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the
     // eightbyte is passed in the upper half of the last used SSE