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