diff options
author | Nick Clifton <nickc@redhat.com> | 2000-11-30 01:57:27 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2000-11-30 01:57:27 +0000 |
commit | 0ffc3b94a0cc452f63eb977633e844dae8539f3a (patch) | |
tree | df045c028255a9399e7a5c489a946561619cac3b /newlib/libc/machine/xscale/strlen.c | |
parent | 09872ef885e9307dc41eb41fdc08bdb1f8ffef7a (diff) | |
download | cygnal-0ffc3b94a0cc452f63eb977633e844dae8539f3a.tar.gz cygnal-0ffc3b94a0cc452f63eb977633e844dae8539f3a.tar.bz2 cygnal-0ffc3b94a0cc452f63eb977633e844dae8539f3a.zip |
Add support for Intel's XScale processor
Diffstat (limited to 'newlib/libc/machine/xscale/strlen.c')
-rw-r--r-- | newlib/libc/machine/xscale/strlen.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/newlib/libc/machine/xscale/strlen.c b/newlib/libc/machine/xscale/strlen.c new file mode 100644 index 000000000..e113ade34 --- /dev/null +++ b/newlib/libc/machine/xscale/strlen.c @@ -0,0 +1,100 @@ +#if defined __thumb__ || defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) + +#include "../../string/strlen.c" + +#else + +#include <string.h> +#include "xscale.h" + +size_t +strlen (const char *str) +{ + _CONST char *start = str; + + /* Skip unaligned part. */ + if ((long)str & 3) + { + str--; + do + { + if (*++str == '\0') + goto out; + } + while ((long)str & 3); + } + + /* Load two constants: + R4 = 0xfefefeff [ == ~(0x80808080 << 1) ] + R5 = 0x80808080 */ + + asm ("mov r5, #0x80 + add r5, r5, #0x8000 + add r5, r5, r5, lsl #16 + mvn r4, r5, lsl #1 +" + +#if defined __ARM_ARCH_5__ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5E__ || defined __ARM_ARCH_5TE__ + +" tst %0, #0x7 + ldreqd r6, [%0] + beq 1f + ldr r2, [%0] + add r3, r2, r4 + bic r3, r3, r2 + ands r2, r3, r5 + bne 2f + sub %0, %0, #4 + +0: + ldrd r6, [%0, #8]! +" + PRELOADSTR ("%0") +" +1: + add r3, r6, r4 + add r2, r7, r4 + bic r3, r3, r6 + bic r2, r2, r7 + and r3, r3, r5 + and r2, r2, r5 + orrs r3, r2, r3 + beq 0b +" +#else + +" sub %0, %0, #4 + +0: + ldr r6, [%0, #4]! +" + PRELOADSTR ("%0") +" + add r3, r6, r4 + bic r3, r3, r6 + ands r3, r3, r5 + beq 0b +" +#endif /* __ARM_ARCH_5[T][E]__ */ +" +2: + ldrb r3, [%0] + cmp r3, #0x0 + beq 1f + +0: + ldrb r3, [%0, #1]! +" + PRELOADSTR ("%0") +" + cmp r3, #0x0 + bne 0b +1: +" + : "=r" (str) : "0" (str) : "r2", "r3", "r4", "r5", "r6", "r7"); + + out: + return str - start; +} + +#endif |