[Pixman] [PATCH 1/1] pixman: Fixing endianness problems for powerpc archs

Fernando Seiti Furusato ferseiti at linux.vnet.ibm.com
Mon May 25 18:43:39 PDT 2015


I have made some changes to the file pixman-vmx.c, which uses vmx (aka altivec)
to optimize pixman. Basically, what I did:
 Changed the usage of vec_perm, vec_mergeh and vec_mergel. They were giving
weird results when running on little endian. That was because the integer
vectors were being cast to char, which made them be ordered and permuted byte
by byte.
 Replaced usage of vec_lvsl to direct unaligned assignment operation (=). That
is because, according to Power ABI Specification, the usage of lvsl is
deprecated on ppc64le.
After those changes, all tests passed on both ppc64le and powerpc vms.

Signed-off-by: Fernando Seiti Furusato <ferseiti at linux.vnet.ibm.com>
---
 pixman/pixman-vmx.c | 61 +++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 45 insertions(+), 16 deletions(-)

diff --git a/pixman/pixman-vmx.c b/pixman/pixman-vmx.c
index c33631c..109104f 100644
--- a/pixman/pixman-vmx.c
+++ b/pixman/pixman-vmx.c
@@ -34,13 +34,25 @@
 
 #define AVV(x...) {x}
 
+#ifndef __LITTLE_ENDIAN__
+#define MERGEH(a,b) vec_mergeh(a,b)
+#define MERGEL(a,b) vec_mergel(a,b)
+#define SPLAT_VEC AVV(						\
+		0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,	\
+		0x08, 0x08, 0x08, 0x08, 0x0C, 0x0C, 0x0C, 0x0C)
+#else
+#define MERGEH(a,b) vec_mergeh(b,a)
+#define MERGEL(a,b) vec_mergel(b,a)
+#define SPLAT_VEC AVV(             				\
+		0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07,	\
+		0x0B, 0x0B, 0x0B, 0x0B, 0x0F, 0x0F, 0x0F, 0x0F)
+#endif
+
 static force_inline vector unsigned int
 splat_alpha (vector unsigned int pix)
 {
     return vec_perm (pix, pix,
-		     (vector unsigned char)AVV (
-			 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
-			 0x08, 0x08, 0x08, 0x08, 0x0C, 0x0C, 0x0C, 0x0C));
+		     (vector unsigned char)SPLAT_VEC);
 }
 
 static force_inline vector unsigned int
@@ -50,11 +62,11 @@ pix_multiply (vector unsigned int p, vector unsigned int a)
 
     /* unpack to short */
     hi = (vector unsigned short)
-	vec_mergeh ((vector unsigned char)AVV (0),
+	MERGEH ((vector unsigned char)AVV (0),
 		    (vector unsigned char)p);
 
     mod = (vector unsigned short)
-	vec_mergeh ((vector unsigned char)AVV (0),
+	MERGEH ((vector unsigned char)AVV (0),
 		    (vector unsigned char)a);
 
     hi = vec_mladd (hi, mod, (vector unsigned short)
@@ -67,10 +79,10 @@ pix_multiply (vector unsigned int p, vector unsigned int a)
 
     /* unpack to short */
     lo = (vector unsigned short)
-	vec_mergel ((vector unsigned char)AVV (0),
+	MERGEL ((vector unsigned char)AVV (0),
 		    (vector unsigned char)p);
     mod = (vector unsigned short)
-	vec_mergel ((vector unsigned char)AVV (0),
+	MERGEL ((vector unsigned char)AVV (0),
 		    (vector unsigned char)a);
 
     lo = vec_mladd (lo, mod, (vector unsigned short)
@@ -125,25 +137,31 @@ over (vector unsigned int src,
 }
 
 /* in == pix_multiply */
+#ifndef __LITTLE_ENDIAN__
+#define MASK_SHIFT(pointer) vec_lvsl(0,pointer)
+#else
+#define MASK_SHIFT(pointer) *((typeof(pointer ## _mask)*)pointer)
+#endif
+
 #define in_over(src, srca, mask, dest)					\
     over (pix_multiply (src, mask),					\
           pix_multiply (srca, mask), dest)
 
-
 #define COMPUTE_SHIFT_MASK(source)					\
-    source ## _mask = vec_lvsl (0, source);
+    source ## _mask = MASK_SHIFT(source);
 
 #define COMPUTE_SHIFT_MASKS(dest, source)				\
-    source ## _mask = vec_lvsl (0, source);
+    source ## _mask = MASK_SHIFT(source);
 
 #define COMPUTE_SHIFT_MASKC(dest, source, mask)				\
-    mask ## _mask = vec_lvsl (0, mask);					\
-    source ## _mask = vec_lvsl (0, source);
+    mask ## _mask = MASK_SHIFT(mask);					\
+    source ## _mask = MASK_SHIFT(source);
 
 /* notice you have to declare temp vars...
  * Note: tmp3 and tmp4 must remain untouched!
  */
 
+#ifndef __LITTLE_ENDIAN__
 #define LOAD_VECTORS(dest, source)			  \
     tmp1 = (typeof(tmp1))vec_ld (0, source);		  \
     tmp2 = (typeof(tmp2))vec_ld (15, source);		  \
@@ -162,11 +180,22 @@ over (vector unsigned int src,
     v ## mask = (typeof(v ## mask))			  \
 	vec_perm (tmp1, tmp2, mask ## _mask);
 
-#define LOAD_VECTORSM(dest, source, mask)				\
-    LOAD_VECTORSC (dest, source, mask)					\
-    v ## source = pix_multiply (v ## source,				\
-                                splat_alpha (v ## mask));
+#else
+#define LOAD_VECTORS(dest, source)                        \
+    v ## source = *((typeof(v ## source)*)source);        \
+    v ## dest = *((typeof(v ## dest)*)dest);
+
+#define LOAD_VECTORSC(dest, source, mask)                 \
+    v ## source = *((typeof(v ## source)*)source);        \
+    v ## dest = *((typeof(v ## dest)*)dest);              \
+    v ## mask = *((typeof(v ## mask)*)mask);
 
+#endif
+
+#define LOAD_VECTORSM(dest, source, mask)                               \
+    LOAD_VECTORSC (dest, source, mask)                                  \
+    v ## source = pix_multiply (v ## source,                            \
+                                splat_alpha (v ## mask));
 #define STORE_VECTOR(dest)						\
     vec_st ((vector unsigned int) v ## dest, 0, dest);
 
-- 
2.1.4



More information about the Pixman mailing list