Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/common/lib/libc/arch/mips/string Add a new O(log(2) implemen...



details:   https://anonhg.NetBSD.org/src/rev/0f9ad90a0d46
branches:  trunk
changeset: 761300:0f9ad90a0d46
user:      matt <matt%NetBSD.org@localhost>
date:      Sun Jan 23 06:47:14 2011 +0000

description:
Add a new O(log(2) implementation.  On mips32/mips64, use clz/dclz.

diffstat:

 common/lib/libc/arch/mips/string/ffs.S |  115 ++++++++++++++++++++++++--------
 1 files changed, 85 insertions(+), 30 deletions(-)

diffs (141 lines):

diff -r e786ba6a002f -r 0f9ad90a0d46 common/lib/libc/arch/mips/string/ffs.S
--- a/common/lib/libc/arch/mips/string/ffs.S    Sun Jan 23 06:31:39 2011 +0000
+++ b/common/lib/libc/arch/mips/string/ffs.S    Sun Jan 23 06:47:14 2011 +0000
@@ -1,11 +1,11 @@
-/*     $NetBSD: ffs.S,v 1.2 2009/12/14 00:39:00 matt Exp $     */
+/*     $NetBSD: ffs.S,v 1.3 2011/01/23 06:47:14 matt Exp $     */
 
 /*-
- * Copyright (c) 1991, 1993
- *     The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
  *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -15,40 +15,95 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <mips/asm.h>
 
-#if defined(LIBC_SCCS) && !defined(lint)
-       /* RCSID("from: @(#)ffs.s       8.1 (Berkeley) 6/4/93") */
-       RCSID("$NetBSD: ffs.S,v 1.2 2009/12/14 00:39:00 matt Exp $")
-#endif /* LIBC_SCCS and not lint */
+RCSID("$NetBSD: ffs.S,v 1.3 2011/01/23 06:47:14 matt Exp $")
 
 /* bit = ffs(value) */
 
+       .text
+       .set    noreorder
+
+#if __mips == 64 || __mips == 32
 LEAF(ffs)
-       move    v0, zero
-       beq     a0, zero, done
+#ifndef _LP64
+XLEAF(ffsl)
+#endif
+       .set    push
+       .set    mips32
+       li      v1, 32
+#if __mips == 64
+       sll     a0, a0, 0
+#endif
+       negu    a1, a0
+       and     a0, a1
+       clz     v0, a0
+       j       ra
+        subu   v0, v1, v0
+       .set    pop
+END(ffs)
+#if defined(_LP64) && __mips == 64
+LEAF(ffsl)
+       li      v1, 64
+       negu    a1, a0
+       and     a0, a1
+       dclz    v0, a0
+       j       ra
+        subu   v0, v1, v0
+END(ffsl)
+#endif
+#else /* __mips != 64 && __mips != 32 */
+
+#ifdef _LP64
+XLEAF(ffsl)
+       beqz    a0, 6f                  # fast escape if 0
+        li     v0, 0
+
+       li      v0, 1
+       li      a3, 0xffffffff          # initial mask
+       b       1f
+        li     a2, 32                  # bit count of mask
+#endif /* _LP64 */
+LEAF(ffs)
+#ifndef _LP64
+XLEAF(ffsl)
+#endif /* !_LP64 */
+       beqz    a0, 6f
+        li     v0, 0
+
+       li      v0, 1
+       li      a3, 0xffff              # initial mask
+       li      a2, 16                  # bit count of mask
 1:
-       and     v1, a0, 1               # bit set?
-       addu    v0, v0, 1
-       srl     a0, a0, 1
-       beq     v1, zero, 1b            # no, continue
-done:
+       and     v1, a0, a3              # focus no lower half of bits left
+       bnez    v1, 2f                  # any of the lower half set?
+        nop
+       addu    v0, a2                  # nope, then bit is in the upper half
+#ifdef _LP64
+       dsrlv   a0, a0, a2              # discard low bits
+#else
+       srlv    a0, a0, a2              # discard low bits
+#endif
+2:
+       srl     a2, 1                   # divide bit count by 2
+       bnez    a2, 1b                  # still bits left to text?
+        srlv   a3, a3, a2              # shrink mask in half
+6:
        j       ra
+        nop
 END(ffs)
+#endif /* __mips == 64 || __mips == 32 */



Home | Main Index | Thread Index | Old Index