diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp index 5c4b353294c..84cf3121c15 100644 --- a/lib/Target/PIC16/PIC16AsmPrinter.cpp +++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp @@ -227,6 +227,11 @@ void PIC16AsmPrinter::EmitExternsAndGlobals (Module &M) { std::string Name = Mang->getValueName(I); if (Name.compare("abort") == 0) continue; + + // If it is llvm intrinsic call then don't emit + if (Name.find("llvm.") != std::string::npos) + continue; + if (I->isDeclaration()) { O << "\textern " <GetTmpSize(); + if (TempSize > 0 ) + O << CurrentFnName << ".tmp RES " << TempSize <<"\n"; + // Emit the function variables. // In PIC16 all the function arguments and local variables are global. @@ -423,7 +433,4 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { O << VarName << " RES " << Size << "\n"; } - int TempSize = PTLI->GetTmpSize(); - if (TempSize > 0 ) - O << CurrentFnName << ".tmp RES " << TempSize <<"\n"; } diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp index e1544a00f03..cc7ce5557fe 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.cpp +++ b/lib/Target/PIC16/PIC16ISelLowering.cpp @@ -326,10 +326,14 @@ SDValue PIC16TargetLowering::ExpandFrameIndex(SDNode *N, SelectionDAG &DAG) { DebugLoc dl = FR->getDebugLoc(); int Index = FR->getIndex(); - SDValue FI[2]; - FI[0] = DAG.getTargetFrameIndex(Index, MVT::i8); - FI[1] = DAG.getTargetFrameIndex(Index + 1, MVT::i8); - return DAG.getNode(ISD::BUILD_PAIR, dl, N->getValueType(0), FI[0], FI[1]); + // Expand FrameIndex like GlobalAddress and ExternalSymbol + // Also use Offset field for lo and hi parts. The default + // offset is zero. + SDValue Offset = DAG.getConstant(0, MVT::i8); + SDValue FI = DAG.getTargetFrameIndex(Index, MVT::i8); + SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, FI, Offset); + SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, FI, Offset); + return DAG.getNode(ISD::BUILD_PAIR, dl, N->getValueType(0), Lo, Hi); } @@ -433,9 +437,9 @@ SDValue PIC16TargetLowering::ExpandExternalSymbol(SDNode *N, SelectionDAG &DAG) DebugLoc dl = ES->getDebugLoc(); SDValue TES = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8); - - SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TES); - SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TES); + SDValue Offset = DAG.getConstant(0, MVT::i8); + SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TES, Offset); + SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TES, Offset); return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, Lo, Hi); } @@ -449,8 +453,9 @@ SDValue PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) { SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8, G->getOffset()); - SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TGA); - SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TGA); + SDValue Offset = DAG.getConstant(0, MVT::i8); + SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TGA, Offset); + SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TGA, Offset); return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, Lo, Hi); } @@ -587,14 +592,16 @@ void PIC16TargetLowering::LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, } } - if (Ptr.getOpcode() == ISD::BUILD_PAIR && - Ptr.getOperand(0).getOpcode() == ISD::TargetFrameIndex) { - - int FrameOffset; - LegalizeFrameIndex(Ptr.getOperand(0), DAG, Lo, FrameOffset); - Hi = DAG.getConstant(1, MVT::i8); - Offset += FrameOffset; - return; + // Expansion of FrameIndex has Lo/Hi parts + if (isDirectAddress(Ptr)) { + SDValue TFI = Ptr.getOperand(0).getOperand(0); + if (TFI.getOpcode() == ISD::TargetFrameIndex) { + int FrameOffset; + LegalizeFrameIndex(TFI, DAG, Lo, FrameOffset); + Hi = DAG.getConstant(1, MVT::i8); + Offset += FrameOffset; + return; + } } if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) { @@ -884,6 +891,12 @@ LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag, for (unsigned i = 0, ArgOffset = RetVals; i < NumOps; i++) { // Get the arguments Arg = TheCall->getArg(i); + // If argument is FrameIndex then map it with temporary + if (Arg.getOpcode() == PIC16ISD::Lo || Arg.getOpcode() == PIC16ISD::Hi) { + if (Arg.getOperand(0).getOpcode() == ISD::TargetFrameIndex) { + Arg = LegalizeFrameArgument(Arg, dl, DAG); + } + } Ops.clear(); Ops.push_back(Chain); Ops.push_back(Arg); @@ -900,9 +913,39 @@ LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag, } return Chain; } - + SDValue PIC16TargetLowering:: -LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue FrameAddress, +LegalizeFrameArgument(SDValue Arg, DebugLoc dl, SelectionDAG &DAG) { + MachineFunction &MF = DAG.getMachineFunction(); + const Function *Func = MF.getFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + const std::string Name = Func->getName(); + + // Caller creates the stack storage to pass the aggregate type + // as argument. So it should be relative to tmp variable. + SDValue FI = Arg.getOperand(0); + char *tmpName = new char [strlen(Name.c_str()) + 8]; + sprintf(tmpName, "%s.tmp", Name.c_str()); + SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); + FrameIndexSDNode *FR = dyn_cast(FI); + + unsigned FIndex = FR->getIndex(); + // Reserve space in tmp variable for the aggregate type + int FrameOffset = GetTmpOffsetForFI(FIndex, MFI->getObjectSize(FIndex)); + + if (Arg.getOpcode() == PIC16ISD::Lo) { + // Lo part of frame index + SDValue FrameConst = DAG.getConstant(FrameOffset, MVT::i8); + return DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, ES, FrameConst); + } else { + // Hi part of frame index + SDValue FrameConst = DAG.getConstant(FrameOffset + 1, MVT::i8); + return DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, ES, FrameConst); + } +} + +SDValue PIC16TargetLowering:: +LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel, SDValue InFlag, SelectionDAG &DAG) { CallSDNode *TheCall = dyn_cast(Op); unsigned NumOps = TheCall->getNumArgs(); @@ -924,7 +967,7 @@ LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue FrameAddress, SDValue PtrLo, PtrHi; unsigned AddressOffset; int StoreOffset = 0; - LegalizeAddress(FrameAddress, DAG, PtrLo, PtrHi, AddressOffset, dl); + LegalizeAddress(ArgLabel, DAG, PtrLo, PtrHi, AddressOffset, dl); SDValue StoreRet; std::vector Ops; @@ -932,7 +975,12 @@ LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue FrameAddress, for (unsigned i=ArgCount, Offset = 0; igetArg(i); - + // If argument is FrameIndex then map it with temporary + if (Arg.getOpcode() == PIC16ISD::Lo || Arg.getOpcode() == PIC16ISD::Hi) { + if (Arg.getOperand(0).getOpcode() == ISD::TargetFrameIndex) { + Arg = LegalizeFrameArgument(Arg, dl, DAG); + } + } StoreOffset = (Offset + AddressOffset); // Store the argument on frame @@ -991,7 +1039,7 @@ LowerIndirectCallReturn (SDValue Op, SDValue Chain, SDValue InFlag, } SDValue PIC16TargetLowering:: -LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue FrameAddress, +LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue RetLabel, SDValue InFlag, SelectionDAG &DAG) { CallSDNode *TheCall = dyn_cast(Op); DebugLoc dl = TheCall->getDebugLoc(); @@ -1010,7 +1058,7 @@ LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue FrameAddress, // Legalize the address before use SDValue LdLo, LdHi; unsigned LdOffset; - LegalizeAddress(FrameAddress, DAG, LdLo, LdHi, LdOffset, dl); + LegalizeAddress(RetLabel, DAG, LdLo, LdHi, LdOffset, dl); SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag); SDValue LoadRet; @@ -1698,4 +1746,3 @@ SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) { Cmp.getValue(1)); } - diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h index 03397beab18..d94f02bb8d4 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.h +++ b/lib/Target/PIC16/PIC16ISelLowering.h @@ -168,6 +168,8 @@ namespace llvm { void LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG, SDValue &ES, int &Offset); + SDValue LegalizeFrameArgument(SDValue Arg, DebugLoc dl, SelectionDAG &DAG); + // CALL node should have all legal operands only. Legalize all non-legal // operands of CALL node and then return the new call will all operands // legal. diff --git a/lib/Target/PIC16/PIC16InstrInfo.td b/lib/Target/PIC16/PIC16InstrInfo.td index abdabc68ca9..8f902594da1 100644 --- a/lib/Target/PIC16/PIC16InstrInfo.td +++ b/lib/Target/PIC16/PIC16InstrInfo.td @@ -72,10 +72,10 @@ def PIC16callseq_end : SDNode<"ISD::CALLSEQ_END", SDTI8VoidOp, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; // Low 8-bits of GlobalAddress. -def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8UnaryOp>; +def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8BinOp>; // High 8-bits of GlobalAddress. -def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8UnaryOp>; +def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8BinOp>; // The MTHI and MTLO nodes are used only to match them in the incoming // DAG for replacement by corresponding set_fsrhi, set_fsrlo insntructions. @@ -187,14 +187,24 @@ def movlw : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src), [(set GPR:$dst, (i8 imm:$src))]>; // Move a Lo(TGA) to W. -def movlw_lo : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src), - "movlw LOW(${src})", - [(set GPR:$dst, (PIC16Lo tglobaladdr:$src))]>; +def movlw_lo_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), + "movlw LOW(${src}) + ${src2}", + [(set GPR:$dst, (PIC16Lo tglobaladdr:$src, imm:$src2 ))]>; + +// Move a Lo(TES) to W. +def movlw_lo_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), + "movlw LOW(${src}) + ${src2}", + [(set GPR:$dst, (PIC16Lo texternalsym:$src, imm:$src2 ))]>; // Move a Hi(TGA) to W. -def movlw_hi : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src), - "movlw HIGH(${src})", - [(set GPR:$dst, (PIC16Hi tglobaladdr:$src))]>; +def movlw_hi_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), + "movlw HIGH(${src}) + ${src2}", + [(set GPR:$dst, (PIC16Hi tglobaladdr:$src, imm:$src2))]>; + +// Move a Hi(TES) to W. +def movlw_hi_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), + "movlw HIGH(${src}) + ${src2}", + [(set GPR:$dst, (PIC16Hi texternalsym:$src, imm:$src2))]>; } //-------------------