Patchwork alignaddr and edge VIS intrinsic refinements

login
register
mail settings
Submitter David Miller
Date Sept. 20, 2011, 5:45 p.m.
Message ID <20110920.134544.2145371066102557128.davem@davemloft.net>
Download mbox | patch
Permalink /patch/115615/
State New
Headers show

Comments

David Miller - Sept. 20, 2011, 5:45 p.m.
We provided the big-endian 'alignaddr' but not the little-endian
version 'alignaddrl', add it.

The edge operations are meant to operate on addresses and return
a very small integer bitmask so use Pmode and return SImode.

Update documentation and intrinsic header, as needed.

Committed to trunk.

gcc/

	* config/sparc/sparc.md (UNSPEC_ALIGNADDRL): New unspec.
	(aligneddrl<P:mode>_vis): New pattern.
	(edge8_vis, edge8l_vis, edge16_vis, edge16l_vis, edge32_vis,
	edge32l_vis): Adjust to take Pmode arguments, and return SImode.
	* config/sparc/sparc.c (sparc_vis_init_builtins): Handle new
	alignaddrl insn, and adjust edge operations for updated types.
	* config/sparc/visintrin.h: Likewise.
	* doc/extend.texi: Make typing in VIS documentation match reality.

Patch

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 6ccc97b..68b5961 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -9149,6 +9149,9 @@  sparc_vis_init_builtins (void)
   tree ptr_ftype_ptr_di = build_function_type_list (ptr_type_node,
 		        			    ptr_type_node,
 					            intDI_type_node, 0);
+  tree si_ftype_ptr_ptr = build_function_type_list (intSI_type_node,
+		        			    ptr_type_node,
+					            ptr_type_node, 0);
 
   /* Packing and expanding vectors.  */
   def_builtin ("__builtin_vis_fpack16", CODE_FOR_fpack16_vis, v4qi_ftype_v4hi);
@@ -9186,29 +9189,55 @@  sparc_vis_init_builtins (void)
   def_builtin ("__builtin_vis_faligndatadi", CODE_FOR_faligndatadi_vis,
                di_ftype_di_di);
   if (TARGET_ARCH64)
-    def_builtin ("__builtin_vis_alignaddr", CODE_FOR_alignaddrdi_vis,
-	         ptr_ftype_ptr_di);
+    {
+      def_builtin ("__builtin_vis_alignaddr", CODE_FOR_alignaddrdi_vis,
+		   ptr_ftype_ptr_di);
+      def_builtin ("__builtin_vis_alignaddrl", CODE_FOR_alignaddrldi_vis,
+		   ptr_ftype_ptr_di);
+    }
   else
-    def_builtin ("__builtin_vis_alignaddr", CODE_FOR_alignaddrsi_vis,
-	         ptr_ftype_ptr_si);
+    {
+      def_builtin ("__builtin_vis_alignaddr", CODE_FOR_alignaddrsi_vis,
+		   ptr_ftype_ptr_si);
+      def_builtin ("__builtin_vis_alignaddrl", CODE_FOR_alignaddrlsi_vis,
+		   ptr_ftype_ptr_si);
+    }
 
   /* Pixel distance.  */
   def_builtin ("__builtin_vis_pdist", CODE_FOR_pdist_vis,
 	       di_ftype_v8qi_v8qi_di);
 
   /* Edge handling.  */
