fxlibc/src/libc/string/target/sh-generic/memchr.S

69 lines
975 B
ArmAsm

.global _memchr
.type _memchr, @function
_memchr:
mov r4, r0
exts.b r5, r5
/* For small inputs, simply check bytes individually */
mov #64, r2
cmp/hi r6, r2
bt .last
.large: /* Make a 4-byte version of r5 for cmp/str */
extu.b r5, r3
swap.b r3, r2
or r3, r2
swap.w r2, r3
or r3, r2
/* First check 3 bytes to ensure we don't skip bytes when aligning */
mov.b @r0+, r1
cmp/eq r1, r5
bt .end
mov.b @r0+, r1
cmp/eq r1, r5
bt .end
mov.b @r0+, r1
cmp/eq r1, r5
bt .end
/* Align to a 4-byte boundary */
shlr2 r0
shll2 r0
add r4, r6
sub r0, r6
mov r6, r7
shlr2 r7
mov #3, r3
and r3, r6
/* Read longwords */
1: mov.l @r0+, r1
cmp/str r1, r2
bt .found
dt r7
bf 1b
.last: /* Don't read if there are no bytes left */
tst r6, r6
bt .none
2: mov.b @r0+, r1
cmp/eq r1, r5
bt .end
dt r6
bf 2b
.none: rts
mov #0, r0
.found: /* Go back to find out which of the last 4 bytes is r5 */
add #-4, r0
bra 2b
mov #4, r6
.end: rts
add #-1, r0