1caab277bSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 24a899227SCatalin Marinas/* 3*9e51cafdSRobin Murphy * Copyright (C) 2021 Arm Ltd. 44a899227SCatalin Marinas */ 54a899227SCatalin Marinas 64a899227SCatalin Marinas#include <linux/linkage.h> 74a899227SCatalin Marinas#include <asm/assembler.h> 84a899227SCatalin Marinas 94a899227SCatalin Marinas/* 104a899227SCatalin Marinas * Find a character in an area of memory. 114a899227SCatalin Marinas * 124a899227SCatalin Marinas * Parameters: 134a899227SCatalin Marinas * x0 - buf 144a899227SCatalin Marinas * x1 - c 154a899227SCatalin Marinas * x2 - n 164a899227SCatalin Marinas * Returns: 174a899227SCatalin Marinas * x0 - address of first occurrence of 'c' or 0 184a899227SCatalin Marinas */ 19*9e51cafdSRobin Murphy 20*9e51cafdSRobin Murphy#define L(label) .L ## label 21*9e51cafdSRobin Murphy 22*9e51cafdSRobin Murphy#define REP8_01 0x0101010101010101 23*9e51cafdSRobin Murphy#define REP8_7f 0x7f7f7f7f7f7f7f7f 24*9e51cafdSRobin Murphy 25*9e51cafdSRobin Murphy#define srcin x0 26*9e51cafdSRobin Murphy#define chrin w1 27*9e51cafdSRobin Murphy#define cntin x2 28*9e51cafdSRobin Murphy 29*9e51cafdSRobin Murphy#define result x0 30*9e51cafdSRobin Murphy 31*9e51cafdSRobin Murphy#define wordcnt x3 32*9e51cafdSRobin Murphy#define rep01 x4 33*9e51cafdSRobin Murphy#define repchr x5 34*9e51cafdSRobin Murphy#define cur_word x6 35*9e51cafdSRobin Murphy#define cur_byte w6 36*9e51cafdSRobin Murphy#define tmp x7 37*9e51cafdSRobin Murphy#define tmp2 x8 38*9e51cafdSRobin Murphy 39*9e51cafdSRobin Murphy .p2align 4 40*9e51cafdSRobin Murphy nop 413ac0f452SMark BrownSYM_FUNC_START_WEAK_PI(memchr) 42*9e51cafdSRobin Murphy and chrin, chrin, #0xff 43*9e51cafdSRobin Murphy lsr wordcnt, cntin, #3 44*9e51cafdSRobin Murphy cbz wordcnt, L(byte_loop) 45*9e51cafdSRobin Murphy mov rep01, #REP8_01 46*9e51cafdSRobin Murphy mul repchr, x1, rep01 47*9e51cafdSRobin Murphy and cntin, cntin, #7 48*9e51cafdSRobin MurphyL(word_loop): 49*9e51cafdSRobin Murphy ldr cur_word, [srcin], #8 50*9e51cafdSRobin Murphy sub wordcnt, wordcnt, #1 51*9e51cafdSRobin Murphy eor cur_word, cur_word, repchr 52*9e51cafdSRobin Murphy sub tmp, cur_word, rep01 53*9e51cafdSRobin Murphy orr tmp2, cur_word, #REP8_7f 54*9e51cafdSRobin Murphy bics tmp, tmp, tmp2 55*9e51cafdSRobin Murphy b.ne L(found_word) 56*9e51cafdSRobin Murphy cbnz wordcnt, L(word_loop) 57*9e51cafdSRobin MurphyL(byte_loop): 58*9e51cafdSRobin Murphy cbz cntin, L(not_found) 59*9e51cafdSRobin Murphy ldrb cur_byte, [srcin], #1 60*9e51cafdSRobin Murphy sub cntin, cntin, #1 61*9e51cafdSRobin Murphy cmp cur_byte, chrin 62*9e51cafdSRobin Murphy b.ne L(byte_loop) 63*9e51cafdSRobin Murphy sub srcin, srcin, #1 644a899227SCatalin Marinas ret 65*9e51cafdSRobin MurphyL(found_word): 66*9e51cafdSRobin MurphyCPU_LE( rev tmp, tmp) 67*9e51cafdSRobin Murphy clz tmp, tmp 68*9e51cafdSRobin Murphy sub tmp, tmp, #64 69*9e51cafdSRobin Murphy add result, srcin, tmp, asr #3 70*9e51cafdSRobin Murphy ret 71*9e51cafdSRobin MurphyL(not_found): 72*9e51cafdSRobin Murphy mov result, #0 734a899227SCatalin Marinas ret 743ac0f452SMark BrownSYM_FUNC_END_PI(memchr) 75ac0e8c72SMark RutlandEXPORT_SYMBOL_NOKASAN(memchr) 76