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