]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - lib/string.c
karo: tx51: remove duplicate CONFIG_SYS_SDRAM_CLK definition
[karo-tx-uboot.git] / lib / string.c
index 09dfae03c247554deb48c29ce98693ffd9c25f9d..3a82efab6194ce394ebc57e225a17062f7e17757 100644 (file)
@@ -617,3 +617,62 @@ void *memchr(const void *s, int c, size_t n)
 }
 
 #endif
+#ifndef __HAVE_ARCH_MEMCHR_INV
+static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
+{
+       while (bytes) {
+               if (*start != value)
+                       return (void *)start;
+               start++;
+               bytes--;
+       }
+       return NULL;
+}
+/**
+ * memchr_inv - Find an unmatching character in an area of memory.
+ * @start: The memory area
+ * @c: Find a character other than c
+ * @bytes: The size of the area.
+ *
+ * returns the address of the first character other than @c, or %NULL
+ * if the whole buffer contains just @c.
+ */
+void *memchr_inv(const void *start, int c, size_t bytes)
+{
+       u8 value = c;
+       u64 value64;
+       unsigned int words, prefix;
+
+       if (bytes <= 16)
+               return check_bytes8(start, value, bytes);
+
+       value64 = value;
+       value64 |= value64 << 8;
+       value64 |= value64 << 16;
+       value64 |= value64 << 32;
+
+       prefix = (unsigned long)start % 8;
+       if (prefix) {
+               u8 *r;
+
+               prefix = 8 - prefix;
+               r = check_bytes8(start, value, prefix);
+               if (r)
+                       return r;
+               start += prefix;
+               bytes -= prefix;
+       }
+
+       words = bytes / 8;
+
+       while (words) {
+               if (*(u64 *)start != value64)
+                       return check_bytes8(start, value, 8);
+               start += 8;
+               words--;
+       }
+
+       return check_bytes8(start, value, bytes % 8);
+}
+#endif
+