1/* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This software was developed by the Computer Systems Engineering group 6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7 * contributed to Berkeley. 8 * 9 * %sccs.include.redist.c% 10 * 11 * from: $Header: ffs.s,v 1.1 91/07/07 05:29:48 torek Exp $ 12 */ 13 14#if defined(LIBC_SCCS) && !defined(lint) 15 .asciz "@(#)ffs.s 5.1 (Berkeley) 06/25/92" 16#endif /* LIBC_SCCS and not lint */ 17 18/* 19 * ffs returns the number of the rightmost bit set in its argument, 20 * i.e., the lowest value such that (x & (ffs(x) - 1)) is nonzero. 21 * If no bits are set, ffs returns 0. 22 * 23 * We use a table lookup, one byte at a time. 24 * Note that the table has a special value in slot 0. 25 */ 26 27ffstab: 28 .byte -24,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 00-0f */ 29 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 10-1f */ 30 .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 20-2f */ 31 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 30-3f */ 32 .byte 7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 40-4f */ 33 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 50-5f */ 34 .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 60-6f */ 35 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 70-7f */ 36 .byte 8,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 80-8f */ 37 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 10-9f */ 38 .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* a0-af */ 39 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* b0-bf */ 40 .byte 7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* c0-cf */ 41 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* d0-df */ 42 .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* e0-ef */ 43 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* f0-ff */ 44 45/* 46 * We use a table lookup on each byte. 47 * 48 * In each section below, %o1 is the current byte (0, 1, 2, or 3). 49 * The last byte is handled specially: for the first three, 50 * if that byte is nonzero, we return the table value 51 * (plus 0, 8, or 16 for the byte number), but for the last 52 * one, we just return the table value plus 24. This means 53 * that ffstab[0] must be -24 so that ffs(0) will return 0. 54 */ 55 .global _ffs 56_ffs: 57 set ffstab, %o2 58 andcc %o0, 0xff, %o1 ! get low byte 59 be,a 1f ! try again if 0 60 srl %o0, 8, %o0 ! delay slot, get ready for next byte 61 62 retl ! return ffstab[%o1] 63 ldsb [%o2 + %o1], %o0 64 651: 66 andcc %o0, 0xff, %o1 ! byte 1 like byte 0... 67 be,a 2f 68 srl %o0, 8, %o0 ! (use delay to prepare for byte 2) 69 70 ldsb [%o2 + %o1], %o0 71 retl ! return ffstab[%o1] + 8 72 add %o0, 8, %o0 73 742: 75 andcc %o0, 0xff, %o1 76 be,a 3f 77 srl %o0, 8, %o0 ! (prepare for byte 3) 78 79 ldsb [%o2 + %o1], %o0 80 retl ! return ffstab[%o1] + 16 81 add %o0, 16, %o0 82 833: ! just return ffstab[%o0] + 24 84 ldsb [%o2 + %o0], %o0 85 retl 86 add %o0, 24, %o0 87