diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index c3714b53102c..dad478e5c5c2 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -185,6 +185,7 @@ def MFHI64 : MoveFromLOHI<"mfhi", GPR64Opnd, AC0_64>, MFLO_FM<0x10>; def MFLO64 : MoveFromLOHI<"mflo", GPR64Opnd, AC0_64>, MFLO_FM<0x12>; def PseudoMFHI64 : PseudoMFLOHI; def PseudoMFLO64 : PseudoMFLOHI; +def PseudoMTLOHI64 : PseudoMTLOHI; /// Sign Ext In Register Instructions. def SEB64 : SignExtInReg<"seb", i8, GPR64Opnd>, SEB_FM<0x10, 0x20>; diff --git a/llvm/lib/Target/Mips/MipsDSPInstrInfo.td b/llvm/lib/Target/Mips/MipsDSPInstrInfo.td index fd4ab5a292c3..d26838404451 100644 --- a/llvm/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsDSPInstrInfo.td @@ -1269,6 +1269,8 @@ def PseudoCMPU_LE_QB : PseudoCMP; def PseudoPICK_PH : PseudoPICK; def PseudoPICK_QB : PseudoPICK; +def PseudoMTLOHI_DSP : PseudoMTLOHI; + // Patterns. class DSPPat : Pat, Requires<[pred]>; diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 842aab08d0d0..44495ff134ac 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -25,8 +25,7 @@ def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>; def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, - SDTCisVT<1, i32>, - SDTCisSameAs<1, 2>]>; + SDTCisInt<1>, SDTCisSameAs<1, 2>]>; def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>, SDTCisSameAs<1, 2>]>; def SDT_MipsMAddMSub : SDTypeProfile<1, 3, @@ -710,6 +709,10 @@ class MoveFromLOHI: let neverHasSideEffects = 1; } +class PseudoMTLOHI + : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi), + [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))], IIHiLo>; + class MoveToLOHI DefRegs>: InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], IIHiLo, FrmR, opstr> { @@ -1069,6 +1072,7 @@ def PseudoMULT : MultDivPseudo; def PseudoMULTu : MultDivPseudo; def PseudoMFHI : PseudoMFLOHI; def PseudoMFLO : PseudoMFLOHI; +def PseudoMTLOHI : PseudoMTLOHI; def PseudoMADD : MAddSubPseudo; def PseudoMADDU : MAddSubPseudo; def PseudoMSUB : MAddSubPseudo; diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 412571e54b1f..0a82a3a83fbd 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -684,19 +684,6 @@ std::pair MipsSEDAGToDAGISel::selectNode(SDNode *Node) { return std::make_pair(true, ResNode.getNode()); } - case MipsISD::MTLOHI: { - unsigned RCID = Subtarget.hasDSP() ? Mips::ACC64DSPRegClassID : - Mips::ACC64RegClassID; - SDValue RegClass = CurDAG->getTargetConstant(RCID, MVT::i32); - SDValue LoIdx = CurDAG->getTargetConstant(Mips::sub_lo, MVT::i32); - SDValue HiIdx = CurDAG->getTargetConstant(Mips::sub_hi, MVT::i32); - const SDValue Ops[] = { RegClass, Node->getOperand(0), LoIdx, - Node->getOperand(1), HiIdx }; - SDNode *Res = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, - MVT::Untyped, Ops); - return std::make_pair(true, Res); - } - case ISD::BUILD_VECTOR: { // Select appropriate ldi.[bhwd] instructions for constant splats of // 128-bit when MSA is enabled. Fixup any register class mismatches that diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp index ef88a63066cd..2f793348c67f 100644 --- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -278,6 +278,15 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { case Mips::PseudoMFLO64: expandPseudoMFHiLo(MBB, MI, Mips::MFLO64); break; + case Mips::PseudoMTLOHI: + expandPseudoMTLoHi(MBB, MI, Mips::MTLO, Mips::MTHI, false); + break; + case Mips::PseudoMTLOHI64: + expandPseudoMTLoHi(MBB, MI, Mips::MTLO64, Mips::MTHI64, false); + break; + case Mips::PseudoMTLOHI_DSP: + expandPseudoMTLoHi(MBB, MI, Mips::MTLO_DSP, Mips::MTHI_DSP, true); + break; case Mips::PseudoCVT_S_W: expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false); break; @@ -432,6 +441,35 @@ void MipsSEInstrInfo::expandPseudoMFHiLo(MachineBasicBlock &MBB, BuildMI(MBB, I, I->getDebugLoc(), get(NewOpc), I->getOperand(0).getReg()); } +void MipsSEInstrInfo::expandPseudoMTLoHi(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned LoOpc, + unsigned HiOpc, + bool HasExplicitDef) const { + // Expand + // lo_hi pseudomtlohi $gpr0, $gpr1 + // to these two instructions: + // mtlo $gpr0 + // mthi $gpr1 + + DebugLoc DL = I->getDebugLoc(); + const MachineOperand &SrcLo = I->getOperand(1), &SrcHi = I->getOperand(2); + MachineInstrBuilder LoInst = BuildMI(MBB, I, DL, get(LoOpc)); + MachineInstrBuilder HiInst = BuildMI(MBB, I, DL, get(HiOpc)); + LoInst.addReg(SrcLo.getReg(), getKillRegState(SrcLo.isKill())); + HiInst.addReg(SrcHi.getReg(), getKillRegState(SrcHi.isKill())); + + // Add lo/hi registers if the mtlo/hi instructions created have explicit + // def registers. + if (HasExplicitDef) { + unsigned DstReg = I->getOperand(0).getReg(); + unsigned DstLo = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo); + unsigned DstHi = getRegisterInfo().getSubReg(DstReg, Mips::sub_hi); + LoInst.addReg(DstLo, RegState::Define); + HiInst.addReg(DstHi, RegState::Define); + } +} + void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned CvtOpc, unsigned MovOpc, diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.h b/llvm/lib/Target/Mips/MipsSEInstrInfo.h index 6a678456c5b8..6d2dd901f33b 100644 --- a/llvm/lib/Target/Mips/MipsSEInstrInfo.h +++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.h @@ -90,6 +90,10 @@ private: void expandPseudoMFHiLo(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned NewOpc) const; + void expandPseudoMTLoHi(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, + unsigned LoOpc, unsigned HiOpc, + bool HasExplicitDef) const; + /// Expand pseudo Int-to-FP conversion instructions. /// /// For example, the following pseudo instruction