mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-08 23:58:31 +08:00
string: simplify find_zero_ne_all
Build the mask from the raw difference, as find_ne_all () now does. index_first () and index_last () only need to know which byte holds the first or the last set bit, and find_zero_all () marks only the bytes that were zero, so each term of the or marks only its own bytes. That drops one of the two carry chains from strcmp () and strncmp () on targets using the generic string-fza.h, and one of the two uqsub8 on armv6t2. As in find_ne_all (), only the generic implementation tests HAVE_BITOPTS_WORKING. powerpc keeps its existing form, where orc folds the complement of cmpb into the or and the raw difference saves nothing. alpha and riscv do not reach this code with the generic index_first (). Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
This commit is contained in:
committed by
Adhemerval Zanella
parent
de5a4687c0
commit
40cf4504a8
@@ -54,9 +54,9 @@ find_zero_eq_all (op_t x1, op_t x2)
|
||||
static __always_inline find_t
|
||||
find_zero_ne_all (op_t x1, op_t x2)
|
||||
{
|
||||
/* Make use of the fact that we'll already have ONES in a register. */
|
||||
op_t ones = repeat_bytes (0x01);
|
||||
return find_zero_all (x1) | (find_zero_all (x1 ^ x2) ^ ones);
|
||||
/* As in find_ne_all; find_zero_all () sets only 0x01 in a byte that was
|
||||
zero, so each term of the or marks only its own bytes. */
|
||||
return (x1 ^ x2) | find_zero_all (x1);
|
||||
}
|
||||
|
||||
/* Identify bytes that are not equal between X1 and X2. */
|
||||
|
||||
@@ -89,11 +89,18 @@ find_zero_eq_all (op_t x1, op_t x2)
|
||||
static __always_inline find_t
|
||||
find_zero_ne_all (op_t x1, op_t x2)
|
||||
{
|
||||
#if HAVE_BITOPTS_WORKING
|
||||
/* As in find_ne_all, the difference does not have to be reduced to one
|
||||
bit per byte. find_zero_all () sets only 0x80 in a byte that was
|
||||
zero, so each term marks only its own bytes. */
|
||||
return (x1 ^ x2) | find_zero_all (x1);
|
||||
#else
|
||||
op_t m = repeat_bytes (0x7f);
|
||||
op_t eq = x1 ^ x2;
|
||||
op_t nz1 = ((x1 & m) + m) | x1;
|
||||
op_t ne2 = ((eq & m) + m) | eq;
|
||||
return (ne2 | ~nz1) & ~m;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* With similar caveats, identify bytes that are not equal between X1
|
||||
|
||||
Reference in New Issue
Block a user