diff options
author | Chris Lattner <sabre@nondot.org> | 2006-02-15 06:41:34 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-02-15 06:41:34 +0000 |
commit | 6fa1f57c66dc3cb762fffd99ec86c29d0cdc103e (patch) | |
tree | e5dbb4c3e4d9050119f96537e9155f44ebe7caf0 /lib/Target/Sparc | |
parent | 197ab8787f2630051e66a46c636b6015bec2de0e (diff) |
Fix SingleSource/Regression/C/2004-08-12-InlinerAndAllocas.c on Sparc.
The ABI specifies that there is a register save area at the bottom of the
stack, which means the actual used pointer needs to be an offset from
the subtracted value.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26202 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r-- | lib/Target/Sparc/SparcISelDAGToDAG.cpp | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index dba02c08cd..8671b608b9 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -211,7 +211,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM) setOperationAction(ISD::VAEND , MVT::Other, Expand); setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); - setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); + setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Custom); setOperationAction(ISD::ConstantFP, MVT::f64, Expand); setOperationAction(ISD::ConstantFP, MVT::f32, Expand); @@ -807,6 +807,27 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops); } } + case ISD::DYNAMIC_STACKALLOC: { + SDOperand Chain = Op.getOperand(0); // Legalize the chain. + SDOperand Size = Op.getOperand(1); // Legalize the size. + + unsigned SPReg = SP::O6; + SDOperand SP = DAG.getCopyFromReg(Chain, SPReg, MVT::i32); + SDOperand NewSP = DAG.getNode(ISD::SUB, MVT::i32, SP, Size); // Value + Chain = DAG.getCopyToReg(SP.getValue(1), SPReg, NewSP); // Output chain + + // The resultant pointer is actually 16 words from the bottom of the stack, + // to provide a register spill area. + SDOperand NewVal = DAG.getNode(ISD::ADD, MVT::i32, NewSP, + DAG.getConstant(96, MVT::i32)); + std::vector<MVT::ValueType> Tys; + Tys.push_back(MVT::i32); + Tys.push_back(MVT::Other); + std::vector<SDOperand> Ops; + Ops.push_back(NewVal); + Ops.push_back(Chain); + return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops); + } case ISD::RET: { SDOperand Copy; |