1/* $NetBSD: ffs.S,v 1.1 2002/06/06 20:31:22 fredette Exp $ */ 2 3/* $OpenBSD: ffs.S,v 1.3 2001/06/04 23:14:02 mickey Exp $ */ 4 5/* 6 * Copyright (c) 1990, 1991, 1992, 1994, The University of Utah and 7 * the Computer Systems Laboratory at the University of Utah (CSL). 8 * All rights reserved. 9 * 10 * Permission to use, copy, modify and distribute this software and its 11 * documentation is hereby granted, provided that both the copyright 12 * notice and this permission notice appear in all copies of the 13 * software, derivative works or modified versions, and any portions 14 * thereof, and that both notices appear in supporting documentation. 15 * 16 * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 17 * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 18 * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 19 * 20 * CSL requests users of this software to return to csl-dist@cs.utah.edu any 21 * improvements that they make and grant CSL redistribution rights. 22 * 23 */ 24 25#include <machine/asm.h> 26 27#ifdef SYSLIBC_SCCS 28 .text 29 .asciz "$OpenBSD: ffs.S,v 1.3 2001/06/04 23:14:02 mickey Exp $" 30 .align 4 31#endif 32 33/* 34 * ffs(bitmask) 35 * 36 * Return the position of the "most significant" bit in `bitmask'. 37 * Since this is similar to the VAX ffs instruction, bits in a word 38 * are numbered as "32, 31, ... 1", 0 is returned if no bits are set. 39 */ 40 41LEAF_ENTRY(ffs) 42 comb,= arg0,r0,ffsdone ; If arg0 is 0 43 or r0,r0,ret0 ; return 0 44 ldi 32,ret0 ; Set return to high bit 45 extru,= arg0,31,16,r0 ; If low 16 bits are non-zero 46 addi,tr -16,ret0,ret0 ; subtract 16 from bitpos 47 shd r0,arg0,16,arg0 ; else shift right 16 bits 48 extru,= arg0,31,8,r0 ; If low 8 bits are non-zero 49 addi,tr -8,ret0,ret0 ; subtract 8 from bitpos 50 shd r0,arg0,8,arg0 ; else shift right 8 bits 51 extru,= arg0,31,4,r0 ; If low 4 bits are non-zero 52 addi,tr -4,ret0,ret0 ; subtract 4 from bitpos 53 shd r0,arg0,4,arg0 ; else shift right 4 bits 54 extru,= arg0,31,2,r0 ; If low 2 bits are non-zero 55 addi,tr -2,ret0,ret0 ; subtract 2 from bitpos 56 shd r0,arg0,2,arg0 ; else shift right 2 bits 57 extru,= arg0,31,1,r0 ; If low bit is non-zero 58 addi -1,ret0,ret0 ; subtract 1 from bitpos 59ffsdone: 60EXIT(ffs) 61 62 .end 63