xref: /openbsd-src/sys/lib/libkern/ffs.c (revision b5be37d2a6fbef83b90ca99497343fa8dbb0f3fc)
1*b5be37d2Sderaadt /*	$OpenBSD: ffs.c,v 1.9 2014/06/10 04:16:57 deraadt Exp $	*/
2c3f6e9cfSniklas 
361ffbdacSmickey /*
461ffbdacSmickey  * Public domain.
561ffbdacSmickey  * Written by Dale Rahn.
6df930be7Sderaadt  */
7df930be7Sderaadt 
8cf4fa783Sderaadt #include <lib/libkern/libkern.h>
9df930be7Sderaadt 
10df930be7Sderaadt /*
11df930be7Sderaadt  * ffs -- vax ffs instruction
12df930be7Sderaadt  */
13df930be7Sderaadt int
ffs(int mask)14a26aa419Sderaadt ffs(int mask)
15df930be7Sderaadt {
16a26aa419Sderaadt 	int bit;
17a26aa419Sderaadt 	unsigned int r = mask;
1861ffbdacSmickey 	static const signed char t[16] = {
1961ffbdacSmickey 		-28, 1, 2, 1,
2061ffbdacSmickey 		  3, 1, 2, 1,
2161ffbdacSmickey 		  4, 1, 2, 1,
222c21b972Smickey 		  3, 1, 2, 1
232c21b972Smickey 	};
24df930be7Sderaadt 
2561ffbdacSmickey 	bit = 0;
262c21b972Smickey 	if (!(r & 0xffff)) {
2761ffbdacSmickey 		bit += 16;
2861ffbdacSmickey 		r >>= 16;
2961ffbdacSmickey 	}
302c21b972Smickey 	if (!(r & 0xff)) {
3161ffbdacSmickey 		bit += 8;
3261ffbdacSmickey 		r >>= 8;
3361ffbdacSmickey 	}
342c21b972Smickey 	if (!(r & 0xf)) {
3561ffbdacSmickey 		bit += 4;
3661ffbdacSmickey 		r >>= 4;
3761ffbdacSmickey 	}
3861ffbdacSmickey 
3961ffbdacSmickey 	return (bit + t[ r & 0xf ]);
40df930be7Sderaadt }
41