diff options
Diffstat (limited to 'newlib/libc/machine/mips/strncpy.c')
-rw-r--r-- | newlib/libc/machine/mips/strncpy.c | 250 |
1 files changed, 0 insertions, 250 deletions
diff --git a/newlib/libc/machine/mips/strncpy.c b/newlib/libc/machine/mips/strncpy.c deleted file mode 100644 index 47413cb7c..000000000 --- a/newlib/libc/machine/mips/strncpy.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * strncpy.S -- strncmp function. On at least some MIPS chips, you get better - * code by hand unrolling the loops, and by using store words to zero the - * remainder of the buffer than the default newlib C version. - * - * Copyright (c) 2001 Red Hat, Inc. - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. */ - -#include <string.h> -#include <stddef.h> -#include <stdlib.h> -#include <stdint.h> - -#if !defined(__GNUC__) || (__GNUC__ < 3) -#define __builtin_expect(a,b) a - -#else -#ifdef __mips64 -/* Don't use limits test for the size of long, in order to allow the use of - 64-bit stores on MIPS3 machines, even if -mlong32 was used. */ -typedef unsigned word_type __attribute__ ((mode (DI))); -#else -typedef unsigned word_type __attribute__ ((mode (SI))); -#endif - -typedef unsigned si_type __attribute__ ((mode (SI))); -typedef unsigned hi_type __attribute__ ((mode (HI))); - -#ifndef UNROLL_FACTOR -#define UNROLL_FACTOR 4 - -#elif (UNROLL_FACTOR != 2) && (UNROLL_FACTOR != 4) -#error "UNROLL_FACTOR must be 2 or 4" -#endif -#endif - -char * -strncpy (char *dst0, const char *src0, size_t count) -{ -#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) || defined(__mips16) || !defined(__GNUC__) || (__GNUC__ < 3) - char *dst, *end; - const char *src; - int ch; - - dst = dst0; - src = src0; - end = dst + count; - while (dst != end) - { - *dst++ = ch = *src++; - if (__builtin_expect (ch == '\0', 0)) - { - while (dst != end) - *dst++ = '\0'; - - break; - } - } - - return dst0; - -#else - unsigned char *dst; - unsigned char *dst_end; - unsigned char *end; - const unsigned char *src; - int ch0, ch1; -#if UNROLL_FACTOR > 2 - int ch2, ch3; -#endif - int ch; - int odd_bytes; - size_t long_count; - - dst = (unsigned char *)dst0; - src = (unsigned const char *)src0; - /* Take care of any odd bytes in the source data because we - * want to unroll where we read ahead 2 or 4 bytes at a time and then - * check each byte for the null terminator. This can result in - * a segfault for the case where the source pointer is unaligned, - * the null terminator is in valid memory, but reading 2 or 4 bytes at a - * time blindly eventually goes outside of valid memory. */ - while (((uintptr_t) src & (UNROLL_FACTOR - 1)) != 0 && count > 0) - { - *dst++ = ch = *src++; - --count; - if (ch == '\0') - { - end = dst + count; - while (dst != end) - *dst++ = '\0'; - - return dst0; - } - } - - if (__builtin_expect (count >= 4, 1)) - { - odd_bytes = (count & (UNROLL_FACTOR - 1)); - count -= odd_bytes; - - do - { - ch0 = src[0]; - ch1 = src[1]; -#if UNROLL_FACTOR > 2 - ch2 = src[2]; - ch3 = src[3]; -#endif - src += UNROLL_FACTOR; - count -= UNROLL_FACTOR; - - dst[0] = ch0; - if (ch0 == '\0') - goto found_null0; - - dst[1] = ch1; - if (ch1 == '\0') - goto found_null1; - -#if UNROLL_FACTOR > 2 - dst[2] = ch2; - if (ch2 == '\0') - goto found_null2; - - dst[3] = ch3; - if (ch3 == '\0') - goto found_null3; -#endif - - dst += UNROLL_FACTOR; - } - while (count); - - /* fall through, count == 0, no null found, deal with last bytes */ - count = odd_bytes; - } - - end = dst + count; - while (dst != end) - { - *dst++ = ch = *src++; - if (ch == '\0') - { - while (dst != end) - *dst++ = '\0'; - - break; - } - } - - return dst0; - - /* Found null byte in first byte, count has been decremented by 4, null has - been stored in dst[0]. */ - found_null0: - count++; /* add 1 to cover remaining byte */ - dst -= 1; /* adjust dst += 4 gets correct ptr */ - /* fall through */ - - /* Found null byte in second byte, count has been decremented by 4, null has - been stored in dst[1]. */ - found_null1: -#if UNROLL_FACTOR > 2 - count++; /* add 1 to cover remaining byte */ - dst -= 1; /* adjust dst += 4 gets correct ptr */ - /* fall through */ - - /* Found null byte in third byte, count has been decremented by 4, null has - been stored in dst[2]. */ - found_null2: - count++; /* add 1 to cover remaining byte */ - dst -= 1; /* adjust dst += 4 gets correct ptr */ - /* fall through */ - - /* Found null byte in fourth byte, count is accurate, dst has not been - updated yet. */ - found_null3: -#endif - count += odd_bytes; /* restore odd byte count */ - dst += UNROLL_FACTOR; - - /* Zero fill remainder of the array. Unroll the loop, and use word/dword - stores where we can. */ - while (count && (((long)dst) & (sizeof (word_type) - 1)) != 0) - { - count--; - *dst++ = 0; - } - - while (count >= UNROLL_FACTOR*sizeof (word_type)) - { - count -= UNROLL_FACTOR*sizeof (word_type); - dst += UNROLL_FACTOR*sizeof (word_type); -#if UNROLL_FACTOR > 2 - ((word_type *)(void *)dst)[-4] = 0; - ((word_type *)(void *)dst)[-3] = 0; -#endif - ((word_type *)(void *)dst)[-2] = 0; - ((word_type *)(void *)dst)[-1] = 0; - } - -#if UNROLL_FACTOR > 2 - if (count >= 2*sizeof (word_type)) - { - count -= 2*sizeof (word_type); - ((word_type *)(void *)dst)[0] = 0; - ((word_type *)(void *)dst)[1] = 0; - dst += 2*sizeof (word_type); - } -#endif - - if (count >= sizeof (word_type)) - { - count -= sizeof (word_type); - ((word_type *)(void *)dst)[0] = 0; - dst += sizeof (word_type); - } - -#ifdef __mips64 - if (count >= sizeof (si_type)) - { - count -= sizeof (si_type); - ((si_type *)(void *)dst)[0] = 0; - dst += sizeof (si_type); - } -#endif - - if (count >= sizeof (hi_type)) - { - count -= sizeof (hi_type); - ((hi_type *)(void *)dst)[0] = 0; - dst += sizeof (hi_type); - } - - if (count) - *dst = '\0'; - - return dst0; -#endif -} |