predicates.md (logical_and_operand): New predicate.
authorOleg Endo <olegendo@gcc.gnu.org>
Tue, 3 Jul 2012 22:26:23 +0000 (22:26 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Tue, 3 Jul 2012 22:26:23 +0000 (22:26 +0000)
* config/sh/predicates.md (logical_and_operand): New predicate.
* config/sh/constraints.md (Jmb, Jmw): New constraints.
* config/sh/sh.md (andsi3): Move expander above insns.  Add handling
of 0xFFFF constant.  Use logical_and_operand predicate and
satisfies_constraint_Jmb, satisfies_constraint_Jmw.
(*andsi3_compact): Make it an insn_and_split.  Use
logical_and_operand predicate.  Add Jmb,Jmw alternatives.

From-SVN: r189241

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

index 9fcf3ca1dbe4decafa619ac89f7b2eda40be8602..f161d63f41dd69980181fd3aca95e64be9d3eeba 100644 (file)
@@ -1,3 +1,13 @@
+2012-07-03  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       * config/sh/predicates.md (logical_and_operand): New predicate.
+       * config/sh/constraints.md (Jmb, Jmw): New constraints.
+       * config/sh/sh.md (andsi3): Move expander above insns.  Add handling
+       of 0xFFFF constant.  Use logical_and_operand predicate and
+       satisfies_constraint_Jmb, satisfies_constraint_Jmw.
+       (*andsi3_compact): Make it an insn_and_split.  Use
+       logical_and_operand predicate.  Add Jmb,Jmw alternatives.
+
 2012-07-03  Jason Merrill  <jason@redhat.com>
 
        PR c++/53826
index 6c9bc5ecc95df71630fe722507076289356beb21..8642ea808a73b4334f48f3ad878a4c5f6a4ec9e7 100644 (file)
@@ -31,6 +31,8 @@
 ;; IJKLMNOP: CONT_INT constants
 ;;  Ixx: signed xx bit
 ;;  J16: 0xffffffff00000000 | 0x00000000ffffffff
+;;  Jmb: 0x000000FF
+;;  Jmw: 0x0000FFFF
 ;;  Kxx: unsigned xx bit
 ;;  M: 1
 ;;  N: 0
   (and (match_code "const_int")
        (match_test "CONST_OK_FOR_J16 (ival)")))
 
+(define_constraint "Jmb"
+  "Low byte mask constant 0x000000FF"
+  (and (match_code "const_int")
+       (match_test "ival == 0xFF")))
+
+(define_constraint "Jmw"
+  "Low word mask constant 0x0000FFFF"
+  (and (match_code "const_int")
+       (match_test "ival == 0xFFFF")))
+
 (define_constraint "K03"
   "An unsigned 3-bit constant, as used in SH2A bclr, bset, etc."
   (and (match_code "const_int")
index d58f657c857de9fc979df3ad22a65f675ec6f103..3e7efd3504483d7a156a2b93c71f8087564fe72d 100644 (file)
   return 0;
 })
 
+;; Like logical_operand but allows additional constant values which can be
+;; done with zero extensions.  Used for the second operand of and insns.
+(define_predicate "logical_and_operand"
+  (match_code "subreg,reg,const_int")
+{
+  if (logical_operand (op, mode))
+    return 1;
+
+  if (! TARGET_SHMEDIA
+      && (satisfies_constraint_Jmb (op) || satisfies_constraint_Jmw (op)))
+    return 1;
+
+  return 0;
+})
+
 ;; TODO: Add a comment here.
 
 (define_predicate "logical_operator"
index 4e2425f4888e0d706ea11fae490ac2a3d34542f9..1dda1943cba7065f3193e2c1397cec57e694f232 100644 (file)
@@ -3113,12 +3113,55 @@ label:
 ;; Logical operations
 ;; -------------------------------------------------------------------------
 
-(define_insn "*andsi3_compact"
-  [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
-       (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
-               (match_operand:SI 2 "logical_operand" "K08,r")))]
+(define_expand "andsi3"
+  [(set (match_operand:SI 0 "arith_reg_operand" "")
+       (and:SI (match_operand:SI 1 "logical_reg_operand" "")
+               (match_operand:SI 2 "logical_and_operand" "")))]
+  ""
+{
+  /* If it is possible to turn the and insn into a zero extension
+     already, redundant zero extensions will be folded, which results
+     in better code.  
+     Ideally the splitter of *andsi_compact would be enough, if reundant
+     zero extensions were detected after the combine pass, which does not
+     happen at the moment.  */
+  if (TARGET_SH1)
+    {
+      if (satisfies_constraint_Jmb (operands[2]))
+       {
+         emit_insn (gen_zero_extendqisi2 (operands[0],
+                                          gen_lowpart (QImode, operands[1])));
+         DONE;
+       }
+      else if (satisfies_constraint_Jmw (operands[2]))
+       {
+         emit_insn (gen_zero_extendhisi2 (operands[0],
+                                          gen_lowpart (HImode, operands[1])));
+         DONE;
+       }
+    }
+})
+
+(define_insn_and_split "*andsi_compact"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,z,r")
+       (and:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,0,0")
+               (match_operand:SI 2 "logical_and_operand" "Jmb,Jmw,K08,r")))]
   "TARGET_SH1"
-  "and %2,%0"
+  "@
+       extu.b  %1,%0
+       extu.w  %1,%0
+       and     %2,%0
+       and     %2,%0"
+  "&& 1"
+ [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
+{
+  if (satisfies_constraint_Jmb (operands[2]))
+    operands[1] = gen_lowpart (QImode, operands[1]);
+  else if (satisfies_constraint_Jmw (operands[2]))
+    operands[1] = gen_lowpart (HImode, operands[1]);
+  else
+    FAIL;
+}
   [(set_attr "type" "arith")])
 
 (define_insn "*andsi3_media"
@@ -3139,24 +3182,6 @@ label:
   "bclr\\t%W2,%0"
   [(set_attr "type" "arith")])
 
-;; If the constant is 255, then emit an extu.b instruction instead of an
-;; and, since that will give better code.
-
-(define_expand "andsi3"
-  [(set (match_operand:SI 0 "arith_reg_operand" "")
-       (and:SI (match_operand:SI 1 "logical_reg_operand" "")
-               (match_operand:SI 2 "logical_operand" "")))]
-  ""
-{
-  if (TARGET_SH1
-      && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
-    {
-      emit_insn (gen_zero_extendqisi2 (operands[0],
-                                      gen_lowpart (QImode, operands[1])));
-      DONE;
-    }
-})
-
 (define_insn_and_split "anddi3"
   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
        (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")