|
@@ -254,25 +254,59 @@ static inline int constant_fls(int x)
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * On ARMv5 and above those functions can be implemented around
|
|
|
|
- * the clz instruction for much better code efficiency.
|
|
|
|
|
|
+ * On ARMv5 and above those functions can be implemented around the
|
|
|
|
+ * clz instruction for much better code efficiency. __clz returns
|
|
|
|
+ * the number of leading zeros, zero input will return 32, and
|
|
|
|
+ * 0x80000000 will return 0.
|
|
*/
|
|
*/
|
|
|
|
+static inline unsigned int __clz(unsigned int x)
|
|
|
|
+{
|
|
|
|
+ unsigned int ret;
|
|
|
|
+
|
|
|
|
+ asm("clz\t%0, %1" : "=r" (ret) : "r" (x));
|
|
|
|
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * fls() returns zero if the input is zero, otherwise returns the bit
|
|
|
|
+ * position of the last set bit, where the LSB is 1 and MSB is 32.
|
|
|
|
+ */
|
|
static inline int fls(int x)
|
|
static inline int fls(int x)
|
|
{
|
|
{
|
|
- int ret;
|
|
|
|
-
|
|
|
|
if (__builtin_constant_p(x))
|
|
if (__builtin_constant_p(x))
|
|
return constant_fls(x);
|
|
return constant_fls(x);
|
|
|
|
|
|
- asm("clz\t%0, %1" : "=r" (ret) : "r" (x));
|
|
|
|
- ret = 32 - ret;
|
|
|
|
- return ret;
|
|
|
|
|
|
+ return 32 - __clz(x);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * __fls() returns the bit position of the last bit set, where the
|
|
|
|
+ * LSB is 0 and MSB is 31. Zero input is undefined.
|
|
|
|
+ */
|
|
|
|
+static inline unsigned long __fls(unsigned long x)
|
|
|
|
+{
|
|
|
|
+ return fls(x) - 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * ffs() returns zero if the input was zero, otherwise returns the bit
|
|
|
|
+ * position of the first set bit, where the LSB is 1 and MSB is 32.
|
|
|
|
+ */
|
|
|
|
+static inline int ffs(int x)
|
|
|
|
+{
|
|
|
|
+ return fls(x & -x);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * __ffs() returns the bit position of the first bit set, where the
|
|
|
|
+ * LSB is 0 and MSB is 31. Zero input is undefined.
|
|
|
|
+ */
|
|
|
|
+static inline unsigned long __ffs(unsigned long x)
|
|
|
|
+{
|
|
|
|
+ return ffs(x) - 1;
|
|
}
|
|
}
|
|
|
|
|
|
-#define __fls(x) (fls(x) - 1)
|
|
|
|
-#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
|
|
|
|
-#define __ffs(x) (ffs(x) - 1)
|
|
|
|
#define ffz(x) __ffs( ~(x) )
|
|
#define ffz(x) __ffs( ~(x) )
|
|
|
|
|
|
#endif
|
|
#endif
|