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 |
41 | SYM_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 |
48 | L(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) |
57 | L(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 |
65 | L(found_word): |
66 | CPU_LE( rev tmp, tmp) |
67 | clz tmp, tmp |
68 | sub tmp, tmp, #64 |
69 | add result, srcin, tmp, asr #3 |
70 | ret |
71 | L(not_found): |
72 | mov result, #0 |
73 | ret |
74 | SYM_FUNC_END(__pi_memchr) |
75 | SYM_FUNC_ALIAS_WEAK(memchr, __pi_memchr) |
76 | EXPORT_SYMBOL_NOKASAN(memchr) |
77 | |