diff mbox series

[02/11] rs6000, fix arguments, add documentation for vector, element conversions

Message ID bc1966af-362c-4e91-ac60-c904328938dc@linux.ibm.com
State New
Headers show
Series [01/11] rs6000, Fix __builtin_vsx_cmple* args and documentation, builtins | expand

Commit Message

Carl Love Feb. 20, 2024, 5:56 p.m. UTC
GCC maintainers:

This patch fixes the  return type for the __builtin_vsx_xvcvdpuxws and __builtin_vsx_xvcvspuxds built-ins.  They were defined as signed but should have been defined as unsigned.

The patch has been tested on Power 10 with no regressions.

Please let me know if this patch is acceptable for mainline.  Thanks.

                      Carl 

-----------------------------------------------------
rs6000, fix arguments, add documentation for vector element conversions

The return type for the __builtin_vsx_xvcvdpuxws, __builtin_vsx_xvcvspuxds,
__builtin_vsx_xvcvspuxws built-ins should be unsigned.  This patch changes
the return values from signed to unsigned.

The documentation for the vector element conversion built-ins:

__builtin_vsx_xvcvspsxws
__builtin_vsx_xvcvspsxds
__builtin_vsx_xvcvspuxds
__builtin_vsx_xvcvdpsxws
__builtin_vsx_xvcvdpuxws
__builtin_vsx_xvcvdpuxds_uns
__builtin_vsx_xvcvspdp
__builtin_vsx_xvcvdpsp
__builtin_vsx_xvcvspuxws
__builtin_vsx_xvcvsxwdp
__builtin_vsx_xvcvuxddp_uns
__builtin_vsx_xvcvuxwdp

is missing from extend.texi.  This patch adds the missing documentation.

This patch also adds runnable test cases for each of the built-ins.

gcc/ChangeLog:
	* config/rs6000/rs6000-builtins.def (__builtin_vsx_xvcvdpuxws,
	__builtin_vsx_xvcvspuxds, __builtin_vsx_xvcvspuxws): Change
	return type from signed to unsigned.
	* doc/extend.texi (__builtin_vsx_xvcvspsxws,
	__builtin_vsx_xvcvspsxds, __builtin_vsx_xvcvspuxds,
	__builtin_vsx_xvcvdpsxws, __builtin_vsx_xvcvdpuxws,
	__builtin_vsx_xvcvdpuxds_uns, __builtin_vsx_xvcvspdp,
	__builtin_vsx_xvcvdpsp, __builtin_vsx_xvcvspuxws,
	__builtin_vsx_xvcvsxwdp, __builtin_vsx_xvcvuxddp_uns,
	__builtin_vsx_xvcvuxwdp): Add documentation for builtins.

gcc/testsuite/ChangeLog:
	* gcc.target/powerpc/vsx-builtin-runnable-1.c: New test file.
---
 gcc/config/rs6000/rs6000-builtins.def         |   6 +-
 gcc/doc/extend.texi                           | 135 ++++++++++
 .../powerpc/vsx-builtin-runnable-1.c          | 233 ++++++++++++++++++
 3 files changed, 371 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-builtin-runnable-1.c

Comments

Kewen.Lin Feb. 28, 2024, 9:23 a.m. UTC | #1
Hi,

on 2024/2/21 01:56, Carl Love wrote:
> 
> GCC maintainers:
> 
> This patch fixes the  return type for the __builtin_vsx_xvcvdpuxws and __builtin_vsx_xvcvspuxds built-ins.  They were defined as signed but should have been defined as unsigned.
> 
> The patch has been tested on Power 10 with no regressions.
> 
> Please let me know if this patch is acceptable for mainline.  Thanks.
> 
>                       Carl 
> 
> -----------------------------------------------------
> rs6000, fix arguments, add documentation for vector element conversions
> 
> The return type for the __builtin_vsx_xvcvdpuxws, __builtin_vsx_xvcvspuxds,
> __builtin_vsx_xvcvspuxws built-ins should be unsigned.  This patch changes
> the return values from signed to unsigned.
> 
> The documentation for the vector element conversion built-ins:
> 
> __builtin_vsx_xvcvspsxws
> __builtin_vsx_xvcvspsxds
> __builtin_vsx_xvcvspuxds
> __builtin_vsx_xvcvdpsxws
> __builtin_vsx_xvcvdpuxws
> __builtin_vsx_xvcvdpuxds_uns
> __builtin_vsx_xvcvspdp
> __builtin_vsx_xvcvdpsp
> __builtin_vsx_xvcvspuxws
> __builtin_vsx_xvcvsxwdp
> __builtin_vsx_xvcvuxddp_uns
> __builtin_vsx_xvcvuxwdp
> 
> is missing from extend.texi.  This patch adds the missing documentation.

I think we should recommend users to adopt the recommended built-ins in
PVIPR, by checking the corresponding mnemonic in PVIPR, I got:

