[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp

Nate Begeman natebegeman at mac.com
Fri Mar 25 17:29:04 PST 2005



Changes in directory llvm/lib/Target/PowerPC:

PPC32ISelPattern.cpp updated: 1.5 -> 1.6
---
Log message:

Next round of pattern isel changes, mostly dealing with calls.


---
Diffs of the changes:  (+139 -31)

 PPC32ISelPattern.cpp |  170 +++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 139 insertions(+), 31 deletions(-)


Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.5 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.6
--- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.5	Fri Mar 25 02:34:25 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp	Fri Mar 25 19:28:53 2005
@@ -58,8 +58,8 @@
     /// LowerCallTo - This hook lowers an abstract call to a function into an
     /// actual call.
     virtual std::pair<SDOperand, SDOperand>
-    LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
-                ArgListTy &Args, SelectionDAG &DAG);
+    LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
+                SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
     
     virtual std::pair<SDOperand, SDOperand>
     LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
@@ -206,35 +206,136 @@
 
 std::pair<SDOperand, SDOperand>
 PPC32TargetLowering::LowerCallTo(SDOperand Chain,
-				 const Type *RetTy, SDOperand Callee,
-				 ArgListTy &Args, SelectionDAG &DAG) {
-  // FIXME
-  int NumBytes = 56;
-
-  Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
-		      DAG.getConstant(NumBytes, getPointerTy()));
+				 const Type *RetTy, bool isVarArg,
+         SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) {
+  // args_to_use will accumulate outgoing args for the ISD::CALL case in
+  // SelectExpr to use to put the arguments in the appropriate registers.
   std::vector<SDOperand> args_to_use;
-  for (unsigned i = 0, e = Args.size(); i != e; ++i)
-  {
-    switch (getValueType(Args[i].second)) {
-    default: assert(0 && "Unexpected ValueType for argument!");
-    case MVT::i1:
-    case MVT::i8:
-    case MVT::i16:
-      // Promote the integer to 32 bits.  If the input type is signed use a
-      // sign extend, otherwise use a zero extend.
-      if (Args[i].second->isSigned())
-        Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first);
-      else
-        Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
-      break;
-    case MVT::i32:
-    case MVT::i64:
-    case MVT::f32:
-    case MVT::f64:
-      break;
+
+  // Count how many bytes are to be pushed on the stack, including the linkage
+  // area, and parameter passing area.
+  unsigned NumBytes = 24;
+
+  if (Args.empty()) {
+    NumBytes = 0;    // Save zero bytes.
+  } else {
+    for (unsigned i = 0, e = Args.size(); i != e; ++i)
+      switch (getValueType(Args[i].second)) {
+      default: assert(0 && "Unknown value type!");
+      case MVT::i1:
+      case MVT::i8:
+      case MVT::i16:
+      case MVT::i32:
+      case MVT::f32:
+        NumBytes += 4;
+        break;
+      case MVT::i64:
+      case MVT::f64:
+        NumBytes += 8;
+        break;
+      }
+    
+    // Just to be safe, we'll always reserve the full 24 bytes of linkage area 
+    // plus 32 bytes of argument space in case any called code gets funky on us.
+    if (NumBytes < 56) NumBytes = 56;
+
+    // Adjust the stack pointer for the new arguments...
+    // These operations are automatically eliminated by the prolog/epilog pass
+    Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
+                        DAG.getConstant(NumBytes, getPointerTy()));
+
+    // Set up a copy of the stack pointer for use loading and storing any
+    // arguments that may not fit in the registers available for argument
+    // passing.
+    SDOperand StackPtr = DAG.getCopyFromReg(PPC::R1, MVT::i32,
+                                            DAG.getEntryNode());
+    
+    // Figure out which arguments are going to go in registers, and which in
+    // memory.  Also, if this is a vararg function, floating point operations
+    // must be stored to our stack, and loaded into integer regs as well, if
+    // any integer regs are available for argument passing.
+    unsigned ArgOffset = 24;
+    unsigned GPR_remaining = 8;
+    unsigned FPR_remaining = 13;
+    std::vector<SDOperand> Stores;
+    for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+      // PtrOff will be used to store the current argument to the stack if a
+      // register cannot be found for it.
+      SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
+      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+      
+      switch (getValueType(Args[i].second)) {
+      default: assert(0 && "Unexpected ValueType for argument!");
+      case MVT::i1:
+      case MVT::i8:
+      case MVT::i16:
+        // Promote the integer to 32 bits.  If the input type is signed use a
+        // sign extend, otherwise use a zero extend.
+        if (Args[i].second->isSigned())
+          Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first);
+        else
+          Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
+        // FALL THROUGH
+      case MVT::i32:
+        if (GPR_remaining > 0) {
+          args_to_use.push_back(Args[i].first);
+          --GPR_remaining;
+        } else {
+          Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                       Args[i].first, PtrOff));
+        }
+        ArgOffset += 4;
+        break;
+      case MVT::i64:
+        // If we have 2 or more GPRs, we won't do anything and let the ISD::CALL
+        // functionality in SelectExpr move pieces for us.
+        if (GPR_remaining > 1) {
+          args_to_use.push_back(Args[i].first);
+          GPR_remaining -= 2;
+        } else if (GPR_remaining > 0) {
+          args_to_use.push_back(Args[i].first);
+          SDOperand LowPart = 
+            DAG.getNode(ISD::TRUNCATE, MVT::i32, Args[i].first);
+          SDOperand ConstFour = DAG.getConstant(4, getPointerTy());
+          PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
+          Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                       LowPart, PtrOff));
+          --GPR_remaining;
+        } else {
+          Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                       Args[i].first, PtrOff));
+        }
+        ArgOffset += 8;
+        break;
+      case MVT::f32:
+        if (FPR_remaining > 0 && GPR_remaining > 0 && isVarArg) {
+          --FPR_remaining;
+          ArgOffset += 4;
+        } else if (FPR_remaining > 0) {
+          --FPR_remaining;
+          if (GPR_remaining > 0) --GPR_remaining;
+        } else {
+          Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                       Args[i].first, PtrOff));
+        }
+        ArgOffset += 4;
+        break;
+      case MVT::f64:
+        if (FPR_remaining > 0 && GPR_remaining > 0 && isVarArg) {
+          --FPR_remaining;
+        } else if (FPR_remaining > 0) {
+          --FPR_remaining;
+          if (GPR_remaining > 0) --GPR_remaining;
+          if (GPR_remaining > 0) --GPR_remaining;
+        } else {
+          Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                       Args[i].first, PtrOff));
+        }
+        ArgOffset += 8;
+        break;
+      }
     }
-    args_to_use.push_back(Args[i].first);
+    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
   }
   
   std::vector<MVT::ValueType> RetVals;
@@ -364,6 +465,9 @@
     if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; }
     if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
     break;
+  case ISD::MUL:
+    if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
+    break;
   }
   return 0;
 }
@@ -813,8 +917,12 @@
   case ISD::MUL:
     assert (DestType == MVT::i32 && "Only do arithmetic on i32s!");
     Tmp1 = SelectExpr(N.getOperand(0));
-    Tmp2 = SelectExpr(N.getOperand(1));
-    BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp2).addReg(Tmp1);
+    if (1 == canUseAsImmediateForOpcode(N.getOperand(1), opcode, Tmp2))
+      BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
+    else {
+      Tmp2 = SelectExpr(N.getOperand(1));
+      BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    }
     return Result;
 
   case ISD::ADD_PARTS:






More information about the llvm-commits mailing list