[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp

Evan Cheng evan.cheng at apple.com
Thu Apr 27 01:31:23 PDT 2006



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.192 -> 1.193
---
Log message:

Support for passing 128-bit vector arguments via XMM registers.


---
Diffs of the changes:  (+97 -27)

 X86ISelLowering.cpp |  124 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 97 insertions(+), 27 deletions(-)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.192 llvm/lib/Target/X86/X86ISelLowering.cpp:1.193
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.192	Thu Apr 27 00:44:50 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Thu Apr 27 03:31:10 2006
@@ -413,10 +413,13 @@
   return VReg;
 }
 
-/// getFormalArgSize - Return the minimum size of the stack frame needed to store
-/// an object of the specified type.
-static unsigned getFormalArgSize(MVT::ValueType ObjectVT) {
-  unsigned ObjSize = 0;
+/// HowToPassCCCArgument - Returns how an formal argument of the specified type
+/// should be passed. If it is through stack, returns the size of the stack
+/// frame; if it is through XMM register, returns the number of XMM registers
+/// are needed.
+static void
+HowToPassCCCArgument(MVT::ValueType ObjectVT, unsigned NumXMMRegs,
+                     unsigned &ObjSize, unsigned &ObjXMMRegs) {
   switch (ObjectVT) {
   default: assert(0 && "Unhandled argument type!");
   case MVT::i1:
@@ -426,8 +429,18 @@
   case MVT::i64: ObjSize = 8; break;
   case MVT::f32: ObjSize = 4; break;
   case MVT::f64: ObjSize = 8; break;
+  case MVT::v16i8:
+  case MVT::v8i16:
+  case MVT::v4i32:
+  case MVT::v2i64:
+  case MVT::v4f32:
+  case MVT::v2f64:
+    if (NumXMMRegs < 3)
+      ObjXMMRegs = 1;
+    else
+      ObjSize = 16;
+    break;
   }
-  return ObjSize;
 }
 
 /// getFormalArgObjects - Returns itself if Op is a FORMAL_ARGUMENTS, otherwise
@@ -466,6 +479,8 @@
   //    ...
   //
   unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
+  unsigned NumXMMRegs = 0;  // XMM regs used for parameter passing.
+  unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 };
   for (unsigned i = 0; i < NumArgs; ++i) {
     SDOperand Op = Args[i];
     std::vector<SDOperand> Objs = getFormalArgObjects(Op);
@@ -474,16 +489,29 @@
       SDOperand Obj = *I;
       MVT::ValueType ObjectVT = Obj.getValueType();
       unsigned ArgIncrement = 4;
-      unsigned ObjSize = getFormalArgSize(ObjectVT);
-      if (ObjSize == 8)
-        ArgIncrement = 8;
-
-      // Create the frame index object for this incoming parameter...
-      int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
-      std::pair<FALocInfo, FALocInfo> Loc =
-        std::make_pair(FALocInfo(FALocInfo::StackFrameLoc, FI), FALocInfo());
-      FormalArgLocs.push_back(Loc);
-      ArgOffset += ArgIncrement;   // Move on to the next argument...
+      unsigned ObjSize = 0;
+      unsigned ObjXMMRegs = 0;
+      HowToPassCCCArgument(ObjectVT, NumXMMRegs, ObjSize, ObjXMMRegs);
+      if (ObjSize >= 8)
+        ArgIncrement = ObjSize;
+
+      if (ObjXMMRegs) {
+        // Passed in a XMM register.
+        unsigned Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs],
+                                 X86::VR128RegisterClass);
+        std::pair<FALocInfo, FALocInfo> Loc =
+          std::make_pair(FALocInfo(FALocInfo::LiveInRegLoc, Reg, ObjectVT),
+                         FALocInfo());
+        FormalArgLocs.push_back(Loc);
+        NumXMMRegs += ObjXMMRegs;
+      } else {
+        // Create the frame index object for this incoming parameter...
+        int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
+        std::pair<FALocInfo, FALocInfo> Loc =
+          std::make_pair(FALocInfo(FALocInfo::StackFrameLoc, FI), FALocInfo());
+        FormalArgLocs.push_back(Loc);
+        ArgOffset += ArgIncrement;   // Move on to the next argument...
+      }
     }
   }
 
