xref: /openbsd-src/sys/lib/libkern/ffs.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: ffs.c,v 1.7 2004/11/28 07:23:41 mickey Exp $	*/
2 
3 /*
4  * Public domain.
5  * Written by Dale Rahn.
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char *rcsid = "$OpenBSD: ffs.c,v 1.7 2004/11/28 07:23:41 mickey Exp $";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #if !defined(_KERNEL) && !defined(_STANDALONE)
13 #include <string.h>
14 #else
15 #include <lib/libkern/libkern.h>
16 #endif
17 
18 /*
19  * ffs -- vax ffs instruction
20  */
21 int
22 ffs(int mask)
23 {
24 	int bit;
25 	unsigned int r = mask;
26 	static const signed char t[16] = {
27 		-28, 1, 2, 1,
28 		  3, 1, 2, 1,
29 		  4, 1, 2, 1,
30 		  3, 1, 2, 1
31 	};
32 
33 	bit = 0;
34 	if (!(r & 0xffff)) {
35 		bit += 16;
36 		r >>= 16;
37 	}
38 	if (!(r & 0xff)) {
39 		bit += 8;
40 		r >>= 8;
41 	}
42 	if (!(r & 0xf)) {
43 		bit += 4;
44 		r >>= 4;
45 	}
46 
47 	return (bit + t[ r & 0xf ]);
48 }
49