1/* 2 * strnlen - calculate the length of a string with limit. 3 * 4 * Copyright (c) 2019-2022, Arm Limited. 5 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 6 */ 7 8#include "asmdefs.h" 9 10.arch armv8-a+sve 11 12/* Assumptions: 13 * 14 * ARMv8-a, AArch64 15 * SVE Available. 16 */ 17 18ENTRY (__strnlen_aarch64_sve) 19 setffr /* initialize FFR */ 20 mov x2, 0 /* initialize len */ 21 b 1f 22 23 .p2align 4 24 /* We have off + vl <= max, and so may read the whole vector. */ 250: ldff1b z0.b, p0/z, [x0, x2] 26 rdffrs p1.b, p0/z 27 b.nlast 2f 28 29 /* First fault did not fail: the whole vector is valid. 30 Avoid depending on the contents of FFR beyond the branch. */ 31 cmpeq p2.b, p0/z, z0.b, 0 32 b.any 8f 33 incb x2 34 351: whilelo p0.b, x2, x1 36 b.last 0b 37 38 /* We have off + vl < max. Test for off == max before proceeding. */ 39 b.none 9f 40 41 ldff1b z0.b, p0/z, [x0, x2] 42 rdffrs p1.b, p0/z 43 b.nlast 2f 44 45 /* First fault did not fail: the vector up to max is valid. 46 Avoid depending on the contents of FFR beyond the branch. 47 Compare for end-of-string, but there are no more bytes. */ 48 cmpeq p2.b, p0/z, z0.b, 0 49 50 /* Found end-of-string or zero. */ 518: brkb p2.b, p0/z, p2.b 52 mov x0, x2 53 incp x0, p2.b 54 ret 55 56 /* First fault failed: only some of the vector is valid. 57 Perform the comparison only on the valid bytes. */ 582: cmpeq p2.b, p1/z, z0.b, 0 59 b.any 8b 60 61 /* No inequality or zero found. Re-init FFR, incr and loop. */ 62 setffr 63 incp x2, p1.b 64 b 1b 65 66 /* End of count. Return max. */ 679: mov x0, x1 68 ret 69 70END (__strnlen_aarch64_sve) 71