1/*-
2 * Copyright (c) 2003 Tim J. Robbins.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <machine/asm.h>
28__FBSDID("$FreeBSD$");
29
30/*
31 * wchar_t *
32 * wmemchr(const wchar_t *buf, wchar_t c, size_t n) --
33 *	Search the wide character array `buf', which has length `n',
34 *	the character `c', return a pointer to it if found, or NULL on
35 *	failure.
36 */
37ENTRY(wmemchr)
38	pushl	%edi
39	pushl	%ebx
40	movl	12(%esp),%edi		/* Buffer */
41	movl	16(%esp),%eax		/* Wide character */
42	movl	20(%esp),%ecx		/* Length of buffer */
43
44	/*
45	 * Search in chunks of 8 wide characters (32 bytes).
46	 */
47	movl	%ecx,%ebx
48	shrl	$3,%ecx
49	jz	small
50.p2align 4,0x90
51bigloop:cmpl	%eax,(%edi)
52	je	found
53	cmpl	%eax,4(%edi)
54	je	found4
55	cmpl	%eax,8(%edi)
56	je	found8
57	cmpl	%eax,12(%edi)
58	je	found12
59	cmpl	%eax,16(%edi)
60	je	found16
61	cmpl	%eax,20(%edi)
62	je	found20
63	cmpl	%eax,24(%edi)
64	je	found24
65	cmpl	%eax,28(%edi)
66	je	found28
67	leal	32(%edi),%edi
68	decl	%ecx
69	jnz	bigloop
70	jmp	small
71found:	movl	%edi,%eax
72	popl	%ebx
73	popl	%edi
74	ret
75found4:	leal	4(%edi),%edi
76	jmp	found
77found8:	leal	8(%edi),%edi
78	jmp	found
79found12:leal	12(%edi),%edi
80	jmp	found
81found16:leal	16(%edi),%edi
82	jmp	found
83found20:leal	20(%edi),%edi
84	jmp	found
85found24:leal	24(%edi),%edi
86	jmp	found
87found28:leal	28(%edi),%edi
88	jmp	found
89
90	/*
91	 * Search remaining part of string.
92	 */
93small:	movl	%ebx,%ecx
94	andl	$7,%ecx
95	jz	no
96.p2align 2,0x90
97smltop:	cmpl	%eax,(%edi)
98	je	found
99	leal	4(%edi),%edi
100	decl	%ecx
101	jnz	smltop
102no:	xorl	%eax,%eax
103	popl	%ebx
104	popl	%edi
105	ret
106END(wmemchr)
107
108	.section .note.GNU-stack,"",%progbits
109