Word-at-a-time memcpy/memmove/memset/strlen/strcmp implementing the level-1 string slice. memcpy carries an optimize(no-tree-loop- distribute-patterns) attribute: GCC's loop-distribution pass rewrites its word-copy loop into a self-recursive memcpy@plt call at -O2/-O3 otherwise. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <[email protected]>
63 lines
1.3 KiB
C
63 lines
1.3 KiB
C
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <string.h>
|
|
|
|
/*
|
|
* True if w contains a zero byte. Subtracting ONES from w propagates a
|
|
* borrow into the high bit of a byte exactly when that byte is zero;
|
|
* ANDing with ~w keeps only bytes that were zero and high-bit-clear in w.
|
|
* ONES and its shifted form are derived from the word width, so this works
|
|
* for both 32- and 64-bit unsigned long.
|
|
*/
|
|
static unsigned long
|
|
haszero(unsigned long w)
|
|
{
|
|
const unsigned long ones = (unsigned long)-1 / 0xff;
|
|
|
|
return (w - ones) & ~w & (ones << 7);
|
|
}
|
|
|
|
/*
|
|
* Return the length of s, excluding the terminating NUL.
|
|
*/
|
|
size_t
|
|
strlen(const char *s)
|
|
{
|
|
const unsigned long word = sizeof(unsigned long);
|
|
const char *p = s;
|
|
|
|
/* Check the head byte-wise until p is word-aligned. */
|
|
for (; (unsigned long)p % word != 0; p++)
|
|
{
|
|
if (*p == '\0')
|
|
{
|
|
return (size_t)(p - s);
|
|
}
|
|
}
|
|
|
|
/* Scan whole words for a zero byte. */
|
|
for (;;)
|
|
{
|
|
unsigned long w;
|
|
|
|
__builtin_memcpy(&w, p, sizeof w);
|
|
if (haszero(w))
|
|
{
|
|
break;
|
|
}
|
|
p += word;
|
|
}
|
|
|
|
/* Resolve the terminating word byte-wise. */
|
|
for (;;)
|
|
{
|
|
if (*p == '\0')
|
|
{
|
|
return (size_t)(p - s);
|
|
}
|
|
p++;
|
|
}
|
|
}
|