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