xref: /openbsd-src/sys/lib/libkern/ctzdi2.c (revision 614862c8bb76e418c62102ea04c9b99d3f680d40)
1*614862c8Sjsg /*	$OpenBSD: ctzdi2.c,v 1.1 2022/12/14 23:50:31 jsg Exp $	*/
2*614862c8Sjsg 
3*614862c8Sjsg /*
4*614862c8Sjsg  * Public domain.
5*614862c8Sjsg  * Written by Dale Rahn.
6*614862c8Sjsg  */
7*614862c8Sjsg 
8*614862c8Sjsg #include <lib/libkern/libkern.h>
9*614862c8Sjsg 
10*614862c8Sjsg /*
11*614862c8Sjsg  * ffsl -- vax ffs instruction with long arg
12*614862c8Sjsg  */
13*614862c8Sjsg 
14*614862c8Sjsg #ifdef __LP64__
15*614862c8Sjsg static int
ffsl(long mask)16*614862c8Sjsg ffsl(long mask)
17*614862c8Sjsg {
18*614862c8Sjsg 	int bit;
19*614862c8Sjsg 	unsigned long r = mask;
20*614862c8Sjsg 	static const signed char t[16] = {
21*614862c8Sjsg 		-60, 1, 2, 1,
22*614862c8Sjsg 		  3, 1, 2, 1,
23*614862c8Sjsg 		  4, 1, 2, 1,
24*614862c8Sjsg 		  3, 1, 2, 1
25*614862c8Sjsg 	};
26*614862c8Sjsg 
27*614862c8Sjsg 	bit = 0;
28*614862c8Sjsg 	if (!(r & 0xffffffff)) {
29*614862c8Sjsg 		bit += 32;
30*614862c8Sjsg 		r >>= 32;
31*614862c8Sjsg 	}
32*614862c8Sjsg 	if (!(r & 0xffff)) {
33*614862c8Sjsg 		bit += 16;
34*614862c8Sjsg 		r >>= 16;
35*614862c8Sjsg 	}
36*614862c8Sjsg 	if (!(r & 0xff)) {
37*614862c8Sjsg 		bit += 8;
38*614862c8Sjsg 		r >>= 8;
39*614862c8Sjsg 	}
40*614862c8Sjsg 	if (!(r & 0xf)) {
41*614862c8Sjsg 		bit += 4;
42*614862c8Sjsg 		r >>= 4;
43*614862c8Sjsg 	}
44*614862c8Sjsg 
45*614862c8Sjsg 	return (bit + t[ r & 0xf ]);
46*614862c8Sjsg }
47*614862c8Sjsg #else
48*614862c8Sjsg static int
ffsl(long mask)49*614862c8Sjsg ffsl(long mask)
50*614862c8Sjsg {
51*614862c8Sjsg 	return ffs(mask);
52*614862c8Sjsg }
53*614862c8Sjsg #endif
54*614862c8Sjsg 
55*614862c8Sjsg int
__ctzdi2(long mask)56*614862c8Sjsg __ctzdi2(long mask)
57*614862c8Sjsg {
58*614862c8Sjsg 	if (mask == 0)
59*614862c8Sjsg 		return 0;
60*614862c8Sjsg 	return ffsl(mask) - 1;
61*614862c8Sjsg }
62