diff options
Diffstat (limited to 'lib/Target/PIC16/PIC16ISelLowering.cpp')
-rw-r--r-- | lib/Target/PIC16/PIC16ISelLowering.cpp | 431 |
1 files changed, 214 insertions, 217 deletions
diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp index 0d24f61..bf986b1 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.cpp +++ b/lib/Target/PIC16/PIC16ISelLowering.cpp @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "pic16-lower" - #include "PIC16ISelLowering.h" +#include "PIC16TargetObjectFile.h" #include "PIC16TargetMachine.h" #include "llvm/DerivedTypes.h" #include "llvm/GlobalValue.h" @@ -23,6 +23,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Support/ErrorHandling.h" using namespace llvm; @@ -30,7 +31,7 @@ using namespace llvm; static const char *getIntrinsicName(unsigned opcode) { std::string Basename; switch(opcode) { - default: assert (0 && "do not know intrinsic name"); + default: llvm_unreachable("do not know intrinsic name"); // Arithmetic Right shift for integer types. case PIC16ISD::SRA_I8: Basename = "sra.i8"; break; case RTLIB::SRA_I16: Basename = "sra.i16"; break; @@ -114,22 +115,48 @@ static const char *getIntrinsicName(unsigned opcode) { std::string Fullname = prefix + tagname + Basename; // The name has to live through program life. - char *tmp = new char[Fullname.size() + 1]; - strcpy (tmp, Fullname.c_str()); - - return tmp; + return createESName(Fullname); +} + +// getStdLibCallName - Get the name for the standard library function. +static const char *getStdLibCallName(unsigned opcode) { + std::string BaseName; + switch(opcode) { + case RTLIB::COS_F32: BaseName = "cos"; + break; + case RTLIB::SIN_F32: BaseName = "sin"; + break; + case RTLIB::MEMCPY: BaseName = "memcpy"; + break; + case RTLIB::MEMSET: BaseName = "memset"; + break; + case RTLIB::MEMMOVE: BaseName = "memmove"; + break; + default: llvm_unreachable("do not know std lib call name"); + } + std::string prefix = PAN::getTagName(PAN::PREFIX_SYMBOL); + std::string LibCallName = prefix + BaseName; + + // The name has to live through program life. + return createESName(LibCallName); } // PIC16TargetLowering Constructor. PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM) - : TargetLowering(TM), TmpSize(0) { + : TargetLowering(TM, new PIC16TargetObjectFile()), TmpSize(0) { Subtarget = &TM.getSubtarget<PIC16Subtarget>(); addRegisterClass(MVT::i8, PIC16::GPRRegisterClass); setShiftAmountType(MVT::i8); - setShiftAmountFlavor(Extend); + + // Std lib call names + setLibcallName(RTLIB::COS_F32, getStdLibCallName(RTLIB::COS_F32)); + setLibcallName(RTLIB::SIN_F32, getStdLibCallName(RTLIB::SIN_F32)); + setLibcallName(RTLIB::MEMCPY, getStdLibCallName(RTLIB::MEMCPY)); + setLibcallName(RTLIB::MEMSET, getStdLibCallName(RTLIB::MEMSET)); + setLibcallName(RTLIB::MEMMOVE, getStdLibCallName(RTLIB::MEMMOVE)); // SRA library call names setPIC16LibcallName(PIC16ISD::SRA_I8, getIntrinsicName(PIC16ISD::SRA_I8)); @@ -226,6 +253,7 @@ PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM) setOperationAction(ISD::STORE, MVT::i8, Legal); setOperationAction(ISD::STORE, MVT::i16, Custom); setOperationAction(ISD::STORE, MVT::i32, Custom); + setOperationAction(ISD::STORE, MVT::i64, Custom); setOperationAction(ISD::ADDE, MVT::i8, Custom); setOperationAction(ISD::ADDC, MVT::i8, Custom); @@ -240,46 +268,27 @@ PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM) setOperationAction(ISD::XOR, MVT::i8, Custom); setOperationAction(ISD::FrameIndex, MVT::i16, Custom); - setOperationAction(ISD::CALL, MVT::i16, Custom); - setOperationAction(ISD::RET, MVT::Other, Custom); - setOperationAction(ISD::MUL, MVT::i8, Custom); - setOperationAction(ISD::MUL, MVT::i16, Expand); - setOperationAction(ISD::MUL, MVT::i32, Expand); + setOperationAction(ISD::MUL, MVT::i8, Custom); setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); - setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); - setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); - setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); - setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); setOperationAction(ISD::MULHU, MVT::i8, Expand); - setOperationAction(ISD::MULHU, MVT::i16, Expand); - setOperationAction(ISD::MULHU, MVT::i32, Expand); setOperationAction(ISD::MULHS, MVT::i8, Expand); - setOperationAction(ISD::MULHS, MVT::i16, Expand); - setOperationAction(ISD::MULHS, MVT::i32, Expand); setOperationAction(ISD::SRA, MVT::i8, Custom); - setOperationAction(ISD::SRA, MVT::i16, Expand); - setOperationAction(ISD::SRA, MVT::i32, Expand); setOperationAction(ISD::SHL, MVT::i8, Custom); - setOperationAction(ISD::SHL, MVT::i16, Expand); - setOperationAction(ISD::SHL, MVT::i32, Expand); setOperationAction(ISD::SRL, MVT::i8, Custom); - setOperationAction(ISD::SRL, MVT::i16, Expand); - setOperationAction(ISD::SRL, MVT::i32, Expand); + + setOperationAction(ISD::ROTL, MVT::i8, Expand); + setOperationAction(ISD::ROTR, MVT::i8, Expand); + + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); // PIC16 does not support shift parts - setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); - setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand); - setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); + setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); setOperationAction(ISD::SHL_PARTS, MVT::i8, Expand); - setOperationAction(ISD::SHL_PARTS, MVT::i16, Expand); - setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); setOperationAction(ISD::SRL_PARTS, MVT::i8, Expand); - setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand); - setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); // PIC16 does not have a SETCC, expand it to SELECT_CC. @@ -356,7 +365,8 @@ static void PopulateResults(SDValue N, SmallVectorImpl<SDValue>&Results) { Results.push_back(N); } -MVT PIC16TargetLowering::getSetCCResultType(MVT ValType) const { +MVT::SimpleValueType +PIC16TargetLowering::getSetCCResultType(EVT ValType) const { return MVT::i8; } @@ -379,7 +389,7 @@ PIC16TargetLowering::getPIC16LibcallName(PIC16ISD::PIC16Libcall Call) { SDValue PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, - MVT RetVT, const SDValue *Ops, + EVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, SelectionDAG &DAG, DebugLoc dl) { @@ -389,17 +399,20 @@ PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, TargetLowering::ArgListEntry Entry; for (unsigned i = 0; i != NumOps; ++i) { Entry.Node = Ops[i]; - Entry.Ty = Entry.Node.getValueType().getTypeForMVT(); + Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); Entry.isSExt = isSigned; Entry.isZExt = !isSigned; Args.push_back(Entry); } - SDValue Callee = DAG.getExternalSymbol(getPIC16LibcallName(Call), MVT::i8); - const Type *RetTy = RetVT.getTypeForMVT(); + SDValue Callee = DAG.getExternalSymbol(getPIC16LibcallName(Call), MVT::i16); + + const Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); std::pair<SDValue,SDValue> CallInfo = LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, - false, 0, CallingConv::C, false, Callee, Args, DAG, dl); + false, 0, CallingConv::C, false, + /*isReturnValueUsed=*/true, + Callee, Args, DAG, dl); return CallInfo.first; } @@ -429,6 +442,7 @@ const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const { case PIC16ISD::SUBCC: return "PIC16ISD::SUBCC"; case PIC16ISD::SELECT_ICC: return "PIC16ISD::SELECT_ICC"; case PIC16ISD::BRCOND: return "PIC16ISD::BRCOND"; + case PIC16ISD::RET: return "PIC16ISD::RET"; case PIC16ISD::Dummy: return "PIC16ISD::Dummy"; } } @@ -502,7 +516,7 @@ SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { SDValue Chain = St->getChain(); SDValue Src = St->getValue(); SDValue Ptr = St->getBasePtr(); - MVT ValueType = Src.getValueType(); + EVT ValueType = Src.getValueType(); unsigned StoreOffset = 0; DebugLoc dl = N->getDebugLoc(); @@ -519,6 +533,10 @@ SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { SDValue SrcLo, SrcHi; GetExpandedParts(Src, DAG, SrcLo, SrcHi); SDValue ChainLo = Chain, ChainHi = Chain; + // FIXME: This makes unsafe assumptions. The Chain may be a TokenFactor + // created for an unrelated purpose, in which case it may not have + // exactly two operands. Also, even if it does have two operands, they + // may not be the low and high parts of an aligned load that was split. if (Chain.getOpcode() == ISD::TokenFactor) { ChainLo = Chain.getOperand(0); ChainHi = Chain.getOperand(1); @@ -546,16 +564,19 @@ SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2); SDValue ChainLo = Chain, ChainHi = Chain; + // FIXME: This makes unsafe assumptions; see the FIXME above. if (Chain.getOpcode() == ISD::TokenFactor) { ChainLo = Chain.getOperand(0); ChainHi = Chain.getOperand(1); } SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi, ChainHi2 = ChainHi; + // FIXME: This makes unsafe assumptions; see the FIXME above. if (ChainLo.getOpcode() == ISD::TokenFactor) { ChainLo1 = ChainLo.getOperand(0); ChainLo2 = ChainLo.getOperand(1); } + // FIXME: This makes unsafe assumptions; see the FIXME above. if (ChainHi.getOpcode() == ISD::TokenFactor) { ChainHi1 = ChainHi.getOperand(0); ChainHi2 = ChainHi.getOperand(1); @@ -583,8 +604,26 @@ SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { getChain(Store3), getChain(Store4)); return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, RetLo, RetHi); - } - else { + } else if (ValueType == MVT::i64) { + SDValue SrcLo, SrcHi; + GetExpandedParts(Src, DAG, SrcLo, SrcHi); + SDValue ChainLo = Chain, ChainHi = Chain; + // FIXME: This makes unsafe assumptions; see the FIXME above. + if (Chain.getOpcode() == ISD::TokenFactor) { + ChainLo = Chain.getOperand(0); + ChainHi = Chain.getOperand(1); + } + SDValue Store1 = DAG.getStore(ChainLo, dl, SrcLo, Ptr, NULL, + 0 + StoreOffset); + + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, + DAG.getConstant(4, Ptr.getValueType())); + SDValue Store2 = DAG.getStore(ChainHi, dl, SrcHi, Ptr, NULL, + 1 + StoreOffset); + + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, + Store2); + } else { assert (0 && "value type not supported"); return SDValue(); } @@ -660,7 +699,7 @@ void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG, SDValue &Lo, SDValue &Hi) { SDNode *N = Op.getNode(); DebugLoc dl = N->getDebugLoc(); - MVT NewVT = getTypeToTransformTo(N->getValueType(0)); + EVT NewVT = getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); // Extract the lo component. Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NewVT, Op, @@ -808,7 +847,7 @@ SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { SDValue Load, Offset; SDVTList Tys; - MVT VT, NewVT; + EVT VT, NewVT; SDValue PtrLo, PtrHi; unsigned LoadOffset; @@ -821,7 +860,7 @@ SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { unsigned NumLoads = VT.getSizeInBits() / 8; std::vector<SDValue> PICLoads; unsigned iter; - MVT MemVT = LD->getMemoryVT(); + EVT MemVT = LD->getMemoryVT(); if(ISD::isNON_EXTLoad(N)) { for (iter=0; iter<NumLoads ; ++iter) { // Add the pointer offset if any @@ -839,7 +878,7 @@ SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { // For extended loads this is the memory value type // i.e. without any extension - MVT MemVT = LD->getMemoryVT(); + EVT MemVT = LD->getMemoryVT(); unsigned MemBytes = MemVT.getSizeInBits() / 8; // if MVT::i1 is extended to MVT::i8 then MemBytes will be zero // So set it to one @@ -945,6 +984,19 @@ SDValue PIC16TargetLowering::LowerShift(SDValue Op, SelectionDAG &DAG) { return Call; } +SDValue PIC16TargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) { + // We should have handled larger operands in type legalizer itself. + assert (Op.getValueType() == MVT::i8 && "illegal multiply to lower"); + + SDNode *N = Op.getNode(); + SmallVector<SDValue, 2> Ops(2); + Ops[0] = N->getOperand(0); + Ops[1] = N->getOperand(1); + SDValue Call = MakePIC16Libcall(PIC16ISD::MUL_I8, N->getValueType(0), + &Ops[0], 2, true, DAG, N->getDebugLoc()); + return Call; +} + void PIC16TargetLowering::LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue>&Results, @@ -953,12 +1005,8 @@ PIC16TargetLowering::LowerOperationWrapper(SDNode *N, SDValue Res; unsigned i; switch (Op.getOpcode()) { - case ISD::FORMAL_ARGUMENTS: - Res = LowerFORMAL_ARGUMENTS(Op, DAG); break; case ISD::LOAD: Res = ExpandLoad(Op.getNode(), DAG); break; - case ISD::CALL: - Res = LowerCALL(Op, DAG); break; default: { // All other operations are handled in LowerOperation. Res = LowerOperation(Op, DAG); @@ -978,8 +1026,6 @@ PIC16TargetLowering::LowerOperationWrapper(SDNode *N, SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { - case ISD::FORMAL_ARGUMENTS: - return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::ADD: case ISD::ADDC: case ISD::ADDE: @@ -992,6 +1038,8 @@ SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { return ExpandLoad(Op.getNode(), DAG); case ISD::STORE: return ExpandStore(Op.getNode(), DAG); + case ISD::MUL: + return LowerMUL(Op, DAG); case ISD::SHL: case ISD::SRA: case ISD::SRL: @@ -1000,10 +1048,6 @@ SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::AND: case ISD::XOR: return LowerBinOp(Op, DAG); - case ISD::CALL: - return LowerCALL(Op, DAG); - case ISD::RET: - return LowerRET(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::SELECT_CC: @@ -1048,12 +1092,12 @@ SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op, } SDValue PIC16TargetLowering:: -LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag, +LowerIndirectCallArguments(SDValue Chain, SDValue InFlag, SDValue DataAddr_Lo, SDValue DataAddr_Hi, - SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - unsigned NumOps = TheCall->getNumArgs(); - DebugLoc dl = TheCall->getDebugLoc(); + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG) { + unsigned NumOps = Outs.size(); // If call has no arguments then do nothing and return. if (NumOps == 0) @@ -1064,10 +1108,10 @@ LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag, SDValue Arg, StoreRet; // For PIC16 ABI the arguments come after the return value. - unsigned RetVals = TheCall->getNumRetVals(); + unsigned RetVals = Ins.size(); for (unsigned i = 0, ArgOffset = RetVals; i < NumOps; i++) { // Get the arguments - Arg = TheCall->getArg(i); + Arg = Outs[i].Val; Ops.clear(); Ops.push_back(Chain); @@ -1087,16 +1131,14 @@ LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag, } SDValue PIC16TargetLowering:: -LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel, - SDValue InFlag, SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - unsigned NumOps = TheCall->getNumArgs(); - DebugLoc dl = TheCall->getDebugLoc(); +LowerDirectCallArguments(SDValue ArgLabel, SDValue Chain, SDValue InFlag, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + unsigned NumOps = Outs.size(); std::string Name; SDValue Arg, StoreAt; - MVT ArgVT; + EVT ArgVT; unsigned Size=0; - unsigned ArgCount=0; // If call has no arguments then do nothing and return. if (NumOps == 0) @@ -1114,9 +1156,9 @@ LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel, std::vector<SDValue> Ops; SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); - for (unsigned i=ArgCount, Offset = 0; i<NumOps; i++) { + for (unsigned i=0, Offset = 0; i<NumOps; i++) { // Get the argument - Arg = TheCall->getArg(i); + Arg = Outs[i].Val; StoreOffset = (Offset + AddressOffset); // Store the argument on frame @@ -1144,12 +1186,12 @@ LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel, } SDValue PIC16TargetLowering:: -LowerIndirectCallReturn (SDValue Op, SDValue Chain, SDValue InFlag, - SDValue DataAddr_Lo, SDValue DataAddr_Hi, - SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - DebugLoc dl = TheCall->getDebugLoc(); - unsigned RetVals = TheCall->getNumRetVals(); +LowerIndirectCallReturn(SDValue Chain, SDValue InFlag, + SDValue DataAddr_Lo, SDValue DataAddr_Hi, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + unsigned RetVals = Ins.size(); // If call does not have anything to return // then do nothing and go back. @@ -1157,7 +1199,6 @@ LowerIndirectCallReturn (SDValue Op, SDValue Chain, SDValue InFlag, return Chain; // Call has something to return - std::vector<SDValue> ResultVals; SDValue LoadRet; SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag); @@ -1167,23 +1208,20 @@ LowerIndirectCallReturn (SDValue Op, SDValue Chain, SDValue InFlag, InFlag); InFlag = getOutFlag(LoadRet); Chain = getChain(LoadRet); - ResultVals.push_back(LoadRet); + InVals.push_back(LoadRet); } - ResultVals.push_back(Chain); - SDValue Res = DAG.getMergeValues(&ResultVals[0], ResultVals.size(), dl); - return Res; + return Chain; } SDValue PIC16TargetLowering:: -LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue RetLabel, - SDValue InFlag, SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - DebugLoc dl = TheCall->getDebugLoc(); +LowerDirectCallReturn(SDValue RetLabel, SDValue Chain, SDValue InFlag, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + // Currently handling primitive types only. They will come in // i8 parts - unsigned RetVals = TheCall->getNumRetVals(); - - std::vector<SDValue> ResultVals; + unsigned RetVals = Ins.size(); // Return immediately if the return type is void if (RetVals == 0) @@ -1209,30 +1247,20 @@ LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue RetLabel, Chain = getChain(LoadRet); Offset++; - ResultVals.push_back(LoadRet); + InVals.push_back(LoadRet); } - // To return use MERGE_VALUES - ResultVals.push_back(Chain); - SDValue Res = DAG.getMergeValues(&ResultVals[0], ResultVals.size(), dl); - return Res; + return Chain; } -SDValue PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { - SDValue Chain = Op.getOperand(0); - DebugLoc dl = Op.getDebugLoc(); - - if (Op.getNumOperands() == 1) // return void - return Op; +SDValue +PIC16TargetLowering::LowerReturn(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { - // 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); + unsigned NumRet = Outs.size(); // Function returns value always on stack with the offset starting // from 0 @@ -1246,68 +1274,13 @@ SDValue PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { SDValue BS = DAG.getConstant(1, MVT::i8); SDValue RetVal; for(unsigned i=0;i<NumRet; ++i) { - RetVal = Op.getNode()->getOperand(2*i + 1); + RetVal = Outs[i].Val; 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); -} - -// CALL node may have some operands non-legal to PIC16. Generate new CALL -// node with all the operands legal. -// Currently only Callee operand of the CALL node is non-legal. This function -// legalizes the Callee operand and uses all other operands as are to generate -// new CALL node. - -SDValue PIC16TargetLowering::LegalizeCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - DebugLoc dl = TheCall->getDebugLoc(); - unsigned i =0; - - assert(Callee.getValueType() == MVT::i16 && - "Don't know how to legalize this call node!!!"); - assert(Callee.getOpcode() == ISD::BUILD_PAIR && - "Don't know how to legalize this call node!!!"); - - if (isDirectAddress(Callee)) { - // Come here for direct calls - Callee = Callee.getOperand(0).getOperand(0); - } else { - // Come here for indirect calls - SDValue Lo, Hi; - // Indirect addresses. Get the hi and lo parts of ptr. - GetExpandedParts(Callee, DAG, Lo, Hi); - // Connect Lo and Hi parts of the callee with the PIC16Connect - Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Lo, Hi); - } - std::vector<SDValue> Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - - // Add the call arguments and their flags - unsigned NumArgs = TheCall->getNumArgs(); - for(i=0;i<NumArgs;i++) { - Ops.push_back(TheCall->getArg(i)); - Ops.push_back(TheCall->getArgFlagsVal(i)); - } - std::vector<MVT> NodeTys; - unsigned NumRets = TheCall->getNumRetVals(); - for(i=0;i<NumRets;i++) - NodeTys.push_back(TheCall->getRetValType(i)); - - // Return a Chain as well - NodeTys.push_back(MVT::Other); - - SDVTList VTs = DAG.getVTList(&NodeTys[0], NodeTys.size()); - // Generate new call with all the operands legal - return DAG.getCall(TheCall->getCallingConv(), dl, - TheCall->isVarArg(), TheCall->isTailCall(), - TheCall->isInreg(), VTs, &Ops[0], Ops.size(), - TheCall->getNumFixedArgs()); + return DAG.getNode(PIC16ISD::RET, dl, MVT::Other, Chain); } void PIC16TargetLowering:: @@ -1372,36 +1345,40 @@ GetDataAddress(DebugLoc dl, SDValue Callee, SDValue &Chain, DataAddr_Hi = DAG.getNode(PIC16ISD::MTHI, dl, MVT::i8, Call, OperFlag); } +SDValue +PIC16TargetLowering::LowerCall(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { -SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - DebugLoc dl = TheCall->getDebugLoc(); - if (Callee.getValueType() == MVT::i16 && - Callee.getOpcode() == ISD::BUILD_PAIR) { - // Control should come here only from TypeLegalizer for lowering - - // Legalize the non-legal arguments of call and return the - // new call with legal arguments. - return LegalizeCALL(Op, DAG); - } - // Control should come here from Legalize DAG. - // Here all the operands of CALL node should be legal. - - // If this is an indirect call then to pass the arguments - // and read the return value back, we need the data address - // of the function being called. - // To get the data address two more calls need to be made. + assert(Callee.getValueType() == MVT::i16 && + "Don't know how to legalize this call node!!!"); // The flag to track if this is a direct or indirect call. bool IsDirectCall = true; - unsigned RetVals = TheCall->getNumRetVals(); - unsigned NumArgs = TheCall->getNumArgs(); + unsigned RetVals = Ins.size(); + unsigned NumArgs = Outs.size(); SDValue DataAddr_Lo, DataAddr_Hi; - if (Callee.getOpcode() == PIC16ISD::PIC16Connect) { + if (!isa<GlobalAddressSDNode>(Callee) && + !isa<ExternalSymbolSDNode>(Callee)) { IsDirectCall = false; // This is indirect call + + // If this is an indirect call then to pass the arguments + // and read the return value back, we need the data address + // of the function being called. + // To get the data address two more calls need to be made. + + // Come here for indirect calls + SDValue Lo, Hi; + // Indirect addresses. Get the hi and lo parts of ptr. + GetExpandedParts(Callee, DAG, Lo, Hi); + // Connect Lo and Hi parts of the callee with the PIC16Connect + Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Lo, Hi); + // Read DataAddress only if we have to pass arguments or // read return value. if ((RetVals > 0) || (NumArgs > 0)) @@ -1457,12 +1434,13 @@ SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Pass the argument to function before making the call. SDValue CallArgs; if (IsDirectCall) { - CallArgs = LowerDirectCallArguments(Op, Chain, ArgLabel, OperFlag, DAG); + CallArgs = LowerDirectCallArguments(ArgLabel, Chain, OperFlag, + Outs, dl, DAG); Chain = getChain(CallArgs); OperFlag = getOutFlag(CallArgs); } else { - CallArgs = LowerIndirectCallArguments(Op, Chain, OperFlag, DataAddr_Lo, - DataAddr_Hi, DAG); + CallArgs = LowerIndirectCallArguments(Chain, OperFlag, DataAddr_Lo, + DataAddr_Hi, Outs, Ins, dl, DAG); Chain = getChain(CallArgs); OperFlag = getOutFlag(CallArgs); } @@ -1483,10 +1461,11 @@ SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Lower the return value reading after the call. if (IsDirectCall) - return LowerDirectCallReturn(Op, Chain, RetLabel, OperFlag, DAG); + return LowerDirectCallReturn(RetLabel, Chain, OperFlag, + Ins, dl, DAG, InVals); else - return LowerIndirectCallReturn(Op, Chain, OperFlag, DataAddr_Lo, - DataAddr_Hi, DAG); + return LowerIndirectCallReturn(Chain, OperFlag, DataAddr_Lo, + DataAddr_Hi, Ins, dl, DAG, InVals); } bool PIC16TargetLowering::isDirectLoad(const SDValue Op) { @@ -1591,11 +1570,20 @@ SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) { SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG, dl); SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag); - if (Op.getOpcode() == ISD::SUBE) - return DAG.getNode(Op.getOpcode(), dl, Tys, NewVal, Op.getOperand(1), - Op.getOperand(2)); - else - return DAG.getNode(Op.getOpcode(), dl, Tys, NewVal, Op.getOperand(1)); + switch (Op.getOpcode()) { + default: + assert (0 && "Opcode unknown."); + case ISD::SUBE: + return DAG.getNode(Op.getOpcode(), dl, Tys, NewVal, Op.getOperand(1), + Op.getOperand(2)); + break; + case ISD::SUBC: + return DAG.getNode(Op.getOpcode(), dl, Tys, NewVal, Op.getOperand(1)); + break; + case ISD::SUB: + return DAG.getNode(Op.getOpcode(), dl, MVT::i8, NewVal, Op.getOperand(1)); + break; + } } void PIC16TargetLowering::InitReservedFrameCount(const Function *F) { @@ -1609,17 +1597,19 @@ void PIC16TargetLowering::InitReservedFrameCount(const Function *F) { ReservedFrameCount = NumArgs + 1; } -// LowerFORMAL_ARGUMENTS - Argument values are loaded from the +// LowerFormalArguments - Argument values are loaded from the // <fname>.args + offset. All arguments are already broken to leaglized // types, so the offset just runs from 0 to NumArgVals - 1. -SDValue PIC16TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, - SelectionDAG &DAG) { - SmallVector<SDValue, 8> ArgValues; - unsigned NumArgVals = Op.getNode()->getNumValues() - 1; - DebugLoc dl = Op.getDebugLoc(); - SDValue Chain = Op.getOperand(0); // Formal arguments' chain - +SDValue +PIC16TargetLowering::LowerFormalArguments(SDValue Chain, + CallingConv::ID CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + unsigned NumArgVals = Ins.size(); // Get the callee's name to create the <fname>.args label to pass args. MachineFunction &MF = DAG.getMachineFunction(); @@ -1643,13 +1633,10 @@ SDValue PIC16TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SDValue PICLoad = DAG.getNode(PIC16ISD::PIC16LdArg, dl, VTs, Chain, ES, BS, Offset); Chain = getChain(PICLoad); - ArgValues.push_back(PICLoad); + InVals.push_back(PICLoad); } - // Return a MERGE_VALUE node. - ArgValues.push_back(Op.getOperand(0)); - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } // Perform DAGCombine of PIC16Load. @@ -1697,7 +1684,7 @@ SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N, static PIC16CC::CondCodes IntCCToPIC16CC(ISD::CondCode CC) { switch (CC) { - default: assert(0 && "Unknown condition code!"); + default: llvm_unreachable("Unknown condition code!"); case ISD::SETNE: return PIC16CC::NE; case ISD::SETEQ: return PIC16CC::EQ; case ISD::SETGT: return PIC16CC::GT; @@ -1826,7 +1813,8 @@ SDValue PIC16TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { MachineBasicBlock * PIC16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB) const { + MachineBasicBlock *BB, + DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const { const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); unsigned CC = (PIC16CC::CondCodes)MI->getOperand(3).getImm(); DebugLoc dl = MI->getDebugLoc(); @@ -1852,9 +1840,18 @@ PIC16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, F->insert(It, copy0MBB); F->insert(It, sinkMBB); - // Update machine-CFG edges by transferring all successors of the current + // Update machine-CFG edges by first adding all successors of the current // block to the new block which will contain the Phi node for the select. - sinkMBB->transferSuccessors(BB); + // Also inform sdisel of the edge changes. + for (MachineBasicBlock::succ_iterator I = BB->succ_begin(), + E = BB->succ_end(); I != E; ++I) { + EM->insert(std::make_pair(*I, sinkMBB)); + sinkMBB->addSuccessor(*I); + } + // Next, remove all successors of the current block, and add the true + // and fallthrough blocks as its successors. + while (!BB->succ_empty()) + BB->removeSuccessor(BB->succ_begin()); // Next, add the true and fallthrough blocks as its successors. BB->addSuccessor(copy0MBB); BB->addSuccessor(sinkMBB); |