new version from Chris Torek
[unix-history] / usr / src / lib / libc / vax / string / strchr.s
CommitLineData
a35f6d0c
KB
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
50c7758a
KB
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.
a35f6d0c
KB
16 */
17
50c7758a 18#if defined(LIBC_SCCS) && !defined(lint)
a856e8fc 19 .asciz "@(#)strchr.s 5.3 (Berkeley) %G%"
50c7758a 20#endif /* LIBC_SCCS and not lint */
a35f6d0c 21
a35f6d0c
KB
22/*
23 * Find the first occurence of c in the string cp.
24 * Return pointer to match or null pointer.
25 *
26 * char *
a856e8fc 27 * strchr(cp, c)
a35f6d0c
KB
28 * char *cp, c;
29 */
30#include "DEFS.h"
31
a856e8fc
KB
32 .lcomm tbl,256
33
a35f6d0c 34ENTRY(strchr, 0)
a856e8fc
KB
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
a35f6d0c 541:
a856e8fc 55 clrb (r5) /* clean up table */
a35f6d0c
KB
56 clrb (r3)
57 ret
58
a856e8fc
KB
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
a35f6d0c
KB
67
68/*
a856e8fc
KB
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.
a35f6d0c 74 */
a856e8fc
KB
75Lreent:
760: /* first phase */
a35f6d0c 77 movl r1,r3
a856e8fc
KB
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 */
a35f6d0c 83 ret
a856e8fc
KB
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