From 09e39001da6a17531b32849964899ccaf50c2cb9 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Thu, 16 Jul 2009 14:17:52 +0000 Subject: [PATCH] Use divide single for 32 bit signed divides git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76010 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 34 +++++++++++++++------- lib/Target/SystemZ/SystemZInstrInfo.td | 8 ++--- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index c63376683a6..8ca936f07df 100644 --- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -636,17 +636,18 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { switch (Opcode) { default: break; case ISD::SDIVREM: { - unsigned Opc, MOpc, ClrOpc = 0; + unsigned Opc, MOpc; SDValue N0 = Node->getOperand(0); SDValue N1 = Node->getOperand(1); MVT ResVT; + bool is32Bit = false; switch (NVT.getSimpleVT()) { default: assert(0 && "Unsupported VT!"); case MVT::i32: Opc = SystemZ::SDIVREM32r; MOpc = SystemZ::SDIVREM32m; - ClrOpc = SystemZ::MOV64Pr0_even; - ResVT = MVT::v2i32; + ResVT = MVT::v2i64; + is32Bit = true; break; case MVT::i64: Opc = SystemZ::SDIVREM64r; MOpc = SystemZ::SDIVREM64m; @@ -658,7 +659,11 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { bool foldedLoad = TryFoldLoad(Op, N1, Tmp0, Tmp1, Tmp2); // Prepare the dividend - SDNode *Dividend = N0.getNode(); + SDNode *Dividend; + if (is32Bit) + Dividend = CurDAG->getTargetNode(SystemZ::MOVSX64rr32, dl, MVT::i64, N0); + else + Dividend = N0.getNode(); // Insert prepared dividend into suitable 'subreg' SDNode *Tmp = CurDAG->getTargetNode(TargetInstrInfo::IMPLICIT_DEF, @@ -668,10 +673,6 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { SDValue(Tmp, 0), SDValue(Dividend, 0), CurDAG->getTargetConstant(subreg_odd, MVT::i32)); - // Zero out even subreg, if needed - if (ClrOpc) - Dividend = CurDAG->getTargetNode(ClrOpc, dl, ResVT, SDValue(Dividend, 0)); - SDNode *Result; SDValue DivVal = SDValue(Dividend, 0); if (foldedLoad) { @@ -686,10 +687,16 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { // Copy the division (odd subreg) result, if it is needed. if (!Op.getValue(0).use_empty()) { SDNode *Div = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG, - dl, NVT, + dl, (is32Bit ? MVT::v2i32 : MVT::i64), SDValue(Result, 0), CurDAG->getTargetConstant(subreg_odd, MVT::i32)); + if (is32Bit) + Div = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG, + dl, NVT, + SDValue(Div, 0), + CurDAG->getTargetConstant(subreg_32bit, + MVT::i32)); ReplaceUses(Op.getValue(0), SDValue(Div, 0)); #ifndef NDEBUG DOUT << std::string(Indent-2, ' ') << "=> "; @@ -701,10 +708,17 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { // Copy the remainder (even subreg) result, if it is needed. if (!Op.getValue(1).use_empty()) { SDNode *Rem = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG, - dl, NVT, + dl, (is32Bit ? MVT::v2i32 : MVT::i64), SDValue(Result, 0), CurDAG->getTargetConstant(subreg_even, MVT::i32)); + if (is32Bit) + Rem = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG, + dl, NVT, + SDValue(Rem, 0), + CurDAG->getTargetConstant(subreg_32bit, + MVT::i32)); + ReplaceUses(Op.getValue(1), SDValue(Rem, 0)); #ifndef NDEBUG DOUT << std::string(Indent-2, ' ') << "=> "; diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index b4e25e6c3ad..d5364aefede 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -588,8 +588,8 @@ def MULSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR32:$src2), "msgfr\t{$dst, $src2}", [(set GR64:$dst, (mul GR64:$src1, (sext GR32:$src2)))]>; -def SDIVREM32r : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2), - "dr\t{$dst, $src2}", +def SDIVREM32r : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR32:$src2), + "dsgfr\t{$dst, $src2}", []>; def SDIVREM64r : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR64:$src2), "dsgr\t{$dst, $src2}", @@ -602,8 +602,8 @@ def UDIVREM64r : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR64:$src2), "dlgr\t{$dst, $src2}", []>; let mayLoad = 1 in { -def SDIVREM32m : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, rriaddr:$src2), - "d\t{$dst, $src2}", +def SDIVREM32m : Pseudo<(outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2), + "dsgf\t{$dst, $src2}", []>; def SDIVREM64m : Pseudo<(outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2), "dsg\t{$dst, $src2}",