aboutsummaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/PIC16/PIC16AsmPrinter.cpp59
-rw-r--r--lib/Target/PIC16/PIC16AsmPrinter.h1
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.cpp104
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.h16
-rw-r--r--lib/Target/PIC16/PIC16InstrInfo.td6
5 files changed, 133 insertions, 53 deletions
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp
index 3696d5afeb..6a5c2e0371 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<Module *>(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"<< " "
- <<indexEnd - indexBegin <<"\n";
- }
- /*
- while (indexBegin < indexEnd) {
- O << CurrentFnName << "_tmp_" << indexBegin << " " << "RES"<< " "
- << 1 << "\n" ;
- indexBegin++;
+ // Emit the variable to hold the space for temporary locations
+ // in function frame.
+ if (MFI->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 5479717a45..5286dd2e7a 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 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();
diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h
index 75e824a0a6..b2a89db3ea 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 40119d0a89..471180fa49 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