diff mbox series

[rs6000] Fix _mm_extract_pi16 for big-endian

Message ID 739c13db-ae01-5547-7597-1accf0208814@us.ibm.com
State New
Headers show
Series [rs6000] Fix _mm_extract_pi16 for big-endian | expand

Commit Message

Paul A. Clarke Oct. 25, 2018, 6:41 p.m. UTC
For compatibility implementation of x86 vector intrinsic, _mm_extract_pi16,
adjust shift value for big-endian mode.

Bootstrapped and tested on Linux POWER8 LE, POWER8 BE (64 & 32), and POWER7.

OK for trunk?

gcc/ChangeLog:

2018-10-25  Paul A. Clarke  <pc@us.ibm.com>

	* config/rs6000/xmmintrin.h: Fix _mm_extract_pi16 for big-endian.

Comments

Segher Boessenkool Oct. 25, 2018, 10:07 p.m. UTC | #1
On Thu, Oct 25, 2018 at 01:41:15PM -0500, Paul Clarke wrote:
> For compatibility implementation of x86 vector intrinsic, _mm_extract_pi16,
> adjust shift value for big-endian mode.
> 
> Bootstrapped and tested on Linux POWER8 LE, POWER8 BE (64 & 32), and POWER7.

Does it fix existing testcases?

Okay for trunk in either case.  Thanks!  Also fine to backport to 8.


Segher


> 2018-10-25  Paul A. Clarke  <pc@us.ibm.com>
> 
> 	* config/rs6000/xmmintrin.h: Fix _mm_extract_pi16 for big-endian.
> 
> diff --git a/trunk/gcc/config/rs6000/xmmintrin.h b/trunk/gcc/config/rs6000/xmmintrin.h
> --- a/trunk/gcc/config/rs6000/xmmintrin.h	(revision 265238)
> +++ b/trunk/gcc/config/rs6000/xmmintrin.h	(working copy)
> @@ -1386,9 +1385,12 @@
>  extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
>  _mm_extract_pi16 (__m64 const __A, int const __N)
>  {
> -  const int shiftr = (__N & 3) * 16;
> +  unsigned int shiftr = __N & 3;
> +#ifdef __BIG_ENDIAN__
> +  shiftr = 3 - shiftr;
> +#endif
>  
> -  return ((__A >> shiftr) & 0xffff);
> +  return ((__A >> (shiftr * 16)) & 0xffff);
>  }
>  
>  extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
Jakub Jelinek Oct. 25, 2018, 10:08 p.m. UTC | #2
On Thu, Oct 25, 2018 at 05:07:03PM -0500, Segher Boessenkool wrote:
> On Thu, Oct 25, 2018 at 01:41:15PM -0500, Paul Clarke wrote:
> > For compatibility implementation of x86 vector intrinsic, _mm_extract_pi16,
> > adjust shift value for big-endian mode.
> > 
> > Bootstrapped and tested on Linux POWER8 LE, POWER8 BE (64 & 32), and POWER7.
> 
> Does it fix existing testcases?
> 
> Okay for trunk in either case.  Thanks!  Also fine to backport to 8.
> 
> 
> Segher
> 
> 
> > 2018-10-25  Paul A. Clarke  <pc@us.ibm.com>
> > 
> > 	* config/rs6000/xmmintrin.h: Fix _mm_extract_pi16 for big-endian.

The ChangeLog entry is incorrect, should be:
	* config/rs6000/xmmintrin.h (_mm_extract_pi16): Fix for big-endian.
or so.

	Jakub
Paul A. Clarke Oct. 26, 2018, 12:10 p.m. UTC | #3
On 10/25/2018 05:08 PM, Jakub Jelinek wrote:
> On Thu, Oct 25, 2018 at 05:07:03PM -0500, Segher Boessenkool wrote:
>> On Thu, Oct 25, 2018 at 01:41:15PM -0500, Paul Clarke wrote:
>>> For compatibility implementation of x86 vector intrinsic, _mm_extract_pi16,
>>> adjust shift value for big-endian mode.
>>>
>>> Bootstrapped and tested on Linux POWER8 LE, POWER8 BE (64 & 32), and POWER7.
>>
>> Does it fix existing testcases?

No. I found it with my own testing. I have a "to-do" to enhance the testing in this area, not only for endian issues, but I think corner/edge cases are not well tested.

>> Okay for trunk in either case.  Thanks!  Also fine to backport to 8.

Thanks!

>>> 2018-10-25  Paul A. Clarke  <pc@us.ibm.com>
>>>
>>> 	* config/rs6000/xmmintrin.h: Fix _mm_extract_pi16 for big-endian.
> 
> The ChangeLog entry is incorrect, should be:
> 	* config/rs6000/xmmintrin.h (_mm_extract_pi16): Fix for big-endian.
> or so.

Will fix before committing. Thanks!

PC
diff mbox series

Patch

diff --git a/trunk/gcc/config/rs6000/xmmintrin.h b/trunk/gcc/config/rs6000/xmmintrin.h
--- a/trunk/gcc/config/rs6000/xmmintrin.h	(revision 265238)
+++ b/trunk/gcc/config/rs6000/xmmintrin.h	(working copy)
@@ -1386,9 +1385,12 @@ 
 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
 _mm_extract_pi16 (__m64 const __A, int const __N)
 {
-  const int shiftr = (__N & 3) * 16;
+  unsigned int shiftr = __N & 3;
+#ifdef __BIG_ENDIAN__
+  shiftr = 3 - shiftr;
+#endif
 
-  return ((__A >> shiftr) & 0xffff);
+  return ((__A >> (shiftr * 16)) & 0xffff);
 }
 
 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))