1/* 2 * memchr - find a character in a memory zone 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 __memchr_aarch64_sve 20 .type __memchr_aarch64_sve, %function 21 .p2align 4 22__memchr_aarch64_sve: 23 dup z1.b, w1 /* duplicate c to a vector */ 24 setffr /* initialize FFR */ 25 mov x3, 0 /* initialize off */ 26 nop 27 280: whilelo p1.b, x3, x2 /* make sure off < max */ 29 b.none 9f 30 31 /* Read a vector's worth of bytes, bounded by max, 32 stopping on first fault. */ 33 ldff1b z0.b, p1/z, [x0, x3] 34 rdffrs p0.b, p1/z 35 b.nlast 2f 36 37 /* First fault did not fail: the vector bounded by max is valid. 38 Avoid depending on the contents of FFR beyond the branch. */ 39 incb x3 /* speculate increment */ 40 cmpeq p2.b, p1/z, z0.b, z1.b /* search for c */ 41 b.none 0b 42 decb x3 /* undo speculate */ 43 44 /* Found C. */ 451: brkb p2.b, p1/z, p2.b /* find the first c */ 46 add x0, x0, x3 /* form partial pointer */ 47 incp x0, p2.b /* form final pointer to c */ 48 ret 49 50 /* First fault failed: only some of the vector is valid. 51 Perform the comparison only on the valid bytes. */ 522: cmpeq p2.b, p0/z, z0.b, z1.b 53 b.any 1b 54 55 /* No C found. Re-init FFR, increment, and loop. */ 56 setffr 57 incp x3, p0.b 58 b 0b 59 60 /* Found end of count. */ 619: mov x0, 0 /* return null */ 62 ret 63 64 .size __memchr_aarch64_sve, . - __memchr_aarch64_sve 65#endif 66