]> granicus.if.org Git - clang/commitdiff
[PowerPC] Enable vec_perm for long long and double vector types for VSX
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Fri, 14 Nov 2014 13:10:13 +0000 (13:10 +0000)
committerBill Schmidt <wschmidt@linux.vnet.ibm.com>
Fri, 14 Nov 2014 13:10:13 +0000 (13:10 +0000)
VSX makes the "vector long long" and "vector double" types available.
This patch enables the vec_perm interface for these types.  The same
builtin is generated regardless of the specified type, so no
additional work or testing is needed in the back end.  Tests are added
to ensure this builtin is generated by the front end.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221988 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Headers/altivec.h
test/CodeGen/builtins-ppc-vsx.c

index 5e27a8327b472e5cdbf92c0b1f6c099df14899a9..eded7b2754effc4781a1baaff18521aa467ebce0 100644 (file)
@@ -4902,6 +4902,52 @@ vec_perm(vector float __a, vector float __b, vector unsigned char __c)
 #endif
 }
 
+#ifdef __VSX__
+vector long long __ATTRS_o_ai
+vec_perm(vector long long __a, vector long long __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector long long)__builtin_altivec_vperm_4si(__b, __a, __d);
+#else
+  return (vector long long)__builtin_altivec_vperm_4si(__a, __b, __c);
+#endif
+}
+
+vector unsigned long long __ATTRS_o_ai
+vec_perm(vector unsigned long long __a, vector unsigned long long __b,
+         vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned long long)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector unsigned long long)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector double __ATTRS_o_ai
+vec_perm(vector double __a, vector double __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector double)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector double)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+#endif
+
 /* vec_vperm */
 
 static vector signed char __ATTRS_o_ai
@@ -4974,6 +5020,27 @@ vec_vperm(vector float __a, vector float __b, vector unsigned char __c)
   return vec_perm(__a, __b, __c);
 }
 
+#ifdef __VSX__
+static vector long long __ATTRS_o_ai
+vec_vperm(vector long long __a, vector long long __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector unsigned long long __ATTRS_o_ai
+vec_vperm(vector unsigned long long __a, vector unsigned long long __b,
+          vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector double __ATTRS_o_ai
+vec_vperm(vector double __a, vector double __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+#endif
+
 /* vec_re */
 
 static vector float __attribute__((__always_inline__))
index a5e3e4f441cdf1383cfe6bface039517db0ab66f..58a8cc32dce30b70b8dd448dea9c1029abbd9221 100644 (file)
@@ -1,6 +1,8 @@
 // REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -faltivec -target-feature +vsx -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
 
+vector unsigned char vuc = { 8,  9, 10, 11, 12, 13, 14, 15,
+                             0,  1,  2,  3,  4,  5,  6,  7};
 vector float vf = { -1.5, 2.5, -3.5, 4.5 };
 vector double vd = { 3.5, -7.5 };
 vector signed int vsi = { -1, 2, -3, 4 };
@@ -53,6 +55,25 @@ void test1() {
   res_d = __builtin_vsx_xsmindp(d, d);
 // CHECK: @llvm.ppc.vsx.xsmindp
 
+  /* vec_perm */
+  res_vsll = vec_perm(vsll, vsll, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
+  res_vull = vec_perm(vull, vull, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
+  res_vd = vec_perm(vd, vd, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
+  res_vsll = vec_vperm(vsll, vsll, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
+  res_vull = vec_vperm(vull, vull, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
+  res_vd = vec_vperm(vd, vd, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
   /* vec_vsx_ld */
 
   res_vsi = vec_vsx_ld(0, &vsi);