[PPC] altivec.h functions for converting half precision to single precision.
authorSean Fertile <sfertile@ca.ibm.com>
Mon, 14 Nov 2016 18:47:15 +0000 (18:47 +0000)
committerSean Fertile <sfertile@ca.ibm.com>
Mon, 14 Nov 2016 18:47:15 +0000 (18:47 +0000)
Adds 2 vector functions for converting from a vector of unsigned short to a
vector of float. One converts the low 4 halfwords and one converts the high
4 halfwords.

Differential Revision: https://reviews.llvm.org/D26534

llvm-svn: 286863

clang/include/clang/Basic/BuiltinsPPC.def
clang/lib/Headers/altivec.h
clang/test/CodeGen/builtins-ppc-p9vector.c

index c258e43..f87a892 100644 (file)
@@ -402,6 +402,7 @@ BUILTIN(__builtin_vsx_xvcvuxdsp, "V4fV2ULLi", "")
 BUILTIN(__builtin_vsx_xvcvdpsp, "V4fV2d", "")
 
 BUILTIN(__builtin_vsx_xvcvsphp, "V4fV4f", "")
+BUILTIN(__builtin_vsx_xvcvhpsp, "V4fV8Us", "")
 
 // Vector Test Data Class builtins
 BUILTIN(__builtin_vsx_xvtstdcdp, "V2ULLiV2dIi", "")
index 8a5312b..66e0359 100644 (file)
@@ -12322,6 +12322,27 @@ vec_extract_sig (vector double __a) {
   return __builtin_vsx_xvxsigdp(__a);
 }
 
+static __inline__ vector float __ATTRS_o_ai
+vec_extract_fp32_from_shorth(vector unsigned short __a) {
+  vector unsigned short __b =
+#ifdef __LITTLE_ENDIAN__
+            __builtin_shufflevector(__a, __a, 0, -1, 1, -1, 2, -1, 3, -1);
+#else
+            __builtin_shufflevector(__a, __a, -1, 0, -1, 1, -1, 2, -1, 3);
+#endif
+  return __builtin_vsx_xvcvhpsp(__b);
+}
+
+static __inline__ vector float __ATTRS_o_ai
+vec_extract_fp32_from_shortl(vector unsigned short __a) {
+  vector unsigned short __b =
+#ifdef __LITTLE_ENDIAN__
+            __builtin_shufflevector(__a, __a, 4, -1, 5, -1, 6, -1, 7, -1);
+#else
+            __builtin_shufflevector(__a, __a, -1, 4, -1, 5, -1, 6, -1, 7);
+#endif
+  return __builtin_vsx_xvcvhpsp(__b);
+}
 #endif /* __POWER9_VECTOR__ */
 
 /* vec_insert */
index c14ad71..80c6a43 100644 (file)
@@ -967,3 +967,21 @@ vector bool long long test87(void) {
 // CHECK-NEXT: ret <2 x i64>
   return vec_test_data_class(vda, __VEC_CLASS_FP_NOT_NORMAL);
 }
+vector float test88(void) {
+// CHECK-BE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 undef, i32 0, i32 undef, i32 1, i32 undef, i32 2, i32 undef, i32 3>
+// CHECK-BE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
+// CHECK-BE-NEXT: ret <4 x float>
+// CHECK-LE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 0, i32 undef, i32 1, i32 undef, i32 2, i32 undef, i32 3, i32 undef>
+// CHECK-LE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
+// CHECK-LE-NEXT: ret <4 x float>
+  return vec_extract_fp32_from_shorth(vusa);
+}
+vector float test89(void) {
+// CHECK-BE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 undef, i32 4, i32 undef, i32 5, i32 undef, i32 6, i32 undef, i32 7>
+// CHECK-BE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
+// CHECK-BE-NEXT: ret <4 x float>
+// CHECK-LE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 4, i32 undef, i32 5, i32 undef, i32 6, i32 undef, i32 7, i32 undef>
+// CHECK-LE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
+// CHECK-LE-NEXT: ret <4 x float>
+  return vec_extract_fp32_from_shortl(vusa);
+}