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