|
|
1.1 ! root 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: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #if defined(LIBC_SCCS) && !defined(lint) ! 21: .asciz "@(#)strrchr.s 5.4 (Berkeley) 6/1/90" ! 22: #endif /* LIBC_SCCS and not lint */ ! 23: ! 24: /* ! 25: * Find the last occurence of c in the string cp. ! 26: * Return pointer to match or null pointer. ! 27: * ! 28: * char * ! 29: * strrchr(cp, c) ! 30: * char *cp, c; ! 31: */ ! 32: #include "DEFS.h" ! 33: ! 34: .lcomm tbl,256 ! 35: ! 36: ENTRY(strrchr, 0) ! 37: movzwl $65535,r4 /* handy 65535 */ ! 38: movq 4(ap),r1 /* r1 = cp; r2 = c */ ! 39: movzbl r2,r2 ! 40: beql Lzero /* special case for c == '\0' */ ! 41: ! 42: clrl r5 /* r5 = pointer to last match */ ! 43: ! 44: /* ! 45: * Fancy scanc version. Alas, it is not reentrant. ! 46: */ ! 47: movab tbl,r3 /* r3 = address of table */ ! 48: bbss $0,(r3),Lreent /* ensure not reentering */ ! 49: movab (r3)[r2],r4 ! 50: incb (r4) /* mark both '\0' and c */ ! 51: 0: ! 52: scanc $65535,(r1),(r3),$1 /* look for c or '\0' */ ! 53: beql 0b /* keep looking */ ! 54: tstb (r1) ! 55: beql 1f /* done if '\0' */ ! 56: movab (r1)+,r5 /* save most recently found, and skip over it */ ! 57: jbr 0b /* keep looking */ ! 58: 1: ! 59: movl r5,r0 /* return last found (if any) */ ! 60: clrb (r4) /* clean up table */ ! 61: clrb (r3) ! 62: ret ! 63: ! 64: /* ! 65: * Special case for \0. ! 66: */ ! 67: Lzero: ! 68: locc $0,r4,(r1) /* just find end of string */ ! 69: beql Lzero /* still looking */ ! 70: movl r1,r0 /* found it */ ! 71: ret ! 72: ! 73: /* ! 74: * Slower reentrant version is two two-step searches. The first ! 75: * phase runs until we know where the string ends; it locates any ! 76: * occurrences of c within a 65535-byte block. Once we have found ! 77: * the end of the string, we find any further occurrences before ! 78: * that location. ! 79: */ ! 80: Lreent: ! 81: 0: /* first phase */ ! 82: movl r1,r3 ! 83: locc $0,r4,(r3) /* look for '\0' */ ! 84: bneq 1f ! 85: locc r2,r4,(r3) /* continue phase 1 search for c */ ! 86: beql 0b ! 87: movab (r1)+,r5 /* found c: save and increment pointer */ ! 88: brb 0b /* and continue */ ! 89: ! 90: 1: /* second phase */ ! 91: subl3 r3,r1,r0 /* length of short block */ ! 92: movl r3,r1 ! 93: 2: ! 94: locc r2,r0,(r1) /* look for c */ ! 95: beql 3f /* skip if not found */ ! 96: movab (r1)+,r5 /* save pointer as before */ ! 97: sobgtr r0,2b /* adjust count and loop */ ! 98: 3: ! 99: movl r5,r0 /* return stashed pointer */ ! 100: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.