[mips] Define a pseudo instruction which writes to both the lower and higher
authorAkira Hatanaka <ahatanaka@mips.com>
Tue, 15 Oct 2013 01:48:30 +0000 (01:48 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Tue, 15 Oct 2013 01:48:30 +0000 (01:48 +0000)
parts of the accumulators and gets expanded post-RA.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192667 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/Mips64InstrInfo.td
lib/Target/Mips/MipsDSPInstrInfo.td
lib/Target/Mips/MipsInstrInfo.td
lib/Target/Mips/MipsSEISelDAGToDAG.cpp
lib/Target/Mips/MipsSEInstrInfo.cpp
lib/Target/Mips/MipsSEInstrInfo.h

index c3714b53102cf63bc5f1c9a3b3b61a1b38f7d683..dad478e5c5c2641171efea31a3ac7079e46e9c3f 100644 (file)
@@ -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<GPR64, ACC128, MipsMFHI>;
 def PseudoMFLO64 : PseudoMFLOHI<GPR64, ACC128, MipsMFLO>;
+def PseudoMTLOHI64 : PseudoMTLOHI<ACC128, GPR64>;
 
 /// Sign Ext In Register Instructions.
 def SEB64 : SignExtInReg<"seb", i8, GPR64Opnd>, SEB_FM<0x10, 0x20>;
index fd4ab5a292c3363000265b571f47d5e13ba79ee9..d26838404451428e7d199e434f4bd6b8212d5000 100644 (file)
@@ -1269,6 +1269,8 @@ def PseudoCMPU_LE_QB : PseudoCMP<CMPU_LE_QB>;
 def PseudoPICK_PH : PseudoPICK<PICK_PH>;
 def PseudoPICK_QB : PseudoPICK<PICK_QB>;
 
+def PseudoMTLOHI_DSP : PseudoMTLOHI<ACC64DSP, GPR32>;
+
 // Patterns.
 class DSPPat<dag pattern, dag result, Predicate pred = HasDSP> :
   Pat<pattern, result>, Requires<[pred]>;
index 842aab08d0d077aa092d9396b5285971d8274d25..44495ff134acdc854d5ba2cdb608c17729056640 100644 (file)
@@ -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<string opstr, RegisterOperand RO, Register UseReg>:
   let neverHasSideEffects = 1;
 }
 
+class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
+  : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
+             [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))], IIHiLo>;
+
 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
   InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], IIHiLo,
   FrmR, opstr> {
@@ -1069,6 +1072,7 @@ def PseudoMULT  : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, IIImult>;
 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, IIImult>;
 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>;
 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>;
+def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>;
 def PseudoMADD  : MAddSubPseudo<MADD, MipsMAdd>;
 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu>;
 def PseudoMSUB  : MAddSubPseudo<MSUB, MipsMSub>;
index 412571e54b1fc653e530cbba51514cb7f23ef3b5..0a82a3a83fbdb7679834f151db64c829a3f4cb89 100644 (file)
@@ -684,19 +684,6 @@ std::pair<bool, SDNode*> 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
index ef88a63066cd2c9a42af7d0cf7ecca028060eef9..2f793348c67f47eff1306f0dd29b2cf73e5f4fae 100644 (file)
@@ -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,
index 6a678456c5b8a80a4f303df60312b6294a683ffc..6d2dd901f33b66eb942fa891dea706010d2d7fa2 100644 (file)
@@ -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