69 lines
975 B
ArmAsm
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
|