Browse Source

[libc] Add inline assembly implementation of flsl() using BSR instruction

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
dce7107fc0
3 changed files with 33 additions and 15 deletions
  1. 31
    0
      src/arch/x86/include/bits/strings.h
  2. 0
    13
      src/core/bitops.c
  3. 2
    2
      src/include/strings.h

+ 31
- 0
src/arch/x86/include/bits/strings.h View File

@@ -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 */

+ 0
- 13
src/core/bitops.c View File

@@ -1,13 +0,0 @@
1
-#include <strings.h>
2
-
3
-FILE_LICENCE ( GPL2_OR_LATER );
4
-
5
-int __flsl ( long x ) {
6
-	unsigned long value = x;
7
-	int ls = 0;
8
-
9
-	for ( ls = 0 ; value ; ls++ ) {
10
-		value >>= 1;
11
-	}
12
-	return ls;
13
-}

+ 2
- 2
src/include/strings.h View File

@@ -5,6 +5,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
5 5
 
6 6
 #include <limits.h>
7 7
 #include <string.h>
8
+#include <bits/strings.h>
8 9
 
9 10
 static inline __attribute__ (( always_inline )) int
10 11
 __constant_flsl ( unsigned long x ) {
@@ -42,8 +43,7 @@ __constant_flsl ( unsigned long x ) {
42 43
 	return r;
43 44
 }
44 45
 
45
-/* We don't actually have these functions yet */
46
-extern int __flsl ( long x );
46
+int __flsl ( long x );
47 47
 
48 48
 #define flsl( x ) \
49 49
 	( __builtin_constant_p ( x ) ? __constant_flsl ( x ) : __flsl ( x ) )

Loading…
Cancel
Save