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  <p...@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__))

Reply via email to