Use divide single for 32 bit signed divides
authorAnton Korobeynikov <asl@math.spbu.ru>
Thu, 16 Jul 2009 14:17:52 +0000 (14:17 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Thu, 16 Jul 2009 14:17:52 +0000 (14:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76010 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
lib/Target/SystemZ/SystemZInstrInfo.td

index c63376683a6eb47cec2634402dfdf0e3b9cf454c..8ca936f07dfd8902f51091cb55d28117ea4bf2a1 100644 (file)
@@ -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, ' ') << "=> ";
index b4e25e6c3ada4a40f12c865159cb99972455a171..d5364aefede441c8813feff7086c6db9da6af334 100644 (file)
@@ -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}",