diff options
Diffstat (limited to 'lib/string.c')
-rw-r--r-- | lib/string.c | 25 |
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; |