xref: /csrg-svn/lib/libc/vax/string/strchr.s (revision 42645)
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley.  The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 */
17
18#if defined(LIBC_SCCS) && !defined(lint)
19	.asciz "@(#)strchr.s	5.3 (Berkeley) 06/01/90"
20#endif /* LIBC_SCCS and not lint */
21
22/*
23 * Find the first occurence of c in the string cp.
24 * Return pointer to match or null pointer.
25 *
26 * char *
27 * strchr(cp, c)
28 *	char *cp, c;
29 */
30#include "DEFS.h"
31
32	.lcomm	tbl,256
33
34ENTRY(strchr, 0)
35	movzwl	$65535,r4	/* handy constant */
36	movq	4(ap),r1	/* r1 = cp; r2 = c */
37	movzbl	r2,r2
38	beql	Lzero		/* special case for c == '\0' */
39
40/*
41 * Fancy scanc version.  Alas, it is not reentrant.
42 */
43	movab	tbl,r3		/* r3 = base of table */
44	bbss	$0,(r3),Lreent	/* ensure not reentering */
45	movab	(r3)[r2],r5
46	incb	(r5)		/* mark both '\0' and c */
470:
48	scanc	r4,(r1),(r3),$1	/* look for c or '\0' */
49	beql	0b		/* still looking */
50	movl	r1,r0		/* return whatever we found */
51	tstb	(r0)
52	bneq	1f		#	unless it was '\0':
53	clrl	r0		#	then return NULL
541:
55	clrb	(r5)		/* clean up table */
56	clrb	(r3)
57	ret
58
59/*
60 * Special case for \0.
61 */
62Lzero:
63	locc	r2,r4,(r1)	/* just find end of string */
64	beql	Lzero		/* still looking */
65	movl	r1,r0		/* found it */
66	ret
67
68/*
69 * Slower reentrant version is two two-step searches.  The first
70 * phase runs until we know where the string ends; it locates the
71 * first occurrence of c within a 65535-byte block.  If we find
72 * the end of the string first, we switch to the second phase,
73 * were we look only up to the known end of string.
74 */
75Lreent:
760:	/* first phase */
77	movl	r1,r3
78	locc	$0,r4,(r3)	/* look for '\0' */
79	bneq	1f
80	locc	r2,r4,(r3)	/* look for c */
81	beql	0b		/* not found: reset pointer and loop */
82	movl	r1,r0		/* found: return it */
83	ret
841:	/* second phase */
85	subl3	r3,r1,r0	/* length of short block */
86	locc	r2,r0,(r3)	/* look for c */
87	beql	2f		/* not found: return NULL */
88	movl	r1,r0
892:	ret
90