1/* 2 * __strlen_aarch64_sve - compute the length of a string 3 * 4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 * See https://llvm.org/LICENSE.txt for license information. 6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 */ 8 9#if __ARM_FEATURE_SVE 10/* Assumptions: 11 * 12 * ARMv8-a, AArch64 13 * SVE Available. 14 */ 15 16 .arch armv8-a+sve 17 .text 18 19 .globl __strlen_aarch64_sve 20 .type __strlen_aarch64_sve, %function 21 .p2align 4 22__strlen_aarch64_sve: 23 setffr /* initialize FFR */ 24 ptrue p2.b /* all ones; loop invariant */ 25 mov x1, 0 /* initialize length */ 26 nop 27 28 /* Read a vector's worth of bytes, stopping on first fault. */ 290: ldff1b z0.b, p2/z, [x0, x1] 30 nop 31 rdffrs p0.b, p2/z 32 b.nlast 2f 33 34 /* First fault did not fail: the whole vector is valid. 35 Avoid depending on the contents of FFR beyond the branch. */ 36 incb x1, all /* speculate increment */ 37 cmpeq p1.b, p2/z, z0.b, 0 /* loop if no zeros */ 38 b.none 0b 39 decb x1, all /* undo speculate */ 40 41 /* Zero found. Select the bytes before the first and count them. */ 421: brkb p0.b, p2/z, p1.b 43 incp x1, p0.b 44 mov x0, x1 45 ret 46 47 /* First fault failed: only some of the vector is valid. 48 Perform the comparison only on the valid bytes. */ 492: cmpeq p1.b, p0/z, z0.b, 0 50 b.any 1b 51 52 /* No zero found. Re-init FFR, increment, and loop. */ 53 setffr 54 incp x1, p0.b 55 b 0b 56 57 .size __strlen_aarch64_sve, . - __strlen_aarch64_sve 58#endif 59