aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/PIC16/PIC16ISelLowering.cpp
diff options
context:
space:
mode:
authorSanjiv Gupta <sanjiv.gupta@microchip.com>2009-04-02 17:42:00 +0000
committerSanjiv Gupta <sanjiv.gupta@microchip.com>2009-04-02 17:42:00 +0000
commitb84d5a476a8e678dbdeef848b22ea22c24632e11 (patch)
treefd84b914b67bc3534e7402c1579ca077602e3f6d /lib/Target/PIC16/PIC16ISelLowering.cpp
parentd0dfbe096dd71ca4d652784705584876f8b18250 (diff)
Params are not being generated as static globals now. The caller passes them onto the callee's stack directly and the callee loads the argvals from its own stack. Clang generated frameindexes validatd by recalculating the stack as if all frameindexes represent 1-byte slots.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68327 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PIC16/PIC16ISelLowering.cpp')
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.cpp104
1 files changed, 91 insertions, 13 deletions
diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp
index 3ace4821d8..cbe3a9dc1e 100644
--- a/lib/Target/PIC16/PIC16ISelLowering.cpp
+++ b/lib/Target/PIC16/PIC16ISelLowering.cpp
@@ -244,6 +244,7 @@ const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
case PIC16ISD::MTHI: return "PIC16ISD::MTHI";
case PIC16ISD::Banksel: return "PIC16ISD::Banksel";
case PIC16ISD::PIC16Load: return "PIC16ISD::PIC16Load";
+ case PIC16ISD::PIC16LdArg: return "PIC16ISD::PIC16LdArg";
case PIC16ISD::PIC16LdWF: return "PIC16ISD::PIC16LdWF";
case PIC16ISD::PIC16Store: return "PIC16ISD::PIC16Store";
case PIC16ISD::PIC16StWF: return "PIC16ISD::PIC16StWF";
@@ -503,13 +504,24 @@ PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG,
MachineFunction &MF = DAG.getMachineFunction();
const Function *Func = MF.getFunction();
+ MachineFrameInfo *MFI = MF.getFrameInfo();
const std::string Name = Func->getName();
char *tmpName = new char [strlen(Name.c_str()) + 8];
- sprintf(tmpName, "%s.args", Name.c_str());
+ sprintf(tmpName, "%s.frame", Name.c_str());
ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(Op);
- Offset = FR->getIndex();
+
+ // FrameIndices are not stack offsets. But they represent the request
+ // for space on stack. That space requested may be more than one byte.
+ // Therefore, to calculate the stack offset that a FrameIndex aligns
+ // with, we need to traverse all the FrameIndices available earlier in
+ // the list and add their requested size.
+ unsigned FIndex = FR->getIndex();
+ Offset = 0;
+ for (unsigned i=0; i<FIndex ; ++i) {
+ Offset += MFI->getObjectSize(i);
+ }
return;
}
@@ -810,7 +822,7 @@ SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
const Function *Func = MF.getFunction();
const std::string FuncName = Func->getName();
- char *tmpName = new char [strlen(FuncName.c_str()) + 6];
+ char *tmpName = new char [strlen(FuncName.c_str()) + 8];
// Put the value on stack.
// Get a stack slot index and convert to es.
@@ -938,11 +950,41 @@ PIC16TargetLowering::LowerCallReturn(SDValue Op, SDValue Chain,
}
SDValue PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
- //int NumOps = Op.getNode()->getNumOperands();
+ SDValue Chain = Op.getOperand(0);
+ DebugLoc dl = Op.getDebugLoc();
+
+ if (Op.getNumOperands() == 1) // return void
+ return Op;
+
+ // return should have odd number of operands
+ if ((Op.getNumOperands() % 2) == 0 ) {
+ assert(0 && "Do not know how to return this many arguments!");
+ abort();
+ }
+
+ // Number of values to return
+ unsigned NumRet = (Op.getNumOperands() / 2);
+
+ // Function returns value always on stack with the offset starting
+ // from 0
+ MachineFunction &MF = DAG.getMachineFunction();
+ const Function *F = MF.getFunction();
+ std::string FuncName = F->getName();
- // For default cases LLVM returns the value on the function frame
- // So let LLVM do this for all the cases other than character
- return Op;
+ char *tmpName = new char [strlen(FuncName.c_str()) + 8];
+ sprintf(tmpName, "%s.frame", FuncName.c_str());
+ SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Other);
+ SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
+ SDValue BS = DAG.getConstant(1, MVT::i8);
+ SDValue RetVal;
+ for(unsigned i=0;i<NumRet; ++i) {
+ RetVal = Op.getNode()->getOperand(2*i + 1);
+ Chain = DAG.getNode (PIC16ISD::PIC16Store, dl, MVT::Other, Chain, RetVal,
+ ES, BS,
+ DAG.getConstant (i, MVT::i8));
+
+ }
+ return DAG.getNode(ISD::RET, dl, MVT::Other, Chain);
}
SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
@@ -1164,13 +1206,26 @@ SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) {
SDValue PIC16TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op,
SelectionDAG &DAG) {
SmallVector<SDValue, 8> ArgValues;
- unsigned NumArgs = Op.getNumOperands() - 3;
+ unsigned NumArgs = Op.getNode()->getNumValues()-1;
DebugLoc dl = Op.getDebugLoc();
+ SDValue Chain = Op.getOperand(0); // Formal arguments' chain
- // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node.
- for(unsigned i = 0 ; i<NumArgs ; i++) {
- SDValue TempNode = DAG.getUNDEF(Op.getNode()->getValueType(i));
- ArgValues.push_back(TempNode);
+ MachineFunction &MF = DAG.getMachineFunction();
+ //const TargetData *TD = getTargetData();
+ const Function *F = MF.getFunction();
+ std::string FuncName = F->getName();
+
+ char *tmpName = new char [strlen(FuncName.c_str()) + 6];
+ sprintf(tmpName, "%s.args", FuncName.c_str());
+ SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Other);
+ SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
+ SDValue BS = DAG.getConstant(1, MVT::i8);
+ for (unsigned i=0; i<NumArgs ; ++i) {
+ SDValue Offset = DAG.getConstant(i, MVT::i8);
+ SDValue PICLoad = DAG.getNode(PIC16ISD::PIC16LdArg, dl, VTs, Chain, ES, BS,
+ Offset);
+ Chain = getChain(PICLoad);
+ ArgValues.push_back(PICLoad);
}
ArgValues.push_back(Op.getOperand(0));
@@ -1191,11 +1246,34 @@ PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
return SDValue();
}
+// For all the functions with arguments some STORE nodes are generated
+// that store the argument on the frameindex. However in PIC16 the arguments
+// are passed on stack only. Therefore these STORE nodes are redundant.
+// To remove these STORE nodes will be removed in PerformStoreCombine
+//
+// Currently this function is doint nothing and will be updated for removing
+// unwanted store operations
+SDValue PIC16TargetLowering::
+PerformStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const {
+ SelectionDAG &DAG = DCI.DAG;
+ SDValue Chain;
+ return SDValue(N, 0);
+ /*
+ // Storing an undef value is of no use, so remove it
+ if (isStoringUndef(N, Chain, DAG)) {
+ return Chain; // remove the store and return the chain
+ }
+ //else everything is ok.
+ return SDValue(N, 0);
+ */
+}
SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
switch (N->getOpcode()) {
- case PIC16ISD::PIC16Load:
+ case ISD::STORE:
+ return PerformStoreCombine(N, DCI);
+ case PIC16ISD::PIC16Load:
return PerformPIC16LoadCombine(N, DCI);
}
return SDValue();