aboutsummaryrefslogtreecommitdiffstats
path: root/lib/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/string.c')
-rw-r--r--lib/string.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/lib/string.c b/lib/string.c
index dc4a86341f91..e5878de4f101 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -22,7 +22,10 @@
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/string.h> 23#include <linux/string.h>
24#include <linux/ctype.h> 24#include <linux/ctype.h>
25#include <linux/module.h> 25#include <linux/kernel.h>
26#include <linux/export.h>
27#include <linux/bug.h>
28#include <linux/errno.h>
26 29
27#ifndef __HAVE_ARCH_STRNICMP 30#ifndef __HAVE_ARCH_STRNICMP
28/** 31/**
@@ -785,12 +788,24 @@ void *memchr_inv(const void *start, int c, size_t bytes)
785 if (bytes <= 16) 788 if (bytes <= 16)
786 return check_bytes8(start, value, bytes); 789 return check_bytes8(start, value, bytes);
787 790
788 value64 = value | value << 8 | value << 16 | value << 24; 791 value64 = value;
789 value64 = (value64 & 0xffffffff) | value64 << 32; 792#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
790 prefix = 8 - ((unsigned long)start) % 8; 793 value64 *= 0x0101010101010101;
794#elif defined(ARCH_HAS_FAST_MULTIPLIER)
795 value64 *= 0x01010101;
796 value64 |= value64 << 32;
797#else
798 value64 |= value64 << 8;
799 value64 |= value64 << 16;
800 value64 |= value64 << 32;
801#endif
791 802
803 prefix = (unsigned long)start % 8;
792 if (prefix) { 804 if (prefix) {
793 u8 *r = check_bytes8(start, value, prefix); 805 u8 *r;
806
807 prefix = 8 - prefix;
808 r = check_bytes8(start, value, prefix);
794 if (r) 809 if (r)
795 return r; 810 return r;
796 start += prefix; 811 start += prefix;