summaryrefslogtreecommitdiff
path: root/libc/string/arm/strlen.S
diff options
context:
space:
mode:
Diffstat (limited to 'libc/string/arm/strlen.S')
-rw-r--r--libc/string/arm/strlen.S25
1 files changed, 25 insertions, 0 deletions
diff --git a/libc/string/arm/strlen.S b/libc/string/arm/strlen.S
index 5b4b02e17..949e918f4 100644
--- a/libc/string/arm/strlen.S
+++ b/libc/string/arm/strlen.S
@@ -20,6 +20,7 @@
#include <features.h>
#include <endian.h>
#include <sys/syscall.h>
+#include <bits/arm_asm.h>
/* size_t strlen(const char *S)
* entry: r0 -> string
@@ -31,6 +32,19 @@
.type strlen,%function
.align 4
+#if defined(THUMB1_ONLY)
+/* A simple implementation for when the ARM implementation can't be used. */
+.thumb_func
+strlen:
+ mov r2, #0
+1:
+ ldrb r1, [r0, r2]
+ add r2, r2, #1
+ cmp r1, #0
+ bne 1b
+ sub r0, r2, #1
+ bx lr
+#else
strlen:
bic r1, r0, $3 @ addr of word containing first byte
ldr r2, [r1], $4 @ get the first word
@@ -41,38 +55,48 @@ strlen:
#if __BYTE_ORDER == __BIG_ENDIAN
orr r2, r2, $0xff000000 @ set this byte to non-zero
subs r3, r3, $1 @ any more to do?
+ IT(t, gt)
orrgt r2, r2, $0x00ff0000 @ if so, set this byte
subs r3, r3, $1 @ more?
+ IT(t, gt)
orrgt r2, r2, $0x0000ff00 @ then set.
#else
orr r2, r2, $0x000000ff @ set this byte to non-zero
subs r3, r3, $1 @ any more to do?
+ IT(t, gt)
orrgt r2, r2, $0x0000ff00 @ if so, set this byte
subs r3, r3, $1 @ more?
+ IT(t, gt)
orrgt r2, r2, $0x00ff0000 @ then set.
#endif
Laligned: @ here, we have a word in r2. Does it
tst r2, $0x000000ff @ contain any zeroes?
+ IT(tttt, ne)
tstne r2, $0x0000ff00 @
tstne r2, $0x00ff0000 @
tstne r2, $0xff000000 @
addne r0, r0, $4 @ if not, the string is 4 bytes longer
+ IT(t, ne)
ldrne r2, [r1], $4 @ and we continue to the next word
bne Laligned @
Llastword: @ drop through to here once we find a
#if __BYTE_ORDER == __BIG_ENDIAN
tst r2, $0xff000000 @ word that has a zero byte in it
+ IT(tttt, ne)
addne r0, r0, $1 @
tstne r2, $0x00ff0000 @ and add up to 3 bytes on to it
addne r0, r0, $1 @
tstne r2, $0x0000ff00 @ (if first three all non-zero, 4th
+ IT(t, ne)
addne r0, r0, $1 @ must be zero)
#else
tst r2, $0x000000ff @
+ IT(tttt, ne)
addne r0, r0, $1 @
tstne r2, $0x0000ff00 @ and add up to 3 bytes on to it
addne r0, r0, $1 @
tstne r2, $0x00ff0000 @ (if first three all non-zero, 4th
+ IT(t, ne)
addne r0, r0, $1 @ must be zero)
#endif
#if defined(__USE_BX__)
@@ -80,6 +104,7 @@ Llastword: @ drop through to here once we find a
#else
mov pc,lr
#endif
+#endif
.size strlen,.-strlen