new version from Chris Torek
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Sat, 2 Jun 1990 06:31:59 +0000 (22:31 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Sat, 2 Jun 1990 06:31:59 +0000 (22:31 -0800)
SCCS-vsn: lib/libc/vax/string/strchr.s 5.3
SCCS-vsn: lib/libc/vax/string/strrchr.s 5.3

usr/src/lib/libc/vax/string/strchr.s
usr/src/lib/libc/vax/string/strrchr.s

index 2900e81..1ed7808 100644 (file)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-       .asciz "@(#)strchr.s    5.2 (Berkeley) %G%"
+       .asciz "@(#)strchr.s    5.3 (Berkeley) %G%"
 #endif /* LIBC_SCCS and not lint */
 
 #endif /* LIBC_SCCS and not lint */
 
-#ifdef notdef
-_sccsid:.asciz "@(#)index.s    5.4 (Berkeley) 5/25/88"
-#endif
-
 /*
  * Find the first occurence of c in the string cp.
  * Return pointer to match or null pointer.
  *
  * char *
 /*
  * Find the first occurence of c in the string cp.
  * Return pointer to match or null pointer.
  *
  * char *
- * index(cp, c)
+ * strchr(cp, c)
  *     char *cp, c;
  */
 #include "DEFS.h"
 
  *     char *cp, c;
  */
 #include "DEFS.h"
 
+       .lcomm  tbl,256
+
 ENTRY(strchr, 0)
 ENTRY(strchr, 0)
-       movq    4(ap),r1        # r1 = cp; r2 = c
-       tstl    r2              # check for special case c == '\0'
-       bneq    2f
+       movzwl  $65535,r4       /* handy constant */
+       movq    4(ap),r1        /* r1 = cp; r2 = c */
+       movzbl  r2,r2
+       beql    Lzero           /* special case for c == '\0' */
+
+/*
+ * Fancy scanc version.  Alas, it is not reentrant.
+ */
+       movab   tbl,r3          /* r3 = base of table */
+       bbss    $0,(r3),Lreent  /* ensure not reentering */
+       movab   (r3)[r2],r5     
+       incb    (r5)            /* mark both '\0' and c */
+0:
+       scanc   r4,(r1),(r3),$1 /* look for c or '\0' */
+       beql    0b              /* still looking */
+       movl    r1,r0           /* return whatever we found */
+       tstb    (r0)
+       bneq    1f              #       unless it was '\0':
+       clrl    r0              #       then return NULL
 1:
 1:
-       locc    $0,$65535,(r1)  # just find end of string
-       beql    1b              # still looking
-       movl    r1,r0           # found it
-       ret
-2:
-       moval   tbl,r3          # r3 = address of table
-       bbss    $0,(r3),5f      # insure not reentering
-       movab   (r3)[r2],r5     # table entry for c
-       incb    (r5)
-       movzwl  $65535,r4       # fast access
-3:
-       scanc   r4,(r1),(r3),$1 # look for c or '\0'
-       beql    3b              # still looking
-       movl    r1,r0           # return pointer to char
-       tstb    (r0)            #    if have found '\0'
-       bneq    4f
-       clrl    r0              # else return 0
-4:
-       clrb    (r5)            # clean up table
+       clrb    (r5)            /* clean up table */
        clrb    (r3)
        ret
 
        clrb    (r3)
        ret
 
-       .data
-tbl:   .space  256
-       .text
+/*
+ * Special case for \0.
+ */
+Lzero:
+       locc    r2,r4,(r1)      /* just find end of string */
+       beql    Lzero           /* still looking */
+       movl    r1,r0           /* found it */
+       ret
 
 /*
 
 /*
- * Reentrant, but slower version of index
+ * Slower reentrant version is two two-step searches.  The first
+ * phase runs until we know where the string ends; it locates the
+ * first occurrence of c within a 65535-byte block.  If we find
+ * the end of the string first, we switch to the second phase,
+ * were we look only up to the known end of string.
  */
  */
-5:
+Lreent:
+0:     /* first phase */
        movl    r1,r3
        movl    r1,r3
-6:
-       locc    $0,$65535,(r3)  # look for '\0'
-       bneq    7f
-       locc    r2,$65535,(r3)  # look for c
-       bneq    8f
-       movl    r1,r3           # reset pointer and ...
-       jbr     6b              # ... try again
-7:
-       subl3   r3,r1,r4        # length of short block
-       incl    r4              # +1 for '\0'
-       locc    r2,r4,(r3)      # look for c
-       bneq    8f
-       ret
-8:
-       movl    r1,r0           # return pointer to char
+       locc    $0,r4,(r3)      /* look for '\0' */
+       bneq    1f
+       locc    r2,r4,(r3)      /* look for c */
+       beql    0b              /* not found: reset pointer and loop */
+       movl    r1,r0           /* found: return it */
        ret
        ret
+1:     /* second phase */
+       subl3   r3,r1,r0        /* length of short block */
+       locc    r2,r0,(r3)      /* look for c */
+       beql    2f              /* not found: return NULL */
+       movl    r1,r0
+2:     ret
index 1666185..b883672 100644 (file)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-       .asciz "@(#)strrchr.s   5.2 (Berkeley) %G%"
+       .asciz "@(#)strrchr.s   5.3 (Berkeley) %G%"
 #endif /* LIBC_SCCS and not lint */
 
 #endif /* LIBC_SCCS and not lint */
 
-#ifdef notdef
-_sccsid:.asciz "@(#)rindex.s   5.4 (Berkeley) 5/25/88"
-#endif
-
 /*
  * Find the last occurence of c in the string cp.
  * Return pointer to match or null pointer.
  *
  * char *
 /*
  * Find the last occurence of c in the string cp.
  * Return pointer to match or null pointer.
  *
  * char *
- * rindex(cp, c)
+ * strrchr(cp, c)
  *     char *cp, c;
  */
 #include "DEFS.h"
 
  *     char *cp, c;
  */
 #include "DEFS.h"
 
+       .lcomm  tbl,256
+
 ENTRY(strrchr, 0)
 ENTRY(strrchr, 0)
-       movq    4(ap),r1        # r1 = cp; r2 = c
-       tstl    r2              # check for special case c == '\0'
-       bneq    2f
+       movzwl  $65535,r4       /* handy 65535 */
+       movq    4(ap),r1        /* r1 = cp; r2 = c */
+       movzbl  r2,r2
+       beql    Lzero           /* special case for c == '\0' */
+
+       clrl    r5              /* r5 = pointer to last match */
+
+/*
+ * Fancy scanc version.  Alas, it is not reentrant.
+ */
+       movab   tbl,r3          /* r3 = address of table */
+       bbss    $0,(r3),Lreent  /* ensure not reentering */
+       movab   (r3)[r2],r4
+       incb    (r4)            /* mark both '\0' and c */
+0:
+       scanc   $65535,(r1),(r3),$1     /* look for c or '\0' */
+       beql    0b              /* keep looking */
+       tstb    (r1)
+       beql    1f              /* done if '\0' */
+       movab   (r1)+,r5        /* save most recently found, and skip over it */
+       jbr     0b              /* keep looking */
 1:
 1:
-       locc    $0,$65535,(r1)  # just find end of string
-       beql    1b              # still looking
-       movl    r1,r0           # found it
-       ret
-2:
-       moval   tbl,r3          # r3 = address of table
-       bbss    $0,(r3),5f      # insure not reentering
-       movab   (r3)[r2],r5     # table entry for c
-       incb    (r5)
-       clrl    r4              # last found
-3:
-       scanc   $65535,(r1),(r3),$1     # look for c or '\0'
-       beql    3b              # keep looking
-       tstb    (r1)            # if have found '\0'
-       beql    4f              #    we are done
-       movl    r1,r4           # save most recently found
-       incl    r1              # skip over character
-       jbr     3b              # keep looking
-4:
-       movl    r4,r0           # return last found (if any)
-       clrb    (r5)            # clean up table
+       movl    r5,r0           /* return last found (if any) */
+       clrb    (r4)            /* clean up table */
        clrb    (r3)
        ret
 
        clrb    (r3)
        ret
 
-       .data
-tbl:   .space  256
-       .text
+/*
+ * Special case for \0.
+ */
+Lzero:
+       locc    $0,r4,(r1)      /* just find end of string */
+       beql    Lzero           /* still looking */
+       movl    r1,r0           /* found it */
+       ret
 
 /*
 
 /*
- * Reentrant, but slower version of rindex
+ * Slower reentrant version is two two-step searches.  The first
+ * phase runs until we know where the string ends; it locates any
+ * occurrences of c within a 65535-byte block.  Once we have found
+ * the end of the string, we find any further occurrences before
+ * that location.
  */
  */
-5:
+Lreent:
+0:     /* first phase */
        movl    r1,r3
        movl    r1,r3
-       clrl    r4              # r4 = pointer to last match
-6:
-       locc    $0,$65535,(r3)  # look for '\0'
-       bneq    8f
-       decw    r0              # r0 = 65535
-1:
-       locc    r2,r0,(r3)      # look for c
-       bneq    7f
-       movl    r1,r3           # reset pointer and ...
-       jbr     6b              # ... try again
-7:
-       movl    r1,r4           # stash pointer ...
-       addl3   $1,r1,r3        # ... skip over match and ...
-       decl    r0              # ... decrement count
-       jbr     6b              # ... try again
-8:
-       subl3   r3,r1,r0        # length of short block
-       incl    r0              # +1 for '\0'
-9:
-       locc    r2,r0,(r3)      # look for c
-       beql    0f
-       movl    r1,r4           # stash pointer ...
-       addl3   $1,r1,r3        # ... skip over match ...
-       decl    r0              # ... adjust count and ...
-       jbr     9b              # ... try again
-0:
-       movl    r4,r0           # return stashed pointer
+       locc    $0,r4,(r3)      /* look for '\0' */
+       bneq    1f
+       locc    r2,r4,(r3)      /* continue phase 1 search for c */
+       beql    0b
+       movab   (r1)+,r5        /* found c: save and increment pointer */
+       brb     0b              /* and continue */
+
+1:     /* second phase */
+       subl3   r3,r1,r0        /* length of short block */
+       movl    r3,r1
+2:
+       locc    r2,r0,(r1)      /* look for c */
+       beql    3f              /* skip if not found */
+       movab   (r1)+,r5        /* save pointer as before */
+       sobgtr  r0,2b           /* adjust count and loop */
+3:
+       movl    r5,r0           /* return stashed pointer */
        ret
        ret