1*259d2a08Smrg/* $NetBSD: ffs.S,v 1.4 2011/07/04 11:35:26 mrg Exp $ */ 237c9f0a6Schristos 337c9f0a6Schristos/*- 43c6f3faaSmatt * Copyright (c) 2010 The NetBSD Foundation, Inc. 53c6f3faaSmatt * All rights reserved. 637c9f0a6Schristos * 73c6f3faaSmatt * This code is derived from software contributed to The NetBSD Foundation 83c6f3faaSmatt * by Matt Thomas of 3am Software Foundry. 937c9f0a6Schristos * 1037c9f0a6Schristos * Redistribution and use in source and binary forms, with or without 1137c9f0a6Schristos * modification, are permitted provided that the following conditions 1237c9f0a6Schristos * are met: 1337c9f0a6Schristos * 1. Redistributions of source code must retain the above copyright 1437c9f0a6Schristos * notice, this list of conditions and the following disclaimer. 1537c9f0a6Schristos * 2. Redistributions in binary form must reproduce the above copyright 1637c9f0a6Schristos * notice, this list of conditions and the following disclaimer in the 1737c9f0a6Schristos * documentation and/or other materials provided with the distribution. 1837c9f0a6Schristos * 193c6f3faaSmatt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 203c6f3faaSmatt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 213c6f3faaSmatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 223c6f3faaSmatt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 233c6f3faaSmatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 243c6f3faaSmatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 253c6f3faaSmatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 263c6f3faaSmatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 273c6f3faaSmatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 283c6f3faaSmatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 293c6f3faaSmatt * POSSIBILITY OF SUCH DAMAGE. 3037c9f0a6Schristos */ 3137c9f0a6Schristos 3237c9f0a6Schristos#include <mips/asm.h> 3337c9f0a6Schristos 34*259d2a08SmrgRCSID("$NetBSD: ffs.S,v 1.4 2011/07/04 11:35:26 mrg Exp $") 3537c9f0a6Schristos 3637c9f0a6Schristos/* bit = ffs(value) */ 3737c9f0a6Schristos 383c6f3faaSmatt .text 393c6f3faaSmatt .set noreorder 403c6f3faaSmatt 41*259d2a08SmrgWEAK_ALIAS(__ffssi2,ffs) 423c6f3faaSmatt#if __mips == 64 || __mips == 32 4337c9f0a6SchristosLEAF(ffs) 443c6f3faaSmatt#ifndef _LP64 453c6f3faaSmattXLEAF(ffsl) 463c6f3faaSmatt#endif 473c6f3faaSmatt .set push 483c6f3faaSmatt .set mips32 493c6f3faaSmatt li v1, 32 503c6f3faaSmatt#if __mips == 64 513c6f3faaSmatt sll a0, a0, 0 523c6f3faaSmatt#endif 533c6f3faaSmatt negu a1, a0 543c6f3faaSmatt and a0, a1 553c6f3faaSmatt clz v0, a0 5637c9f0a6Schristos j ra 573c6f3faaSmatt subu v0, v1, v0 583c6f3faaSmatt .set pop 5937c9f0a6SchristosEND(ffs) 603c6f3faaSmatt#if defined(_LP64) && __mips == 64 613c6f3faaSmattLEAF(ffsl) 623c6f3faaSmatt li v1, 64 633c6f3faaSmatt negu a1, a0 643c6f3faaSmatt and a0, a1 653c6f3faaSmatt dclz v0, a0 663c6f3faaSmatt j ra 673c6f3faaSmatt subu v0, v1, v0 683c6f3faaSmattEND(ffsl) 693c6f3faaSmatt#endif 703c6f3faaSmatt#else /* __mips != 64 && __mips != 32 */ 713c6f3faaSmatt 723c6f3faaSmatt#ifdef _LP64 733c6f3faaSmattXLEAF(ffsl) 743c6f3faaSmatt beqz a0, 6f # fast escape if 0 753c6f3faaSmatt li v0, 0 763c6f3faaSmatt 773c6f3faaSmatt li v0, 1 783c6f3faaSmatt li a3, 0xffffffff # initial mask 793c6f3faaSmatt b 1f 803c6f3faaSmatt li a2, 32 # bit count of mask 813c6f3faaSmatt#endif /* _LP64 */ 823c6f3faaSmattLEAF(ffs) 833c6f3faaSmatt#ifndef _LP64 843c6f3faaSmattXLEAF(ffsl) 853c6f3faaSmatt#endif /* !_LP64 */ 863c6f3faaSmatt beqz a0, 6f 873c6f3faaSmatt li v0, 0 883c6f3faaSmatt 893c6f3faaSmatt li v0, 1 903c6f3faaSmatt li a3, 0xffff # initial mask 913c6f3faaSmatt li a2, 16 # bit count of mask 923c6f3faaSmatt1: 933c6f3faaSmatt and v1, a0, a3 # focus no lower half of bits left 943c6f3faaSmatt bnez v1, 2f # any of the lower half set? 953c6f3faaSmatt nop 963c6f3faaSmatt addu v0, a2 # nope, then bit is in the upper half 973c6f3faaSmatt#ifdef _LP64 983c6f3faaSmatt dsrlv a0, a0, a2 # discard low bits 993c6f3faaSmatt#else 1003c6f3faaSmatt srlv a0, a0, a2 # discard low bits 1013c6f3faaSmatt#endif 1023c6f3faaSmatt2: 1033c6f3faaSmatt srl a2, 1 # divide bit count by 2 1043c6f3faaSmatt bnez a2, 1b # still bits left to text? 1053c6f3faaSmatt srlv a3, a3, a2 # shrink mask in half 1063c6f3faaSmatt6: 1073c6f3faaSmatt j ra 1083c6f3faaSmatt nop 1093c6f3faaSmattEND(ffs) 1103c6f3faaSmatt#endif /* __mips == 64 || __mips == 32 */ 111