diff --git a/lib/libc/riscv/string/Makefile.inc b/lib/libc/riscv/string/Makefile.inc new file mode 100644 --- /dev/null +++ b/lib/libc/riscv/string/Makefile.inc @@ -0,0 +1,4 @@ + +MDSRCS+= \ + strlen.S + diff --git a/lib/libc/riscv/string/strlen.S b/lib/libc/riscv/string/strlen.S new file mode 100644 --- /dev/null +++ b/lib/libc/riscv/string/strlen.S @@ -0,0 +1,65 @@ + +#include + +# https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord +# uses haszero(v) (((v) - 0x01010101UL) & ~(v) & 0x80808080UL) +# which evalutates > 0 when there is zero in v +# register a0 - char* str +ENTRY(strlen) + # register a0 - char* str_start + # register a1 - char* str_ptr + # register a2 - char[8] iter + + # load constants for haszero + li t0, 0x0101010101010101 + slli t1, t0, 7 # 0x8080808080808080, avoid li + + # check alignment of str_start + andi a1, a0, ~0b111 + ld a2, (a1) + beq a1, a0, .Lhas_zero + + # fill bytes before str_start with 0xFF + slli t2, a0, 3 + li t3, -1 # load 0xFFFFFFFFFFFFFFFF + sll t3, t3, t2 # shift mask by unaligned bytes + not t3, t3 # mask bytes before str_start + or a2, a2, t3 # fill with 0xFF + + # unrolled iteration of haszero + not t2, a2 + sub a2, a2, t0 + and a2, a2, t2 + and a2, a2, t1 + + bnez a2, .Lfind_zero + +.Lloop_has_zero: + ld a2, 8(a1) + addi a1, a1, 8 # move ptr to next 8byte +.Lhas_zero: + not t2, a2 + sub a2, a2, t0 + and a2, a2, t2 + and a2, a2, t1 + + beqz a2, .Lloop_has_zero + +.Lfind_zero: + #use (iter & -iter) to isolate lowest set bit + sub a3, zero, a2 #a3 = -iter + and t1, a2, a3 #t1 = (iter & -iter) + + li t0, 0x0001020304050607 + srli t1, t1, 7 + # lowest set bit is 2^(8*k) + # multiplying by it shifts the idx array in t0 by k bytes to the left + mul t1, t1, t0 + # highest byte contains idx of first zero + srli t1, t1, 56 + + add a1, a1, t1 + sub a0, a1, a0 + ret +END(strlen) + diff --git a/share/man/man7/simd.7 b/share/man/man7/simd.7 --- a/share/man/man7/simd.7 +++ b/share/man/man7/simd.7 @@ -50,7 +50,7 @@ .Pp Enhanced functions are present for the following architectures: .Bl -column FUNCTION_________ aarch64_ arm_ amd64_ i386_ ppc64_ -offset indent -.It Em FUNCTION Ta Em AARCH64 Ta Em ARM Ta Em AMD64 Ta Em I386 Ta Em PPC64 +.It Em FUNCTION Ta Em AARCH64 Ta Em ARM Ta Em AMD64 Ta Em I386 Ta Em PPC64 Ta Em RISC-V .It bcmp Ta Ta Ta S1 Ta S .It bcopy Ta Ta S Ta S Ta S Ta SV .It bzero Ta Ta S Ta S Ta S @@ -76,7 +76,7 @@ .It strcspn Ta Ta Ta S2 .It strlcat Ta Ta Ta S1 .It strlcpy Ta Ta Ta S1 -.It strlen Ta A Ta S Ta S1 +.It strlen Ta A Ta S Ta S1 Ta Ta Ta S .It strncat Ta Ta Ta S1 .It strncmp Ta S Ta S Ta S1 Ta S .It strncpy Ta Ta Ta S1 Ta Ta S2