diff options
Diffstat (limited to 'libc/string/generic')
-rw-r--r-- | libc/string/generic/memmove.c | 10 | ||||
-rw-r--r-- | libc/string/generic/strchr.c | 23 | ||||
-rw-r--r-- | libc/string/generic/strchrnul.c | 23 | ||||
-rw-r--r-- | libc/string/generic/strlen.c | 21 |
4 files changed, 29 insertions, 48 deletions
diff --git a/libc/string/generic/memmove.c b/libc/string/generic/memmove.c index bf78c4778..5389cc029 100644 --- a/libc/string/generic/memmove.c +++ b/libc/string/generic/memmove.c @@ -23,8 +23,9 @@ #include "memcopy.h" #include "pagecopy.h" -#ifdef __ARCH_HAS_BWD_MEMCPY__ +#if defined(__ARCH_HAS_BWD_MEMCPY__) || defined(__mips__) /* generic-opt memmove assumes memcpy does forward copying! */ +/* also needed for MIPS as its memcpy does not support overlapping regions */ #include "_memcpy_fwd.c" #endif @@ -224,8 +225,11 @@ void *memmove (void *dest, const void *src, size_t len) Reduces the working set. */ if (dstp - srcp >= len) /* *Unsigned* compare! */ { -#ifndef __ARCH_HAS_BWD_MEMCPY__ - /* Backward memcpy implementation cannot be used */ + /* Calling memcpy() from memmove() should be skipped in two cases: + * a) if arch's memcpy uses a backward copying (SH4) + * b) if arch's memcpy is not fully safe for overlapping regions (MIPS) + */ +#if !defined(__ARCH_HAS_BWD_MEMCPY_) && !defined(__mips__) memcpy(dest, src, len); #else /* Copy from the beginning to the end. */ diff --git a/libc/string/generic/strchr.c b/libc/string/generic/strchr.c index 321d2b8c3..b34884d67 100644 --- a/libc/string/generic/strchr.c +++ b/libc/string/generic/strchr.c @@ -60,22 +60,19 @@ char *strchr (const char *s, int c_in) The 1-bits make sure that carries propagate to the next 0-bit. The 0-bits provide holes for carries to fall into. */ - switch (sizeof (longword)) - { - case 4: magic_bits = 0x7efefeffL; break; - case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break; - default: - abort (); - } - /* Set up a longword, each of whose bytes is C. */ +#if __WORDSIZE == 32 + magic_bits = 0x7efefeffL; charmask = c | (c << 8); charmask |= charmask << 16; - if (sizeof (longword) > 4) - /* Do the shift in two steps to avoid a warning if long has 32 bits. */ - charmask |= (charmask << 16) << 16; - if (sizeof (longword) > 8) - abort (); +#elif __WORDSIZE == 64 + magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; + charmask = c | (c << 8); + charmask |= charmask << 16; + charmask |= (charmask << 16) << 16; +#else + #error unexpected integer size strchr() +#endif /* Instead of the traditional loop which tests each character, we will test a longword at a time. The tricky part is testing diff --git a/libc/string/generic/strchrnul.c b/libc/string/generic/strchrnul.c index d11d9e00d..d9fadc776 100644 --- a/libc/string/generic/strchrnul.c +++ b/libc/string/generic/strchrnul.c @@ -59,22 +59,19 @@ char *strchrnul (const char *s, int c_in) The 1-bits make sure that carries propagate to the next 0-bit. The 0-bits provide holes for carries to fall into. */ - switch (sizeof (longword)) - { - case 4: magic_bits = 0x7efefeffL; break; - case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break; - default: - abort (); - } - /* Set up a longword, each of whose bytes is C. */ +#if __WORDSIZE == 32 + magic_bits = 0x7efefeffL; charmask = c | (c << 8); charmask |= charmask << 16; - if (sizeof (longword) > 4) - /* Do the shift in two steps to avoid a warning if long has 32 bits. */ - charmask |= (charmask << 16) << 16; - if (sizeof (longword) > 8) - abort (); +#elif __WORDSIZE == 64 + magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; + charmask = c | (c << 8); + charmask |= charmask << 16; + charmask |= (charmask << 16) << 16; +#else + #error unexpected integer size strchr() +#endif /* Instead of the traditional loop which tests each character, we will test a longword at a time. The tricky part is testing diff --git a/libc/string/generic/strlen.c b/libc/string/generic/strlen.c index dc383398b..dcc032ddc 100644 --- a/libc/string/generic/strlen.c +++ b/libc/string/generic/strlen.c @@ -28,7 +28,7 @@ size_t strlen (const char *str) { const char *char_ptr; const unsigned long int *longword_ptr; - unsigned long int longword, magic_bits, himagic, lomagic; + unsigned long int longword, himagic, lomagic; /* Handle the first few characters by reading one character at a time. Do this until CHAR_PTR is aligned on a longword boundary. */ @@ -52,14 +52,12 @@ size_t strlen (const char *str) The 1-bits make sure that carries propagate to the next 0-bit. The 0-bits provide holes for carries to fall into. */ - magic_bits = 0x7efefeffL; himagic = 0x80808080L; lomagic = 0x01010101L; if (sizeof (longword) > 4) { /* 64-bit version of the magic. */ /* Do the shift in two steps to avoid a warning if long has 32 bits. */ - magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; himagic = ((himagic << 16) << 16) | himagic; lomagic = ((lomagic << 16) << 16) | lomagic; } @@ -102,22 +100,7 @@ size_t strlen (const char *str) longword = *longword_ptr++; - if ( -#if 0 - /* Add MAGIC_BITS to LONGWORD. */ - (((longword + magic_bits) - - /* Set those bits that were unchanged by the addition. */ - ^ ~longword) - - /* Look at only the hole bits. If any of the hole bits - are unchanged, most likely one of the bytes was a - zero. */ - & ~magic_bits) -#else - ((longword - lomagic) & himagic) -#endif - != 0) + if (((longword - lomagic) & himagic) != 0) { /* Which of the bytes was the zero? If none of them were, it was a misfire; continue the search. */ |