r210391 - [PPC64LE] Implement little-endian semantics for vec_unpack[hl]
Bill Schmidt
wschmidt at linux.vnet.ibm.com
Fri Jun 6 19:20:52 PDT 2014
Author: wschmidt
Date: Fri Jun 6 21:20:52 2014
New Revision: 210391
URL: http://llvm.org/viewvc/llvm-project?rev=210391&view=rev
Log:
[PPC64LE] Implement little-endian semantics for vec_unpack[hl]
The PowerPC vector-unpack-high and vector-unpack-low instructions
are defined architecturally with a big-endian bias, in that the vector
element numbering is assumed to be "left to right" regardless of
whether the processor is in big-endian or little-endian mode. This
effectively reverses the meaning of "high" and "low." Such a
definition is unnatural for little-endian code generation.
To facilitate ease of porting, the vec_unpackh and vec_unpackl
interfaces are designed to use natural element ordering, so that
elements are numbered according to little-endian design principles
when code is generated for a little-endian target. The desired
semantics can be achieved by using the opposite instruction for
little-endian mode. That is, when a call to vec_unpackh appears in
the code, a vector-unpack-low is generated, and when a call to
vec_unpackl appears in the code, a vector-unpack-high is generated.
The correctness of this code is tested by the new unpack.c test
added in a previous patch, as well as the modifications to
builtins-ppc-altivec.c in the present patch.
Note that these interfaces were originally incorrectly implemented
when they take a vector pixel argument. This patch corrects this
implementation for both big- and little-endian code generation.
Modified:
cfe/trunk/lib/Headers/altivec.h
cfe/trunk/test/CodeGen/builtins-ppc-altivec.c
Modified: cfe/trunk/lib/Headers/altivec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/altivec.h?rev=210391&r1=210390&r2=210391&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/altivec.h (original)
+++ cfe/trunk/lib/Headers/altivec.h Fri Jun 6 21:20:52 2014
@@ -8430,34 +8430,57 @@ vec_vrfiz(vector float __a)
/* vec_unpackh */
+/* The vector unpack instructions all have a big-endian bias, so for
+ little endian we must reverse the meanings of "high" and "low." */
+
static vector short __ATTRS_o_ai
vec_unpackh(vector signed char __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return __builtin_altivec_vupklsb((vector char)__a);
+#else
return __builtin_altivec_vupkhsb((vector char)__a);
+#endif
}
static vector bool short __ATTRS_o_ai
vec_unpackh(vector bool char __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#else
return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#endif
}
static vector int __ATTRS_o_ai
vec_unpackh(vector short __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return __builtin_altivec_vupklsh(__a);
+#else
return __builtin_altivec_vupkhsh(__a);
+#endif
}
static vector bool int __ATTRS_o_ai
vec_unpackh(vector bool short __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#else
return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#endif
}
static vector unsigned int __ATTRS_o_ai
vec_unpackh(vector pixel __a)
{
- return (vector unsigned int)__builtin_altivec_vupkhsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+ return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#else
+ return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#endif
}
/* vec_vupkhsb */
@@ -8465,13 +8488,21 @@ vec_unpackh(vector pixel __a)
static vector short __ATTRS_o_ai
vec_vupkhsb(vector signed char __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return __builtin_altivec_vupklsb((vector char)__a);
+#else
return __builtin_altivec_vupkhsb((vector char)__a);
+#endif
}
static vector bool short __ATTRS_o_ai
vec_vupkhsb(vector bool char __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#else
return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#endif
}
/* vec_vupkhsh */
@@ -8479,19 +8510,31 @@ vec_vupkhsb(vector bool char __a)
static vector int __ATTRS_o_ai
vec_vupkhsh(vector short __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return __builtin_altivec_vupklsh(__a);
+#else
return __builtin_altivec_vupkhsh(__a);
+#endif
}
static vector bool int __ATTRS_o_ai
vec_vupkhsh(vector bool short __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#else
return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#endif
}
static vector unsigned int __ATTRS_o_ai
vec_vupkhsh(vector pixel __a)
{
- return (vector unsigned int)__builtin_altivec_vupkhsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+ return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#else
+ return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#endif
}
/* vec_unpackl */
@@ -8499,31 +8542,51 @@ vec_vupkhsh(vector pixel __a)
static vector short __ATTRS_o_ai
vec_unpackl(vector signed char __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return __builtin_altivec_vupkhsb((vector char)__a);
+#else
return __builtin_altivec_vupklsb((vector char)__a);
+#endif
}
static vector bool short __ATTRS_o_ai
vec_unpackl(vector bool char __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#else
return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#endif
}
static vector int __ATTRS_o_ai
vec_unpackl(vector short __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return __builtin_altivec_vupkhsh(__a);
+#else
return __builtin_altivec_vupklsh(__a);
+#endif
}
static vector bool int __ATTRS_o_ai
vec_unpackl(vector bool short __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#else
return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#endif
}
static vector unsigned int __ATTRS_o_ai
vec_unpackl(vector pixel __a)
{
- return (vector unsigned int)__builtin_altivec_vupklsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+ return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#else
+ return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#endif
}
/* vec_vupklsb */
@@ -8531,13 +8594,21 @@ vec_unpackl(vector pixel __a)
static vector short __ATTRS_o_ai
vec_vupklsb(vector signed char __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return __builtin_altivec_vupkhsb((vector char)__a);
+#else
return __builtin_altivec_vupklsb((vector char)__a);
+#endif
}
static vector bool short __ATTRS_o_ai
vec_vupklsb(vector bool char __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#else
return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#endif
}
/* vec_vupklsh */
@@ -8545,19 +8616,31 @@ vec_vupklsb(vector bool char __a)
static vector int __ATTRS_o_ai
vec_vupklsh(vector short __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return __builtin_altivec_vupkhsh(__a);
+#else
return __builtin_altivec_vupklsh(__a);
+#endif
}
static vector bool int __ATTRS_o_ai
vec_vupklsh(vector bool short __a)
{
+#ifdef __LITTLE_ENDIAN__
+ return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#else
return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#endif
}
static vector unsigned int __ATTRS_o_ai
vec_vupklsh(vector pixel __a)
{
- return (vector unsigned int)__builtin_altivec_vupklsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+ return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#else
+ return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#endif
}
/* vec_xor */
Modified: cfe/trunk/test/CodeGen/builtins-ppc-altivec.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins-ppc-altivec.c?rev=210391&r1=210390&r2=210391&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/builtins-ppc-altivec.c (original)
+++ cfe/trunk/test/CodeGen/builtins-ppc-altivec.c Fri Jun 6 21:20:52 2014
@@ -5173,84 +5173,84 @@ void test6() {
/* vec_unpackh */
res_vs = vec_unpackh(vsc);
// CHECK: @llvm.ppc.altivec.vupkhsb
-// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
res_vbs = vec_unpackh(vbc);
// CHECK: @llvm.ppc.altivec.vupkhsb
-// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
res_vi = vec_unpackh(vs);
// CHECK: @llvm.ppc.altivec.vupkhsh
-// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
res_vbi = vec_unpackh(vbs);
// CHECK: @llvm.ppc.altivec.vupkhsh
-// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
res_vui = vec_unpackh(vp);
-// CHECK: @llvm.ppc.altivec.vupkhsh
-// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+// CHECK: @llvm.ppc.altivec.vupkhpx
+// CHECK-LE: @llvm.ppc.altivec.vupklpx
res_vs = vec_vupkhsb(vsc);
// CHECK: @llvm.ppc.altivec.vupkhsb
-// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
res_vbs = vec_vupkhsb(vbc);
// CHECK: @llvm.ppc.altivec.vupkhsb
-// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
res_vi = vec_vupkhsh(vs);
// CHECK: @llvm.ppc.altivec.vupkhsh
-// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
res_vbi = vec_vupkhsh(vbs);
// CHECK: @llvm.ppc.altivec.vupkhsh
-// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
res_vui = vec_vupkhsh(vp);
-// CHECK: @llvm.ppc.altivec.vupkhsh
-// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+// CHECK: @llvm.ppc.altivec.vupkhpx
+// CHECK-LE: @llvm.ppc.altivec.vupklpx
/* vec_unpackl */
res_vs = vec_unpackl(vsc);
// CHECK: @llvm.ppc.altivec.vupklsb
-// CHECK-LE: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
res_vbs = vec_unpackl(vbc);
// CHECK: @llvm.ppc.altivec.vupklsb
-// CHECK-LE: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
res_vi = vec_unpackl(vs);
// CHECK: @llvm.ppc.altivec.vupklsh
-// CHECK-LE: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
res_vbi = vec_unpackl(vbs);
// CHECK: @llvm.ppc.altivec.vupklsh
-// CHECK-LE: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
res_vui = vec_unpackl(vp);
-// CHECK: @llvm.ppc.altivec.vupklsh
-// CHECK-LE: @llvm.ppc.altivec.vupklsh
+// CHECK: @llvm.ppc.altivec.vupklpx
+// CHECK-LE: @llvm.ppc.altivec.vupkhpx
res_vs = vec_vupklsb(vsc);
// CHECK: @llvm.ppc.altivec.vupklsb
-// CHECK-LE: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
res_vbs = vec_vupklsb(vbc);
// CHECK: @llvm.ppc.altivec.vupklsb
-// CHECK-LE: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
res_vi = vec_vupklsh(vs);
// CHECK: @llvm.ppc.altivec.vupklsh
-// CHECK-LE: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
res_vbi = vec_vupklsh(vbs);
// CHECK: @llvm.ppc.altivec.vupklsh
-// CHECK-LE: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
res_vui = vec_vupklsh(vp);
-// CHECK: @llvm.ppc.altivec.vupklsh
-// CHECK-LE: @llvm.ppc.altivec.vupklsh
+// CHECK: @llvm.ppc.altivec.vupklpx
+// CHECK-LE: @llvm.ppc.altivec.vupkhpx
/* vec_xor */
res_vsc = vec_xor(vsc, vsc);
More information about the cfe-commits
mailing list