From patchwork Tue May 26 18:55:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ondrej Bilka X-Patchwork-Id: 6926 Received: (qmail 86111 invoked by alias); 26 May 2015 18:55:45 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 86095 invoked by uid 89); 26 May 2015 18:55:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.7 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, SPF_NEUTRAL autolearn=no version=3.3.2 X-HELO: popelka.ms.mff.cuni.cz Date: Tue, 26 May 2015 20:55:34 +0200 From: =?utf-8?B?T25kxZllaiBCw61sa2E=?= To: libc-alpha@sourceware.org Subject: [RFC PATCH 4/3] Fix previous patch and add header. Message-ID: <20150526185534.GA28344@domone> References: <20150526173150.GA26817@domone> <20150526181035.GA27596@domone> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20150526181035.GA27596@domone> User-Agent: Mutt/1.5.20 (2009-06-14) Sorry, found that my method of testing as compiling these as standalone file then including them to libc caused problems. This should fix these. Also moved reusable functions to separate header as I will cover a strlen, rawmemchr, memchr and rawmemchr. diff --git a/string/common.h b/string/common.h new file mode 100644 index 0000000..84f9767 --- /dev/null +++ b/string/common.h @@ -0,0 +1,35 @@ +#include + +static const unsigned long int ones = (~0UL / 255); /* 0x0101...*/ +static const unsigned long int add = 127 * (~0UL / 255); +static const unsigned long int high_bits = 128 * (~0UL / 255); + +/* Use vector arithmetic tricks. Idea is to take expression works on + unsigned byte and evaluates 0 for nozero byte and nonzero on zero byte. + Our expression is ((s + 127) ^ (~s)) & 128 + Now we evaluate this expression on each byte in parallel and on first + nonzero byte our expression will have nonzero value. */ + +static __always_inline +unsigned long int +contains_zero (unsigned long int s) +{ + return ((s + add) ^ ~s) & high_bits; +} + +#define LSIZE sizeof (unsigned long int) +#define CROSS_PAGE(x, n) (((uintptr_t)x) % 4096 >= 4096 - n) + +static __always_inline +size_t +first_nonzero_byte (unsigned long int u) +{ +#ifdef FAST_FFS + return ffsl (u) / 8 - 1; +#else + u = u = u ^ (u - 1); + u = u & ones; + u = u * ones; + return (u >> (8 * LSIZE - 8)) - 1; +#endif +} diff --git a/string/strchr.c b/string/strchr.c index 17473b8..ca543f4 100644 --- a/string/strchr.c +++ b/string/strchr.c @@ -25,9 +25,8 @@ #undef strchr - /* Include strchrnul and let gcc inline it. */ -#define AS_STRCHRNUL +#define AS_STRCHR #define STRCHRNUL strchrnul_i #include "string/strchrnul.c" diff --git a/string/strchrnul.c b/string/strchrnul.c index ea91195..5be9da9 100644 --- a/string/strchrnul.c +++ b/string/strchrnul.c @@ -23,6 +23,7 @@ #include #include #include +#include "string/common.h" #undef __strchrnul #undef strchrnul @@ -30,24 +31,8 @@ # define STRCHRNUL __strchrnul #endif -static const unsigned long int ones = (~0UL / 255); /* 0x0101...*/ -static const unsigned long int add = 127 * (~0UL / 255); -static const unsigned long int high_bits = 128 * (~0UL / 255); -/* Use vector arithmetic tricks. Idea is to take expression works on - unsigned byte and evaluates 0 for nozero byte and nonzero on zero byte. - Our expression is ((s + 127) ^ (~s)) & 128 - Now we evaluate this expression on each byte in parallel and on first - nonzero byte our expression will have nonzero value. */ - -static always_inline -unsigned long int -contains_zero (unsigned long int s) -{ - return ((s + add) ^ ~s) & high_bits; -} - -static always_inline +static __always_inline int found_in_long_bytes(char *s, unsigned long int cmask, char **result) { @@ -55,19 +40,16 @@ found_in_long_bytes(char *s, unsigned long int cmask, char **result) unsigned long int mask = contains_zero (*lptr) | contains_zero (*lptr ^ cmask); if (mask) { - *result = s + ffsl (mask) / 8 - 1; + *result = s + first_nonzero_byte (mask); return 1; } else return 0; } -#define LSIZE sizeof (unsigned long int) -#define CROSS_PAGE(x, n) (((uintptr_t)x)%4096 >= 4096 - n) - /* Find the first occurrence of C in S or the final NUL byte. */ #ifdef AS_STRCHR -static always_inline +static __always_inline #endif char * STRCHRNUL (const char *s_in, int c_in) @@ -122,7 +104,7 @@ STRCHRNUL (const char *s_in, int c_in) >> (8 * (s_aligned - s)); if (mask) - return s + ffsl (mask) / 8 - 1; + return s + first_nonzero_byte (mask); if (found_in_long_bytes (s + 1 * LSIZE, cmask, &r)) return r; @@ -160,14 +142,6 @@ STRCHRNUL (const char *s_in, int c_in) return r; } - -char *strchr(char *s, int c) -{ - char *r = __strchrnule(s,c); - return *r ? r : 0; - -} - -#ifndef AS_STRCHR +#ifdef AS_STRCHR weak_alias (__strchrnul, strchrnul) #endif