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 "@(#)strrchr.s 8.1 (Berkeley) 06/04/93" 10#endif /* LIBC_SCCS and not lint */ 11 12/* 13 * Find the last occurence of c in the string cp. 14 * Return pointer to match or null pointer. 15 * 16 * char * 17 * strrchr(cp, c) 18 * char *cp, c; 19 */ 20#include "DEFS.h" 21 22 .lcomm tbl,256 23 24ENTRY(strrchr, 0) 25 movzwl $65535,r4 /* handy 65535 */ 26 movq 4(ap),r1 /* r1 = cp; r2 = c */ 27 movzbl r2,r2 28 beql Lzero /* special case for c == '\0' */ 29 30 clrl r5 /* r5 = pointer to last match */ 31 32/* 33 * Fancy scanc version. Alas, it is not reentrant. 34 */ 35 movab tbl,r3 /* r3 = address of table */ 36 bbss $0,(r3),Lreent /* ensure not reentering */ 37 movab (r3)[r2],r4 38 incb (r4) /* mark both '\0' and c */ 390: 40 scanc $65535,(r1),(r3),$1 /* look for c or '\0' */ 41 beql 0b /* keep looking */ 42 tstb (r1) 43 beql 1f /* done if '\0' */ 44 movab (r1)+,r5 /* save most recently found, and skip over it */ 45 jbr 0b /* keep looking */ 461: 47 movl r5,r0 /* return last found (if any) */ 48 clrb (r4) /* clean up table */ 49 clrb (r3) 50 ret 51 52/* 53 * Special case for \0. 54 */ 55Lzero: 56 locc $0,r4,(r1) /* just find end of string */ 57 beql Lzero /* still looking */ 58 movl r1,r0 /* found it */ 59 ret 60 61/* 62 * Slower reentrant version is two two-step searches. The first 63 * phase runs until we know where the string ends; it locates any 64 * occurrences of c within a 65535-byte block. Once we have found 65 * the end of the string, we find any further occurrences before 66 * that location. 67 */ 68Lreent: 690: /* first phase */ 70 movl r1,r3 71 locc $0,r4,(r3) /* look for '\0' */ 72 bneq 1f 73 locc r2,r4,(r3) /* continue phase 1 search for c */ 74 beql 0b 75 movab (r1)+,r5 /* found c: save and increment pointer */ 76 brb 0b /* and continue */ 77 781: /* second phase */ 79 subl3 r3,r1,r0 /* length of short block */ 80 movl r3,r1 812: 82 locc r2,r0,(r1) /* look for c */ 83 beql 3f /* skip if not found */ 84 movab (r1)+,r5 /* save pointer as before */ 85 sobgtr r0,2b /* adjust count and loop */ 863: 87 movl r5,r0 /* return stashed pointer */ 88 ret 89