This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, rs6000] Fix libcpp/lex.c Altivec code to be correct for little endian


Hi, 

As Ulrich Weigand discovered, libcpp/lex.c contains some code optimized
for use with Altivec that is incorrect for little endian targets.  This
breaks bootstrap on powerpc64le-unknown-linux-gnu when configured with
--with-cpu=power7.

This patch makes appropriate modifications for little endian.  The
transformation of lvsr/vperm(x,y,z) into lvsl/vperm(y,x,z) is familiar
from a previous patch.  The other obvious change is converting
count-leading-zeroes into count-trailing-zeroes.

Bootstrapped on powerpc64-unknown-linux-gnu (BE) using --with-cpu=power7
with no regressions.  Bootstrap for powerpc64le-unknown-linux-gnu (LE)
using --with-cpu=power7 now completes with this patch.  There are still
failures for --with-cpu=power7 that are not present using
--with-cpu=power6 that need to be investigated, but they are unrelated
to this change.

Ok for trunk?

Thanks,
Bill


2013-11-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	* lex.c (search_line_fast): Correct for little endian.


Index: libcpp/lex.c
===================================================================
--- libcpp/lex.c	(revision 204928)
+++ libcpp/lex.c	(working copy)
@@ -559,8 +559,13 @@ search_line_fast (const uchar *s, const uchar *end
      beginning with all ones and shifting in zeros according to the
      mis-alignment.  The LVSR instruction pulls the exact shift we
      want from the address.  */
+#ifdef __BIG_ENDIAN__
   mask = __builtin_vec_lvsr(0, s);
   mask = __builtin_vec_perm(zero, ones, mask);
+#else
+  mask = __builtin_vec_lvsl(0, s);
+  mask = __builtin_vec_perm(ones, zero, mask);
+#endif
   data &= mask;
 
   /* While altivec loads mask addresses, we still need to align S so
@@ -624,7 +629,11 @@ search_line_fast (const uchar *s, const uchar *end
     /* L now contains 0xff in bytes for which we matched one of the
        relevant characters.  We can find the byte index by finding
        its bit index and dividing by 8.  */
+#ifdef __BIG_ENDIAN__
     l = __builtin_clzl(l) >> 3;
+#else
+    l = __builtin_ctzl(l) >> 3;
+#endif
     return s + l;
 
 #undef N



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]