1/* Copyright (C) 2000-2021 Free Software Foundation, Inc.
2   This file is part of the GNU C Library.
3
4   The GNU C Library is free software; you can redistribute it and/or
5   modify it under the terms of the GNU Lesser General Public
6   License as published by the Free Software Foundation; either
7   version 2.1 of the License, or (at your option) any later version.
8
9   The GNU C Library is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public
15   License along with the GNU C Library.  If not, see
16   <https://www.gnu.org/licenses/>.  */
17
18/* Return pointer to first occurrence of CH in STR.  */
19
20#include <sysdep.h>
21
22	.set noreorder
23	.set noat
24
25ENTRY(__rawmemchr)
26#ifdef PROF
27	ldgp	gp, 0(pv)
28	lda	AT, _mcount
29	jsr	AT, (AT), _mcount
30	.prologue 1
31#else
32	.prologue 0
33#endif
34
35	zapnot	a1, 1, a1	# e0    : zero extend the search character
36	ldq_u   t0, 0(a0)	# .. e1 : load first quadword
37	sll	a1, 8, t5	# e0    : replicate the search character
38	andnot  a0, 7, v0	# .. e1 : align our loop pointer
39
40	or	t5, a1, a1	# e0    :
41	lda	t4, -1		# .. e1 : build garbage mask
42	sll	a1, 16, t5	# e0    :
43	unop			#	:
44
45	mskqh	t4, a0, t4	# e0    :
46	or	t5, a1, a1	# .. e1 :
47	sll	a1, 32, t5	# e0    :
48	cmpbge	zero, t4, t4	# .. e1 : bits set iff byte is garbage
49
50	or	t5, a1, a1	# e0    :
51	xor	t0, a1, t1	# .. e1 : make bytes == c zero
52	cmpbge  zero, t1, t3	# e0    : bits set iff byte == c
53	unop			#	:
54
55	andnot	t3, t4, t0	# e0    : clear garbage bits
56	fnop			# .. fa :
57	unop			#	:
58	bne	t0, $found	# .. e1 (zdb)
59
60	.align 4
61$loop:
62	ldq	t0, 8(v0)	# e0    :
63	addq	v0, 8, v0	# .. e1 :
64	nop			# e0    :
65	xor	t0, a1, t1	# .. e1 (ev5 data stall)
66
67	cmpbge	zero, t1, t0	# e0	: bits set iff byte == c
68	beq	t0, $loop	# .. e1 (zdb)
69
70$found:
71	negq    t0, t1		# e0    : clear all but least set bit
72	and     t0, t1, t0	# e1 (stall)
73	and     t0, 0xf0, t2	# e0    : binary search for that set bit
74	and	t0, 0xcc, t3	# .. e1 :
75
76	and	t0, 0xaa, t4	# e0    :
77	cmovne	t2, 4, t2	# .. e1 :
78	cmovne	t3, 2, t3	# e0    :
79	cmovne	t4, 1, t4	# .. e1 :
80
81	addq	t2, t3, t2	# e0    :
82	addq	v0, t4, v0	# .. e1 :
83	addq	v0, t2, v0	# e0    :
84	ret			# .. e1 :
85
86	END(__rawmemchr)
87
88libc_hidden_def (__rawmemchr)
89weak_alias (__rawmemchr, rawmemchr)
90