diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp index 3696d5afeb5..6a5c2e03718 100644 --- a/lib/Target/PIC16/PIC16AsmPrinter.cpp +++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp @@ -335,6 +335,7 @@ bool PIC16AsmPrinter::doFinalization(Module &M) { void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { const Function *F = MF.getFunction(); std::string FuncName = Mang->getValueName(F); + MachineFrameInfo *MFI= MF.getFrameInfo(); Module *M = const_cast(F->getParent()); const TargetData *TD = TM.getTargetData(); unsigned FrameSize = 0; @@ -346,15 +347,30 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { SectionFlags::Writeable); SwitchToSection(fDataSection); - //Emit function return value. - O << CurrentFnName << ".retval:\n"; + + // Emit function frame label + O << CurrentFnName << ".frame:\n"; + const Type *RetType = F->getReturnType(); unsigned RetSize = 0; if (RetType->getTypeID() != Type::VoidTyID) RetSize = TD->getTypePaddedSize(RetType); - // Emit function arguments. - O << CurrentFnName << ".args:\n"; + //Emit function return value space + if(RetSize > 0) + O << CurrentFnName << ".retval RES " << RetSize << "\n"; + else + O << CurrentFnName << ".retval:\n"; + + // Emit variable to hold the space for function arguments + unsigned ArgSize = 0; + for (Function::const_arg_iterator argi = F->arg_begin(), + arge = F->arg_end(); argi != arge ; ++argi) { + const Type *Ty = argi->getType(); + ArgSize += TD->getTypePaddedSize(Ty); + } + O << CurrentFnName << ".args RES " << ArgSize << "\n"; + // Emit the function variables. // In PIC16 all the function arguments and local variables are global. @@ -382,34 +398,15 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { O << VarName << " RES " << Size << "\n"; } - // Return value can not overlap with temp data, becasue a temp slot - // may be read/written after a return value is calculated and saved - // within the function. - if (RetSize > FrameSize) - O << CurrentFnName << ".dummy" << " RES " << (RetSize - FrameSize) << "\n"; - emitFunctionTempData(MF, FrameSize); -} - -void PIC16AsmPrinter::emitFunctionTempData(MachineFunction &MF, - unsigned &FrameSize) { - // Emit temporary variables. - MachineFrameInfo *FrameInfo = MF.getFrameInfo(); - if (FrameInfo->hasStackObjects()) { - int indexBegin = FrameInfo->getObjectIndexBegin(); - int indexEnd = FrameInfo->getObjectIndexEnd(); - - if (indexBegin < indexEnd) { - FrameSize += indexEnd - indexBegin; - O << CurrentFnName << ".tmp RES"<< " " - <hasStackObjects()) { + int indexBegin = MFI->getObjectIndexBegin(); + int indexEnd = MFI->getObjectIndexEnd(); + if (indexBegin < indexEnd) { + int TempSize = indexEnd - indexBegin; + O << CurrentFnName << ".tmp RES " << TempSize <<"\n"; } - */ } } diff --git a/lib/Target/PIC16/PIC16AsmPrinter.h b/lib/Target/PIC16/PIC16AsmPrinter.h index 5479717a455..5286dd2e7a3 100644 --- a/lib/Target/PIC16/PIC16AsmPrinter.h +++ b/lib/Target/PIC16/PIC16AsmPrinter.h @@ -45,7 +45,6 @@ namespace llvm { void EmitUnInitData (Module &M); void EmitRomData (Module &M); void emitFunctionData(MachineFunction &MF); - void emitFunctionTempData(MachineFunction &MF, unsigned &FrameSize); protected: bool doInitialization(Module &M); diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp index 3ace4821d8d..cbe3a9dc1ea 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(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; igetObjectSize(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(); - // 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; + 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(); + + 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;igetOperand(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 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 ; igetValueType(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; igetOpcode()) { - case PIC16ISD::PIC16Load: + case ISD::STORE: + return PerformStoreCombine(N, DCI); + case PIC16ISD::PIC16Load: return PerformPIC16LoadCombine(N, DCI); } return SDValue(); diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h index 75e824a0a6b..b2a89db3ea8 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.h +++ b/lib/Target/PIC16/PIC16ISelLowering.h @@ -29,6 +29,10 @@ namespace llvm { Lo, // Low 8-bits of GlobalAddress. Hi, // High 8-bits of GlobalAddress. PIC16Load, + PIC16LdArg, // This is replica of PIC16Load but used to load function + // arguments and is being used for facilitating for some + // store removal optimizations. + PIC16LdWF, PIC16Store, PIC16StWF, @@ -103,17 +107,17 @@ namespace llvm { SDValue ExpandStore(SDNode *N, SelectionDAG &DAG); SDValue ExpandLoad(SDNode *N, SelectionDAG &DAG); - //SDValue ExpandAdd(SDNode *N, SelectionDAG &DAG); SDValue ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG); SDValue ExpandExternalSymbol(SDNode *N, SelectionDAG &DAG); SDValue ExpandFrameIndex(SDNode *N, SelectionDAG &DAG); SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; SDValue PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const; + SDValue PerformStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const; private: - // If the Node is a BUILD_PAIR representing representing an Address - // then this function will return true + // If the Node is a BUILD_PAIR representing a direct Address, + // then this function will return true. bool isDirectAddress(const SDValue &Op); // If the Node is a DirectAddress in ROM_SPACE then this @@ -149,14 +153,14 @@ namespace llvm { // Extending the LIB Call framework of LLVM - // To hold the names of PIC16Libcalls + // to hold the names of PIC16Libcalls. const char *PIC16LibcallNames[PIC16ISD::PIC16UnknownCall]; - // To set and retrieve the lib call names + // To set and retrieve the lib call names. void setPIC16LibcallName(PIC16ISD::PIC16Libcall Call, const char *Name); const char *getPIC16LibcallName(PIC16ISD::PIC16Libcall Call); - // Make PIC16 Libcall + // Make PIC16 Libcall. SDValue MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, MVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, SelectionDAG &DAG, DebugLoc dl); diff --git a/lib/Target/PIC16/PIC16InstrInfo.td b/lib/Target/PIC16/PIC16InstrInfo.td index 40119d0a89d..471180fa491 100644 --- a/lib/Target/PIC16/PIC16InstrInfo.td +++ b/lib/Target/PIC16/PIC16InstrInfo.td @@ -88,8 +88,9 @@ def PIC16StWF : SDNode<"PIC16ISD::PIC16StWF", SDT_PIC16Store, [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; // Node to match a direct load operation. -def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>; -def PIC16LdWF : SDNode<"PIC16ISD::PIC16LdWF", SDT_PIC16Load, +def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>; +def PIC16LdArg : SDNode<"PIC16ISD::PIC16LdArg", SDT_PIC16Load, [SDNPHasChain]>; +def PIC16LdWF : SDNode<"PIC16ISD::PIC16LdWF", SDT_PIC16Load, [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; // Node to match PIC16 call @@ -267,6 +268,7 @@ def movf : MOVF_INSN<0, tglobaladdr, PIC16Load>; // Load from an ES. def movf_1 : MOVF_INSN<0, texternalsym, PIC16Load>; +def movf_1_1 : MOVF_INSN<0, texternalsym, PIC16LdArg>; // Load with InFlag and OutFlag // This is same as movf_1 but has a flag. A flag is required to