OSDN Git Service

sparc: Use match_code in zero_or_v7_operand.
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / predicates.md
index 4af960a..308fbd6 100644 (file)
@@ -1,5 +1,5 @@
 ;; Predicate definitions for SPARC.
-;; Copyright (C) 2005, 2007, 2008, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 2005, 2007, 2008, 2010, 2012 Free Software Foundation, Inc.
 ;;
 ;; This file is part of GCC.
 ;;
   (and (match_code "const_int,const_double,const_vector")
        (match_test "op == CONST0_RTX (mode)")))
 
-;; Return true if OP is the one constant for MODE.
-(define_predicate "const_one_operand"
-  (and (match_code "const_int,const_double,const_vector")
-       (match_test "op == CONST1_RTX (mode)")))
+;; Return true if the integer representation of OP is
+;; all-ones.
+(define_predicate "const_all_ones_operand"
+  (match_code "const_int,const_double,const_vector")
+{
+  if (GET_CODE (op) == CONST_INT && INTVAL (op) == -1)
+    return true;
+#if HOST_BITS_PER_WIDE_INT == 32
+  if (GET_CODE (op) == CONST_DOUBLE
+      && GET_MODE (op) == VOIDmode
+      && CONST_DOUBLE_HIGH (op) == ~(HOST_WIDE_INT)0
+      && CONST_DOUBLE_LOW (op) == ~(HOST_WIDE_INT)0)
+    return true;
+#endif
+  if (GET_CODE (op) == CONST_VECTOR)
+    {
+      int i, num_elem = CONST_VECTOR_NUNITS (op);
+
+      for (i = 0; i < num_elem; i++)
+        {
+          rtx n = CONST_VECTOR_ELT (op, i);
+          if (! const_all_ones_operand (n, mode))
+            return false;
+        }
+      return true;
+    }
+  return false;
+})
 
 ;; Return true if OP is the integer constant 4096.
 (define_predicate "const_4096_operand"
 (define_predicate "const_double_or_vector_operand"
   (match_code "const_double,const_vector"))
 
+;; Return true if OP is Zero, or if the target is V7.
+(define_predicate "zero_or_v7_operand"
+  (and (match_code "const_int")
+       (ior (match_test "INTVAL (op) == 0")
+           (match_test "!TARGET_V8 && !TARGET_V9"))))
 
 ;; Predicates for symbolic constants.
 
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "const_zero_operand")))
 
+(define_predicate "register_or_v9_zero_operand"
+  (ior (match_operand 0 "register_operand")
+       (and (match_test "TARGET_V9")
+           (match_operand 0 "const_zero_operand"))))
+
+;; Return true if OP is either the zero constant, the all-ones
+;; constant, or a register.
+(define_predicate "register_or_zero_or_all_ones_operand"
+  (ior (match_operand 0 "register_or_zero_operand")
+       (match_operand 0 "const_all_ones_operand")))
+
 ;; Return true if OP is a register operand in a floating point register.
 (define_predicate "fp_register_operand"
   (match_operand 0 "register_operand")
       && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
     return true;
 
-  if ((mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
-      || (mclass == MODE_VECTOR_INT && GET_CODE (op) == CONST_VECTOR))
+  if (mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
+    return true;
+
+  if (mclass == MODE_VECTOR_INT && GET_CODE (op) == CONST_VECTOR
+      && (const_zero_operand (op, mode)
+          || const_all_ones_operand (op, mode)))
     return true;
 
   if (register_operand (op, mode))
        (match_test "call_address_operand (XEXP (op, 0), mode)")))
 
 
+(define_predicate "mem_noofs_operand"
+  (and (match_code "mem")
+       (match_code "reg" "0")))
+
 ;; Predicates for operators.
 
 ;; Return true if OP is a comparison operator.  This allows the use of