/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2021 Arm Ltd. */ #include <linux/linkage.h> #include <asm/assembler.h> /* * Find a character in an area of memory. * * Parameters: * x0 - buf * x1 - c * x2 - n * Returns: * x0 - address of first occurrence of 'c' or 0 */ #define L(label) .L ## label #define REP8_01 0x0101010101010101 #define REP8_7f 0x7f7f7f7f7f7f7f7f #define srcin x0 #define chrin w1 #define cntin x2 #define result x0 #define wordcnt x3 #define rep01 x4 #define repchr x5 #define cur_word x6 #define cur_byte w6 #define tmp x7 #define tmp2 x8 .p2align 4 nop SYM_FUNC_START(__pi_memchr) and chrin, chrin, #0xff lsr wordcnt, cntin, #3 cbz wordcnt, L(byte_loop) mov rep01, #REP8_01 mul repchr, x1, rep01 and cntin, cntin, #7 L(word_loop): ldr cur_word, [srcin], #8 sub wordcnt, wordcnt, #1 eor cur_word, cur_word, repchr sub tmp, cur_word, rep01 orr tmp2, cur_word, #REP8_7f bics tmp, tmp, tmp2 b.ne L(found_word) cbnz wordcnt, L(word_loop) L(byte_loop): cbz cntin, L(not_found) ldrb cur_byte, [srcin], #1 sub cntin, cntin, #1 cmp cur_byte, chrin b.ne L(byte_loop) sub srcin, srcin, #1 ret L(found_word): CPU_LE( rev tmp, tmp) clz tmp, tmp sub tmp, tmp, #64 add result, srcin, tmp, asr #3 ret L(not_found): mov result, #0 ret SYM_FUNC_END(__pi_memchr) SYM_FUNC_ALIAS_WEAK(memchr, __pi_memchr) EXPORT_SYMBOL_NOKASAN(memchr)