forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
1.3 KiB
75 lines
1.3 KiB
/* 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_WEAK_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) |
|
EXPORT_SYMBOL_NOKASAN(memchr)
|
|
|