Message ID | 1384738414.8213.214.camel@gnopaine |
---|---|
State | New |
Headers | show |
On Sun, Nov 17, 2013 at 8:33 PM, Bill Schmidt <wschmidt@linux.vnet.ibm.com> wrote: > 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. Okay. Thanks, David
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