1/* 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. 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.3 92/07/07 00:23:57 torek Exp $ 12 */ 13 14#if defined(LIBC_SCCS) && !defined(lint) 15 .asciz "@(#)ffs.s 8.1 (Berkeley) 06/04/93" 16#endif /* LIBC_SCCS and not lint */ 17 18#include "DEFS.h" 19 20/* 21 * ffs returns the number of the rightmost bit set in its argument, 22 * i.e., the lowest value such that (x & (ffs(x) - 1)) is nonzero. 23 * If no bits are set, ffs returns 0. 24 * 25 * We use a table lookup on each byte. 26 * 27 * In each section below, %o1 is the current byte (0, 1, 2, or 3). 28 * The last byte is handled specially: for the first three, 29 * if that byte is nonzero, we return the table value 30 * (plus 0, 8, or 16 for the byte number), but for the last 31 * one, we just return the table value plus 24. This means 32 * that ffstab[0] must be -24 so that ffs(0) will return 0. 33 */ 34ENTRY(ffs) 35 set ffstab, %o2 36 andcc %o0, 0xff, %o1 ! get low byte 37 be,a 1f ! try again if 0 38 srl %o0, 8, %o0 ! delay slot, get ready for next byte 39 40 retl ! return ffstab[%o1] 41 ldsb [%o2 + %o1], %o0 42 431: 44 andcc %o0, 0xff, %o1 ! byte 1 like byte 0... 45 be,a 2f 46 srl %o0, 8, %o0 ! (use delay to prepare for byte 2) 47 48 ldsb [%o2 + %o1], %o0 49 retl ! return ffstab[%o1] + 8 50 add %o0, 8, %o0 51 522: 53 andcc %o0, 0xff, %o1 54 be,a 3f 55 srl %o0, 8, %o0 ! (prepare for byte 3) 56 57 ldsb [%o2 + %o1], %o0 58 retl ! return ffstab[%o1] + 16 59 add %o0, 16, %o0 60 613: ! just return ffstab[%o0] + 24 62 ldsb [%o2 + %o0], %o0 63 retl 64 add %o0, 24, %o0 65 66ffstab: 67 .byte -24,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 00-0f */ 68 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 10-1f */ 69 .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 20-2f */ 70 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 30-3f */ 71 .byte 7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 40-4f */ 72 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 50-5f */ 73 .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 60-6f */ 74 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 70-7f */ 75 .byte 8,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 80-8f */ 76 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 10-9f */ 77 .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* a0-af */ 78 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* b0-bf */ 79 .byte 7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* c0-cf */ 80 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* d0-df */ 81 .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* e0-ef */ 82 .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* f0-ff */ 83