|
@@ -0,0 +1,31 @@
|
|
1
|
+#ifndef _BITS_STRINGS_H
|
|
2
|
+#define _BITS_STRINGS_H
|
|
3
|
+
|
|
4
|
+FILE_LICENCE ( GPL2_OR_LATER );
|
|
5
|
+
|
|
6
|
+/**
|
|
7
|
+ * Find last (i.e. most significant) set bit
|
|
8
|
+ *
|
|
9
|
+ * @v value Value
|
|
10
|
+ * @ret msb Most significant bit set in value (LSB=1), or zero
|
|
11
|
+ */
|
|
12
|
+static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
|
|
13
|
+ long msb_minus_one;
|
|
14
|
+
|
|
15
|
+ /* If the input value is zero, the BSR instruction returns
|
|
16
|
+ * ZF=1 and leaves an undefined value in the output register.
|
|
17
|
+ * Perform this check in C rather than asm so that it can be
|
|
18
|
+ * omitted in cases where the compiler is able to prove that
|
|
19
|
+ * the input is non-zero.
|
|
20
|
+ */
|
|
21
|
+ if ( value ) {
|
|
22
|
+ __asm__ ( "bsr %1, %0"
|
|
23
|
+ : "=r" ( msb_minus_one )
|
|
24
|
+ : "rm" ( value ) );
|
|
25
|
+ return ( msb_minus_one + 1 );
|
|
26
|
+ } else {
|
|
27
|
+ return 0;
|
|
28
|
+ }
|
|
29
|
+}
|
|
30
|
+
|
|
31
|
+#endif /* _BITS_STRINGS_H */
|