Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 277463
b: refs/heads/master
c: ca3d30c
h: refs/heads/master
i:
  277461: ce86580
  277459: 5c4d665
  277455: 412af8c
v: v3
  • Loading branch information
David Howells authored and H. Peter Anvin committed Dec 15, 2011
1 parent 822b76f commit 17fd15f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 83d99df7c4bf37176d8c7b199e3b129a51fa04c8
refs/heads/master: ca3d30cc02f780f68771087040ce935add6ba2b7
67 changes: 62 additions & 5 deletions trunk/arch/x86/include/asm/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,10 +397,25 @@ static inline unsigned long __fls(unsigned long word)
static inline int ffs(int x)
{
int r;
#ifdef CONFIG_X86_CMOV

#ifdef CONFIG_X86_64
/*
* AMD64 says BSFL won't clobber the dest reg if x==0; Intel64 says the
* dest reg is undefined if x==0, but their CPU architect says its
* value is written to set it to the same as before, except that the
* top 32 bits will be cleared.
*
* We cannot do this on 32 bits because at the very least some
* 486 CPUs did not behave this way.
*/
long tmp = -1;
asm("bsfl %1,%0"
: "=r" (r)
: "rm" (x), "0" (tmp));
#elif defined(CONFIG_X86_CMOV)
asm("bsfl %1,%0\n\t"
"cmovzl %2,%0"
: "=r" (r) : "rm" (x), "r" (-1));
: "=&r" (r) : "rm" (x), "r" (-1));
#else
asm("bsfl %1,%0\n\t"
"jnz 1f\n\t"
Expand All @@ -424,7 +439,22 @@ static inline int ffs(int x)
static inline int fls(int x)
{
int r;
#ifdef CONFIG_X86_CMOV

#ifdef CONFIG_X86_64
/*
* AMD64 says BSRL won't clobber the dest reg if x==0; Intel64 says the
* dest reg is undefined if x==0, but their CPU architect says its
* value is written to set it to the same as before, except that the
* top 32 bits will be cleared.
*
* We cannot do this on 32 bits because at the very least some
* 486 CPUs did not behave this way.
*/
long tmp = -1;
asm("bsrl %1,%0"
: "=r" (r)
: "rm" (x), "0" (tmp));
#elif defined(CONFIG_X86_CMOV)
asm("bsrl %1,%0\n\t"
"cmovzl %2,%0"
: "=&r" (r) : "rm" (x), "rm" (-1));
Expand All @@ -437,6 +467,35 @@ static inline int fls(int x)
return r + 1;
}

/**
* fls64 - find last set bit in a 64-bit word
* @x: the word to search
*
* This is defined in a similar way as the libc and compiler builtin
* ffsll, but returns the position of the most significant set bit.
*
* fls64(value) returns 0 if value is 0 or the position of the last
* set bit if value is nonzero. The last (most significant) bit is
* at position 64.
*/
#ifdef CONFIG_X86_64
static __always_inline int fls64(__u64 x)
{
long bitpos = -1;
/*
* AMD64 says BSRQ won't clobber the dest reg if x==0; Intel64 says the
* dest reg is undefined if x==0, but their CPU architect says its
* value is written to set it to the same as before.
*/
asm("bsrq %1,%0"
: "+r" (bitpos)
: "rm" (x));
return bitpos + 1;
}
#else
#include <asm-generic/bitops/fls64.h>
#endif

#include <asm-generic/bitops/find.h>

#include <asm-generic/bitops/sched.h>
Expand All @@ -447,8 +506,6 @@ static inline int fls(int x)

#include <asm-generic/bitops/const_hweight.h>

#include <asm-generic/bitops/fls64.h>

#include <asm-generic/bitops/le.h>

#include <asm-generic/bitops/ext2-atomic-setbit.h>
Expand Down

0 comments on commit 17fd15f

Please sign in to comment.