1/* Optimized rawmemchr implementation using basic LoongArch instructions.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library. If not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <sysdep.h>
20#include <sys/regdef.h>
21#include <sys/asm.h>
22
23#if IS_IN (libc)
24# define RAWMEMCHR_NAME __rawmemchr_aligned
25#else
26# define RAWMEMCHR_NAME __rawmemchr
27#endif
28
29LEAF(RAWMEMCHR_NAME, 6)
30 andi t1, a0, 0x7
31 bstrins.d a0, zero, 2, 0
32 lu12i.w a2, 0x01010
33 bstrins.d a1, a1, 15, 8
34
35 ld.d t0, a0, 0
36 slli.d t1, t1, 3
37 ori a2, a2, 0x101
38 bstrins.d a1, a1, 31, 16
39
40 li.w t8, -1
41 bstrins.d a1, a1, 63, 32
42 bstrins.d a2, a2, 63, 32
43 sll.d t2, t8, t1
44
45 sll.d t3, a1, t1
46 orn t0, t0, t2
47 slli.d a3, a2, 7
48 beqz a1, L(find_zero)
49
50 xor t0, t0, t3
51 sub.d t1, t0, a2
52 andn t2, a3, t0
53 and t3, t1, t2
54
55 bnez t3, L(count_pos)
56 addi.d a0, a0, 8
57
58L(loop):
59 ld.d t0, a0, 0
60 xor t0, t0, a1
61
62 sub.d t1, t0, a2
63 andn t2, a3, t0
64 and t3, t1, t2
65 bnez t3, L(count_pos)
66
67 ld.d t0, a0, 8
68 addi.d a0, a0, 16
69 xor t0, t0, a1
70 sub.d t1, t0, a2
71
72 andn t2, a3, t0
73 and t3, t1, t2
74 beqz t3, L(loop)
75 addi.d a0, a0, -8
76L(count_pos):
77 ctz.d t0, t3
78 srli.d t0, t0, 3
79 add.d a0, a0, t0
80 jr ra
81
82L(loop_7bit):
83 ld.d t0, a0, 0
84L(find_zero):
85 sub.d t1, t0, a2
86 and t2, t1, a3
87 bnez t2, L(more_check)
88
89 ld.d t0, a0, 8
90 addi.d a0, a0, 16
91 sub.d t1, t0, a2
92 and t2, t1, a3
93
94 beqz t2, L(loop_7bit)
95 addi.d a0, a0, -8
96
97L(more_check):
98 andn t2, a3, t0
99 and t3, t1, t2
100 bnez t3, L(count_pos)
101 addi.d a0, a0, 8
102
103L(loop_8bit):
104 ld.d t0, a0, 0
105
106 sub.d t1, t0, a2
107 andn t2, a3, t0
108 and t3, t1, t2
109 bnez t3, L(count_pos)
110
111 ld.d t0, a0, 8
112 addi.d a0, a0, 16
113 sub.d t1, t0, a2
114
115 andn t2, a3, t0
116 and t3, t1, t2
117 beqz t3, L(loop_8bit)
118
119 addi.d a0, a0, -8
120 b L(count_pos)
121
122END(RAWMEMCHR_NAME)
123
124libc_hidden_builtin_def (__rawmemchr)
125

source code of glibc/sysdeps/loongarch/lp64/multiarch/rawmemchr-aligned.S