[ARC] Avoid use of hard registers before reg-alloc.
authorClaudiu Zissulescu <claziss@synopsys.com>
Thu, 1 Jun 2017 09:41:46 +0000 (11:41 +0200)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Thu, 1 Jun 2017 09:41:46 +0000 (11:41 +0200)
gcc/
2017-06-01  Claudiu Zissulescu  <claziss@synopsys.com>

* config/arc/arc.md (mulsi3): Avoid use of hard registers before
reg-alloc when having mul64 or mul32x16 instructions.
(mulsidi3): Likewise.
(umulsidi3): Likewise.
(mulsi32x16): New pattern.
(mulsi64): Likewise.
(mulsidi64): Likewise.
(umulsidi64): Likewise.
(MUL32x16_REG): Define.
(mul64_600): Use MUL32x16_REG.
(mac64_600): Likewise.
(umul64_600): Likewise.
(umac64_600): Likewise.

From-SVN: r248777

gcc/ChangeLog
gcc/config/arc/arc.md

index 2af5953aaee4fc967687b4d824dcc8610a60e835..909c1dd8e93967e3f42c6e5046e15e2ba649c692 100644 (file)
@@ -1,3 +1,19 @@
+2017-06-01  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * config/arc/arc.md (mulsi3): Avoid use of hard registers before
+       reg-alloc when having mul64 or mul32x16 instructions.
+       (mulsidi3): Likewise.
+       (umulsidi3): Likewise.
+       (mulsi32x16): New pattern.
+       (mulsi64): Likewise.
+       (mulsidi64): Likewise.
+       (umulsidi64): Likewise.
+       (MUL32x16_REG): Define.
+       (mul64_600): Use MUL32x16_REG.
+       (mac64_600): Likewise.
+       (umul64_600): Likewise.
+       (umac64_600): Likewise.
+
 2017-06-01  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * config/arc/arc.md (mulsi3_700): Make it commutative.
index cce5973ce6c5eae76b9e9660eb1c86243e985132..3628efcc098a2d1db1258a5cfd9c90bd7c9f4aab 100644 (file)
    (ILINK2_REGNUM 30)
    (RETURN_ADDR_REGNUM 31)
    (MUL64_OUT_REG 58)
+   (MUL32x16_REG 56)
    (ARCV2_ACC 58)
 
    (LP_COUNT 60)
     }
   else if (TARGET_MUL64_SET)
     {
-      emit_insn (gen_mulsi_600 (operands[1], operands[2],
-                               gen_mlo (), gen_mhi ()));
-      emit_move_insn (operands[0], gen_mlo ());
-      DONE;
+     rtx tmp = gen_reg_rtx (SImode);
+     emit_insn (gen_mulsi64 (tmp, operands[1], operands[2]));
+     emit_move_insn (operands[0], tmp);
+     DONE;
     }
   else if (TARGET_MULMAC_32BY16_SET)
     {
-      if (immediate_operand (operands[2], SImode)
-         && INTVAL (operands[2]) >= 0
-         && INTVAL (operands[2]) <= 65535)
-       {
-         emit_insn (gen_umul_600 (operands[1], operands[2],
-                                    gen_acc2 (), gen_acc1 ()));
-         emit_move_insn (operands[0], gen_acc2 ());
-         DONE;
-       }
-      operands[2] = force_reg (SImode, operands[2]);
-      emit_insn (gen_umul_600 (operands[1], operands[2],
-                              gen_acc2 (), gen_acc1 ()));
-      emit_insn (gen_mac_600 (operands[1], operands[2],
-                              gen_acc2 (), gen_acc1 ()));
-      emit_move_insn (operands[0], gen_acc2 ());
-      DONE;
+     rtx tmp = gen_reg_rtx (SImode);
+     emit_insn (gen_mulsi32x16 (tmp, operands[1], operands[2]));
+     emit_move_insn (operands[0], tmp);
+     DONE;
     }
   else
     {
     }
 })
 
