This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Add VIS intrinsics header for sparc.


From: David Miller <davem@davemloft.net>
Date: Sat, 24 Sep 2011 02:08:32 -0400 (EDT)

> I'll look into your other suggestion in PR48974, namely making use of
> fone VIS instructions.

Hans, just FYI, here is a patch I am regression testing which
implements this.

diff --git a/gcc/config/sparc/constraints.md b/gcc/config/sparc/constraints.md
index cca34ed..317602c 100644
--- a/gcc/config/sparc/constraints.md
+++ b/gcc/config/sparc/constraints.md
@@ -18,7 +18,7 @@
 ;; <http://www.gnu.org/licenses/>.
 
 ;;; Unused letters:
-;;;    ABCD           P         Z
+;;;    AB                       
 ;;;    a        jkl    q  tuvwxyz
 
 
@@ -52,6 +52,10 @@
  (and (match_code "const_double")
       (match_test "const_zero_operand (op, mode)")))
 
+(define_constraint "C"
+ "The floating-point all-ones constant"
+ (and (match_code "const_double")
+      (match_test "const_all_ones_operand (op, mode)")))
 
 ;; Integer constant constraints
 
@@ -95,6 +99,10 @@
  (and (match_code "const_int")
       (match_test "ival == 4096")))
 
+(define_constraint "P"
+ "The integer constant -1"
+ (and (match_code "const_int")
+      (match_test "ival == -1")))
 
 ;; Extra constraints
 ;; Our memory extra constraints have to emulate the behavior of 'm' and 'o',
@@ -146,3 +154,8 @@
  "The vector zero constant"
  (and (match_code "const_vector")
       (match_test "const_zero_operand (op, mode)")))
