#include <machine/asm.h>
ENTRY(memchr)
beqz a2, .Lno_match
andi a1, a1, 0xFF
add a3, a0, a2
li t0, 0x01010101
sltu t2, a0, a3
slli t1, t0, 32
neg t2, t2
or t0, t0, t1
and a3, a3, t2
slli t1, t0, 7
slli t2, a0, 3
and a0, a0, ~0b111
mul a1, t0, a1
ld a2, (a0)
sll t2, t0, t2
xor a2, a2, a1
xor t2, t2, t0
or a2, a2, t2
addi a4, a3, 7
not t2, a2
sub a2, a2, t0
and t2, t2, t1
andi a4, a4, ~0b111
and a2, a2, t2
addi a0, a0, 8
bnez a2, .Lfind_zero
beq a0, a4, .Lno_match
andi a5, a4, ~0b1111
ld a2, (a0)
xor a2, a2, a1
not t2, a2
sub a2, a2, t0
and t2, t2, t1
and a2, a2, t2
addi a0, a0, 8
bnez a2, .Lfind_zero
andi a0, a0, ~0b1111
beq a0, a5, .Lskip_loop
.Lloop:
ld a2, (a0)
ld t3, 8(a0)
xor a2, a2, a1
xor t3, t3, a1
not t2, a2
not t4, t3
sub a2, a2, t0
sub t3, t3, t0
and t2, t2, t1
and t4, t4, t1
and a2, a2, t2
and t3, t3, t4
addi a0, a0, 8
bnez a2, .Lfind_zero
mv a2, t3
addi a0, a0, 8
bnez a2, .Lfind_zero
bne a0, a5, .Lloop
.Lskip_loop:
beq a0, a4, .Lno_match
ld a2, (a0)
xor a2, a2, a1
not t2, a2
sub a2, a2, t0
and t2, t2, t1
and a2, a2, t2
addi a0, a0, 8
beqz a2, .Lno_match
.Lfind_zero:
li t1, 0x10203000
neg t0, a2
slli t1, t1, 4
and a2, a2, t0
addi t1, t1, 0x405
srli a2, a2, 7
slli t1, t1, 16
addi a0, a0, -8
addi t1, t1, 0x607
mul a2, a2, t1
srli a2, a2, 56
sub t0, a3, a0
sltu t1, a2, t0
neg t1, t1
add a0, a0, a2
and a0, a0, t1
ret
.Lno_match:
li a0, 0
ret
END(memchr)