diff options
Diffstat (limited to 'libc/arch-riscv64/string/strnlen_vext.S')
-rw-r--r-- | libc/arch-riscv64/string/strnlen_vext.S | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/libc/arch-riscv64/string/strnlen_vext.S b/libc/arch-riscv64/string/strnlen_vext.S new file mode 100644 index 000000000..f546689bb --- /dev/null +++ b/libc/arch-riscv64/string/strnlen_vext.S @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * Copyright (c) 2023 SiFive, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the company may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(__riscv_v) + +#include "sys/asm.h" + +#define pStr a0 +#define pCopyStr a2 +#define iRetValue a0 +#define iMaxlen a1 +#define iCurrentVL a3 +#define iEndOffset a4 + +#define ELEM_LMUL_SETTING m1 +#define vStr v0 +#define vMaskEnd v8 + +ENTRY(strnlen_vext) + + mv pCopyStr, pStr + mv iRetValue, iMaxlen +L(strnlen_loop): + beqz iMaxlen, L(end_strnlen_loop) + vsetvli zero, iMaxlen, e8, ELEM_LMUL_SETTING, ta, ma + vle8ff.v vStr, (pCopyStr) + vmseq.vi vMaskEnd, vStr, 0 + vfirst.m iEndOffset, vMaskEnd /* first occurrence of \0 */ + csrr iCurrentVL, vl + add pCopyStr, pCopyStr, iCurrentVL + sub iMaxlen, iMaxlen, iCurrentVL + bltz iEndOffset, L(strnlen_loop) + add iMaxlen, iMaxlen, iCurrentVL + sub iRetValue, iRetValue, iMaxlen + add iRetValue, iRetValue, iEndOffset +L(end_strnlen_loop): + ret + +END(strnlen_vext) + +#endif |