134632Sbostic/* 2*61222Sbostic * Copyright (c) 1988, 1993 3*61222Sbostic * The Regents of the University of California. All rights reserved. 434632Sbostic * 542647Sbostic * %sccs.include.redist.c% 634632Sbostic */ 734632Sbostic 834829Sbostic#if defined(LIBC_SCCS) && !defined(lint) 9*61222Sbostic .asciz "@(#)strchr.s 8.1 (Berkeley) 06/04/93" 1034829Sbostic#endif /* LIBC_SCCS and not lint */ 1134632Sbostic 1234632Sbostic/* 1334632Sbostic * Find the first occurence of c in the string cp. 1434632Sbostic * Return pointer to match or null pointer. 1534632Sbostic * 1634632Sbostic * char * 1742645Sbostic * strchr(cp, c) 1834632Sbostic * char *cp, c; 1934632Sbostic */ 2034632Sbostic#include "DEFS.h" 2134632Sbostic 2242645Sbostic .lcomm tbl,256 2342645Sbostic 2434632SbosticENTRY(strchr, 0) 2542645Sbostic movzwl $65535,r4 /* handy constant */ 2642645Sbostic movq 4(ap),r1 /* r1 = cp; r2 = c */ 2742645Sbostic movzbl r2,r2 2842645Sbostic beql Lzero /* special case for c == '\0' */ 2942645Sbostic 3042645Sbostic/* 3142645Sbostic * Fancy scanc version. Alas, it is not reentrant. 3242645Sbostic */ 3342645Sbostic movab tbl,r3 /* r3 = base of table */ 3442645Sbostic bbss $0,(r3),Lreent /* ensure not reentering */ 3542645Sbostic movab (r3)[r2],r5 3642645Sbostic incb (r5) /* mark both '\0' and c */ 3742645Sbostic0: 3842645Sbostic scanc r4,(r1),(r3),$1 /* look for c or '\0' */ 3942645Sbostic beql 0b /* still looking */ 4042645Sbostic movl r1,r0 /* return whatever we found */ 4142645Sbostic tstb (r0) 4242645Sbostic bneq 1f # unless it was '\0': 4342645Sbostic clrl r0 # then return NULL 4434632Sbostic1: 4542645Sbostic clrb (r5) /* clean up table */ 4634632Sbostic clrb (r3) 4734632Sbostic ret 4834632Sbostic 4942645Sbostic/* 5042645Sbostic * Special case for \0. 5142645Sbostic */ 5242645SbosticLzero: 5342645Sbostic locc r2,r4,(r1) /* just find end of string */ 5442645Sbostic beql Lzero /* still looking */ 5542645Sbostic movl r1,r0 /* found it */ 5642645Sbostic ret 5734632Sbostic 5834632Sbostic/* 5942645Sbostic * Slower reentrant version is two two-step searches. The first 6042645Sbostic * phase runs until we know where the string ends; it locates the 6142645Sbostic * first occurrence of c within a 65535-byte block. If we find 6242645Sbostic * the end of the string first, we switch to the second phase, 6342645Sbostic * were we look only up to the known end of string. 6434632Sbostic */ 6542645SbosticLreent: 6642645Sbostic0: /* first phase */ 6734632Sbostic movl r1,r3 6842645Sbostic locc $0,r4,(r3) /* look for '\0' */ 6942645Sbostic bneq 1f 7042645Sbostic locc r2,r4,(r3) /* look for c */ 7142645Sbostic beql 0b /* not found: reset pointer and loop */ 7242645Sbostic movl r1,r0 /* found: return it */ 7334632Sbostic ret 7442645Sbostic1: /* second phase */ 7542645Sbostic subl3 r3,r1,r0 /* length of short block */ 7642645Sbostic locc r2,r0,(r3) /* look for c */ 7742645Sbostic beql 2f /* not found: return NULL */ 7842645Sbostic movl r1,r0 7942645Sbostic2: ret 80