@@ -502,11 +530,19 @@
   MachineFrameInfo *MFI = MF.getFrameInfo();
 
   for (unsigned i = 0; i < NumArgs; ++i) {
-    // Create the SelectionDAG nodes corresponding to a load from this parameter
-    unsigned FI = FormalArgLocs[i].first.Loc;
-    SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
-    SDOperand ArgValue = DAG.getLoad(Op.Val->getValueType(i),DAG.getEntryNode(),
-                                     FIN, DAG.getSrcValue(NULL));
+    std::pair<FALocInfo, FALocInfo> Loc = FormalArgLocs[i];
+    SDOperand ArgValue;
+    if (Loc.first.Kind == FALocInfo::StackFrameLoc) {
+      // Create the SelectionDAG nodes corresponding to a load from this parameter
+      unsigned FI = FormalArgLocs[i].first.Loc;
+      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+      ArgValue = DAG.getLoad(Op.Val->getValueType(i),
+                             DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL));
+    } else {
+      // Must be a CopyFromReg
+      ArgValue= DAG.getCopyFromReg(DAG.getEntryNode(), Loc.first.Loc,
+                                   Loc.first.Typ);
+    }
     FormalArgs.push_back(ArgValue);
   }
 }
@@ -741,9 +777,15 @@
 static unsigned FASTCC_NUM_INT_ARGS_INREGS = 0;
 
 
+/// HowToPassFastCCArgument - Returns how an formal argument of the specified
+/// type should be passed. If it is through stack, returns the size of the stack
+/// frame; if it is through integer or XMM register, returns the number of
+/// integer or XMM registers are needed.
 static void
-HowToPassFastCCArgument(MVT::ValueType ObjectVT, unsigned NumIntRegs,
-                        unsigned &ObjSize, unsigned &ObjIntRegs) {
+HowToPassFastCCArgument(MVT::ValueType ObjectVT,
+                        unsigned NumIntRegs, unsigned NumXMMRegs,
+                        unsigned &ObjSize, unsigned &ObjIntRegs,
+                        unsigned &ObjXMMRegs) {
   ObjSize = 0;
   NumIntRegs = 0;
 
@@ -782,6 +824,17 @@
   case MVT::f64:
     ObjSize = 8;
     break;
+  case MVT::v16i8:
+  case MVT::v8i16:
+  case MVT::v4i32:
+  case MVT::v2i64:
+  case MVT::v4f32:
+  case MVT::v2f64:
+    if (NumXMMRegs < 3)
+      ObjXMMRegs = 1;
+    else
+      ObjSize = 16;
+    break;
   }
 }
 
@@ -805,6 +858,8 @@
   // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
   // used).
   unsigned NumIntRegs = 0;
+  unsigned NumXMMRegs = 0;  // XMM regs used for parameter passing.
+  unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 };
   
   for (unsigned i = 0; i < NumArgs; ++i) {
     SDOperand Op = Args[i];
@@ -816,10 +871,12 @@
       unsigned ArgIncrement = 4;
       unsigned ObjSize = 0;
       unsigned ObjIntRegs = 0;
+      unsigned ObjXMMRegs = 0;
 
-      HowToPassFastCCArgument(ObjectVT, NumIntRegs, ObjSize, ObjIntRegs);
-      if (ObjSize == 8)
-        ArgIncrement = 8;
+      HowToPassFastCCArgument(ObjectVT, NumIntRegs, NumXMMRegs,
+                              ObjSize, ObjIntRegs, ObjXMMRegs);
+      if (ObjSize >= 8)
+        ArgIncrement = ObjSize;
 
       unsigned Reg;
       std::pair<FALocInfo,FALocInfo> Loc = std::make_pair(FALocInfo(),
@@ -862,8 +919,20 @@
             Loc.second.Typ = MVT::i32;
           }
           break;
+        case MVT::v16i8:
+        case MVT::v8i16:
+        case MVT::v4i32:
+        case MVT::v2i64:
+        case MVT::v4f32:
+        case MVT::v2f64:
+          Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], X86::VR128RegisterClass);
+          Loc.first.Kind = FALocInfo::LiveInRegLoc;
+          Loc.first.Loc = Reg;
+          Loc.first.Typ = ObjectVT;
+          break;
         }
         NumIntRegs += ObjIntRegs;
+        NumXMMRegs += ObjXMMRegs;
       }
       if (ObjSize) {
         int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
@@ -928,7 +997,8 @@
                              DAG.getSrcValue(NULL));
     } else {
       // Must be a CopyFromReg
-      ArgValue= DAG.getCopyFromReg(DAG.getRoot(), Loc.first.Loc, Loc.first.Typ);
+      ArgValue= DAG.getCopyFromReg(DAG.getEntryNode(), Loc.first.Loc,
+                                   Loc.first.Typ);
     }
 
     if (Loc.second.Kind != FALocInfo::None) {
@@ -940,7 +1010,7 @@
                                 DAG.getSrcValue(NULL));
       } else {
         // Must be a CopyFromReg
-        ArgValue2 = DAG.getCopyFromReg(DAG.getRoot(),
+        ArgValue2 = DAG.getCopyFromReg(DAG.getEntryNode(),
                                        Loc.second.Loc, Loc.second.Typ);
       }
       ArgValue = DAG.getNode(ISD::BUILD_PAIR, VT, ArgValue, ArgValue2);






More information about the llvm-commits mailing list