+
+(define_constraint "Z"
+ "The vector all ones constant"
+ (and (match_code "const_vector")
+      (match_test "const_all_ones_operand (op, mode)")))
diff --git a/gcc/config/sparc/predicates.md b/gcc/config/sparc/predicates.md
index 4af960a..21399b5 100644
--- a/gcc/config/sparc/predicates.md
+++ b/gcc/config/sparc/predicates.md
@@ -29,6 +29,35 @@
   (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"
   (and (match_code "const_int")
@@ -211,6 +240,12 @@
   (ior (match_operand 0 "register_operand")
        (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")
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index d648e87..3446379 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1170,9 +1170,11 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
       if (operands [1] == const0_rtx)
 	operands[1] = CONST0_RTX (mode);
 
-      /* We can clear FP registers if TARGET_VIS, and always other regs.  */
+      /* We can clear or set to all-ones FP registers if TARGET_VIS, and
+	 always other regs.  */
       if ((TARGET_VIS || REGNO (operands[0]) < SPARC_FIRST_FP_REG)
-	  && const_zero_operand (operands[1], mode))
+	  && (const_zero_operand (operands[1], mode)
+	      || const_all_ones_operand (operands[1], mode)))
 	return false;
 
       if (REGNO (operands[0]) < SPARC_FIRST_FP_REG
@@ -3096,19 +3098,21 @@ sparc_legitimate_constant_p (enum machine_mode mode, rtx x)
         return true;
 
       /* Floating point constants are generally not ok.
-	 The only exception is 0.0 in VIS.  */
+	 The only exception is 0.0 and all-ones in VIS.  */
       if (TARGET_VIS
 	  && SCALAR_FLOAT_MODE_P (mode)
-	  && const_zero_operand (x, mode))
+	  && (const_zero_operand (x, mode)
+	      || const_all_ones_operand (x, mode)))
 	return true;
 
       return false;
 
     case CONST_VECTOR:
       /* Vector constants are generally not ok.
-	 The only exception is 0 in VIS.  */
+	 The only exception is 0 or -1 in VIS.  */
       if (TARGET_VIS
-	  && const_zero_operand (x, mode))
+	  && (const_zero_operand (x, mode)
+	      || const_all_ones_operand (x, mode)))
 	return true;
 
       return false;
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index e5cf821..f830a39 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -1303,10 +1303,10 @@
 })
 
 (define_insn "*movsi_insn"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
-	(match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
+	(match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J,P"))]
   "(register_operand (operands[0], SImode)
-    || register_or_zero_operand (operands[1], SImode))"
+    || register_or_zero_or_all_ones_operand (operands[1], SImode))"
   "@
    mov\t%1, %0
    sethi\t%%hi(%a1), %0
@@ -1315,8 +1315,9 @@
    fmovs\t%1, %0
    ld\t%1, %0
    st\t%1, %0
-   fzeros\t%0"
-  [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
+   fzeros\t%0
+   fones\t%0"
+  [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
 
 (define_insn "*movsi_lo_sum"
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -1505,11 +1506,11 @@
    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
 
 (define_insn "*movdi_insn_sp64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
-        (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
+        (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J,P"))]
   "TARGET_ARCH64
    && (register_operand (operands[0], DImode)
-       || register_or_zero_operand (operands[1], DImode))"
+       || register_or_zero_or_all_ones_operand (operands[1], DImode))"
   "@
    mov\t%1, %0
    sethi\t%%hi(%a1), %0
@@ -1518,9 +1519,10 @@
    fmovd\t%1, %0
    ldd\t%1, %0
    std\t%1, %0
-   fzero\t%0"
-  [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
-   (set_attr "fptype" "*,*,*,*,double,*,*,double")])
+   fzero\t%0
+   fone\t%0"
+  [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
+   (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
 
 (define_expand "movdi_pic_label_ref"
   [(set (match_dup 3) (high:DI
@@ -1918,16 +1920,16 @@
 })
 
 (define_insn "*movsf_insn"
-  [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
-	(match_operand:V32 1 "input_operand"        "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
+  [(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
+	(match_operand:V32 1 "input_operand"        "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
   "TARGET_FPU
    && (register_operand (operands[0], <V32:MODE>mode)
-       || register_or_zero_operand (operands[1], <V32:MODE>mode))"
+       || register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
 {
   if (GET_CODE (operands[1]) == CONST_DOUBLE
-      && (which_alternative == 2
-          || which_alternative == 3
-          || which_alternative == 4))
+      && (which_alternative == 3
+          || which_alternative == 4
+          || which_alternative == 5))
     {
       REAL_VALUE_TYPE r;
       long i;
@@ -1942,24 +1944,26 @@
     case 0:
       return "fzeros\t%0";
     case 1:
-      return "fmovs\t%1, %0";
+      return "fones\t%0";
     case 2:
-      return "mov\t%1, %0";
+      return "fmovs\t%1, %0";
     case 3:
-      return "sethi\t%%hi(%a1), %0";
+      return "mov\t%1, %0";
     case 4:
-      return "#";
+      return "sethi\t%%hi(%a1), %0";
     case 5:
+      return "#";
     case 6:
-      return "ld\t%1, %0";
     case 7:
+      return "ld\t%1, %0";
     case 8:
+    case 9:
       return "st\t%r1, %0";
     default:
       gcc_unreachable ();
     }
 }
-  [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
+  [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
 
 ;; Exactly the same as above, except that all `f' cases are deleted.
 ;; This is necessary to prevent reload from ever trying to use a `f' reg
@@ -2091,15 +2095,16 @@
 
 ;; We have available v9 double floats but not 64-bit integer registers.
 (define_insn "*movdf_insn_sp32_v9"
-  [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
-        (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
+  [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
+        (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
   "TARGET_FPU
    && TARGET_V9
    && ! TARGET_ARCH64
    && (register_operand (operands[0], <V64:MODE>mode)
-       || register_or_zero_operand (operands[1], <V64:MODE>mode))"
+       || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
   "@
   fzero\t%0
+  fone\t%0
   fmovd\t%1, %0
   ldd\t%1, %0
   stx\t%r1, %0
@@ -2109,9 +2114,9 @@
   #
   #
   #"
-  [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
-   (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
-   (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
+  [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
+   (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
+   (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
 
 (define_insn "*movdf_insn_sp32_v9_no_fpu"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
@@ -2132,14 +2137,15 @@
 
 ;; We have available both v9 double floats and 64-bit integer registers.
 (define_insn "*movdf_insn_sp64"
-  [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
-        (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
+  [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
+        (match_operand:V64 1 "input_operand"    "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
   "TARGET_FPU
    && TARGET_ARCH64
    && (register_operand (operands[0], <V64:MODE>mode)
-       || register_or_zero_operand (operands[1], <V64:MODE>mode))"
+       || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
   "@
   fzero\t%0
+  fone\t%0
   fmovd\t%1, %0
   ldd\t%1, %0
   std\t%1, %0
@@ -2147,9 +2153,9 @@
   ldx\t%1, %0
   stx\t%r1, %0
   #"
-  [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
-   (set_attr "length" "*,*,*,*,*,*,*,2")
-   (set_attr "fptype" "double,double,*,*,*,*,*,*")])
+  [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
+   (set_attr "length" "*,*,*,*,*,*,*,*,2")
+   (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
 
 (define_insn "*movdf_insn_sp64_no_fpu"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]