Path: blob/main/contrib/arm-optimized-routines/string/aarch64/experimental/strrchr-sve.S
39536 views
/*1* strrchr - find the last of a character in a string2*3* Copyright (c) 2019-2022, Arm Limited.4* SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception5*/67#include "asmdefs.h"89.arch armv8-a+sve1011/* Assumptions:12*13* ARMv8-a, AArch6414* SVE Available.15*/1617ENTRY (__strrchr_aarch64_sve)18dup z1.b, w1 /* replicate byte across vector */19setffr /* initialize FFR */20ptrue p1.b /* all ones; loop invariant */21mov x2, 0 /* no match found so far */22pfalse p2.b2324.p2align 425/* Read a vector's worth of bytes, stopping on first fault. */260: ldff1b z0.b, p1/z, [x0, xzr]27rdffrs p0.b, p1/z28b.nlast 1f2930/* First fault did not fail: the whole vector is valid.31Avoid depending on the contents of FFR beyond the branch. */32incb x0, all /* skip bytes this round */33cmpeq p3.b, p1/z, z0.b, 0 /* search for 0 */34b.any 3f3536cmpeq p3.b, p1/z, z0.b, z1.b /* search for c; no eos */37b.none 0b3839mov x2, x0 /* save advanced base */40mov p2.b, p3.b /* save current search */41b 0b4243/* First fault failed: only some of the vector is valid.44Perform the comparisions only on the valid bytes. */451: cmpeq p3.b, p0/z, z0.b, 0 /* search for 0 */46b.any 2f4748cmpeq p3.b, p0/z, z0.b, z1.b /* search for c; no eos */49mov x3, x050incp x0, p0.b /* skip bytes this round */51setffr /* re-init FFR */52b.none 0b5354addvl x2, x3, 1 /* save advanced base */55mov p2.b, p3.b /* save current search */56b 0b5758/* Found end-of-string. */592: incb x0, all /* advance base */603: brka p3.b, p1/z, p3.b /* mask after first 0 */61cmpeq p3.b, p3/z, z0.b, z1.b /* search for c not after eos */62b.any 4f6364/* No C within last vector. Did we have one before? */65cbz x2, 5f66mov x0, x2 /* restore advanced base */67mov p3.b, p2.b /* restore saved search */6869/* Find the *last* match in the predicate. This is slightly70more complicated than finding the first match. */714: rev p3.b, p3.b /* reverse the bits */72brka p3.b, p1/z, p3.b /* find position of last match */73decp x0, p3.b /* retard pointer to last match */74ret7576/* No C whatsoever. Return NULL. */775: mov x0, 078ret7980END (__strrchr_aarch64_sve)818283