add support for dynamic_stackalloc to the dag isel (thanks andrew ;)
authorDuraid Madina <duraid@octopus.com.au>
Fri, 25 Nov 2005 07:49:25 +0000 (07:49 +0000)
committerDuraid Madina <duraid@octopus.com.au>
Fri, 25 Nov 2005 07:49:25 +0000 (07:49 +0000)
next up: support argument passing in memory, not just registers

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

lib/Target/IA64/IA64ISelDAGToDAG.cpp

index a22db6c60ad2e423a05fe10ff54cd970036e6b78..f342370ad20bb1f59e8c98094d3e920e0adf3a51 100644 (file)
@@ -536,9 +536,37 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
   case ISD::SREM:
   case ISD::UREM: return SelectDIV(Op);
  
-/* todo:
- * case ISD::DYNAMIC_STACKALLOC:
-*/
+  case ISD::DYNAMIC_STACKALLOC: {
+    if (!isa<ConstantSDNode>(N->getOperand(2)) ||
+        cast<ConstantSDNode>(N->getOperand(2))->getValue() != 0) {
+      std::cerr << "Cannot allocate stack object with greater alignment than"
+                << " the stack alignment yet!";
+      abort();
+    }
+
+    SDOperand Chain = Select(N->getOperand(0));
+    SDOperand Amt   = Select(N->getOperand(1));
+    SDOperand Reg = CurDAG->getRegister(IA64::r12, MVT::i64);
+    SDOperand Val = CurDAG->getCopyFromReg(Chain, IA64::r12, MVT::i64);
+    Chain = Val.getValue(1);
+    
+    // Subtract the amount (guaranteed to be a multiple of the stack alignment)
+    // from the stack pointer, giving us the result pointer.
+    SDOperand Result = Select(CurDAG->getNode(ISD::SUB, MVT::i64, Val, Amt));
+    
+    // Copy this result back into r12.
+    Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, Reg, Result);
+    
+    // Copy this result back out of r12 to make sure we're not using the stack
+    // space without decrementing the stack pointer.
+    Result = CurDAG->getCopyFromReg(Chain, IA64::r12, MVT::i64);
+  
+    // Finally, replace the DYNAMIC_STACKALLOC with the copyfromreg.
+    CodeGenMap[Op.getValue(0)] = Result;
+    CodeGenMap[Op.getValue(1)] = Result.getValue(1);
+    return SDOperand(Result.Val, Op.ResNo);
+  }
+
   case ISD::ConstantFP: {
     SDOperand Chain = CurDAG->getEntryNode(); // this is a constant, so..