[PATCH 1/2] string: add find_ne_all to string-fza.h

Matt Turner mattst88@gmail.com
Thu Aug 13 20:07:41 GMT 2026


find_zero_ne_all () searches for a zero byte in X1 or a byte that differs
between X1 and X2.  A caller that knows X2 contains no NUL byte does not
need the zero test, since a NUL byte in X1 already differs from every
byte of X2.

Add find_ne_all (), which searches for inequality alone, to the generic
implementation and to each target that provides its own string-fza.h.
Dropping the zero test makes it cheaper than find_zero_ne_all () on every
target.
---
 sysdeps/alpha/string-fza.h       |  6 ++++++
 sysdeps/arm/armv6t2/string-fza.h |  8 ++++++++
 sysdeps/generic/string-fza.h     | 10 ++++++++++
 sysdeps/powerpc/string-fza.h     |  8 ++++++++
 sysdeps/riscv/string-fza.h       |  7 +++++++
 5 files changed, 39 insertions(+)

diff --git ./sysdeps/alpha/string-fza.h ./sysdeps/alpha/string-fza.h
index ae5d890a7e..1e3715e7c7 100644
--- ./sysdeps/alpha/string-fza.h
+++ ./sysdeps/alpha/string-fza.h
@@ -52,6 +52,12 @@ find_zero_ne_all (op_t x1, op_t x2)
   return find_zero_all (x1) | (find_zero_all (x1 ^ x2) ^ 0xff);
 }
 
+static __always_inline find_t
+find_ne_all (op_t x1, op_t x2)
+{
+  return find_zero_all (x1 ^ x2) ^ 0xff;
+}
+
 /* Define the "inexact" versions in terms of the exact versions.  */
 #define find_zero_low		find_zero_all
 #define find_eq_low		find_eq_all
diff --git ./sysdeps/arm/armv6t2/string-fza.h ./sysdeps/arm/armv6t2/string-fza.h
index 1eab43fdc3..bd342b1c15 100644
--- ./sysdeps/arm/armv6t2/string-fza.h
+++ ./sysdeps/arm/armv6t2/string-fza.h
@@ -61,6 +61,14 @@ find_zero_ne_all (op_t x1, op_t x2)
   return find_zero_all (x1) | (find_zero_all (x1 ^ x2) ^ ones);
 }
 
+/* Identify bytes that are not equal between X1 and X2.  */
+static __always_inline find_t
+find_ne_all (op_t x1, op_t x2)
+{
+  op_t ones = repeat_bytes (0x01);
+  return find_zero_all (x1 ^ x2) ^ ones;
+}
+
 /* Define the "inexact" versions in terms of the exact versions.  */
 #define find_zero_low		find_zero_all
 #define find_eq_low		find_eq_all
diff --git ./sysdeps/generic/string-fza.h ./sysdeps/generic/string-fza.h
index 362c7a8fe6..d6f7dda696 100644
--- ./sysdeps/generic/string-fza.h
+++ ./sysdeps/generic/string-fza.h
@@ -95,4 +95,14 @@ find_zero_ne_all (op_t x1, op_t x2)
   return (ne2 | ~nz1) & ~m;
 }
 
+/* With similar caveats, identify bytes that are not equal between X1
+   and X2.  */
+static __always_inline find_t
+find_ne_all (op_t x1, op_t x2)
+{
+  op_t m = repeat_bytes (0x7f);
+  op_t ne = x1 ^ x2;
+  return (((ne & m) + m) | ne) & ~m;
+}
+
 #endif /* _STRING_FZA_H */
diff --git ./sysdeps/powerpc/string-fza.h ./sysdeps/powerpc/string-fza.h
index 43aa0db952..16fde5dfbd 100644
--- ./sysdeps/powerpc/string-fza.h
+++ ./sysdeps/powerpc/string-fza.h
@@ -60,6 +60,14 @@ find_zero_ne_all (op_t x1, op_t x2)
   return find_zero_all (x1) | ~find_eq_all (x1, x2);
 }
 
+/* Identify bytes that are not equal between X1 and X2.  */
+
+static __always_inline find_t
+find_ne_all (op_t x1, op_t x2)
+{
+  return ~find_eq_all (x1, x2);
+}
+
 /* Define the "inexact" versions in terms of the exact versions.  */
 # define find_zero_low		find_zero_all
 # define find_eq_low		find_eq_all
diff --git ./sysdeps/riscv/string-fza.h ./sysdeps/riscv/string-fza.h
index 7df4dfe415..fa2ddc3c46 100644
--- ./sysdeps/riscv/string-fza.h
+++ ./sysdeps/riscv/string-fza.h
@@ -63,6 +63,13 @@ find_zero_ne_all (op_t x1, op_t x2)
   return find_zero_all (x1) | ~find_eq_all (x1, x2);
 }
 
+/* Identify bytes that are not equal between X1 and X2.  */
+static __always_inline find_t
+find_ne_all (op_t x1, op_t x2)
+{
+  return ~find_eq_all (x1, x2);
+}
+
 /* Define the "inexact" versions in terms of the exact versions.  */
 # define find_zero_low		find_zero_all
 # define find_eq_low		find_eq_all
-- 
2.54.0



More information about the Libc-alpha mailing list