-  def_builtin ("__builtin_vis_edge8", CODE_FOR_edge8_vis,
-               di_ftype_di_di);
-  def_builtin ("__builtin_vis_edge8l", CODE_FOR_edge8l_vis,
-               di_ftype_di_di);
-  def_builtin ("__builtin_vis_edge16", CODE_FOR_edge16_vis,
-               di_ftype_di_di);
-  def_builtin ("__builtin_vis_edge16l", CODE_FOR_edge16l_vis,
-               di_ftype_di_di);
-  def_builtin ("__builtin_vis_edge32", CODE_FOR_edge32_vis,
-               di_ftype_di_di);
-  def_builtin ("__builtin_vis_edge32l", CODE_FOR_edge32l_vis,
-               di_ftype_di_di);
+  if (TARGET_ARCH64)
+    {
+      def_builtin ("__builtin_vis_edge8", CODE_FOR_edge8di_vis,
+		   si_ftype_ptr_ptr);
+      def_builtin ("__builtin_vis_edge8l", CODE_FOR_edge8ldi_vis,
+		   si_ftype_ptr_ptr);
+      def_builtin ("__builtin_vis_edge16", CODE_FOR_edge16di_vis,
+		   si_ftype_ptr_ptr);
+      def_builtin ("__builtin_vis_edge16l", CODE_FOR_edge16ldi_vis,
+		   si_ftype_ptr_ptr);
+      def_builtin ("__builtin_vis_edge32", CODE_FOR_edge32di_vis,
+		   si_ftype_ptr_ptr);
+      def_builtin ("__builtin_vis_edge32l", CODE_FOR_edge32ldi_vis,
+		   si_ftype_ptr_ptr);
+    }
+  else
+    {
+      def_builtin ("__builtin_vis_edge8", CODE_FOR_edge8si_vis,
+		   si_ftype_ptr_ptr);
+      def_builtin ("__builtin_vis_edge8l", CODE_FOR_edge8lsi_vis,
+		   si_ftype_ptr_ptr);
+      def_builtin ("__builtin_vis_edge16", CODE_FOR_edge16si_vis,
+		   si_ftype_ptr_ptr);
+      def_builtin ("__builtin_vis_edge16l", CODE_FOR_edge16lsi_vis,
+		   si_ftype_ptr_ptr);
+      def_builtin ("__builtin_vis_edge32", CODE_FOR_edge32si_vis,
+		   si_ftype_ptr_ptr);
+      def_builtin ("__builtin_vis_edge32l", CODE_FOR_edge32lsi_vis,
+		   si_ftype_ptr_ptr);
+    }
 }
 
 /* Handle TARGET_EXPAND_BUILTIN target hook.
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 483dea1..1fb59cc 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -66,6 +66,7 @@ 
    (UNSPEC_EDGE16L		54)
    (UNSPEC_EDGE32		55)
    (UNSPEC_EDGE32L		56)
+   (UNSPEC_ALIGNADDRL		57)
 
    (UNSPEC_SP_SET		60)
    (UNSPEC_SP_TEST		61)
@@ -7798,6 +7799,14 @@ 
   "TARGET_VIS"
   "alignaddr\t%r1, %r2, %0")
 
+(define_insn "alignaddrl<P:mode>_vis"
+  [(set (match_operand:P 0 "register_operand" "=r")
+        (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
+                   (match_operand:P 2 "register_or_zero_operand" "rJ")]
+         UNSPEC_ALIGNADDRL))]
+  "TARGET_VIS"
+  "alignaddrl\t%r1, %r2, %0")
+
 (define_insn "pdist_vis"
   [(set (match_operand:DI 0 "register_operand" "=e")
         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
@@ -7811,68 +7820,68 @@ 
 
 ;; Edge instructions produce condition codes equivalent to a 'subcc'
 ;; with the same operands.
-(define_insn "edge8_vis"
-  [(set (reg:CCX_NOOV 100)
-        (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
-			  	    (match_operand:DI 2 "register_operand" "rJ"))
-			  (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
-        (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
+(define_insn "edge8<P:mode>_vis"
+  [(set (reg:CC_NOOV 100)
+        (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
+			  	  (match_operand:P 2 "register_operand" "rJ"))
+			 (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
   "TARGET_VIS"
   "edge8\t%r1, %r2, %0"
   [(set_attr "type" "edge")])
 
-(define_insn "edge8l_vis"
-  [(set (reg:CCX_NOOV 100)
-        (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
-			  	    (match_operand:DI 2 "register_operand" "rJ"))
-			  (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
-        (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
+(define_insn "edge8l<P:mode>_vis"
+  [(set (reg:CC_NOOV 100)
+        (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
+			  	  (match_operand:P 2 "register_operand" "rJ"))
+			 (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
   "TARGET_VIS"
   "edge8l\t%r1, %r2, %0"
   [(set_attr "type" "edge")])
 
-(define_insn "edge16_vis"
-  [(set (reg:CCX_NOOV 100)
-        (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
-			  	    (match_operand:DI 2 "register_operand" "rJ"))
-			  (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
-        (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
+(define_insn "edge16<P:mode>_vis"
+  [(set (reg:CC_NOOV 100)
+        (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
+			  	  (match_operand:P 2 "register_operand" "rJ"))
+			 (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
   "TARGET_VIS"
   "edge16\t%r1, %r2, %0"
   [(set_attr "type" "edge")])
 
-(define_insn "edge16l_vis"
-  [(set (reg:CCX_NOOV 100)
-        (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
-			  	    (match_operand:DI 2 "register_operand" "rJ"))
-			  (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
-        (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
+(define_insn "edge16l<P:mode>_vis"
+  [(set (reg:CC_NOOV 100)
+        (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
+			  	  (match_operand:P 2 "register_operand" "rJ"))
+			 (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
   "TARGET_VIS"
   "edge16l\t%r1, %r2, %0"
   [(set_attr "type" "edge")])
 
-(define_insn "edge32_vis"
-  [(set (reg:CCX_NOOV 100)
-        (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
-			  	    (match_operand:DI 2 "register_operand" "rJ"))
-			  (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
-        (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
+(define_insn "edge32<P:mode>_vis"
+  [(set (reg:CC_NOOV 100)
+        (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
+			  	  (match_operand:P 2 "register_operand" "rJ"))
+			 (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
   "TARGET_VIS"
   "edge32\t%r1, %r2, %0"
   [(set_attr "type" "edge")])
 
-(define_insn "edge32l_vis"
-  [(set (reg:CCX_NOOV 100)
-        (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "rJ")
-			  	    (match_operand:DI 2 "register_operand" "rJ"))
-			  (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
-        (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
+(define_insn "edge32l<P:mode>_vis"
+  [(set (reg:CC_NOOV 100)
+        (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
+			  	  (match_operand:P 2 "register_operand" "rJ"))
+			 (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
   "TARGET_VIS"
   "edge32l\t%r1, %r2, %0"
   [(set_attr "type" "edge")])
diff --git a/gcc/config/sparc/visintrin.h b/gcc/config/sparc/visintrin.h
index 25d7bab..1b31451 100644
--- a/gcc/config/sparc/visintrin.h
+++ b/gcc/config/sparc/visintrin.h
@@ -38,6 +38,13 @@  __vis_alignaddr (void *__A, long __B)
   return __builtin_vis_alignaddr (__A, __B);
 }
 
+extern __inline void *
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_alignaddrl (void *__A, long __B)
+{
+  return __builtin_vis_alignaddrl (__A, __B);
+}
+
 extern __inline __i64
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
 __vis_faligndatadi (__i64 __A, __i64 __B)
@@ -157,44 +164,44 @@  __vis_pdist (__v8qi __A, __v8qi __B, __i64 __C)
   return __builtin_vis_pdist (__A, __B, __C);
 }
 
-extern __inline __i64
+extern __inline int
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-__vis_edge8 (__i64 __A, __i64 __B)
+__vis_edge8 (void *__A, void *__B)
 {
   return __builtin_vis_edge8 (__A, __B);
 }
 
-extern __inline __i64
+extern __inline int
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-__vis_edge8l (__i64 __A, __i64 __B)
+__vis_edge8l (void *__A, void *__B)
 {
   return __builtin_vis_edge8l (__A, __B);
 }
 
-extern __inline __i64
+extern __inline int
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-__vis_edge16 (__i64 __A, __i64 __B)
+__vis_edge16 (void *__A, void *__B)
 {
   return __builtin_vis_edge16 (__A, __B);
 }
 
-extern __inline __i64
+extern __inline int
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-__vis_edge16l (__i64 __A, __i64 __B)
+__vis_edge16l (void *__A, void *__B)
 {
   return __builtin_vis_edge16l (__A, __B);
 }
 
-extern __inline __i64
+extern __inline int
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-__vis_edge32 (__i64 __A, __i64 __B)
+__vis_edge32 (void *__A, void *__B)
 {
   return __builtin_vis_edge32 (__A, __B);
 }
 
-extern __inline __i64
+extern __inline int
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-__vis_edge32l (__i64 __A, __i64 __B)
+__vis_edge32l (void *__A, void *__B)
 {
   return __builtin_vis_edge32l (__A, __B);
 }
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 75f4874..3e6e05e 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -12932,10 +12932,11 @@  switch, the VIS extension is exposed as the following built-in functions:
 typedef int v2si __attribute__ ((vector_size (8)));
 typedef short v4hi __attribute__ ((vector_size (8)));
 typedef short v2hi __attribute__ ((vector_size (4)));
-typedef char v8qi __attribute__ ((vector_size (8)));
-typedef char v4qi __attribute__ ((vector_size (4)));
+typedef unsigned char v8qi __attribute__ ((vector_size (8)));
+typedef unsigned char v4qi __attribute__ ((vector_size (4)));
 
 void * __builtin_vis_alignaddr (void *, long);
+void * __builtin_vis_alignaddrl (void *, long);
 int64_t __builtin_vis_faligndatadi (int64_t, int64_t);
 v2si __builtin_vis_faligndatav2si (v2si, v2si);
 v4hi __builtin_vis_faligndatav4hi (v4si, v4si);
@@ -12944,26 +12945,26 @@  v8qi __builtin_vis_faligndatav8qi (v8qi, v8qi);
 v4hi __builtin_vis_fexpand (v4qi);
 
 v4hi __builtin_vis_fmul8x16 (v4qi, v4hi);
-v4hi __builtin_vis_fmul8x16au (v4qi, v4hi);
-v4hi __builtin_vis_fmul8x16al (v4qi, v4hi);
+v4hi __builtin_vis_fmul8x16au (v4qi, v2hi);
+v4hi __builtin_vis_fmul8x16al (v4qi, v2hi);
 v4hi __builtin_vis_fmul8sux16 (v8qi, v4hi);
 v4hi __builtin_vis_fmul8ulx16 (v8qi, v4hi);
 v2si __builtin_vis_fmuld8sux16 (v4qi, v2hi);
 v2si __builtin_vis_fmuld8ulx16 (v4qi, v2hi);
 
 v4qi __builtin_vis_fpack16 (v4hi);
-v8qi __builtin_vis_fpack32 (v2si, v2si);
+v8qi __builtin_vis_fpack32 (v2si, v8qi);
 v2hi __builtin_vis_fpackfix (v2si);
 v8qi __builtin_vis_fpmerge (v4qi, v4qi);
 
 int64_t __builtin_vis_pdist (v8qi, v8qi, int64_t);
 
-int64_t __builtin_vis_edge8 (int64_t, int64_t);
-int64_t __builtin_vis_edge8l (int64_t, int64_t);
-int64_t __builtin_vis_edge16 (int64_t, int64_t);
-int64_t __builtin_vis_edge16l (int64_t, int64_t);
-int64_t __builtin_vis_edge32 (int64_t, int64_t);
-int64_t __builtin_vis_edge32l (int64_t, int64_t);
+int __builtin_vis_edge8 (void *, void *);
+int __builtin_vis_edge8l (void *, void *);
+int __builtin_vis_edge16 (void *, void *);
+int __builtin_vis_edge16l (void *, void *);
+int __builtin_vis_edge32 (void *, void *);
+int __builtin_vis_edge32l (void *, void *);
 @end smallexample
 
 @node SPU Built-in Functions