1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2021 Arm Ltd.
4 */
5
6#include <linux/linkage.h>
7#include <asm/assembler.h>
8
9/*
10 * Find a character in an area of memory.
11 *
12 * Parameters:
13 * x0 - buf
14 * x1 - c
15 * x2 - n
16 * Returns:
17 * x0 - address of first occurrence of 'c' or 0
18 */
19
20#define L(label) .L ## label
21
22#define REP8_01 0x0101010101010101
23#define REP8_7f 0x7f7f7f7f7f7f7f7f
24
25#define srcin x0
26#define chrin w1
27#define cntin x2
28
29#define result x0
30
31#define wordcnt x3
32#define rep01 x4
33#define repchr x5
34#define cur_word x6
35#define cur_byte w6
36#define tmp x7
37#define tmp2 x8
38
39 .p2align 4
40 nop
41SYM_FUNC_START(__pi_memchr)
42 and chrin, chrin, #0xff
43 lsr wordcnt, cntin, #3
44 cbz wordcnt, L(byte_loop)
45 mov rep01, #REP8_01
46 mul repchr, x1, rep01
47 and cntin, cntin, #7
48L(word_loop):
49 ldr cur_word, [srcin], #8
50 sub wordcnt, wordcnt, #1
51 eor cur_word, cur_word, repchr
52 sub tmp, cur_word, rep01
53 orr tmp2, cur_word, #REP8_7f
54 bics tmp, tmp, tmp2
55 b.ne L(found_word)
56 cbnz wordcnt, L(word_loop)
57L(byte_loop):
58 cbz cntin, L(not_found)
59 ldrb cur_byte, [srcin], #1
60 sub cntin, cntin, #1
61 cmp cur_byte, chrin
62 b.ne L(byte_loop)
63 sub srcin, srcin, #1
64 ret
65L(found_word):
66CPU_LE( rev tmp, tmp)
67 clz tmp, tmp
68 sub tmp, tmp, #64
69 add result, srcin, tmp, asr #3
70 ret
71L(not_found):
72 mov result, #0
73 ret
74SYM_FUNC_END(__pi_memchr)
75SYM_FUNC_ALIAS_WEAK(memchr, __pi_memchr)
76EXPORT_SYMBOL_NOKASAN(memchr)
77

source code of linux/arch/arm64/lib/memchr.S