1*7c5b184dSJason Gunthorpe /* SPDX-License-Identifier: GPL-2.0-only */
2*7c5b184dSJason Gunthorpe /*
3*7c5b184dSJason Gunthorpe * Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES
4*7c5b184dSJason Gunthorpe *
5*7c5b184dSJason Gunthorpe * Helper macros for working with log2 values
6*7c5b184dSJason Gunthorpe *
7*7c5b184dSJason Gunthorpe */
8*7c5b184dSJason Gunthorpe #ifndef __GENERIC_PT_LOG2_H
9*7c5b184dSJason Gunthorpe #define __GENERIC_PT_LOG2_H
10*7c5b184dSJason Gunthorpe #include <linux/bitops.h>
11*7c5b184dSJason Gunthorpe #include <linux/limits.h>
12*7c5b184dSJason Gunthorpe
13*7c5b184dSJason Gunthorpe /* Compute a */
14*7c5b184dSJason Gunthorpe #define log2_to_int_t(type, a_lg2) ((type)(((type)1) << (a_lg2)))
15*7c5b184dSJason Gunthorpe static_assert(log2_to_int_t(unsigned int, 0) == 1);
16*7c5b184dSJason Gunthorpe
17*7c5b184dSJason Gunthorpe /* Compute a - 1 (aka all low bits set) */
18*7c5b184dSJason Gunthorpe #define log2_to_max_int_t(type, a_lg2) ((type)(log2_to_int_t(type, a_lg2) - 1))
19*7c5b184dSJason Gunthorpe
20*7c5b184dSJason Gunthorpe /* Compute a / b */
21*7c5b184dSJason Gunthorpe #define log2_div_t(type, a, b_lg2) ((type)(((type)a) >> (b_lg2)))
22*7c5b184dSJason Gunthorpe static_assert(log2_div_t(unsigned int, 4, 2) == 1);
23*7c5b184dSJason Gunthorpe
24*7c5b184dSJason Gunthorpe /*
25*7c5b184dSJason Gunthorpe * Compute:
26*7c5b184dSJason Gunthorpe * a / c == b / c
27*7c5b184dSJason Gunthorpe * aka the high bits are equal
28*7c5b184dSJason Gunthorpe */
29*7c5b184dSJason Gunthorpe #define log2_div_eq_t(type, a, b, c_lg2) \
30*7c5b184dSJason Gunthorpe (log2_div_t(type, (a) ^ (b), c_lg2) == 0)
31*7c5b184dSJason Gunthorpe static_assert(log2_div_eq_t(unsigned int, 1, 1, 2));
32*7c5b184dSJason Gunthorpe
33*7c5b184dSJason Gunthorpe /* Compute a % b */
34*7c5b184dSJason Gunthorpe #define log2_mod_t(type, a, b_lg2) \
35*7c5b184dSJason Gunthorpe ((type)(((type)a) & log2_to_max_int_t(type, b_lg2)))
36*7c5b184dSJason Gunthorpe static_assert(log2_mod_t(unsigned int, 1, 2) == 1);
37*7c5b184dSJason Gunthorpe
38*7c5b184dSJason Gunthorpe /*
39*7c5b184dSJason Gunthorpe * Compute:
40*7c5b184dSJason Gunthorpe * a % b == b - 1
41*7c5b184dSJason Gunthorpe * aka the low bits are all 1s
42*7c5b184dSJason Gunthorpe */
43*7c5b184dSJason Gunthorpe #define log2_mod_eq_max_t(type, a, b_lg2) \
44*7c5b184dSJason Gunthorpe (log2_mod_t(type, a, b_lg2) == log2_to_max_int_t(type, b_lg2))
45*7c5b184dSJason Gunthorpe static_assert(log2_mod_eq_max_t(unsigned int, 3, 2));
46*7c5b184dSJason Gunthorpe
47*7c5b184dSJason Gunthorpe /*
48*7c5b184dSJason Gunthorpe * Return a value such that:
49*7c5b184dSJason Gunthorpe * a / b == ret / b
50*7c5b184dSJason Gunthorpe * ret % b == val
51*7c5b184dSJason Gunthorpe * aka set the low bits to val. val must be < b
52*7c5b184dSJason Gunthorpe */
53*7c5b184dSJason Gunthorpe #define log2_set_mod_t(type, a, val, b_lg2) \
54*7c5b184dSJason Gunthorpe ((((type)(a)) & (~log2_to_max_int_t(type, b_lg2))) | ((type)(val)))
55*7c5b184dSJason Gunthorpe static_assert(log2_set_mod_t(unsigned int, 3, 1, 2) == 1);
56*7c5b184dSJason Gunthorpe
57*7c5b184dSJason Gunthorpe /* Return a value such that:
58*7c5b184dSJason Gunthorpe * a / b == ret / b
59*7c5b184dSJason Gunthorpe * ret % b == b - 1
60*7c5b184dSJason Gunthorpe * aka set the low bits to all 1s
61*7c5b184dSJason Gunthorpe */
62*7c5b184dSJason Gunthorpe #define log2_set_mod_max_t(type, a, b_lg2) \
63*7c5b184dSJason Gunthorpe (((type)(a)) | log2_to_max_int_t(type, b_lg2))
64*7c5b184dSJason Gunthorpe static_assert(log2_set_mod_max_t(unsigned int, 2, 2) == 3);
65*7c5b184dSJason Gunthorpe
66*7c5b184dSJason Gunthorpe /* Compute a * b */
67*7c5b184dSJason Gunthorpe #define log2_mul_t(type, a, b_lg2) ((type)(((type)a) << (b_lg2)))
68*7c5b184dSJason Gunthorpe static_assert(log2_mul_t(unsigned int, 2, 2) == 8);
69*7c5b184dSJason Gunthorpe
70*7c5b184dSJason Gunthorpe #define _dispatch_sz(type, fn, a) \
71*7c5b184dSJason Gunthorpe (sizeof(type) == 4 ? fn##32((u32)a) : fn##64(a))
72*7c5b184dSJason Gunthorpe
73*7c5b184dSJason Gunthorpe /*
74*7c5b184dSJason Gunthorpe * Return the highest value such that:
75*7c5b184dSJason Gunthorpe * fls_t(u32, 0) == 0
76*7c5b184dSJason Gunthorpe * fls_t(u3, 1) == 1
77*7c5b184dSJason Gunthorpe * a >= log2_to_int(ret - 1)
78*7c5b184dSJason Gunthorpe * aka find last set bit
79*7c5b184dSJason Gunthorpe */
fls32(u32 a)80*7c5b184dSJason Gunthorpe static inline unsigned int fls32(u32 a)
81*7c5b184dSJason Gunthorpe {
82*7c5b184dSJason Gunthorpe return fls(a);
83*7c5b184dSJason Gunthorpe }
84*7c5b184dSJason Gunthorpe #define fls_t(type, a) _dispatch_sz(type, fls, a)
85*7c5b184dSJason Gunthorpe
86*7c5b184dSJason Gunthorpe /*
87*7c5b184dSJason Gunthorpe * Return the highest value such that:
88*7c5b184dSJason Gunthorpe * ffs_t(u32, 0) == UNDEFINED
89*7c5b184dSJason Gunthorpe * ffs_t(u32, 1) == 0
90*7c5b184dSJason Gunthorpe * log_mod(a, ret) == 0
91*7c5b184dSJason Gunthorpe * aka find first set bit
92*7c5b184dSJason Gunthorpe */
__ffs32(u32 a)93*7c5b184dSJason Gunthorpe static inline unsigned int __ffs32(u32 a)
94*7c5b184dSJason Gunthorpe {
95*7c5b184dSJason Gunthorpe return __ffs(a);
96*7c5b184dSJason Gunthorpe }
97*7c5b184dSJason Gunthorpe #define ffs_t(type, a) _dispatch_sz(type, __ffs, a)
98*7c5b184dSJason Gunthorpe
99*7c5b184dSJason Gunthorpe /*
100*7c5b184dSJason Gunthorpe * Return the highest value such that:
101*7c5b184dSJason Gunthorpe * ffz_t(u32, U32_MAX) == UNDEFINED
102*7c5b184dSJason Gunthorpe * ffz_t(u32, 0) == 0
103*7c5b184dSJason Gunthorpe * ffz_t(u32, 1) == 1
104*7c5b184dSJason Gunthorpe * log_mod(a, ret) == log_to_max_int(ret)
105*7c5b184dSJason Gunthorpe * aka find first zero bit
106*7c5b184dSJason Gunthorpe */
ffz32(u32 a)107*7c5b184dSJason Gunthorpe static inline unsigned int ffz32(u32 a)
108*7c5b184dSJason Gunthorpe {
109*7c5b184dSJason Gunthorpe return ffz(a);
110*7c5b184dSJason Gunthorpe }
ffz64(u64 a)111*7c5b184dSJason Gunthorpe static inline unsigned int ffz64(u64 a)
112*7c5b184dSJason Gunthorpe {
113*7c5b184dSJason Gunthorpe if (sizeof(u64) == sizeof(unsigned long))
114*7c5b184dSJason Gunthorpe return ffz(a);
115*7c5b184dSJason Gunthorpe
116*7c5b184dSJason Gunthorpe if ((u32)a == U32_MAX)
117*7c5b184dSJason Gunthorpe return ffz32(a >> 32) + 32;
118*7c5b184dSJason Gunthorpe return ffz32(a);
119*7c5b184dSJason Gunthorpe }
120*7c5b184dSJason Gunthorpe #define ffz_t(type, a) _dispatch_sz(type, ffz, a)
121*7c5b184dSJason Gunthorpe
122*7c5b184dSJason Gunthorpe #endif
123