131914882SAlex Richardson/* 231914882SAlex Richardson * strnlen - calculate the length of a string with limit. 331914882SAlex Richardson * 4*072a4ba8SAndrew Turner * Copyright (c) 2019-2022, Arm Limited. 5*072a4ba8SAndrew Turner * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 631914882SAlex Richardson */ 731914882SAlex Richardson 8*072a4ba8SAndrew Turner#include "asmdefs.h" 931914882SAlex Richardson 1031914882SAlex Richardson#if __ARM_FEATURE_SVE 1131914882SAlex Richardson/* Assumptions: 1231914882SAlex Richardson * 1331914882SAlex Richardson * ARMv8-a, AArch64 1431914882SAlex Richardson * SVE Available. 1531914882SAlex Richardson */ 1631914882SAlex Richardson 1731914882SAlex RichardsonENTRY (__strnlen_aarch64_sve) 1831914882SAlex Richardson PTR_ARG (0) 1931914882SAlex Richardson SIZE_ARG (1) 2031914882SAlex Richardson setffr /* initialize FFR */ 2131914882SAlex Richardson mov x2, 0 /* initialize len */ 2231914882SAlex Richardson b 1f 2331914882SAlex Richardson 2431914882SAlex Richardson .p2align 4 2531914882SAlex Richardson /* We have off + vl <= max, and so may read the whole vector. */ 2631914882SAlex Richardson0: ldff1b z0.b, p0/z, [x0, x2] 2731914882SAlex Richardson rdffrs p1.b, p0/z 2831914882SAlex Richardson b.nlast 2f 2931914882SAlex Richardson 3031914882SAlex Richardson /* First fault did not fail: the whole vector is valid. 3131914882SAlex Richardson Avoid depending on the contents of FFR beyond the branch. */ 3231914882SAlex Richardson cmpeq p2.b, p0/z, z0.b, 0 3331914882SAlex Richardson b.any 8f 3431914882SAlex Richardson incb x2 3531914882SAlex Richardson 3631914882SAlex Richardson1: whilelo p0.b, x2, x1 3731914882SAlex Richardson b.last 0b 3831914882SAlex Richardson 3931914882SAlex Richardson /* We have off + vl < max. Test for off == max before proceeding. */ 4031914882SAlex Richardson b.none 9f 4131914882SAlex Richardson 4231914882SAlex Richardson ldff1b z0.b, p0/z, [x0, x2] 4331914882SAlex Richardson rdffrs p1.b, p0/z 4431914882SAlex Richardson b.nlast 2f 4531914882SAlex Richardson 4631914882SAlex Richardson /* First fault did not fail: the vector up to max is valid. 4731914882SAlex Richardson Avoid depending on the contents of FFR beyond the branch. 4831914882SAlex Richardson Compare for end-of-string, but there are no more bytes. */ 4931914882SAlex Richardson cmpeq p2.b, p0/z, z0.b, 0 5031914882SAlex Richardson 5131914882SAlex Richardson /* Found end-of-string or zero. */ 5231914882SAlex Richardson8: brkb p2.b, p0/z, p2.b 5331914882SAlex Richardson mov x0, x2 5431914882SAlex Richardson incp x0, p2.b 5531914882SAlex Richardson ret 5631914882SAlex Richardson 5731914882SAlex Richardson /* First fault failed: only some of the vector is valid. 5831914882SAlex Richardson Perform the comparison only on the valid bytes. */ 5931914882SAlex Richardson2: cmpeq p2.b, p1/z, z0.b, 0 6031914882SAlex Richardson b.any 8b 6131914882SAlex Richardson 6231914882SAlex Richardson /* No inequality or zero found. Re-init FFR, incr and loop. */ 6331914882SAlex Richardson setffr 6431914882SAlex Richardson incp x2, p1.b 6531914882SAlex Richardson b 1b 6631914882SAlex Richardson 6731914882SAlex Richardson /* End of count. Return max. */ 6831914882SAlex Richardson9: mov x0, x1 6931914882SAlex Richardson ret 7031914882SAlex Richardson 7131914882SAlex RichardsonEND (__strnlen_aarch64_sve) 7231914882SAlex Richardson 7331914882SAlex Richardson#endif 7431914882SAlex Richardson 75