1*f14fb602SLionel Sambuc/* $NetBSD: ffs.S,v 1.4 2011/07/04 11:35:26 mrg Exp $ */ 2b6cbf720SGianluca Guida 3b6cbf720SGianluca Guida/*- 4*f14fb602SLionel Sambuc * Copyright (c) 2010 The NetBSD Foundation, Inc. 5*f14fb602SLionel Sambuc * All rights reserved. 6b6cbf720SGianluca Guida * 7*f14fb602SLionel Sambuc * This code is derived from software contributed to The NetBSD Foundation 8*f14fb602SLionel Sambuc * by Matt Thomas of 3am Software Foundry. 9b6cbf720SGianluca Guida * 10b6cbf720SGianluca Guida * Redistribution and use in source and binary forms, with or without 11b6cbf720SGianluca Guida * modification, are permitted provided that the following conditions 12b6cbf720SGianluca Guida * are met: 13b6cbf720SGianluca Guida * 1. Redistributions of source code must retain the above copyright 14b6cbf720SGianluca Guida * notice, this list of conditions and the following disclaimer. 15b6cbf720SGianluca Guida * 2. Redistributions in binary form must reproduce the above copyright 16b6cbf720SGianluca Guida * notice, this list of conditions and the following disclaimer in the 17b6cbf720SGianluca Guida * documentation and/or other materials provided with the distribution. 18b6cbf720SGianluca Guida * 19*f14fb602SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20*f14fb602SLionel Sambuc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21*f14fb602SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22*f14fb602SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23*f14fb602SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*f14fb602SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*f14fb602SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*f14fb602SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*f14fb602SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*f14fb602SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*f14fb602SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE. 30b6cbf720SGianluca Guida */ 31b6cbf720SGianluca Guida 32b6cbf720SGianluca Guida#include <mips/asm.h> 33b6cbf720SGianluca Guida 34*f14fb602SLionel SambucRCSID("$NetBSD: ffs.S,v 1.4 2011/07/04 11:35:26 mrg Exp $") 35b6cbf720SGianluca Guida 36b6cbf720SGianluca Guida/* bit = ffs(value) */ 37b6cbf720SGianluca Guida 38*f14fb602SLionel Sambuc .text 39*f14fb602SLionel Sambuc .set noreorder 40*f14fb602SLionel Sambuc 41*f14fb602SLionel SambucWEAK_ALIAS(__ffssi2,ffs) 42*f14fb602SLionel Sambuc#if __mips == 64 || __mips == 32 43b6cbf720SGianluca GuidaLEAF(ffs) 44*f14fb602SLionel Sambuc#ifndef _LP64 45*f14fb602SLionel SambucXLEAF(ffsl) 46*f14fb602SLionel Sambuc#endif 47*f14fb602SLionel Sambuc .set push 48*f14fb602SLionel Sambuc .set mips32 49*f14fb602SLionel Sambuc li v1, 32 50*f14fb602SLionel Sambuc#if __mips == 64 51*f14fb602SLionel Sambuc sll a0, a0, 0 52*f14fb602SLionel Sambuc#endif 53*f14fb602SLionel Sambuc negu a1, a0 54*f14fb602SLionel Sambuc and a0, a1 55*f14fb602SLionel Sambuc clz v0, a0 56b6cbf720SGianluca Guida j ra 57*f14fb602SLionel Sambuc subu v0, v1, v0 58*f14fb602SLionel Sambuc .set pop 59b6cbf720SGianluca GuidaEND(ffs) 60*f14fb602SLionel Sambuc#if defined(_LP64) && __mips == 64 61*f14fb602SLionel SambucLEAF(ffsl) 62*f14fb602SLionel Sambuc li v1, 64 63*f14fb602SLionel Sambuc negu a1, a0 64*f14fb602SLionel Sambuc and a0, a1 65*f14fb602SLionel Sambuc dclz v0, a0 66*f14fb602SLionel Sambuc j ra 67*f14fb602SLionel Sambuc subu v0, v1, v0 68*f14fb602SLionel SambucEND(ffsl) 69*f14fb602SLionel Sambuc#endif 70*f14fb602SLionel Sambuc#else /* __mips != 64 && __mips != 32 */ 71*f14fb602SLionel Sambuc 72*f14fb602SLionel Sambuc#ifdef _LP64 73*f14fb602SLionel SambucXLEAF(ffsl) 74*f14fb602SLionel Sambuc beqz a0, 6f # fast escape if 0 75*f14fb602SLionel Sambuc li v0, 0 76*f14fb602SLionel Sambuc 77*f14fb602SLionel Sambuc li v0, 1 78*f14fb602SLionel Sambuc li a3, 0xffffffff # initial mask 79*f14fb602SLionel Sambuc b 1f 80*f14fb602SLionel Sambuc li a2, 32 # bit count of mask 81*f14fb602SLionel Sambuc#endif /* _LP64 */ 82*f14fb602SLionel SambucLEAF(ffs) 83*f14fb602SLionel Sambuc#ifndef _LP64 84*f14fb602SLionel SambucXLEAF(ffsl) 85*f14fb602SLionel Sambuc#endif /* !_LP64 */ 86*f14fb602SLionel Sambuc beqz a0, 6f 87*f14fb602SLionel Sambuc li v0, 0 88*f14fb602SLionel Sambuc 89*f14fb602SLionel Sambuc li v0, 1 90*f14fb602SLionel Sambuc li a3, 0xffff # initial mask 91*f14fb602SLionel Sambuc li a2, 16 # bit count of mask 92*f14fb602SLionel Sambuc1: 93*f14fb602SLionel Sambuc and v1, a0, a3 # focus no lower half of bits left 94*f14fb602SLionel Sambuc bnez v1, 2f # any of the lower half set? 95*f14fb602SLionel Sambuc nop 96*f14fb602SLionel Sambuc addu v0, a2 # nope, then bit is in the upper half 97*f14fb602SLionel Sambuc#ifdef _LP64 98*f14fb602SLionel Sambuc dsrlv a0, a0, a2 # discard low bits 99*f14fb602SLionel Sambuc#else 100*f14fb602SLionel Sambuc srlv a0, a0, a2 # discard low bits 101*f14fb602SLionel Sambuc#endif 102*f14fb602SLionel Sambuc2: 103*f14fb602SLionel Sambuc srl a2, 1 # divide bit count by 2 104*f14fb602SLionel Sambuc bnez a2, 1b # still bits left to text? 105*f14fb602SLionel Sambuc srlv a3, a3, a2 # shrink mask in half 106*f14fb602SLionel Sambuc6: 107*f14fb602SLionel Sambuc j ra 108*f14fb602SLionel Sambuc nop 109*f14fb602SLionel SambucEND(ffs) 110*f14fb602SLionel Sambuc#endif /* __mips == 64 || __mips == 32 */ 111