__builtin_vsx_xvcvspsxws -> vec_signed
__builtin_vsx_xvcvspsxds -> N/A
__builtin_vsx_xvcvspuxds -> N/A
__builtin_vsx_xvcvdpsxws -> vec_signed{e,o}
__builtin_vsx_xvcvdpuxws -> vec_unsigned{e,o}
__builtin_vsx_xvcvdpuxds_uns -> vec_unsigned
__builtin_vsx_xvcvspdp   -> vec_double{e,o}
__builtin_vsx_xvcvdpsp   -> vec_float{e,o}
__builtin_vsx_xvcvspuxws -> vec_unsigned
__builtin_vsx_xvcvsxwdp  -> vec_double{e,o}
__builtin_vsx_xvcvuxddp_uns> vec_double

For __builtin_vsx_xvcvspsxds and __builtin_vsx_xvcvspuxds which don't have
the according PVIPR built-ins, we can extend the current vec_{un,}signed{e,o}
to cover them and document them following the section mentioning PVIPR.

BR,
Kewen

> 
> This patch also adds runnable test cases for each of the built-ins.
> 
> gcc/ChangeLog:
> 	* config/rs6000/rs6000-builtins.def (__builtin_vsx_xvcvdpuxws,
> 	__builtin_vsx_xvcvspuxds, __builtin_vsx_xvcvspuxws): Change
> 	return type from signed to unsigned.
> 	* doc/extend.texi (__builtin_vsx_xvcvspsxws,
> 	__builtin_vsx_xvcvspsxds, __builtin_vsx_xvcvspuxds,
> 	__builtin_vsx_xvcvdpsxws, __builtin_vsx_xvcvdpuxws,
> 	__builtin_vsx_xvcvdpuxds_uns, __builtin_vsx_xvcvspdp,
> 	__builtin_vsx_xvcvdpsp, __builtin_vsx_xvcvspuxws,
> 	__builtin_vsx_xvcvsxwdp, __builtin_vsx_xvcvuxddp_uns,
> 	__builtin_vsx_xvcvuxwdp): Add documentation for builtins.
> 
> gcc/testsuite/ChangeLog:
> 	* gcc.target/powerpc/vsx-builtin-runnable-1.c: New test file.
> ---
>  gcc/config/rs6000/rs6000-builtins.def         |   6 +-
>  gcc/doc/extend.texi                           | 135 ++++++++++
>  .../powerpc/vsx-builtin-runnable-1.c          | 233 ++++++++++++++++++
>  3 files changed, 371 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-builtin-runnable-1.c
> 
> diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
> index d66a53a0fab..fd316f629e5 100644
> --- a/gcc/config/rs6000/rs6000-builtins.def
> +++ b/gcc/config/rs6000/rs6000-builtins.def
> @@ -1724,7 +1724,7 @@
>    const vull __builtin_vsx_xvcvdpuxds_uns (vd);
>      XVCVDPUXDS_UNS vsx_fixuns_truncv2dfv2di2 {}
>  
> -  const vsi __builtin_vsx_xvcvdpuxws (vd);
> +  const vui __builtin_vsx_xvcvdpuxws (vd);
>      XVCVDPUXWS vsx_xvcvdpuxws {}
>  
>    const vd __builtin_vsx_xvcvspdp (vf);
> @@ -1736,10 +1736,10 @@
>    const vsi __builtin_vsx_xvcvspsxws (vf);
>      XVCVSPSXWS vsx_fix_truncv4sfv4si2 {}
>  
> -  const vsll __builtin_vsx_xvcvspuxds (vf);
> +  const vull __builtin_vsx_xvcvspuxds (vf);
>      XVCVSPUXDS vsx_xvcvspuxds {}
>  
> -  const vsi __builtin_vsx_xvcvspuxws (vf);
> +  const vui __builtin_vsx_xvcvspuxws (vf);
>      XVCVSPUXWS vsx_fixuns_truncv4sfv4si2 {}
>  
>    const vd __builtin_vsx_xvcvsxddp (vsll);
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 4d8610f6aa8..583b1d890bf 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -21360,6 +21360,141 @@ __float128 __builtin_sqrtf128 (__float128);
>  __float128 __builtin_fmaf128 (__float128, __float128, __float128);
>  @end smallexample
>  
> +@smallexample
> +vector int __builtin_vsx_xvcvspsxws (vector float);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvspsxws} converts the single precision floating
> +point vector element i to a signed single-precision integer value using
> +round to zero storing the result in element i.  If the source element is NaN
> +the result is set to 0x80000000 and VXCI is set to 1.  If the source
> +element is SNaN then VXSNAN is also set to 1.  If the rounded value is greater
> +than 2^31 - 1 the result is 0x7FFFFFFF and VXCVI is set to 1.  If the
> +rounded value is less than -2^31, the result is set to 0x80000000 and
> +VXCVI is set to 1. If the rounded result is inexact then XX is set to 1.
>> +@smallexample
> +vector signed long long int __builtin_vsx_xvcvspsxds (vector float);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvspsxds} converts the single precision floating
> +point vector element to a double precision signed integer value using the
> +round to zero rounding mode.  If the source element is NaN the result
> +is set to 0x8000000000000000 and VXCI is set to 1.  If the source element is
> +SNaN then VXSNAN is also set to 1.  If the rounded value is greater than
> +2^63 - 1 the result is 0x7FFFFFFFFFFFFFFF and VXCVI is set to 1.  If the
> +rounded value is less than zero, the result is set to 0x8000000000000000 and
> +VXCVI is set to 1.  If the rounded result is inexact then XX is set to 1.
> +
> +@smallexample
> +vector unsigned long long __builtin_vsx_xvcvspuxds (vector float);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvspuxds} converts the single precision floating
> +point vector element 2*i to an unsigned double-precision integer value using
> +round to zero storing the result in element i.  If the source element is NaN
> +the result is set to 0x0000000000000000 and VXCI is set to 1.  If the source
> +element is SNaN then VXSNAN is also set to 1.  If the rounded value is greater
> +than 2^63 - 1 the result is 0xFFFFFFFFFFFFFFFF and VXCVI is set to 1.  If the
> +rounded value is less than -2^63, the result is set to 0x0000000000000000 and
> +VXCVI is set to 1.  If the rounded result is inexact then XX is set to 1.
> +
> +@smallexample
> +vector signed int __builtin_vsx_xvcvdpsxws (vector double);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvdpsxws} converts the ith double precision floating
> +point vector element to a single-precision integer value using the round to
> +zero rounding mode.  The single precision integer value is placed into vector
> +elements j and j+1 where j = i*2.  If the source element is NaN the result
> +is set to 0x80000000 and VXCI is set to 1.  If the source element is SNaN then
> +VXSNAN is also set to 1.  If the rounded value is greater than 2^31 - 1 the
> +result is 0x7FFFFFFF and VXCVI is set to 1.  If the rounded value is less than
> +-2^31, the result is set to 0x80000000 and VXCVI is set to 1.  If the rounded
> +result is inexact then XX is set to 1.
> +
> +@smallexample
> +vector unsigned int __builtin_vsx_xvcvdpuxws (vector double);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvdpuxws} converts the ith double precision floating
> +point vector element to a unsigned single-precision integer value using the
> +round to zero rounding mode.  The single precision integer value is placed into
> +vector elements j and j+1 where j = i*2.  If the source element is NaN the
> +result is set to 0x00000000 and VXCI is set to 1.  If the source element is
> +SNaN then VXSNAN is also set to 1.  If the rounded value is greater than
> +2^31 - 1 the result is 0xFFFFFFFF and VXCVI is set to 1.  If the rounded value
> +is less than zero, the result is set to 0x00000000 and VXCVI is set to 1.  If
> +the rounded result is inexact then XX is set to 1.
> +
> +@smallexample
> +vector unsigned long long int __builtin_vsx_xvcvdpuxds_uns (vector double);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvdpuxds_uns} converts the double precision floating
> +point vector element to a double precision unsigned integer value using the
> +round to zero rounding mode.  If the source element is NaN the result is set
> +to 0x0000000000000000 and VXCI is set to 1.  If the source element is SNaN
> +then VXSNAN is also set to 1.  If the rounded value is greater than 2^63 - 1
> +the result is 0xFFFFFFFFFFFFFFFF and VXCVI is set to 1.  If the rounded value
> +is less than zero, the result is set to 0x0000000000000000 and VXCVI is set to
> +1.  If the rounded result is inexact then XX is set to 1.
> +
> +@smallexample
> +vector double __builtin_vsx_xvcvspdp (vector float);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvspdp} converts single precision floating
> +point vector element to a double precision floating point value.  Input element
> +at index 2*i is stored in the destination element i.
> +
> +@smallexample
> +vector float __builtin_vsx_xvcvdpsp (vector double);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvdpsp} converts the ith double precision floating
> +point vector element to a single-precision floating point value using the
> +rounding mode specified by RN.  The single precision value is placed into
> +vector elements j and j+1 where j = i*2.  The rounding mode, RN, is specified
> +by bits [62:63] of the FPSCR.
> +
> +@smallexample
> +vector unsigned int __builtin_vsx_xvcvspuxws (vector float);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvspuxws} converts the single precision floating
> +point vector element i to an unsigned single-precision integer value using
> +round to zero storing the result in element i.  If the source element is NaN
> +the result is set to 0x00000000 and VXCI is set to 1.  If the source element
> +is SNaN then VXSNAN is also set to 1.  If the rounded value is greater than
> +2^31 - 1 the result is 0xFFFFFFFF and VXCVI is set to 1.  If the rounded
> +value is less than -2^31, the result is set to 0x00000000 and VXCVI is set
> +to 1. If the rounded result is inexact then XX is set to 1.
> +
> +@smallexample
> +vector double __builtin_vsx_xvcvsxwdp (vector signed int);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvsxwdp} converts single precision integer value
> +to a double precision floating point value.  Input element at index 2*i is
> +stored in the destination element i.
> +
> +@smallexample
> +vector double __builtin_vsx_xvcvuxddp_uns (vector unsigned long long);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvuxddp_uns} converts unsigned double-precision
> +integer value to a double precision floating point value.  Input element
> +at index i is stored in the destination element i.
> +
> +@smallexample
> +vector double __builtin_vsx_xvcvuxwdp (vector unsigned int);
> +@end smallexample
> +
> +The @code{__builtin_vsx_xvcvuxwdp} converts single precision unsigned integer
> +value to a double precision floating point value.  Input element at index 2*i
> +is stored in the destination element i.
> +
>  @node Basic PowerPC Built-in Functions Available on ISA 2.07
>  @subsubsection Basic PowerPC Built-in Functions Available on ISA 2.07
>  
> diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-runnable-1.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-runnable-1.c
> new file mode 100644
> index 00000000000..91d16c3ba72
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-runnable-1.c
> @@ -0,0 +1,233 @@
> +/* { dg-do run { target { lp64 } } } */
> +/* { dg-require-effective-target powerpc_vsx_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power7" } */
> +
> +#define DEBUG 0
> +
> +#if DEBUG
> +#include <stdio.h>
> +#include <stdlib.h>
> +#endif
> +
> +void abort (void);
> +
> +int main ()
> +{
> +  int i;
> +  vector double vd_arg1, vd_result, vd_expected_result;
> +  vector float vf_arg1, vf_result, vf_expected_result;
> +  vector int vsi_arg1;
> +  vector unsigned int vui_arg1;
> +  vector int vsi_result, vsi_expected_result;
> +  vector unsigned int vui_result, vui_expected_result;
> +  vector signed long long int vsll_result, vsll_expected_result;
> +  vector unsigned long long int vull_arg1;
> +  vector unsigned long long int vull_result, vull_expected_result;
> +
> +  /* VSX Vector Convert with round to zero Single-Precision floating point to
> +     Single-Precision signed integer format using the round to zero mode.  */
> +
> +  vf_arg1 = (vector float) {12345.98, 7654.321, -2.1234,
> +			    9999999999956789012345678.9};
> +  vsi_result = __builtin_vsx_xvcvspsxws (vf_arg1);
> +  vsi_expected_result = (vector signed int) {12345, 7654, -2, 0x7fffffff};
> +
> +  for (i = 0; i < 4; i++)
> +    if (vsi_result[i] != vsi_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvspsxws: vsi_result[%d] = 0x%x, vsi_expected_result[%d] = 0x%x\n",
> +	     i, vsi_result[i], i, vsi_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert with round Single-Precision floating point to
> +     Double-Precision signed integer format using the round to zero mode.  */
> +
> +  vf_arg1 = (vector float) {12345.98, 7654.321, -2.1234,
> +			    9999999999956789012345678.9};
> +  vsll_result = __builtin_vsx_xvcvspsxds (vf_arg1);
> +  vsll_expected_result = (vector signed long long) {7654, 0x7fffffffffffffff};
> +
> +  for (i = 0; i < 2; i++)
> +    if (vsll_result[i] != vsll_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvspsxds: vsll_result[%d] = 0x%llx, vsll_expected_result[%d] = 0x%llx\n",
> +	     i, vsll_result[i], i, vsll_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert with round Single-Precision floating point to
> +     Double-Precision unsigned integer format using the round to zero mode.  */
> +
> +  vf_arg1 = (vector float) {12345.98, 764.321, -2.1234,
> +			    9999999999956789012345678.9};
> +  vull_result = __builtin_vsx_xvcvspuxds (vf_arg1);
> +  vull_expected_result = (vector unsigned long long) {764, 0xffffffffffffffff};
> +
> +  for (i = 0; i < 2; i++)
> +    if (vull_result[i] != vull_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvspuxds: vull_result[%d] = 0x%llx, vull_expected_result[%d] = 0x%llx\n",
> +	     i, vull_result[i], i, vull_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert with round Double-Precision floating point to
> +     signed Single-Precision integer format using the round to zero mode.  */
> +
> +  vd_arg1 = (vector double) {12345.987654321, -2.1234567890123456789};
> +  /* Each double-precision value, i, is converted to single precision integer
> +     and placed in vector elements j and j+1 where j = i*2.  The round to
> +     zero rounding mode is used.  */
> +  vsi_result = __builtin_vsx_xvcvdpsxws (vd_arg1);
> +  vsi_expected_result = (vector int) {12345, 12345, -2, -2};
> +
> +  for (i = 0; i < 4; i++)
> +    if (vsi_result[i] != vsi_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvdpsxws: vsi_result[%d] = %d, vsi_expected_result[%d] = %d\n",
> +	     i, vsi_result[i], i, vsi_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert with round Double-Precision floating point to
> +     unsigned Single-Precision integer format using the round to zero mode.  */
> +
> +  vd_arg1 = (vector double) {12345.987654321, -2.1234567890123456789};
> +  /* Each double-precision value, i, is converted to single precision integer
> +     and placed in vector elements j and j+1 where j = i*2.  The round to
> +     zero rounding mode is used.  */
> +  vui_result = __builtin_vsx_xvcvdpuxws (vd_arg1);
> +  vui_expected_result = (vector unsigned int) {12345, 12345, 0, 0};
> +
> +  for (i = 0; i < 4; i++)
> +    if (vui_result[i] != vui_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvdpuxws: vui_result[%d] = %d, vui_expected_result[%d] = %d\n",
> +	     i, vui_result[i], i, vui_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert with round Double-Precision floating point to
> +     Double-Precision unsigned integer format using the round to zero mode.  */
> +
> +  vd_arg1 = (vector double) {12345.987654321, -2.1234567890123456789};
> +  vull_result = __builtin_vsx_xvcvdpuxds_uns (vd_arg1);
> +  vull_expected_result = (vector unsigned long long) {12345, 0};
> +
> +  for (i = 0; i < 2; i++)
> +    if (vull_result[i] != vull_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvdpuxds_uns: vull_result[%d] = %lld, vull_expected_result[%d] = %lld\n",
> +	     i, vull_result[i], i, vull_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert Single-Precision floating point to Double-Precision
> +     floating point  */
> +
> +  vf_arg1 = (vector float) {12345.98, -2.0, 31.11, -55.5};
> +  vd_result = __builtin_vsx_xvcvspdp (vf_arg1);
> +  vd_expected_result = (vector double) {-2.0, -55.5};
> +
> +  for (i = 0; i < 2; i++)
> +    if (vd_result[i] != vd_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvspdp: vd_result[%d] = %f, vf_expected_result[%d] = %f\n",
> +	     i, vd_result[i], i, vd_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert with round Double-Precision float point format to
> +     Single-Precision floating point format using the rounding mode specified
> +     by the RN field of the FPSCR.  */
> +
> +  vd_arg1 = (vector double) {12345.12345, -0.1234567890123456789};
> +  /* Each double-precision value, i, is converted to single precision and
> +     placed in vector elements j and j+1 where j = i*2.  */
> +  vf_result = __builtin_vsx_xvcvdpsp (vd_arg1);
> +  vf_expected_result = (vector float) {12345.12345, 12345.12345,
> +				       -0.1234567890, -0.1234567890};
> +
> +  for (i = 0; i < 4; i++)
> +    if (vf_result[i] != vf_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvdpsp: vf_result[%d] = %f, vf_expected_result[%d] = %f\n",
> +	     i, vf_result[i], i, vf_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert with round Single-Precision floating point to
> +     Single-Precision unsigned integer format using the round to zero mode.  */
> +
> +  vf_arg1 = (vector float) {12345.98, 7654.321, -2.1234,
> +			    9999999999956789012345678.9};
> +  vui_result = __builtin_vsx_xvcvspuxws (vf_arg1);
> +  vui_expected_result = (vector unsigned int) {12345, 7654, 0x0, 0xffffffff};
> +
> +  for (i = 0; i < 4; i++)
> +    if (vui_result[i] != vui_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvspuxws: vui_result[%d] = 0x%x, vui_expected_result[%d] = 0x%x\n",
> +	     i, vui_result[i], i, vui_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert Signed integer word to Double-Precision floating point
> +     format. */
> +
> +  vsi_arg1 = (vector int) {2345, 98, -2, -55};
> +  vd_result = __builtin_vsx_xvcvsxwdp (vsi_arg1);
> +  vd_expected_result = (vector double) {98.0, -55.0};
> +
> +  for (i = 0; i < 2; i++)
> +    if (vd_result[i] != vd_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvsxwdp: vd_result[%d] = %f, vd_expected_result[%d] = %f\n",
> +	     i, vd_result[i], i, vd_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert with round unsigned Double-Word integer to
> +     Double-Precision floating point format.  */
> +
> +  vull_arg1 = (vector unsigned long long) {12398, 22255};
> +  vd_result = __builtin_vsx_xvcvuxddp_uns (vull_arg1);
> +  vd_expected_result = (vector double) {12398.0, 22255.0};
> +
> +  for (i = 0; i < 2; i++)
> +    if (vd_result[i] != vd_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvuxddp_uns: vd_result[%d] = %f, vd_expected_result[%d] = %f\n",
> +	     i, vd_result[i], i, vd_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +
> +  /* VSX Vector Convert unsigned Single-Precision integer to Double-Precision
> +     floating point format.  */
> +
> +  vui_arg1 = (vector unsigned int) {12398, 22255, 345, 87};
> +  vd_result = __builtin_vsx_xvcvuxwdp (vui_arg1);
> +  vd_expected_result = (vector double) {22255.0, 87.0};
> +
> +  for (i = 0; i < 2; i++)
> +    if (vd_result[i] != vd_expected_result[i])
> +#if DEBUG
> +      printf("ERROR, __builtin_vsx_xvcvuxwdp: vd_result[%d] = %f, vd_expected_result[%d] = %f\n",
> +	     i, vd_result[i], i, vd_expected_result[i]);
> +#else
> +      abort();
> +#endif
> +  return 0;
> +}
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index d66a53a0fab..fd316f629e5 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -1724,7 +1724,7 @@ 
   const vull __builtin_vsx_xvcvdpuxds_uns (vd);
     XVCVDPUXDS_UNS vsx_fixuns_truncv2dfv2di2 {}
 
-  const vsi __builtin_vsx_xvcvdpuxws (vd);
+  const vui __builtin_vsx_xvcvdpuxws (vd);
     XVCVDPUXWS vsx_xvcvdpuxws {}
 
   const vd __builtin_vsx_xvcvspdp (vf);
@@ -1736,10 +1736,10 @@ 
   const vsi __builtin_vsx_xvcvspsxws (vf);
     XVCVSPSXWS vsx_fix_truncv4sfv4si2 {}
 
-  const vsll __builtin_vsx_xvcvspuxds (vf);
+  const vull __builtin_vsx_xvcvspuxds (vf);
     XVCVSPUXDS vsx_xvcvspuxds {}
 
-  const vsi __builtin_vsx_xvcvspuxws (vf);
+  const vui __builtin_vsx_xvcvspuxws (vf);
     XVCVSPUXWS vsx_fixuns_truncv4sfv4si2 {}
 
   const vd __builtin_vsx_xvcvsxddp (vsll);
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 4d8610f6aa8..583b1d890bf 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21360,6 +21360,141 @@  __float128 __builtin_sqrtf128 (__float128);
 __float128 __builtin_fmaf128 (__float128, __float128, __float128);
 @end smallexample
 
+@smallexample
+vector int __builtin_vsx_xvcvspsxws (vector float);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvspsxws} converts the single precision floating
+point vector element i to a signed single-precision integer value using
+round to zero storing the result in element i.  If the source element is NaN
+the result is set to 0x80000000 and VXCI is set to 1.  If the source
+element is SNaN then VXSNAN is also set to 1.  If the rounded value is greater
+than 2^31 - 1 the result is 0x7FFFFFFF and VXCVI is set to 1.  If the
+rounded value is less than -2^31, the result is set to 0x80000000 and
+VXCVI is set to 1. If the rounded result is inexact then XX is set to 1.
+
+@smallexample
+vector signed long long int __builtin_vsx_xvcvspsxds (vector float);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvspsxds} converts the single precision floating
+point vector element to a double precision signed integer value using the
+round to zero rounding mode.  If the source element is NaN the result
+is set to 0x8000000000000000 and VXCI is set to 1.  If the source element is
+SNaN then VXSNAN is also set to 1.  If the rounded value is greater than
+2^63 - 1 the result is 0x7FFFFFFFFFFFFFFF and VXCVI is set to 1.  If the
+rounded value is less than zero, the result is set to 0x8000000000000000 and
+VXCVI is set to 1.  If the rounded result is inexact then XX is set to 1.
+
+@smallexample
+vector unsigned long long __builtin_vsx_xvcvspuxds (vector float);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvspuxds} converts the single precision floating
+point vector element 2*i to an unsigned double-precision integer value using
+round to zero storing the result in element i.  If the source element is NaN
+the result is set to 0x0000000000000000 and VXCI is set to 1.  If the source
+element is SNaN then VXSNAN is also set to 1.  If the rounded value is greater
+than 2^63 - 1 the result is 0xFFFFFFFFFFFFFFFF and VXCVI is set to 1.  If the
+rounded value is less than -2^63, the result is set to 0x0000000000000000 and
+VXCVI is set to 1.  If the rounded result is inexact then XX is set to 1.
+
+@smallexample
+vector signed int __builtin_vsx_xvcvdpsxws (vector double);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvdpsxws} converts the ith double precision floating
+point vector element to a single-precision integer value using the round to
+zero rounding mode.  The single precision integer value is placed into vector
+elements j and j+1 where j = i*2.  If the source element is NaN the result
+is set to 0x80000000 and VXCI is set to 1.  If the source element is SNaN then
+VXSNAN is also set to 1.  If the rounded value is greater than 2^31 - 1 the
+result is 0x7FFFFFFF and VXCVI is set to 1.  If the rounded value is less than
+-2^31, the result is set to 0x80000000 and VXCVI is set to 1.  If the rounded
+result is inexact then XX is set to 1.
+
+@smallexample
+vector unsigned int __builtin_vsx_xvcvdpuxws (vector double);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvdpuxws} converts the ith double precision floating
+point vector element to a unsigned single-precision integer value using the
+round to zero rounding mode.  The single precision integer value is placed into
+vector elements j and j+1 where j = i*2.  If the source element is NaN the
+result is set to 0x00000000 and VXCI is set to 1.  If the source element is
+SNaN then VXSNAN is also set to 1.  If the rounded value is greater than
+2^31 - 1 the result is 0xFFFFFFFF and VXCVI is set to 1.  If the rounded value
+is less than zero, the result is set to 0x00000000 and VXCVI is set to 1.  If
+the rounded result is inexact then XX is set to 1.
+
+@smallexample
+vector unsigned long long int __builtin_vsx_xvcvdpuxds_uns (vector double);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvdpuxds_uns} converts the double precision floating
+point vector element to a double precision unsigned integer value using the
+round to zero rounding mode.  If the source element is NaN the result is set
+to 0x0000000000000000 and VXCI is set to 1.  If the source element is SNaN
+then VXSNAN is also set to 1.  If the rounded value is greater than 2^63 - 1
+the result is 0xFFFFFFFFFFFFFFFF and VXCVI is set to 1.  If the rounded value
+is less than zero, the result is set to 0x0000000000000000 and VXCVI is set to
+1.  If the rounded result is inexact then XX is set to 1.
+
+@smallexample
+vector double __builtin_vsx_xvcvspdp (vector float);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvspdp} converts single precision floating
+point vector element to a double precision floating point value.  Input element
+at index 2*i is stored in the destination element i.
+
+@smallexample
+vector float __builtin_vsx_xvcvdpsp (vector double);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvdpsp} converts the ith double precision floating
+point vector element to a single-precision floating point value using the
+rounding mode specified by RN.  The single precision value is placed into
+vector elements j and j+1 where j = i*2.  The rounding mode, RN, is specified
+by bits [62:63] of the FPSCR.
+
+@smallexample
+vector unsigned int __builtin_vsx_xvcvspuxws (vector float);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvspuxws} converts the single precision floating
+point vector element i to an unsigned single-precision integer value using
+round to zero storing the result in element i.  If the source element is NaN
+the result is set to 0x00000000 and VXCI is set to 1.  If the source element
+is SNaN then VXSNAN is also set to 1.  If the rounded value is greater than
+2^31 - 1 the result is 0xFFFFFFFF and VXCVI is set to 1.  If the rounded
+value is less than -2^31, the result is set to 0x00000000 and VXCVI is set
+to 1. If the rounded result is inexact then XX is set to 1.
+
+@smallexample
+vector double __builtin_vsx_xvcvsxwdp (vector signed int);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvsxwdp} converts single precision integer value
+to a double precision floating point value.  Input element at index 2*i is
+stored in the destination element i.
+
+@smallexample
+vector double __builtin_vsx_xvcvuxddp_uns (vector unsigned long long);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvuxddp_uns} converts unsigned double-precision
+integer value to a double precision floating point value.  Input element
+at index i is stored in the destination element i.
+
+@smallexample
+vector double __builtin_vsx_xvcvuxwdp (vector unsigned int);
+@end smallexample
+
+The @code{__builtin_vsx_xvcvuxwdp} converts single precision unsigned integer
+value to a double precision floating point value.  Input element at index 2*i
+is stored in the destination element i.
+
 @node Basic PowerPC Built-in Functions Available on ISA 2.07
 @subsubsection Basic PowerPC Built-in Functions Available on ISA 2.07
 
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-runnable-1.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-runnable-1.c
new file mode 100644
index 00000000000..91d16c3ba72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-runnable-1.c
@@ -0,0 +1,233 @@ 
+/* { dg-do run { target { lp64 } } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power7" } */
+
+#define DEBUG 0
+
+#if DEBUG
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+void abort (void);
+
+int main ()
+{
+  int i;
+  vector double vd_arg1, vd_result, vd_expected_result;
+  vector float vf_arg1, vf_result, vf_expected_result;
+  vector int vsi_arg1;
+  vector unsigned int vui_arg1;
+  vector int vsi_result, vsi_expected_result;
+  vector unsigned int vui_result, vui_expected_result;
+  vector signed long long int vsll_result, vsll_expected_result;
+  vector unsigned long long int vull_arg1;
+  vector unsigned long long int vull_result, vull_expected_result;
+
+  /* VSX Vector Convert with round to zero Single-Precision floating point to
+     Single-Precision signed integer format using the round to zero mode.  */
+
+  vf_arg1 = (vector float) {12345.98, 7654.321, -2.1234,
+			    9999999999956789012345678.9};
+  vsi_result = __builtin_vsx_xvcvspsxws (vf_arg1);
+  vsi_expected_result = (vector signed int) {12345, 7654, -2, 0x7fffffff};
+
+  for (i = 0; i < 4; i++)
+    if (vsi_result[i] != vsi_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvspsxws: vsi_result[%d] = 0x%x, vsi_expected_result[%d] = 0x%x\n",
+	     i, vsi_result[i], i, vsi_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert with round Single-Precision floating point to
+     Double-Precision signed integer format using the round to zero mode.  */
+
+  vf_arg1 = (vector float) {12345.98, 7654.321, -2.1234,
+			    9999999999956789012345678.9};
+  vsll_result = __builtin_vsx_xvcvspsxds (vf_arg1);
+  vsll_expected_result = (vector signed long long) {7654, 0x7fffffffffffffff};
+
+  for (i = 0; i < 2; i++)
+    if (vsll_result[i] != vsll_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvspsxds: vsll_result[%d] = 0x%llx, vsll_expected_result[%d] = 0x%llx\n",
+	     i, vsll_result[i], i, vsll_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert with round Single-Precision floating point to
+     Double-Precision unsigned integer format using the round to zero mode.  */
+
+  vf_arg1 = (vector float) {12345.98, 764.321, -2.1234,
+			    9999999999956789012345678.9};
+  vull_result = __builtin_vsx_xvcvspuxds (vf_arg1);
+  vull_expected_result = (vector unsigned long long) {764, 0xffffffffffffffff};
+
+  for (i = 0; i < 2; i++)
+    if (vull_result[i] != vull_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvspuxds: vull_result[%d] = 0x%llx, vull_expected_result[%d] = 0x%llx\n",
+	     i, vull_result[i], i, vull_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert with round Double-Precision floating point to
+     signed Single-Precision integer format using the round to zero mode.  */
+
+  vd_arg1 = (vector double) {12345.987654321, -2.1234567890123456789};
+  /* Each double-precision value, i, is converted to single precision integer
+     and placed in vector elements j and j+1 where j = i*2.  The round to
+     zero rounding mode is used.  */
+  vsi_result = __builtin_vsx_xvcvdpsxws (vd_arg1);
+  vsi_expected_result = (vector int) {12345, 12345, -2, -2};
+
+  for (i = 0; i < 4; i++)
+    if (vsi_result[i] != vsi_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvdpsxws: vsi_result[%d] = %d, vsi_expected_result[%d] = %d\n",
+	     i, vsi_result[i], i, vsi_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert with round Double-Precision floating point to
+     unsigned Single-Precision integer format using the round to zero mode.  */
+
+  vd_arg1 = (vector double) {12345.987654321, -2.1234567890123456789};
+  /* Each double-precision value, i, is converted to single precision integer
+     and placed in vector elements j and j+1 where j = i*2.  The round to
+     zero rounding mode is used.  */
+  vui_result = __builtin_vsx_xvcvdpuxws (vd_arg1);
+  vui_expected_result = (vector unsigned int) {12345, 12345, 0, 0};
+
+  for (i = 0; i < 4; i++)
+    if (vui_result[i] != vui_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvdpuxws: vui_result[%d] = %d, vui_expected_result[%d] = %d\n",
+	     i, vui_result[i], i, vui_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert with round Double-Precision floating point to
+     Double-Precision unsigned integer format using the round to zero mode.  */
+
+  vd_arg1 = (vector double) {12345.987654321, -2.1234567890123456789};
+  vull_result = __builtin_vsx_xvcvdpuxds_uns (vd_arg1);
+  vull_expected_result = (vector unsigned long long) {12345, 0};
+
+  for (i = 0; i < 2; i++)
+    if (vull_result[i] != vull_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvdpuxds_uns: vull_result[%d] = %lld, vull_expected_result[%d] = %lld\n",
+	     i, vull_result[i], i, vull_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert Single-Precision floating point to Double-Precision
+     floating point  */
+
+  vf_arg1 = (vector float) {12345.98, -2.0, 31.11, -55.5};
+  vd_result = __builtin_vsx_xvcvspdp (vf_arg1);
+  vd_expected_result = (vector double) {-2.0, -55.5};
+
+  for (i = 0; i < 2; i++)
+    if (vd_result[i] != vd_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvspdp: vd_result[%d] = %f, vf_expected_result[%d] = %f\n",
+	     i, vd_result[i], i, vd_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert with round Double-Precision float point format to
+     Single-Precision floating point format using the rounding mode specified
+     by the RN field of the FPSCR.  */
+
+  vd_arg1 = (vector double) {12345.12345, -0.1234567890123456789};
+  /* Each double-precision value, i, is converted to single precision and
+     placed in vector elements j and j+1 where j = i*2.  */
+  vf_result = __builtin_vsx_xvcvdpsp (vd_arg1);
+  vf_expected_result = (vector float) {12345.12345, 12345.12345,
+				       -0.1234567890, -0.1234567890};
+
+  for (i = 0; i < 4; i++)
+    if (vf_result[i] != vf_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvdpsp: vf_result[%d] = %f, vf_expected_result[%d] = %f\n",
+	     i, vf_result[i], i, vf_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert with round Single-Precision floating point to
+     Single-Precision unsigned integer format using the round to zero mode.  */
+
+  vf_arg1 = (vector float) {12345.98, 7654.321, -2.1234,
+			    9999999999956789012345678.9};
+  vui_result = __builtin_vsx_xvcvspuxws (vf_arg1);
+  vui_expected_result = (vector unsigned int) {12345, 7654, 0x0, 0xffffffff};
+
+  for (i = 0; i < 4; i++)
+    if (vui_result[i] != vui_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvspuxws: vui_result[%d] = 0x%x, vui_expected_result[%d] = 0x%x\n",
+	     i, vui_result[i], i, vui_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert Signed integer word to Double-Precision floating point
+     format. */
+
+  vsi_arg1 = (vector int) {2345, 98, -2, -55};
+  vd_result = __builtin_vsx_xvcvsxwdp (vsi_arg1);
+  vd_expected_result = (vector double) {98.0, -55.0};
+
+  for (i = 0; i < 2; i++)
+    if (vd_result[i] != vd_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvsxwdp: vd_result[%d] = %f, vd_expected_result[%d] = %f\n",
+	     i, vd_result[i], i, vd_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert with round unsigned Double-Word integer to
+     Double-Precision floating point format.  */
+
+  vull_arg1 = (vector unsigned long long) {12398, 22255};
+  vd_result = __builtin_vsx_xvcvuxddp_uns (vull_arg1);
+  vd_expected_result = (vector double) {12398.0, 22255.0};
+
+  for (i = 0; i < 2; i++)
+    if (vd_result[i] != vd_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvuxddp_uns: vd_result[%d] = %f, vd_expected_result[%d] = %f\n",
+	     i, vd_result[i], i, vd_expected_result[i]);
+#else
+      abort();
+#endif
+
+  /* VSX Vector Convert unsigned Single-Precision integer to Double-Precision
+     floating point format.  */
+
+  vui_arg1 = (vector unsigned int) {12398, 22255, 345, 87};
+  vd_result = __builtin_vsx_xvcvuxwdp (vui_arg1);
+  vd_expected_result = (vector double) {22255.0, 87.0};
+
+  for (i = 0; i < 2; i++)
+    if (vd_result[i] != vd_expected_result[i])
+#if DEBUG
+      printf("ERROR, __builtin_vsx_xvcvuxwdp: vd_result[%d] = %f, vd_expected_result[%d] = %f\n",
+	     i, vd_result[i], i, vd_expected_result[i]);
+#else
+      abort();
+#endif
+  return 0;
+}