diff options
Diffstat (limited to 'lib/Target/MSP430')
-rw-r--r-- | lib/Target/MSP430/MSP430BranchSelector.cpp | 4 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430CallingConv.td | 8 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 4 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430ISelLowering.cpp | 87 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430ISelLowering.h | 6 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430MCInstLower.cpp | 2 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430MachineFunctionInfo.h | 10 |
7 files changed, 92 insertions, 29 deletions
diff --git a/lib/Target/MSP430/MSP430BranchSelector.cpp b/lib/Target/MSP430/MSP430BranchSelector.cpp index 5fd6b6305f68..424b5ae418f7 100644 --- a/lib/Target/MSP430/MSP430BranchSelector.cpp +++ b/lib/Target/MSP430/MSP430BranchSelector.cpp @@ -194,8 +194,8 @@ bool MSP430BSel::expandBranches(OffsetVector &BlockOffsets) { // Jump over the long branch on the opposite condition TII->reverseBranchCondition(Cond); MI = BuildMI(*MBB, MI, dl, TII->get(MSP430::JCC)) - .addMBB(NextMBB) - .addOperand(Cond[0]); + .addMBB(NextMBB) + .add(Cond[0]); InstrSizeDiff += TII->getInstSizeInBytes(*MI); ++MI; } diff --git a/lib/Target/MSP430/MSP430CallingConv.td b/lib/Target/MSP430/MSP430CallingConv.td index b38f5781c84a..0434f8abfbf4 100644 --- a/lib/Target/MSP430/MSP430CallingConv.td +++ b/lib/Target/MSP430/MSP430CallingConv.td @@ -13,11 +13,11 @@ // MSP430 Return Value Calling Convention //===----------------------------------------------------------------------===// def RetCC_MSP430 : CallingConv<[ - // i8 are returned in registers R15B, R14B, R13B, R12B - CCIfType<[i8], CCAssignToReg<[R15B, R14B, R13B, R12B]>>, + // i8 are returned in registers R12B, R13B, R14B, R15B + CCIfType<[i8], CCAssignToReg<[R12B, R13B, R14B, R15B]>>, - // i16 are returned in registers R15, R14, R13, R12 - CCIfType<[i16], CCAssignToReg<[R15, R14, R13, R12]>> + // i16 are returned in registers R12, R13, R14, R15 + CCIfType<[i16], CCAssignToReg<[R12, R13, R14, R15]>> ]>; //===----------------------------------------------------------------------===// diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp index 6e481b68e038..cd58eda5d924 100644 --- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp +++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp @@ -61,7 +61,8 @@ namespace { return GV != nullptr || CP != nullptr || ES != nullptr || JT != -1; } - void dump() { +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + LLVM_DUMP_METHOD void dump() { errs() << "MSP430ISelAddressMode " << this << '\n'; if (BaseType == RegBase && Base.Reg.getNode() != nullptr) { errs() << "Base.Reg "; @@ -83,6 +84,7 @@ namespace { } else if (JT != -1) errs() << " JT" << JT << " Align" << Align << '\n'; } +#endif }; } diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index 73346b9ce41d..40b1dd3cc2eb 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -245,13 +245,20 @@ MSP430TargetLowering::getRegForInlineAsmConstraint( template<typename ArgT> static void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args, SmallVectorImpl<unsigned> &Out) { - unsigned CurrentArgIndex = ~0U; - for (unsigned i = 0, e = Args.size(); i != e; i++) { - if (CurrentArgIndex == Args[i].OrigArgIndex) { - Out.back()++; + unsigned CurrentArgIndex; + + if (Args.empty()) + return; + + CurrentArgIndex = Args[0].OrigArgIndex; + Out.push_back(0); + + for (auto &Arg : Args) { + if (CurrentArgIndex == Arg.OrigArgIndex) { + Out.back() += 1; } else { Out.push_back(1); - CurrentArgIndex++; + CurrentArgIndex = Arg.OrigArgIndex; } } } @@ -275,7 +282,7 @@ static void AnalyzeArguments(CCState &State, SmallVectorImpl<CCValAssign> &ArgLocs, const SmallVectorImpl<ArgT> &Args) { static const MCPhysReg RegList[] = { - MSP430::R15, MSP430::R14, MSP430::R13, MSP430::R12 + MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15 }; static const unsigned NbRegs = array_lengthof(RegList); @@ -288,7 +295,7 @@ static void AnalyzeArguments(CCState &State, ParseFunctionArgs(Args, ArgsParts); unsigned RegsLeft = NbRegs; - bool UseStack = false; + bool UsedStack = false; unsigned ValNo = 0; for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) { @@ -316,20 +323,22 @@ static void AnalyzeArguments(CCState &State, unsigned Parts = ArgsParts[i]; - if (!UseStack && Parts <= RegsLeft) { - unsigned FirstVal = ValNo; + if (!UsedStack && Parts == 2 && RegsLeft == 1) { + // Special case for 32-bit register split, see EABI section 3.3.3 + unsigned Reg = State.AllocateReg(RegList); + State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo)); + RegsLeft -= 1; + + UsedStack = true; + CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State); + } else if (Parts <= RegsLeft) { for (unsigned j = 0; j < Parts; j++) { unsigned Reg = State.AllocateReg(RegList); State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo)); RegsLeft--; } - - // Reverse the order of the pieces to agree with the "big endian" format - // required in the calling convention ABI. - SmallVectorImpl<CCValAssign>::iterator B = ArgLocs.begin() + FirstVal; - std::reverse(B, B + Parts); } else { - UseStack = true; + UsedStack = true; for (unsigned j = 0; j < Parts; j++) CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State); } @@ -351,10 +360,6 @@ static void AnalyzeReturnValues(CCState &State, SmallVectorImpl<CCValAssign> &RVLocs, const SmallVectorImpl<ArgT> &Args) { AnalyzeRetResult(State, Args); - - // Reverse splitted return values to get the "big endian" format required - // to agree with the calling convention ABI. - std::reverse(RVLocs.begin(), RVLocs.end()); } SDValue MSP430TargetLowering::LowerFormalArguments( @@ -496,9 +501,33 @@ SDValue MSP430TargetLowering::LowerCCCArguments( } } + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { + if (Ins[i].Flags.isSRet()) { + unsigned Reg = FuncInfo->getSRetReturnReg(); + if (!Reg) { + Reg = MF.getRegInfo().createVirtualRegister( + getRegClassFor(MVT::i16)); + FuncInfo->setSRetReturnReg(Reg); + } + SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[i]); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); + } + } + return Chain; } +bool +MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv, + MachineFunction &MF, + bool IsVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + LLVMContext &Context) const { + SmallVector<CCValAssign, 16> RVLocs; + CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); + return CCInfo.CheckReturn(Outs, RetCC_MSP430); +} + SDValue MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, @@ -506,6 +535,8 @@ MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl, SelectionDAG &DAG) const { + MachineFunction &MF = DAG.getMachineFunction(); + // CCValAssign - represent the assignment of the return value to a location SmallVector<CCValAssign, 16> RVLocs; @@ -537,6 +568,22 @@ MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); } + if (MF.getFunction()->hasStructRetAttr()) { + MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); + unsigned Reg = FuncInfo->getSRetReturnReg(); + + if (!Reg) + llvm_unreachable("sret virtual register not created in entry block"); + + SDValue Val = + DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy(DAG.getDataLayout())); + unsigned R12 = MSP430::R12; + + Chain = DAG.getCopyToReg(Chain, dl, R12, Val, Flag); + Flag = Chain.getValue(1); + RetOps.push_back(DAG.getRegister(R12, getPointerTy(DAG.getDataLayout()))); + } + unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); @@ -1219,7 +1266,7 @@ MSP430TargetLowering::EmitShiftInstr(MachineInstr &MI, BB->end()); RemBB->transferSuccessorsAndUpdatePHIs(BB); - // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB + // Add edges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB BB->addSuccessor(LoopBB); BB->addSuccessor(RemBB); LoopBB->addSuccessor(RemBB); diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h index 8864807e999e..3a729623c99a 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.h +++ b/lib/Target/MSP430/MSP430ISelLowering.h @@ -158,6 +158,12 @@ namespace llvm { LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const override; + bool CanLowerReturn(CallingConv::ID CallConv, + MachineFunction &MF, + bool IsVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + LLVMContext &Context) const override; + SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, diff --git a/lib/Target/MSP430/MSP430MCInstLower.cpp b/lib/Target/MSP430/MSP430MCInstLower.cpp index 47b0e270c5b3..e7716382b222 100644 --- a/lib/Target/MSP430/MSP430MCInstLower.cpp +++ b/lib/Target/MSP430/MSP430MCInstLower.cpp @@ -119,7 +119,7 @@ void MSP430MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { MCOperand MCOp; switch (MO.getType()) { default: - MI->dump(); + MI->print(errs()); llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: // Ignore all implicit register operands. diff --git a/lib/Target/MSP430/MSP430MachineFunctionInfo.h b/lib/Target/MSP430/MSP430MachineFunctionInfo.h index 2d937318c7e5..fcaa8a1d6c72 100644 --- a/lib/Target/MSP430/MSP430MachineFunctionInfo.h +++ b/lib/Target/MSP430/MSP430MachineFunctionInfo.h @@ -33,15 +33,23 @@ class MSP430MachineFunctionInfo : public MachineFunctionInfo { /// VarArgsFrameIndex - FrameIndex for start of varargs area. int VarArgsFrameIndex; + /// SRetReturnReg - Some subtargets require that sret lowering includes + /// returning the value of the returned struct in a register. This field + /// holds the virtual register into which the sret argument is passed. + unsigned SRetReturnReg; + public: MSP430MachineFunctionInfo() : CalleeSavedFrameSize(0) {} explicit MSP430MachineFunctionInfo(MachineFunction &MF) - : CalleeSavedFrameSize(0), ReturnAddrIndex(0) {} + : CalleeSavedFrameSize(0), ReturnAddrIndex(0), SRetReturnReg(0) {} unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; } void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; } + unsigned getSRetReturnReg() const { return SRetReturnReg; } + void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; } + int getRAIndex() const { return ReturnAddrIndex; } void setRAIndex(int Index) { ReturnAddrIndex = Index; } |