59 lines · plain
1/*2 * __strlen_aarch64_sve - compute the length of a string3 *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-exception7 */8 9#if __ARM_FEATURE_SVE10/* Assumptions:11 *12 * ARMv8-a, AArch6413 * SVE Available.14 */15 16 .arch armv8-a+sve17 .text18 19 .globl __strlen_aarch64_sve20 .type __strlen_aarch64_sve, %function21 .p2align 422__strlen_aarch64_sve:23 setffr /* initialize FFR */24 ptrue p2.b /* all ones; loop invariant */25 mov x1, 0 /* initialize length */26 nop27 28 /* Read a vector's worth of bytes, stopping on first fault. */290: ldff1b z0.b, p2/z, [x0, x1]30 nop31 rdffrs p0.b, p2/z32 b.nlast 2f33 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 0b39 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.b43 incp x1, p0.b44 mov x0, x145 ret46 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, 050 b.any 1b51 52 /* No zero found. Re-init FFR, increment, and loop. */53 setffr54 incp x1, p0.b55 b 0b56 57 .size __strlen_aarch64_sve, . - __strlen_aarch64_sve58#endif59