aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/PIC16/PIC16ISelLowering.cpp
diff options
context:
space:
mode:
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();