Home | History | Annotate | Line # | Download | only in string
      1 /*	$NetBSD: strlen.S,v 1.1 2005/12/20 19:28:50 christos Exp $	*/
      2 
      3 /*
      4  * Copyright 2002 Wasabi Systems, Inc.
      5  * All rights reserved.
      6  *
      7  * Written by Eduardo Horvath for Wasabi Systems, Inc.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *      This product includes software developed for the NetBSD Project by
     20  *      Wasabi Systems, Inc.
     21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22  *    or promote products derived from this software without specific prior
     23  *    written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 
     38 
     39 
     40 #include <machine/asm.h>
     41 #if defined(LIBC_SCCS) && !defined(lint)
     42 	RCSID("$NetBSD: strlen.S,v 1.1 2005/12/20 19:28:50 christos Exp $")
     43 #endif /* LIBC_SCCS and not lint */
     44 
     45 /* The algorithm here uses the following techniques:
     46  *
     47  * 1) Given a word 'x', we can test to see if it contains any 0 bytes
     48  *    by subtracting 0x01010101, and seeing if any of the high bits of each
     49  *    byte changed from 0 to 1. This works because the least significant
     50  *    0 byte must have had no incoming carry (otherwise it's not the least
     51  *    significant), so it is 0x00 - 0x01 == 0xff. For all other
     52  *    byte values, either they have the high bit set initially, or when
     53  *    1 is subtracted you get a value in the range 0x00-0x7f, none of which
     54  *    have their high bit set. The expression here is
     55  *    (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
     56  *    there were no 0x00 bytes in the word.
     57  *
     58  * 2) Now just hunt for the first byte that's 0x00 in 'x'.
     59  *
     60  *    This is from the book 'The PowerPC Compiler Writer's Guide',
     61  *    by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
     62  */
     63 
     64 ENTRY(strlen)
     65 	/*
     66 	 * Calculate address for and load the first xword.
     67 	 */
     68 	andn	%o0, 0x7, %o1
     69 	ldx	[%o1], %g1
     70 
     71 	/*
     72 	 * Now prepare some constants while the data arrives...
     73 	 */
     74 	sethi	%hi(0xfefefefe), %o3
     75 	sethi	%hi(0x7f7f7f7f), %o2
     76 
     77 	or	%o3, %lo(0xfefefefe), %o3
     78 	or	%o2, %lo(0x7f7f7f7f), %o2
     79 
     80 	sllx	%o3, 32, %o5
     81 	andcc	%o0, 0x7, %g5	! Hoisted from below to fill a slot
     82 
     83 	sllx	%o2, 32, %o4
     84 	or	%o3, %o5, %o3
     85 
     86 	sll	%g5, 3,	%g5	! Convert to bytes. hoisted
     87 	or	%o2, %o4, %o2
     88 
     89 	inc	%o3
     90 	neg	%g5		! hoisted
     91 
     92 	/*
     93 	 * Mask off the leading bits:
     94 	 *
     95 	 * if (ptr & 0x7)
     96 	 *	mask = -1 << (64 - ((ptr & 0x7) << 3));
     97 	 */
     98 
     99 !	andcc	%o0, 0x7, %g5	! Hoisted above
    100 	bz,pt	%icc, 0f
    101 
    102 
    103 !	 sll	%g5, 3,	%g5	! Convert to bytes. Also hoisted
    104 
    105 !	neg	%g5		! Hoisted
    106 
    107 	 add	%g5, 64, %g5
    108 	mov	-1, %o4
    109 
    110 	sllx	%o4, %g5, %o4
    111 
    112 	or	%o4, %g1, %g1	! Make leading bytes != 0
    113 
    114 0:
    115 	or	%g1, %o2, %o5	! Do step 1 -- use or/andn instead of nor/and
    116 	add	%g1, %o3, %g5
    117 
    118 	inc	8, %o1		! Point to next word
    119 	andncc	%g5, %o5, %g0
    120 	bz,a,pt	%xcc, 0b
    121 	 ldx	[%o1], %g1
    122 
    123 	mov	-1, %o4
    124 	dec	8, %o1
    125 
    126 	sllx	%o4, 64-8, %o5
    127 
    128 	btst	%g1, %o5	! Check high byte
    129 	bz	%xcc,0f
    130 	 srlx	%o5, 8, %o5
    131 
    132 	inc	%o1
    133 	btst	%g1, %o5	! Check 2nd byte
    134 	bz	%xcc,0f
    135 	 srlx	%o5, 8, %o5
    136 
    137 	inc	%o1
    138 	btst	%g1, %o5	! Check 3rd byte
    139 	bz	%xcc,0f
    140 	 srlx	%o5, 8, %o5
    141 
    142 	inc	%o1
    143 	btst	%g1, %o5	! Check 4th byte
    144 	bz	%xcc,0f
    145 	 srlx	%o5, 8, %o5
    146 
    147 	inc	%o1
    148 	btst	%g1, %o5	! Check 5th byte
    149 	bz	%xcc,0f
    150 	 srlx	%o5, 8, %o5
    151 
    152 	inc	%o1
    153 	btst	%g1, %o5	! Check 6th byte
    154 	bz	%xcc,0f
    155 	 srlx	%o5, 8, %o5
    156 
    157 	inc	%o1
    158 	btst	%g1, %o5	! Check 7th byte
    159 	bz	%xcc,0f
    160 	 nop
    161 
    162 	inc	%o1
    163 0:
    164 	retl
    165 	 sub	%o1, %o0, %o0	! return length (ptr - (origptr+1))
    166