+(define_insn_and_split "mulsi32x16"
+ [(set (match_operand:SI 0 "register_operand"            "=w")
+       (mult:SI (match_operand:SI 1 "register_operand"  "%c")
+                (match_operand:SI 2 "nonmemory_operand" "ci")))
+  (clobber (reg:DI MUL32x16_REG))]
+ "TARGET_MULMAC_32BY16_SET"
+ "#"
+ "TARGET_MULMAC_32BY16_SET && reload_completed"
+ [(const_int 0)]
+ {
+  if (immediate_operand (operands[2], SImode)
+    && INTVAL (operands[2]) >= 0
+    && INTVAL (operands[2]) <= 65535)
+     {
+      emit_insn (gen_umul_600 (operands[1], operands[2],
+                                      gen_acc2 (), gen_acc1 ()));
+      emit_move_insn (operands[0], gen_acc2 ());
+      DONE;
+     }
+   emit_insn (gen_umul_600 (operands[1], operands[2],
+                                  gen_acc2 (), gen_acc1 ()));
+   emit_insn (gen_mac_600 (operands[1], operands[2],
+                                  gen_acc2 (), gen_acc1 ()));
+   emit_move_insn (operands[0], gen_acc2 ());
+   DONE;
+  }
+ [(set_attr "type" "multi")
+  (set_attr "length" "8")])
+
 ; mululw conditional execution without a LIMM clobbers an input register;
 ; we'd need a different pattern to describe this.
 ; To make the conditional execution valid for the LIMM alternative, we
    (set_attr "predicable" "no, no, yes")
    (set_attr "cond" "nocond, canuse_limm, canuse")])
 
