* [SH] Add splitter to addsi3_compact.
authorKaz Kojima <kkojima@gcc.gnu.org>
Fri, 19 Dec 2014 04:53:57 +0000 (04:53 +0000)
committerKaz Kojima <kkojima@gcc.gnu.org>
Fri, 19 Dec 2014 04:53:57 +0000 (04:53 +0000)
From-SVN: r218891

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

index 255b8dbd61f7e6768c7e6c0ed49404f4b9ae30fd..a9741366392184a677327010dd5e507380c361be 100644 (file)
@@ -1,3 +1,12 @@
+2014-12-19  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       * config/sh/predicates.md (arith_or_int_operand): New predicate.
+       * config/sh/sh.md (addsi3): Use arith_or_int_operand for operand 2.
+       Return fail if operands[0] and operands[1] are overlap when
+       operands[2] is integer constant.
+       (*addsi3_compact): Make it define_insn_and_split which splits
+       reg0 := reg1 + constant to reg0 = constant and reg0 := reg0 + reg1.
+
 2014-12-19  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        * config/sh/sh-protos.h (sh_movsf_ie_ra_split_p): Declare.
index 152056ae360e604531d6079bd18879405bcbf6db..8772332bac1bcdae0cc6d7ebaab231a807ccfca0 100644 (file)
   return 0;
 })
 
+;; Likewise arith_operand but always permits const_int.
+(define_predicate "arith_or_int_operand"
+  (match_code "subreg,reg,const_int,const_vector")
+{
+  if (arith_operand (op, mode))
+    return 1;
+
+  if (CONST_INT_P (op))
+    return 1;
+
+  return 0;
+})
+
 ;; Returns 1 if OP is a valid source operand for a compare insn.
 (define_predicate "arith_reg_or_0_operand"
   (match_code "subreg,reg,const_int,const_vector")
index 76f5c4ad1ab5b91e97b20d6877279a46c0fbe3a5..a74e17f151f459dc988739714c923653df2f4bf4 100644 (file)
 (define_expand "addsi3"
   [(set (match_operand:SI 0 "arith_reg_operand" "")
        (plus:SI (match_operand:SI 1 "arith_operand" "")
-                (match_operand:SI 2 "arith_operand" "")))]
+                (match_operand:SI 2 "arith_or_int_operand" "")))]
   ""
 {
   if (TARGET_SHMEDIA)
     operands[1] = force_reg (SImode, operands[1]);
+  else if (! arith_operand (operands[2], SImode))
+    {
+      if (reg_overlap_mentioned_p (operands[0], operands[1]))
+       FAIL;
+    }
 })
 
 (define_insn "addsi3_media"
   [(set_attr "type" "arith_media")
    (set_attr "highpart" "ignore")])
 
-(define_insn "*addsi3_compact"
-  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
-       (plus:SI (match_operand:SI 1 "arith_operand" "%0")
-                (match_operand:SI 2 "arith_operand" "rI08")))]
-  "TARGET_SH1"
-  "add %2,%0"
+(define_insn_and_split "*addsi3_compact"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r,&r")
+       (plus:SI (match_operand:SI 1 "arith_operand" "%0,r")
+                (match_operand:SI 2 "arith_or_int_operand" "rI08,rn")))]
+  "TARGET_SH1
+   && (rtx_equal_p (operands[0], operands[1])
+       && arith_operand (operands[2], SImode))
+      || ! reg_overlap_mentioned_p (operands[0], operands[1])"
+  "@
+       add     %2,%0
+       #"
+  "reload_completed
+   && ! reg_overlap_mentioned_p (operands[0], operands[1])"
+  [(set (match_dup 0) (match_dup 2))
+   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
+  ""
   [(set_attr "type" "arith")])
 
 ;; -------------------------------------------------------------------------