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..