+(define_insn_and_split "mulsi64"
+ [(set (match_operand:SI 0 "register_operand"            "=w")
+       (mult:SI (match_operand:SI 1 "register_operand"  "%c")
+                (match_operand:SI 2 "nonmemory_operand" "ci")))
+  (clobber (reg:DI MUL64_OUT_REG))]
+ "TARGET_MUL64_SET"
+ "#"
+ "TARGET_MUL64_SET && reload_completed"
+  [(const_int 0)]
+{
+  emit_insn (gen_mulsi_600 (operands[1], operands[2],
+                       gen_mlo (), gen_mhi ()));
+  emit_move_insn (operands[0], gen_mlo ());
+  DONE;
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "8")])
+
 (define_insn "mulsi_600"
   [(set (match_operand:SI 2 "mlo_operand" "")
        (mult:SI (match_operand:SI 0 "register_operand"  "%Rcq#q,c,c,c")
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
                 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
   "TARGET_ANY_MPY"
-"
-{
+  {
   if (TARGET_PLUS_MACD)
     {
      if (CONST_INT_P (operands[2]))
     }
   else if (TARGET_MULMAC_32BY16_SET)
     {
-      rtx result_hi = gen_highpart(SImode, operands[0]);
-      rtx result_low = gen_lowpart(SImode, operands[0]);
-
-      emit_insn (gen_mul64_600 (operands[1], operands[2]));
-      emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
-      emit_move_insn (result_low, gen_acc2 ());
+      operands[2] = force_reg (SImode, operands[2]);
+      emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
       DONE;
     }
-}")
+  operands[2] = force_reg (SImode, operands[2]);
+  })
+
+(define_insn_and_split "mulsidi64"
+  [(set (match_operand:DI 0 "register_operand" "=w")
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
+                (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
+   (clobber (reg:DI MUL32x16_REG))]
+  "TARGET_MULMAC_32BY16_SET"
+  "#"
+  "TARGET_MULMAC_32BY16_SET && reload_completed"
+  [(const_int 0)]
+  {
+   rtx result_hi = gen_highpart (SImode, operands[0]);
+   rtx result_low = gen_lowpart (SImode, operands[0]);
+
+   emit_insn (gen_mul64_600 (operands[1], operands[2]));
+   emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
+   emit_move_insn (result_low, gen_acc2 ());
+   DONE;
+  }
+  [(set_attr "type" "multi")
+   (set_attr "length" "8")])
+
 
 (define_insn "mul64_600"
-  [(set (reg:DI 56)
+  [(set (reg:DI MUL32x16_REG)
        (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
                                  "c,c,c"))
                 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
 
 ;; ??? check if this is canonical rtl
 (define_insn "mac64_600"
-  [(set (reg:DI 56)
+  [(set (reg:DI MUL32x16_REG)
        (plus:DI
          (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
                   (ashift:DI
                     (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
                                      (const_int 16) (const_int 16))
                     (const_int 16)))
-         (reg:DI 56)))
+         (reg:DI MUL32x16_REG)))
    (set (match_operand:SI 0 "register_operand" "=w,w,w")
        (zero_extract:SI
          (plus:DI
                       (sign_extract:DI (match_dup 2)
                                        (const_int 16) (const_int 16))
                          (const_int 16)))
-           (reg:DI 56))
+           (reg:DI MUL32x16_REG))
          (const_int 32) (const_int 32)))]
   "TARGET_MULMAC_32BY16_SET"
   "machlw%? %0, %1, %2"
     }
   else if (TARGET_MUL64_SET)
     {
-      emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
+     operands[2] = force_reg (SImode, operands[2]);
+     emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
       DONE;
     }
   else if (TARGET_MULMAC_32BY16_SET)
     {
-      rtx result_hi = gen_reg_rtx (SImode);
-      rtx result_low = gen_reg_rtx (SImode);
-
-      result_hi = gen_highpart(SImode , operands[0]);
-      result_low = gen_lowpart(SImode , operands[0]);
-
-      emit_insn (gen_umul64_600 (operands[1], operands[2]));
-      emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
-      emit_move_insn (result_low, gen_acc2 ());
+     operands[2] = force_reg (SImode, operands[2]);
+     emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
       DONE;
     }
   else
     }
 })
 
+(define_insn_and_split "umulsidi64"
+  [(set (match_operand:DI 0 "register_operand" "=w")
+       (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
+                (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
+   (clobber (reg:DI MUL32x16_REG))]
+  "TARGET_MULMAC_32BY16_SET"
+  "#"
+  "TARGET_MULMAC_32BY16_SET && reload_completed"
+  [(const_int 0)]
+  {
+   rtx result_hi;
+   rtx result_low;
+
+   result_hi = gen_highpart (SImode, operands[0]);
+   result_low = gen_lowpart (SImode, operands[0]);
+
+   emit_insn (gen_umul64_600 (operands[1], operands[2]));
+   emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
+   emit_move_insn (result_low, gen_acc2 ());
+   DONE;
+   }
+  [(set_attr "type" "multi")
+   (set_attr "length" "8")])
+
 (define_insn "umul64_600"
-  [(set (reg:DI 56)
+  [(set (reg:DI MUL32x16_REG)
        (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
                                  "c,c,c"))
                 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
 
 
 (define_insn "umac64_600"
-  [(set (reg:DI 56)
+  [(set (reg:DI MUL32x16_REG)
        (plus:DI
          (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
                   (ashift:DI
                     (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
                                      (const_int 16) (const_int 16))
                     (const_int 16)))
-         (reg:DI 56)))
+         (reg:DI MUL32x16_REG)))
    (set (match_operand:SI 0 "register_operand" "=w,w,w")
        (zero_extract:SI
          (plus:DI
                       (zero_extract:DI (match_dup 2)
                                        (const_int 16) (const_int 16))
                          (const_int 16)))
-           (reg:DI 56))
+           (reg:DI MUL32x16_REG))
          (const_int 32) (const_int 32)))]
   "TARGET_MULMAC_32BY16_SET"
   "machulw%? %0, %1, %2"
    (set_attr "predicable" "no,no,yes")
    (set_attr "cond" "nocond, canuse_limm, canuse")])
 
-
-
 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
 (define_insn_and_split "umulsidi3_700"
   [(set (match_operand:DI 0 "dest_reg_operand" "=&r")