1/* 2 * memchr - find a character in a memory zone 3 * 4 * Copyright (c) 2018-2022, Arm Limited. 5 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 6 */ 7 8#include "asmdefs.h" 9 10.arch armv8-a+sve 11 12/* Assumptions: 13 * 14 * ARMv8-a, AArch64 15 * SVE Available. 16 */ 17 18ENTRY (__memchr_aarch64_sve) 19 dup z1.b, w1 /* duplicate c to a vector */ 20 setffr /* initialize FFR */ 21 mov x3, 0 /* initialize off */ 22 23 .p2align 4 240: whilelo p1.b, x3, x2 /* make sure off < max */ 25 b.none 9f 26 27 /* Read a vector's worth of bytes, bounded by max, 28 stopping on first fault. */ 29 ldff1b z0.b, p1/z, [x0, x3] 30 rdffrs p0.b, p1/z 31 b.nlast 2f 32 33 /* First fault did not fail: the vector bounded by max is valid. 34 Avoid depending on the contents of FFR beyond the branch. */ 35 incb x3 /* speculate increment */ 36 cmpeq p2.b, p1/z, z0.b, z1.b /* search for c */ 37 b.none 0b 38 decb x3 /* undo speculate */ 39 40 /* Found C. */ 411: brkb p2.b, p1/z, p2.b /* find the first c */ 42 add x0, x0, x3 /* form partial pointer */ 43 incp x0, p2.b /* form final pointer to c */ 44 ret 45 46 /* First fault failed: only some of the vector is valid. 47 Perform the comparision only on the valid bytes. */ 482: cmpeq p2.b, p0/z, z0.b, z1.b 49 b.any 1b 50 51 /* No C found. Re-init FFR, increment, and loop. */ 52 setffr 53 incp x3, p0.b 54 b 0b 55 56 /* Found end of count. */ 579: mov x0, 0 /* return null */ 58 ret 59 60END (__memchr_aarch64_sve) 61