sh.md (udivsi3, [...]): Simplify.
authorOleg Endo <olegendo@gcc.gnu.org>
Tue, 3 May 2016 06:47:34 +0000 (06:47 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Tue, 3 May 2016 06:47:34 +0000 (06:47 +0000)
gcc/
* config/sh/sh.md (udivsi3, divsi3, mulsi3): Simplify.
(mulhisi3, umulhisi3, (smulsi3_highpart, umulsi3_highpart): Convert to
define_insn_and_split.
(mulsi3_i): New define_insn_and_split.
(mulsi3_call): Convert to define_insn.
(mulsidi3, mulsidi3_compact, umulsidi3, umulsidi3_compact):
Remove constraints.

From-SVN: r235803

gcc/ChangeLog
gcc/config/sh/sh.md

index 6f1663ffe673abec90978c585084da8117e63e19..3910c62b5ab21f166f5bbfdb33c30d49d4d7a919 100644 (file)
@@ -1,3 +1,13 @@
+2016-05-03  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       * config/sh/sh.md (udivsi3, divsi3, mulsi3): Simplify.
+       (mulhisi3, umulhisi3, (smulsi3_highpart, umulsi3_highpart): Convert to
+       define_insn_and_split.
+       (mulsi3_i): New define_insn_and_split.
+       (mulsi3_call): Convert to define_insn.
+       (mulsidi3, mulsidi3_compact, umulsidi3, umulsidi3_compact):
+       Remove constraints.
+
 2016-05-02  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * machmode.h (mode_complex): Add support to give the complex mode
index da1dfe98c206d74e7cc06429cbb9a9e49318a5ef..2d9502b7aa7488aa5e4166d07b466152e7ea66a0 100644 (file)
 
 
 (define_expand "udivsi3"
-  [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
-   (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
-   (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
-   (parallel [(set (match_operand:SI 0 "register_operand" "")
-                  (udiv:SI (reg:SI R4_REG)
-                           (reg:SI R5_REG)))
-             (clobber (reg:SI T_REG))
-             (clobber (reg:SI PR_REG))
-             (clobber (reg:SI R4_REG))
-             (use (match_dup 3))])]
+  [(set (match_operand:SI 0 "register_operand")
+       (udiv:SI (match_operand:SI 1 "general_operand")
+                (match_operand:SI 2 "general_operand")))]
   ""
 {
   rtx last;
    (set_attr "needs_delay_slot" "yes")])
 
 (define_expand "divsi3"
-  [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
-   (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
-   (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
-   (parallel [(set (match_operand:SI 0 "register_operand" "")
-                  (div:SI (reg:SI R4_REG)
-                          (reg:SI R5_REG)))
-             (clobber (reg:SI T_REG))
-             (clobber (reg:SI PR_REG))
-             (clobber (reg:SI R1_REG))
-             (clobber (reg:SI R2_REG))
-             (clobber (reg:SI R3_REG))
-             (use (match_dup 3))])]
+  [(set (match_operand:SI 0 "register_operand")
+       (div:SI (match_operand:SI 1 "general_operand")
+               (match_operand:SI 2 "general_operand")))]
   ""
 {
   rtx last;
 ;; Multiplication instructions
 ;; -------------------------------------------------------------------------
 
+(define_insn_and_split "mulhisi3"
+  [(set (match_operand:SI 0 "arith_reg_dest")
+       (mult:SI (sign_extend:SI (match_operand:HI 1 "arith_reg_operand"))
+                (sign_extend:SI (match_operand:HI 2 "arith_reg_operand"))))
+   (clobber (reg:SI MACL_REG))]
+  "TARGET_SH1 && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(set (reg:SI MACL_REG) (mult:SI (sign_extend:SI (match_dup 1))
+                                  (sign_extend:SI (match_dup 2))))
+   (set (match_dup 0) (reg:SI MACL_REG))])
+
+(define_insn_and_split "umulhisi3"
+  [(set (match_operand:SI 0 "arith_reg_dest")
+       (mult:SI (zero_extend:SI (match_operand:HI 1 "arith_reg_operand"))
+                (zero_extend:SI (match_operand:HI 2 "arith_reg_operand"))))
+   (clobber (reg:SI MACL_REG))]
+  "TARGET_SH1 && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(set (reg:SI MACL_REG) (mult:SI (zero_extend:SI (match_dup 1))
+                                  (zero_extend:SI (match_dup 2))))
+   (set (match_dup 0) (reg:SI MACL_REG))])
+
 (define_insn "umulhisi3_i"
   [(set (reg:SI MACL_REG)
        (mult:SI (zero_extend:SI
   "muls.w      %1,%0"
   [(set_attr "type" "smpy")])
 
-(define_expand "mulhisi3"
-  [(set (reg:SI MACL_REG)
-       (mult:SI (sign_extend:SI
-                 (match_operand:HI 1 "arith_reg_operand" ""))
-                (sign_extend:SI
-                 (match_operand:HI 2 "arith_reg_operand" ""))))
-   (set (match_operand:SI 0 "arith_reg_operand" "")
-       (reg:SI MACL_REG))]
-  "TARGET_SH1"
-{
-  rtx_insn *insn;
-  rtx macl;
-
-  macl = gen_rtx_REG (SImode, MACL_REG);
-  start_sequence ();
-  emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
-  insn = get_insns ();  
-  end_sequence ();
-  /* expand_binop can't find a suitable code in umul_widen_optab to
-     make a REG_EQUAL note from, so make one here.
-     See also smulsi3_highpart.
-     ??? Alternatively, we could put this at the calling site of expand_binop,
-     i.e. expand_expr.  */
-  /* Use emit_libcall_block for loop invariant code motion and to make
-     a REG_EQUAL note.  */
-  emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
-
-  DONE;
-})
-
-(define_expand "umulhisi3"
-  [(set (reg:SI MACL_REG)
-       (mult:SI (zero_extend:SI
-                 (match_operand:HI 1 "arith_reg_operand" ""))
-                (zero_extend:SI
-                 (match_operand:HI 2 "arith_reg_operand" ""))))
-   (set (match_operand:SI 0 "arith_reg_operand" "")
-       (reg:SI MACL_REG))]
-  "TARGET_SH1"
-{
-  rtx_insn *insn;
-  rtx macl;
-
-  macl = gen_rtx_REG (SImode, MACL_REG);
-  start_sequence ();
-  emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
-  insn = get_insns ();  
-  end_sequence ();
-  /* expand_binop can't find a suitable code in umul_widen_optab to
-     make a REG_EQUAL note from, so make one here.
-     See also smulsi3_highpart.
-     ??? Alternatively, we could put this at the calling site of expand_binop,
-     i.e. expand_expr.  */
-  /* Use emit_libcall_block for loop invariant code motion and to make
-     a REG_EQUAL note.  */
-  emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
-
-  DONE;
-})
 
 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
 ;; a call to a routine which clobbers known registers.
-(define_insn ""
+(define_insn "mulsi3_call"
   [(set (match_operand:SI 1 "register_operand" "=z")
        (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
    (clobber (reg:SI MACL_REG))
   [(set_attr "type" "sfunc")
    (set_attr "needs_delay_slot" "yes")])
 
-(define_expand "mulsi3_call"
-  [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
-   (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
-   (parallel[(set (match_operand:SI 0 "register_operand" "")
-                 (mult:SI (reg:SI R4_REG)
-                          (reg:SI R5_REG)))
-            (clobber (reg:SI MACL_REG))
-            (clobber (reg:SI T_REG))
-            (clobber (reg:SI PR_REG))
-            (clobber (reg:SI R3_REG))
-            (clobber (reg:SI R2_REG))
-            (clobber (reg:SI R1_REG))
-            (use (match_operand:SI 3 "register_operand" ""))])]
-  "TARGET_SH1"
-  "")
-
 (define_insn "mul_r"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
        (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
   "mul.l       %1,%0"
   [(set_attr "type" "dmpy")])
 
+(define_insn_and_split "mulsi3_i"
+  [(set (match_operand:SI 0 "arith_reg_dest")
+       (mult:SI (match_operand:SI 1 "arith_reg_operand")
+                (match_operand:SI 2 "arith_reg_operand")))
+   (clobber (reg:SI MACL_REG))]
+  "TARGET_SH2 && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(set (reg:SI MACL_REG) (mult:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0) (reg:SI MACL_REG))])
+
 (define_expand "mulsi3"
-  [(set (reg:SI MACL_REG)
-       (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
-                 (match_operand:SI 2 "arith_reg_operand" "")))
-   (set (match_operand:SI 0 "arith_reg_operand" "")
-       (reg:SI MACL_REG))]
+  [(set (match_operand:SI 0 "arith_reg_dest")
+       (mult:SI (match_operand:SI 1 "arith_reg_operand")
+                (match_operand:SI 2 "arith_reg_operand")))]
   "TARGET_SH1"
 {
   if (!TARGET_SH2)
     {
-      /* The address must be set outside the libcall,
-        since it goes into a pseudo.  */
+      emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
+      emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
+
       rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC).sym;
-      rtx addr = force_reg (SImode, sym);
-      rtx insns = gen_mulsi3_call (operands[0], operands[1],
-                                  operands[2], addr);
-      emit_insn (insns);
+
+      emit_insn (gen_mulsi3_call (force_reg (SImode, sym), operands[0]));
     }
   else
     {
-      rtx macl = gen_rtx_REG (SImode, MACL_REG);
+      /* FIXME: For some reason, expanding the mul_l insn and the macl store
+        insn early gives slightly better code.  In particular it prevents
+        the decrement-test loop type to be used in some cases which saves
+        one multiplication in the loop setup code.
+
+         emit_insn (gen_mulsi3_i (operands[0], operands[1], operands[2]));
+      */
 
       emit_insn (gen_mul_l (operands[1], operands[2]));
-      /* consec_sets_giv can only recognize the first insn that sets a
-        giv as the giv insn.  So we must tag this also with a REG_EQUAL
-        note.  */
-      emit_insn (gen_movsi_i ((operands[0]), macl));
+      emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
     }
   DONE;
 })
   [(set_attr "type" "dmpy")])
 
 (define_expand "mulsidi3"
-  [(set (match_operand:DI 0 "arith_reg_dest" "")
-       (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
-                (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
+  [(set (match_operand:DI 0 "arith_reg_dest")
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+                (sign_extend:DI (match_operand:SI 2 "arith_reg_operand"))))]
   "TARGET_SH2"
 {
   emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
 })
 
 (define_insn_and_split "mulsidi3_compact"
-  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
-       (mult:DI
-        (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
-        (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
+  [(set (match_operand:DI 0 "arith_reg_dest")
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+                (sign_extend:DI (match_operand:SI 2 "arith_reg_operand"))))
    (clobber (reg:SI MACH_REG))
    (clobber (reg:SI MACL_REG))]
-  "TARGET_SH2"
+  "TARGET_SH2 && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
   [(set_attr "type" "dmpy")])
 
 (define_expand "umulsidi3"
-  [(set (match_operand:DI 0 "arith_reg_dest" "")
-       (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
-                (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
+  [(set (match_operand:DI 0 "arith_reg_dest")
+       (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+                (zero_extend:DI (match_operand:SI 2 "arith_reg_operand"))))]
   "TARGET_SH2"
 {
   emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
 })
 
 (define_insn_and_split "umulsidi3_compact"
-  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
-       (mult:DI
-        (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
-        (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
+  [(set (match_operand:DI 0 "arith_reg_dest")
+       (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+                (zero_extend:DI (match_operand:SI 2 "arith_reg_operand"))))
    (clobber (reg:SI MACH_REG))
    (clobber (reg:SI MACL_REG))]
-  "TARGET_SH2"
+  "TARGET_SH2 && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
   "dmuls.l     %1,%0"
   [(set_attr "type" "dmpy")])
 
-(define_expand "smulsi3_highpart"
-  [(parallel
-    [(set (reg:SI MACH_REG)
-         (truncate:SI
-          (lshiftrt:DI
+(define_insn_and_split "smulsi3_highpart"
+  [(set (match_operand:SI 0 "arith_reg_dest")
+       (truncate:SI
+         (lshiftrt:DI
            (mult:DI
-            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
-            (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
-           (const_int 32))))
-    (clobber (reg:SI MACL_REG))])
-   (set (match_operand:SI 0 "arith_reg_operand" "")
-       (reg:SI MACH_REG))]
-  "TARGET_SH2"
+             (sign_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+             (sign_extend:DI (match_operand:SI 2 "arith_reg_operand")))
+         (const_int 32))))
+   (clobber (reg:SI MACL_REG))
+   (clobber (reg:SI MACH_REG))]
+  "TARGET_SH2 && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
 {
-  rtx_insn *insn;
-  rtx mach;
-
-  mach = gen_rtx_REG (SImode, MACH_REG);
-  start_sequence ();
   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
-  insn = get_insns ();  
-  end_sequence ();
-  /* expand_binop can't find a suitable code in mul_highpart_optab to
-     make a REG_EQUAL note from, so make one here.
-     See also {,u}mulhisi.
-     ??? Alternatively, we could put this at the calling site of expand_binop,
-     i.e. expand_mult_highpart.  */
-  /* Use emit_libcall_block for loop invariant code motion and to make
-     a REG_EQUAL note.  */
-  emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
-
-  DONE;
+  emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
 })
 
 (define_insn "umulsi3_highpart_i"
   "dmulu.l     %1,%0"
   [(set_attr "type" "dmpy")])
 
-(define_expand "umulsi3_highpart"
-  [(parallel
-    [(set (reg:SI MACH_REG)
-         (truncate:SI
-          (lshiftrt:DI
+(define_insn_and_split "umulsi3_highpart"
+  [(set (match_operand:SI 0 "arith_reg_dest")
+       (truncate:SI
+         (lshiftrt:DI
            (mult:DI
-            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
-            (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
-           (const_int 32))))
-    (clobber (reg:SI MACL_REG))])
-   (set (match_operand:SI 0 "arith_reg_operand" "")
-       (reg:SI MACH_REG))]
-  "TARGET_SH2"
+             (zero_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+             (zero_extend:DI (match_operand:SI 2 "arith_reg_operand")))
+         (const_int 32))))
+   (clobber (reg:SI MACL_REG))]
+  "TARGET_SH2 && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
 {
-  rtx_insn *insn;
-  rtx mach;
-
-  mach = gen_rtx_REG (SImode, MACH_REG);
-  start_sequence ();
   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
-  insn = get_insns ();  
-  end_sequence ();
-  /* Use emit_libcall_block for loop invariant code motion and to make
-     a REG_EQUAL note.  */
-  emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
-
-  DONE;
+  emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
 })
 
 ;; -------------------------------------------------------------------------