1*4d12bfcdSjoerg/* $NetBSD: ffs.S,v 1.3 2013/09/12 15:36:14 joerg Exp $ */ 237c9f0a6Schristos 337c9f0a6Schristos/* 437c9f0a6Schristos * Copyright (c) 1992, 1993 537c9f0a6Schristos * The Regents of the University of California. All rights reserved. 637c9f0a6Schristos * 737c9f0a6Schristos * This software was developed by the Computer Systems Engineering group 837c9f0a6Schristos * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 937c9f0a6Schristos * contributed to Berkeley. 1037c9f0a6Schristos * 1137c9f0a6Schristos * Redistribution and use in source and binary forms, with or without 1237c9f0a6Schristos * modification, are permitted provided that the following conditions 1337c9f0a6Schristos * are met: 1437c9f0a6Schristos * 1. Redistributions of source code must retain the above copyright 1537c9f0a6Schristos * notice, this list of conditions and the following disclaimer. 1637c9f0a6Schristos * 2. Redistributions in binary form must reproduce the above copyright 1737c9f0a6Schristos * notice, this list of conditions and the following disclaimer in the 1837c9f0a6Schristos * documentation and/or other materials provided with the distribution. 1937c9f0a6Schristos * 3. Neither the name of the University nor the names of its contributors 2037c9f0a6Schristos * may be used to endorse or promote products derived from this software 2137c9f0a6Schristos * without specific prior written permission. 2237c9f0a6Schristos * 2337c9f0a6Schristos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2437c9f0a6Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2537c9f0a6Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2637c9f0a6Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2737c9f0a6Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2837c9f0a6Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2937c9f0a6Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3037c9f0a6Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3137c9f0a6Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3237c9f0a6Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3337c9f0a6Schristos * SUCH DAMAGE. 3437c9f0a6Schristos * 3537c9f0a6Schristos * from: Header: ffs.s,v 1.3 92/07/07 00:23:57 torek Exp 3637c9f0a6Schristos */ 3737c9f0a6Schristos 3837c9f0a6Schristos#include <machine/asm.h> 3937c9f0a6Schristos#if defined(LIBC_SCCS) && !defined(lint) 4037c9f0a6Schristos#if 0 4137c9f0a6Schristos .asciz "@(#)ffs.s 8.1 (Berkeley) 6/4/93" 4237c9f0a6Schristos#else 43*4d12bfcdSjoerg RCSID("$NetBSD: ffs.S,v 1.3 2013/09/12 15:36:14 joerg Exp $") 4437c9f0a6Schristos#endif 4537c9f0a6Schristos#endif /* LIBC_SCCS and not lint */ 4637c9f0a6Schristos 4737c9f0a6Schristos#if 0 4837c9f0a6Schristos /* 4937c9f0a6Schristos * We have a popcount instruction -- use it. 5037c9f0a6Schristos * only uses %o0, %o1, %o2 5137c9f0a6Schristos * 5237c9f0a6Schristos * Here's the pseudo-code from the v9 spec: 5337c9f0a6Schristos * 5437c9f0a6Schristos * int ffs(unsigned zz) { 5537c9f0a6Schristos * return popc( zz ^ ( ~ (-zz))); 5637c9f0a6Schristos * } 5737c9f0a6Schristos * 5837c9f0a6Schristos * XXXX sptifires and blackbirds don't implement popc, 5937c9f0a6Schristos * so we won't use this nice clean code 8^(. 6037c9f0a6Schristos */ 6137c9f0a6SchristosENTRY(ffs) 6237c9f0a6Schristos neg %o0, %o1 ! %o1 = -zz 6337c9f0a6Schristos xnor %o0, %o1, %o2 ! %o2 = zz ^ ~ -zz 6437c9f0a6Schristos popc %o2, %o1 6537c9f0a6Schristos movrz %o0, %g0, %o1 ! result of ffs(0) should be zero 6637c9f0a6Schristos retl 6737c9f0a6Schristos mov %o1, %o0 6837c9f0a6Schristos#endif 6937c9f0a6Schristos/* 7037c9f0a6Schristos * ffs returns the number of the rightmost bit set in its argument, 7137c9f0a6Schristos * i.e., the lowest value such that (x & (ffs(x) - 1)) is nonzero. 7237c9f0a6Schristos * If no bits are set, ffs returns 0. 7337c9f0a6Schristos * 7437c9f0a6Schristos * We use a table lookup on each byte. 7537c9f0a6Schristos * 7637c9f0a6Schristos * In each section below, %o1 is the current byte (0, 1, 2, or 3). 7737c9f0a6Schristos * The last byte is handled specially: for the first three, 7837c9f0a6Schristos * if that byte is nonzero, we return the table value 7937c9f0a6Schristos * (plus 0, 8, or 16 for the byte number), but for the last 8037c9f0a6Schristos * one, we just return the table value plus 24. This means 8137c9f0a6Schristos * that ffstab[0] must be -24 so that ffs(0) will return 0. 8237c9f0a6Schristos */ 8337c9f0a6SchristosENTRY(ffs) 84*4d12bfcdSjoerg#ifdef __PIC__ 85817cd315Spooka PICCY_SET(ffstab, %o2, %o3) 8637c9f0a6Schristos#else 87817cd315Spooka set ffstab, %o2 8837c9f0a6Schristos#endif 8937c9f0a6Schristos andcc %o0, 0xff, %o1 ! get low byte 9037c9f0a6Schristos be,a 1f ! try again if 0 9137c9f0a6Schristos srl %o0, 8, %o0 ! delay slot, get ready for next byte 9237c9f0a6Schristos 9337c9f0a6Schristos retl ! return ffstab[%o1] 9437c9f0a6Schristos ldsb [%o2 + %o1], %o0 9537c9f0a6Schristos 9637c9f0a6Schristos1: 9737c9f0a6Schristos andcc %o0, 0xff, %o1 ! byte 1 like byte 0... 9837c9f0a6Schristos be,a 2f 9937c9f0a6Schristos srl %o0, 8, %o0 ! (use delay to prepare for byte 2) 10037c9f0a6Schristos 10137c9f0a6Schristos ldsb [%o2 + %o1], %o0 10237c9f0a6Schristos retl ! return ffstab[%o1] + 8 10337c9f0a6Schristos add %o0, 8, %o0 10437c9f0a6Schristos 10537c9f0a6Schristos2: 10637c9f0a6Schristos andcc %o0, 0xff, %o1 10737c9f0a6Schristos be,a 3f 10837c9f0a6Schristos srl %o0, 8, %o0 ! (prepare for byte 3) 10937c9f0a6Schristos 11037c9f0a6Schristos ldsb [%o2 + %o1], %o0 11137c9f0a6Schristos retl ! return ffstab[%o1] + 16 11237c9f0a6Schristos add %o0, 16, %o0 11337c9f0a6Schristos 11437c9f0a6Schristos3: ! just return ffstab[%o0] + 24 11537c9f0a6Schristos ldsb [%o2 + %o0], %o0 11637c9f0a6Schristos retl 11737c9f0a6Schristos add %o0, 24, %o0 11837c9f0a6Schristos 119817cd315Spookaffstab: 12037c9f0a6Schristos .byte -24,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 00-0f */ 12137c9f0a6Schristos .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 10-1f */ 12237c9f0a6Schristos .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 20-2f */ 12337c9f0a6Schristos .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 30-3f */ 12437c9f0a6Schristos .byte 7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 40-4f */ 12537c9f0a6Schristos .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 50-5f */ 12637c9f0a6Schristos .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 60-6f */ 12737c9f0a6Schristos .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 70-7f */ 12837c9f0a6Schristos .byte 8,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 80-8f */ 12937c9f0a6Schristos .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 10-9f */ 13037c9f0a6Schristos .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* a0-af */ 13137c9f0a6Schristos .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* b0-bf */ 13237c9f0a6Schristos .byte 7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* c0-cf */ 13337c9f0a6Schristos .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* d0-df */ 13437c9f0a6Schristos .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* e0-ef */ 13537c9f0a6Schristos .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* f0-ff */ 136