xref: /openbsd-src/lib/libc/string/ffs.c (revision ae3cb403620ab940fbaabb3055fac045a63d56b7)
1*ae3cb403Sguenther /*	$OpenBSD: ffs.c,v 1.10 2018/01/18 08:23:44 guenther Exp $	*/
24d534b91Smickey 
34d534b91Smickey /*
44d534b91Smickey  * Public domain.
54d534b91Smickey  * Written by Dale Rahn.
6df930be7Sderaadt  */
7df930be7Sderaadt 
8df930be7Sderaadt #include <string.h>
9df930be7Sderaadt 
10df930be7Sderaadt /*
11df930be7Sderaadt  * ffs -- vax ffs instruction
12df930be7Sderaadt  */
13df930be7Sderaadt int
ffs(int mask)1486b54bb2Sderaadt ffs(int mask)
15df930be7Sderaadt {
1686b54bb2Sderaadt 	int bit;
1786b54bb2Sderaadt 	unsigned int r = mask;
184d534b91Smickey 	static const signed char t[16] = {
194d534b91Smickey 		-28, 1, 2, 1,
204d534b91Smickey 		  3, 1, 2, 1,
214d534b91Smickey 		  4, 1, 2, 1,
222c21b972Smickey 		  3, 1, 2, 1
232c21b972Smickey 	};
24df930be7Sderaadt 
254d534b91Smickey 	bit = 0;
262c21b972Smickey 	if (!(r & 0xffff)) {
274d534b91Smickey 		bit += 16;
284d534b91Smickey 		r >>= 16;
294d534b91Smickey 	}
302c21b972Smickey 	if (!(r & 0xff)) {
314d534b91Smickey 		bit += 8;
324d534b91Smickey 		r >>= 8;
334d534b91Smickey 	}
342c21b972Smickey 	if (!(r & 0xf)) {
354d534b91Smickey 		bit += 4;
364d534b91Smickey 		r >>= 4;
374d534b91Smickey 	}
384d534b91Smickey 
394d534b91Smickey 	return (bit + t[ r & 0xf ]);
40df930be7Sderaadt }
41