diff options
Diffstat (limited to 'newlib/libc/machine/mips/strcmp.c')
-rw-r--r-- | newlib/libc/machine/mips/strcmp.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/newlib/libc/machine/mips/strcmp.c b/newlib/libc/machine/mips/strcmp.c new file mode 100644 index 000000000..c9c1c6595 --- /dev/null +++ b/newlib/libc/machine/mips/strcmp.c @@ -0,0 +1,71 @@ +/* + * strcmp.c -- strcmp function. On at least some MIPS chips, a strcmp that is + * unrolled twice is faster than the 'optimized' C version in newlib. + * + * 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 <stddef.h> +#include <string.h> +#include <stdlib.h> + +int +strcmp (const char *s1, const char *s2) +{ + unsigned const char *us1 = (unsigned const char *)s1; + unsigned const char *us2 = (unsigned const char *)s2; + int c1a, c1b; + int c2a, c2b; + + /* If the pointers aren't both aligned to a 16-byte boundary, do the + comparison byte by byte, so that we don't get an invalid page fault if we + are comparing a string whose null byte is at the last byte on the last + valid page. */ + if (((((long)us1) | ((long)us2)) & 1) == 0) + { + c1a = *us1; + for (;;) + { + c1b = *us2; + us1 += 2; + if (c1a == '\0') + goto ret1; + + c2a = us1[-1]; + if (c1a != c1b) + goto ret1; + + c2b = us2[1]; + us2 += 2; + if (c2a == '\0') + break; + + c1a = *us1; + if (c2a != c2b) + break; + } + + return c2a - c2b; + } + else + { + do + { + c1a = *us1++; + c1b = *us2++; + } + while (c1a != '\0' && c1a == c1b); + } + + ret1: + return c1a - c1b; +} |