1/* 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8#if defined(LIBC_SCCS) && !defined(lint) 9 .asciz "@(#)strchr.s 8.1 (Berkeley) 06/04/93" 10#endif /* LIBC_SCCS and not lint */ 11 12/* 13 * Find the first occurence of c in the string cp. 14 * Return pointer to match or null pointer. 15 * 16 * char * 17 * strchr(cp, c) 18 * char *cp, c; 19 */ 20#include "DEFS.h" 21 22 .lcomm tbl,256 23 24ENTRY(strchr, 0) 25 movzwl $65535,r4 /* handy constant */ 26 movq 4(ap),r1 /* r1 = cp; r2 = c */ 27 movzbl r2,r2 28 beql Lzero /* special case for c == '\0' */ 29 30/* 31 * Fancy scanc version. Alas, it is not reentrant. 32 */ 33 movab tbl,r3 /* r3 = base of table */ 34 bbss $0,(r3),Lreent /* ensure not reentering */ 35 movab (r3)[r2],r5 36 incb (r5) /* mark both '\0' and c */ 370: 38 scanc r4,(r1),(r3),$1 /* look for c or '\0' */ 39 beql 0b /* still looking */ 40 movl r1,r0 /* return whatever we found */ 41 tstb (r0) 42 bneq 1f # unless it was '\0': 43 clrl r0 # then return NULL 441: 45 clrb (r5) /* clean up table */ 46 clrb (r3) 47 ret 48 49/* 50 * Special case for \0. 51 */ 52Lzero: 53 locc r2,r4,(r1) /* just find end of string */ 54 beql Lzero /* still looking */ 55 movl r1,r0 /* found it */ 56 ret 57 58/* 59 * Slower reentrant version is two two-step searches. The first 60 * phase runs until we know where the string ends; it locates the 61 * first occurrence of c within a 65535-byte block. If we find 62 * the end of the string first, we switch to the second phase, 63 * were we look only up to the known end of string. 64 */ 65Lreent: 660: /* first phase */ 67 movl r1,r3 68 locc $0,r4,(r3) /* look for '\0' */ 69 bneq 1f 70 locc r2,r4,(r3) /* look for c */ 71 beql 0b /* not found: reset pointer and loop */ 72 movl r1,r0 /* found: return it */ 73 ret 741: /* second phase */ 75 subl3 r3,r1,r0 /* length of short block */ 76 locc r2,r0,(r3) /* look for c */ 77 beql 2f /* not found: return NULL */ 78 movl r1,r0 792: ret 80