b/gcc/config/rs6000/rs6000-builtins.def
@@ -1119,6 +1119,14 @@
const signed short __builtin_vec_ext_v8hi (vss, signed int);
VEC_EXT_V8HI nothing {extract}
+;; __builtin_vsx_xvcvsxwsp, __builtin_vsx_xvcvuxwsp generate VSX
instructions
+;; if VSX enabled and Altivec instructions if VSX is not enabled.
+ const vf __builtin_vsx_xvcvsxwsp (vsi);
+ XVCVSXWSP vsx_floatv4siv4sf2 {}
+
+ const vf __builtin_vsx_xvcvuxwsp (vui);
+ XVCVUXWSP vsx_floatunsv4siv4sf2 {}
+
; Cell builtins.
[cell]
pure vsc __builtin_altivec_lvlx (signed long, const void *);
@@ -1454,22 +1462,22 @@
const vull __builtin_vsx_udiv_2di (vull, vull);
UDIV_V2DI vsx_udiv_v2di {}
- const vd __builtin_vsx_uns_doublee_v4si (vsi);
+ const vd __builtin_vsx_uns_doublee_v4si (vui);
UNS_DOUBLEE_V4SI unsdoubleev4si2 {}
- const vd __builtin_vsx_uns_doubleh_v4si (vsi);
+ const vd __builtin_vsx_uns_doubleh_v4si (vui);
UNS_DOUBLEH_V4SI unsdoublehv4si2 {}
- const vd __builtin_vsx_uns_doublel_v4si (vsi);
+ const vd __builtin_vsx_uns_doublel_v4si (vui);
UNS_DOUBLEL_V4SI unsdoublelv4si2 {}
- const vd __builtin_vsx_uns_doubleo_v4si (vsi);
+ const vd __builtin_vsx_uns_doubleo_v4si (vui);
UNS_DOUBLEO_V4SI unsdoubleov4si2 {}
- const vf __builtin_vsx_uns_floate_v2di (vsll);
+ const vf __builtin_vsx_uns_floate_v2di (vull);
UNS_FLOATE_V2DI unsfloatev2di {}
- const vf __builtin_vsx_uns_floato_v2di (vsll);
+ const vf __builtin_vsx_uns_floato_v2di (vull);
UNS_FLOATO_V2DI unsfloatov2di {}
const vsll __builtin_vsx_vsigned_v2df (vd);
@@ -1604,9 +1612,6 @@
const vf __builtin_vsx_xvcvsxdsp (vsll);
XVCVSXDSP vsx_xvcvsxdsp {}
- const vf __builtin_vsx_xvcvsxwsp (vsi);
- XVCVSXWSP vsx_floatv4siv4sf2 {}
-
const vd __builtin_vsx_xvcvuxddp (vsll);
XVCVUXDDP vsx_floatunsv2div2df2 {}
@@ -1616,9 +1621,6 @@
const vf __builtin_vsx_xvcvuxdsp (vull);
XVCVUXDSP vsx_xvcvuxdsp {}
- const vf __builtin_vsx_xvcvuxwsp (vsi);
- XVCVUXWSP vsx_floatunsv4siv4sf2 {}
-
fpmath vd __builtin_vsx_xvdivdp (vd, vd);
XVDIVDP divv2df3 {}
@@ -2278,7 +2280,7 @@
const vss __builtin_vsx_revb_v8hi (vss);
REVB_V8HI revb_v8hi {}
- const vf __builtin_vsx_uns_float2_v2di (vsll, vsll);
+ const vf __builtin_vsx_uns_float2_v2di (vull, vull);
UNS_FLOAT2_V2DI uns_float2_v2di {}
const vsi __builtin_vsx_vsigned2_v2df (vd, vd);
@@ -2272,14 +2272,60 @@ (define_insn "vsx_copysign<mode>3"
;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX.
;; Don't use vsx_register_operand here, use gpc_reg_operand to match
rs6000.md
;; in allowing virtual registers.
-(define_insn "vsx_float<VSi><mode>2"
+(define_expand "vsx_floatv4siv4sf2"
+ [(set (match_operand:V4SF 0 "gpc_reg_operand" "=wa")
+ (float:V4SF (match_operand:V4SI 1 "gpc_reg_operand" "wa")))]
+ "VECTOR_UNIT_VSX_P (V4SFmode)"
+{
+ if (VECTOR_UNIT_VSX_P (V4SFmode))
+ emit_insn (gen_vsx_floatv4siv4sf2_internal (operands[0],
+ operands[1]));
+ else
+ emit_insn (gen_altivec_vcfsx (operands[0], operands[1],
+ const0_rtx));
+ DONE;
+})
+
+(define_expand "vsx_floatv2div2df2"
+ [(set (match_operand:V2DF 0 "gpc_reg_operand" "=wa")
+ (float:V2DF (match_operand:V2DI 1 "gpc_reg_operand" "wa")))]
+ "VECTOR_UNIT_VSX_P (V2DFmode)"
+{
+ emit_insn (gen_vsx_floatv2div2df2_internal (operands[0],
+ operands[1]));
+})
+
+(define_insn "vsx_float<VSi><mode>2_internal"
[(set (match_operand:VSX_F 0 "gpc_reg_operand" "=wa")
(float:VSX_F (match_operand:<VSI> 1 "gpc_reg_operand" "wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"xvcvsx<VSc><sd>p %x0,%x1"
[(set_attr "type" "<VStype_simple>")])
-(define_insn "vsx_floatuns<VSi><mode>2"
+(define_expand "vsx_floatunsv4siv4sf2"
+ [(set (match_operand:V4SF 0 "gpc_reg_operand" "=wa")
+ (unsigned_float:V4SF (match_operand:V4SI 1 "gpc_reg_operand" "wa")))]
+ "VECTOR_UNIT_VSX_P (V4SFmode)"
+{
+ if (VECTOR_UNIT_VSX_P (V4SFmode))
+ emit_insn (gen_vsx_floatunsv4siv4sf2_internal (operands[0],
+ operands[1]));
+ else
+ emit_insn (gen_altivec_vcfux (operands[0], operands[1],
+ const0_rtx));
+ DONE;
+})
+
+(define_expand "vsx_floatunsv2div2df2"
+ [(set (match_operand:V2DF 0 "gpc_reg_operand" "=wa")
+ (unsigned_float:V2DF (match_operand:V2DI 1 "gpc_reg_operand" "wa")))]
+ "VECTOR_UNIT_VSX_P (V2DFmode)"
+{
+ emit_insn (gen_vsx_floatunsv2div2df2_internal (operands[0],
+ operands[1]));
+})
+
+(define_insn "vsx_floatuns<VSi><mode>2_internal"
[(set (match_operand:VSX_F 0 "gpc_reg_operand" "=wa")
(unsigned_float:VSX_F (match_operand:<VSI> 1 "gpc_reg_operand"
"wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
@@ -23008,6 +23008,28 @@ but the index value must be 0.
Only functions excluded from the PVIPR are listed here.
+The following built-ins convert signed and unsigned vectors of ints and
+long long ints to a vector of 32-bit floating point values.
+
+@smallexample
+vector float __builtin_altivec_float_sisf (vector int);
+vector float __builtin_altivec_uns_float_sisf (vector unsigned int);
+@end smallexample
+
+The @code{__builtin_altivec_float_sisf} and
+@code{__builtin_altivec_uns_float_sisf} built-ins convert signed and
+unsigned vectors of 32-bit integers to a vector of 32-bit floating point
+values.
+
+@smallexample
+vector int __builtin_altivec_fix_sfsi (vector float);
+vector int __builtin_altivec_fixuns_sfsi (vector float);
+@end smallexample
+
+The @code{__builtin_altivec_fix_sfsi} and
@code{__builtin_altivec_fixuns_sfsi}
+built-ins convert vectors of 32-bit floating point values to
+signed or unsigned 32-bit integers respectively.
+
@smallexample
vector __int128 vec_vaddcuq (vector __int128, vector __int128);
vector __uint128 vec_vaddcuq (vector __uint128, vector __uint128);
a/gcc/testsuite/gcc.target/powerpc/builtins-3-altivec-runnable.c
b/gcc/testsuite/gcc.target/powerpc/builtins-3-altivec-runnable.c
new file mode 100644
@@ -0,0 +1,35 @@
+/* { dg-do run { target { vsx_hw } } } */
+/* { dg-options "-mdejagnu-cpu=power6 -maltivec -O2" } */
+/* { dg-require-effective-target powerpc_altivec } */
+
+/* This test if for the vector signed/unsigned integer to vector float
+ conversions when VSX is not available. The overloaded built-ins for the
+ conversions will generate Altivec conversions when VSX is not available.
+*/
+
+#include <altivec.h> // vector
+#include "builtins-3-runnable.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+int main()
+{
+ int i;
+ vector unsigned int vec_unint, vec_uns_int_expected,
vec_uns_int_result;
+ vector signed int vec_int, vec_int_expected, vec_int_result;
+ vector float vec_flt_result, vec_flt_expected;
+
+ vec_int = (vector signed int){ -1, 3, -5, 1234567 };
+ vec_unint = (vector unsigned int){ 9, 11, 15, 2468013579 };
+
+ /* conversion of integer vector to single precision float vector */
+ vec_flt_expected = (vector float){-1.00, 3.00, -5.00, 1234567.00};
+ vec_flt_result = vec_float (vec_int);
+ test_result_sp(ALL, vec_flt_result, vec_flt_expected);
+
+ vec_flt_expected = (vector float){9.00, 11.00, 15.00, 2468013579.0};
+ vec_flt_result = vec_float (vec_unint);
+ test_result_sp(ALL, vec_flt_result, vec_flt_expected);
+}
b/gcc/testsuite/gcc.target/powerpc/builtins-3-runnable.c
@@ -3,16 +3,8 @@
/* { dg-options "-maltivec -mvsx" } */
#include <altivec.h> // vector
+#include "builtins-3-runnable.h"
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
-#define ALL 1
-#define EVEN 2
-#define ODD 3
-
-void abort (void);
void test_int_result(int check, vector int vec_result, vector int
vec_expected)
{
@@ -116,39 +108,6 @@ void test_ll_unsigned_int_result(vector long long
unsigned int vec_result,
}
}
-void test_result_sp(int check, vector float vec_result,
- vector float vec_expected)
-{
- int i;
- for(i = 0; i<4; i++) {
-
- switch (check) {
- case ALL:
- break;
- case EVEN:
- if (i%2 == 0)
- break;
- else
- continue;
- case ODD:
- if (i%2 != 0)
- break;
- else
- continue;
- }
-
- if (vec_result[i] != vec_expected[i]) {
-#ifdef DEBUG
- printf("Test_result_sp: ");
- printf("vec_result[%d] (%f) != vec_expected[%d] (%f)\n",
- i, vec_result[i], i, vec_expected[i]);
-#else
- abort();
-#endif
- }
- }
-}
-
void test_result_dp(vector double vec_result, vector double vec_expected)
{
if (vec_result[0] != vec_expected[0]) {
b/gcc/testsuite/gcc.target/powerpc/builtins-3-runnable.h
new file mode 100644
@@ -0,0 +1,51 @@
+/* Builtins vsx_floatv4siv4sf2 and vsx_floatunsv4siv4sf2 generate VSX
+ instructions if VSX if available. They fall back to Altivec
instructions
+ if VSX is not available. The functions are used in the test the
conversion
+ of signed and unsigned vectors of integers to a vector of single
precision
+ floating point values. The function is used in the VSX text
+ builtins-3-runnable.c and in the altivec test
builtins-3-altivec-runnable.c.
+*/
+
+#define ALL 1
+#define EVEN 2
+#define ODD 3
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+void abort (void);
+
+void test_result_sp(int check, vector float vec_result,
+ vector float vec_expected)
+{
+ int i;
+ for(i = 0; i<4; i++) {
+
+ switch (check) {
+ case ALL:
+ break;
+ case EVEN:
+ if (i%2 == 0)
+ break;
+ else
+ continue;
+ case ODD:
+ if (i%2 != 0)
+ break;
+ else
+ continue;
+ }
+
+ if (vec_result[i] != vec_expected[i]) {
+#ifdef DEBUG
+ printf("Test_result_sp: ");
+ printf("vec_result[%d] (%f) != vec_expected[%d] (%f)\n",
+ i, vec_result[i], i, vec_expected[i]);
+#else
+ abort();
+#endif
+ }
+ }
+}
+
a/gcc/testsuite/gcc.target/powerpc/vsx-int-to-float-runnable.c
b/gcc/testsuite/gcc.target/powerpc/vsx-int-to-float-runnable.c
new file mode 100644
@@ -0,0 +1,260 @@
+/* { dg-do run } */
+/* { dg-options "-mvsx -mdejagnu-cpu=power8 -O2" } */
+/* { dg-require-effective-target powerpc_vsx } */
+
+/* The __builtin_vsx_float2_v2di builtin uses the vmgrow instruction
which is
+ Power 8. The conversion instructions are all Power 7. */
+
+#include <altivec.h> // vector
+
+#define DEBUG 0
+
+#if DEBUG
+#include <stdio.h>
+#endif
+
+void abort (void);
+
+int main (void)
+{
+ int i;
+ vector int src_int = { 5, 17, 400, 9000 };
+ vector unsigned int src_uint = { 1, 20, 300, 4000 };
+ vector signed long long int src_sll = { 13, 513 };
+ vector unsigned long long int src_ull = { 27, 731 };
+ vector signed long long int srcB_sll = { 27, 739 };
+ vector unsigned long long int srcB_ull = { 19, 57 };
+ vector int result_int, expected_result_int;
+ vector unsigned int result_uint, expected_result_uint;
+ vector float src_f = { 3.1, -9.1, 20.9, -99.99};
+ vector float result_float, expected_result_float;
+ vector double result_double, expected_result_double;
+
+ /* Test vector signed and unsigned int to float. */
+ expected_result_float[0] = 5.0;
+ expected_result_float[1] = 17.0;
+ expected_result_float[2] = 400.0;
+ expected_result_float[3] = 9000.0;
+
+ result_float = __builtin_altivec_float_sisf (src_int);
+
+ for (i = 0; i < 4; i++)
+ {
+ if (result_float[i] != expected_result_float[i])
+#if DEBUG
+ {
+ printf ("ERROR, __builtin_altivec_float_sisf (src_uint) result
doe not match expected output.\n");
+ printf (" result_float[%d] = %f ", i, result_float[i]);
+ printf (" expected result_float[%d] = %f\n", i,
+ expected_result_float[i]);
+ }
+#else
+ abort ();
+#endif
+ }
+
+ expected_result_float[0] = 1.0;
+ expected_result_float[1] = 20.0;
+ expected_result_float[2] = 300.0;
+ expected_result_float[3] = 4000.0;
+
+ result_float = __builtin_altivec_uns_float_sisf (src_uint);
+
+ for (i = 0; i < 4; i++)
+ {
+ if (result_float[i] != expected_result_float[i])
+#if DEBUG
+ {
+ printf ("ERROR, __builtin_altivec_uns_float_sisf (src_uint)
result doe not match expected output.\n");
+ printf (" result_float[%d] = %f ", i, result_float[i]);
+ printf (" expected result_float[%d] = %f\n", i,
+ expected_result_float[i]);
+ }
+#else
+ abort ();
+#endif
+ }
+
+ /* Test vector signed and unsigned long long int to Double. */
+
+ /* Test even result elements. */
+ expected_result_float[0] = 13.0;
+ expected_result_float[1] = 0.0;
+ expected_result_float[2] = 513.0;
+ expected_result_float[3] = 0.0;
+
+ result_float = __builtin_vsx_floate_v2di(src_sll);
+
+ for (i = 0; i < 4; i = i + 2)
+ {
+ if (result_float[i] != expected_result_float[i])
+#if DEBUG
+ {
+ printf ("ERROR, __builtin_altivec_floate_v2di (src_sll) result
doe not match expected output.\n");
+ printf (" result_float[%d] = %f ", i, result_float[i]);
+ printf (" expected result_float[%d] = %f\n", i,
+ expected_result_float[i]);
+ }
+#else
+ abort ();
+#endif
+ }
+
+ expected_result_float[0] = 27.0;
+ expected_result_float[1] = 0.0;
+ expected_result_float[2] = 731.0;
+ expected_result_float[3] = 0.0;
+
+ result_float = __builtin_vsx_uns_floate_v2di(src_ull);
+
+ for (i = 0; i < 4; i = i + 2)
+ {
+ if (result_float[i] != expected_result_float[i])
+#if DEBUG
+ {
+ printf ("ERROR, __builtin_altivec_uns_floate_v2di (src_ull)
result doe not match expected output.\n");
+ printf (" result_float[%d] = %f ", i, result_float[i]);
+ printf (" expected result_float[%d] = %f\n", i,
+ expected_result_float[i]);
+ }
+#else
+ abort ();
+#endif
+
+ }
+
+ /* Test odd result elements. */
+ expected_result_float[0] = 0.0;
+ expected_result_float[1] = 13.0;
+ expected_result_float[2] = 0.0;
+ expected_result_float[3] = 513.0;
+
+ result_float = __builtin_vsx_floato_v2di(src_sll);
+
+ for (i = 1; i < 4; i = i + 2)
+ {
+ if (result_float[i] != expected_result_float[i])
+#if DEBUG
+ {
+ printf ("ERROR, __builtin_altivec_floato_v2di (src_sll) result
doe not match expected output.\n");
+ printf (" result_float[%d] = %f ", i, result_float[i]);
+ printf (" expected result_float[%d] = %f\n", i,
+ expected_result_float[i]);
+ }
+#else
+ abort ();
+#endif
+
+ }
+
+ expected_result_float[0] = 0.0;
+ expected_result_float[1] = 27.0;
+ expected_result_float[2] = 0.0;
+ expected_result_float[3] = 731.0;
+
+ result_float = __builtin_vsx_uns_floato_v2di(src_ull);
+
+ for (i = 1; i < 4; i = i + 2)
+ {
+ if (result_float[i] != expected_result_float[i])
+#if DEBUG
+ {
+ printf ("ERROR, __builtin_altivec_uns_floato_v2di (src_ull)
result doe not match expected output.\n");
+ printf (" result_float[%d] = %f ", i, result_float[i]);
+ printf (" expected result_float[%d] = %f\n", i,
+ expected_result_float[i]);
+ }
+#else
+ abort ();
+#endif
+ }
+
+ /* Test two source args. */
+ expected_result_float[0] = 13.0;
+ expected_result_float[1] = 513.0;
+ expected_result_float[2] = 27.0;
+ expected_result_float[3] = 739.0;
+
+ result_float = __builtin_vsx_float2_v2di(src_sll, srcB_sll);
+
+ for (i = 1; i < 4; i++)
+ {
+ if (result_float[i] != expected_result_float[i])
+#if DEBUG
+ {
+ printf ("ERROR, __builtin_altivec_uns_float2_v2di (src_sll,
src_sll) result doe not match expected output.\n");
+ printf (" result_float[%d] = %f ", i, result_float[i]);
+ printf (" expected result_float[%d] = %f\n", i,
+ expected_result_float[i]);
+ }
+#else
+ abort ();
+#endif
+ }
+ expected_result_float[0] = 27.0;
+ expected_result_float[1] = 731.0;
+ expected_result_float[2] = 19.0;
+ expected_result_float[3] = 57.0;
+
+ result_float = __builtin_vsx_uns_float2_v2di(src_ull, srcB_ull);
+
+ for (i = 1; i < 4; i++)
+ {
+ if (result_float[i] != expected_result_float[i])
+#if DEBUG
+ {
+ printf ("ERROR, __builtin_altivec_uns_float2_v2di (src_ull,
src_ull) result doe not match expected output.\n");
+ printf (" result_float[%d] = %f ", i, result_float[i]);
+ printf (" expected result_float[%d] = %f\n", i,
+ expected_result_float[i]);
+ }
+#else
+ abort ();
+#endif
+ }
+
+ /* Test vector float to signed/unsigned vector int. */
+ expected_result_int[0] = 3;
+ expected_result_int[1] = -9;
+ expected_result_int[2] = 20;
+ expected_result_int[3] = -99;
+
+ result_int = __builtin_altivec_fix_sfsi(src_f);
+
+ for (i = 0; i < 4; i++)
+ {
+ if (result_int[i] != expected_result_int[i])
+#if DEBUG
+ {
+ printf ("ERROR, __builtin_altivec_fix_sfsi (src_f) result doe not
match expected output.\n");
+ printf (" result_int[%d] = %d ", i, result_int[i]);
+ printf (" expected_result_int[%d] = %d\n", i,
+ expected_result_int[i]);
+ }
+#else
+ abort ();
+#endif
+ }
+
+ expected_result_uint[0] = 3;
+ expected_result_uint[1] = 0;
+ expected_result_uint[2] = 20;
+ expected_result_uint[3] = 0;
+
+ result_uint = __builtin_altivec_fixuns_sfsi(src_f);
+
+ for (i = 0; i < 4; i++)
+ {
+ if (result_uint[i] != expected_result_uint[i])
+#if DEBUG
+ {