diff options
Diffstat (limited to 'llvm/lib/Target/Mips/MipsCallLowering.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MipsCallLowering.cpp | 124 |
1 files changed, 92 insertions, 32 deletions
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp index fd0f7921ba3..0cee6e732ec 100644 --- a/llvm/lib/Target/Mips/MipsCallLowering.cpp +++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp @@ -23,10 +23,10 @@ using namespace llvm; MipsCallLowering::MipsCallLowering(const MipsTargetLowering &TLI) : CallLowering(&TLI) {} -bool MipsCallLowering::MipsHandler::assign(unsigned VReg, - const CCValAssign &VA) { +bool MipsCallLowering::MipsHandler::assign(unsigned VReg, const CCValAssign &VA, + const EVT &VT) { if (VA.isRegLoc()) { - assignValueToReg(VReg, VA); + assignValueToReg(VReg, VA, VT); } else if (VA.isMemLoc()) { assignValueToAddress(VReg, VA); } else { @@ -37,9 +37,10 @@ bool MipsCallLowering::MipsHandler::assign(unsigned VReg, bool MipsCallLowering::MipsHandler::assignVRegs(ArrayRef<unsigned> VRegs, ArrayRef<CCValAssign> ArgLocs, - unsigned ArgLocsStartIndex) { + unsigned ArgLocsStartIndex, + const EVT &VT) { for (unsigned i = 0; i < VRegs.size(); ++i) - if (!assign(VRegs[i], ArgLocs[ArgLocsStartIndex + i])) + if (!assign(VRegs[i], ArgLocs[ArgLocsStartIndex + i], VT)) return false; return true; } @@ -71,10 +72,10 @@ bool MipsCallLowering::MipsHandler::handle( for (unsigned i = 0; i < SplitLength; ++i) VRegs.push_back(MRI.createGenericVirtualRegister(LLT{RegisterVT})); - if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Reg)) + if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Reg, VT)) return false; } else { - if (!assign(Args[ArgsIndex].Reg, ArgLocs[ArgLocsIndex])) + if (!assign(Args[ArgsIndex].Reg, ArgLocs[ArgLocsIndex], VT)) return false; } } @@ -88,7 +89,8 @@ public: : MipsHandler(MIRBuilder, MRI) {} private: - void assignValueToReg(unsigned ValVReg, const CCValAssign &VA) override; + void assignValueToReg(unsigned ValVReg, const CCValAssign &VA, + const EVT &VT) override; unsigned getStackAddress(const CCValAssign &VA, MachineMemOperand *&MMO) override; @@ -97,7 +99,7 @@ private: bool handleSplit(SmallVectorImpl<unsigned> &VRegs, ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex, - unsigned ArgsReg) override; + unsigned ArgsReg, const EVT &VT) override; virtual void markPhysRegUsed(unsigned PhysReg) { MIRBuilder.getMBB().addLiveIn(PhysReg); @@ -127,21 +129,47 @@ private: } // end anonymous namespace void IncomingValueHandler::assignValueToReg(unsigned ValVReg, - const CCValAssign &VA) { + const CCValAssign &VA, + const EVT &VT) { + const MipsSubtarget &STI = + static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget()); unsigned PhysReg = VA.getLocReg(); - switch (VA.getLocInfo()) { - case CCValAssign::LocInfo::SExt: - case CCValAssign::LocInfo::ZExt: - case CCValAssign::LocInfo::AExt: { - auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg); - MIRBuilder.buildTrunc(ValVReg, Copy); - break; - } - default: - MIRBuilder.buildCopy(ValVReg, PhysReg); - break; + if (VT == MVT::f64 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { + const MipsSubtarget &STI = + static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget()); + + MIRBuilder + .buildInstr(STI.isFP64bit() ? Mips::BuildPairF64_64 + : Mips::BuildPairF64) + .addDef(ValVReg) + .addUse(PhysReg + (STI.isLittle() ? 0 : 1)) + .addUse(PhysReg + (STI.isLittle() ? 1 : 0)) + .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(), + *STI.getRegBankInfo()); + markPhysRegUsed(PhysReg); + markPhysRegUsed(PhysReg + 1); + } else if (VT == MVT::f32 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { + MIRBuilder.buildInstr(Mips::MTC1) + .addDef(ValVReg) + .addUse(PhysReg) + .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(), + *STI.getRegBankInfo()); + markPhysRegUsed(PhysReg); + } else { + switch (VA.getLocInfo()) { + case CCValAssign::LocInfo::SExt: + case CCValAssign::LocInfo::ZExt: + case CCValAssign::LocInfo::AExt: { + auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg); + MIRBuilder.buildTrunc(ValVReg, Copy); + break; + } + default: + MIRBuilder.buildCopy(ValVReg, PhysReg); + break; + } + markPhysRegUsed(PhysReg); } - markPhysRegUsed(PhysReg); } unsigned IncomingValueHandler::getStackAddress(const CCValAssign &VA, @@ -180,8 +208,8 @@ void IncomingValueHandler::assignValueToAddress(unsigned ValVReg, bool IncomingValueHandler::handleSplit(SmallVectorImpl<unsigned> &VRegs, ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex, - unsigned ArgsReg) { - if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex)) + unsigned ArgsReg, const EVT &VT) { + if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex, VT)) return false; setLeastSignificantFirst(VRegs); MIRBuilder.buildMerge(ArgsReg, VRegs); @@ -196,7 +224,8 @@ public: : MipsHandler(MIRBuilder, MRI), MIB(MIB) {} private: - void assignValueToReg(unsigned ValVReg, const CCValAssign &VA) override; + void assignValueToReg(unsigned ValVReg, const CCValAssign &VA, + const EVT &VT) override; unsigned getStackAddress(const CCValAssign &VA, MachineMemOperand *&MMO) override; @@ -205,7 +234,7 @@ private: bool handleSplit(SmallVectorImpl<unsigned> &VRegs, ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex, - unsigned ArgsReg) override; + unsigned ArgsReg, const EVT &VT) override; unsigned extendRegister(unsigned ValReg, const CCValAssign &VA); @@ -214,11 +243,40 @@ private: } // end anonymous namespace void OutgoingValueHandler::assignValueToReg(unsigned ValVReg, - const CCValAssign &VA) { + const CCValAssign &VA, + const EVT &VT) { unsigned PhysReg = VA.getLocReg(); - unsigned ExtReg = extendRegister(ValVReg, VA); - MIRBuilder.buildCopy(PhysReg, ExtReg); - MIB.addUse(PhysReg, RegState::Implicit); + const MipsSubtarget &STI = + static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget()); + + if (VT == MVT::f64 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { + MIRBuilder + .buildInstr(STI.isFP64bit() ? Mips::ExtractElementF64_64 + : Mips::ExtractElementF64) + .addDef(PhysReg + (STI.isLittle() ? 1 : 0)) + .addUse(ValVReg) + .addImm(1) + .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(), + *STI.getRegBankInfo()); + MIRBuilder + .buildInstr(STI.isFP64bit() ? Mips::ExtractElementF64_64 + : Mips::ExtractElementF64) + .addDef(PhysReg + (STI.isLittle() ? 0 : 1)) + .addUse(ValVReg) + .addImm(0) + .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(), + *STI.getRegBankInfo()); + } else if (VT == MVT::f32 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { + MIRBuilder.buildInstr(Mips::MFC1) + .addDef(PhysReg) + .addUse(ValVReg) + .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(), + *STI.getRegBankInfo()); + } else { + unsigned ExtReg = extendRegister(ValVReg, VA); + MIRBuilder.buildCopy(PhysReg, ExtReg); + MIB.addUse(PhysReg, RegState::Implicit); + } } unsigned OutgoingValueHandler::getStackAddress(const CCValAssign &VA, @@ -286,10 +344,10 @@ unsigned OutgoingValueHandler::extendRegister(unsigned ValReg, bool OutgoingValueHandler::handleSplit(SmallVectorImpl<unsigned> &VRegs, ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex, - unsigned ArgsReg) { + unsigned ArgsReg, const EVT &VT) { MIRBuilder.buildUnmerge(VRegs, ArgsReg); setLeastSignificantFirst(VRegs); - if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex)) + if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex, VT)) return false; return true; @@ -300,6 +358,8 @@ static bool isSupportedType(Type *T) { return true; if (T->isPointerTy()) return true; + if (T->isFloatingPointTy()) + return true; return false; } |