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