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