mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-14 09:52:27 -05:00
Merge tag 'x86_asm_for_v6.1_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 asm update from Borislav Petkov: - Use the __builtin_ffs/ctzl() compiler builtins for the constant argument case in the kernel's optimized ffs()/ffz() helpers in order to make use of the compiler's constant folding optmization passes. * tag 'x86_asm_for_v6.1_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/asm/bitops: Use __builtin_ctzl() to evaluate constant expressions x86/asm/bitops: Use __builtin_ffs() to evaluate constant expressions
This commit is contained in:
@@ -247,17 +247,30 @@ arch_test_bit_acquire(unsigned long nr, const volatile unsigned long *addr)
|
||||
variable_test_bit(nr, addr);
|
||||
}
|
||||
|
||||
static __always_inline unsigned long variable__ffs(unsigned long word)
|
||||
{
|
||||
asm("rep; bsf %1,%0"
|
||||
: "=r" (word)
|
||||
: "rm" (word));
|
||||
return word;
|
||||
}
|
||||
|
||||
/**
|
||||
* __ffs - find first set bit in word
|
||||
* @word: The word to search
|
||||
*
|
||||
* Undefined if no bit exists, so code should check against 0 first.
|
||||
*/
|
||||
static __always_inline unsigned long __ffs(unsigned long word)
|
||||
#define __ffs(word) \
|
||||
(__builtin_constant_p(word) ? \
|
||||
(unsigned long)__builtin_ctzl(word) : \
|
||||
variable__ffs(word))
|
||||
|
||||
static __always_inline unsigned long variable_ffz(unsigned long word)
|
||||
{
|
||||
asm("rep; bsf %1,%0"
|
||||
: "=r" (word)
|
||||
: "rm" (word));
|
||||
: "r" (~word));
|
||||
return word;
|
||||
}
|
||||
|
||||
@@ -267,13 +280,10 @@ static __always_inline unsigned long __ffs(unsigned long word)
|
||||
*
|
||||
* Undefined if no zero exists, so code should check against ~0UL first.
|
||||
*/
|
||||
static __always_inline unsigned long ffz(unsigned long word)
|
||||
{
|
||||
asm("rep; bsf %1,%0"
|
||||
: "=r" (word)
|
||||
: "r" (~word));
|
||||
return word;
|
||||
}
|
||||
#define ffz(word) \
|
||||
(__builtin_constant_p(word) ? \
|
||||
(unsigned long)__builtin_ctzl(~word) : \
|
||||
variable_ffz(word))
|
||||
|
||||
/*
|
||||
* __fls: find last set bit in word
|
||||
@@ -292,18 +302,7 @@ static __always_inline unsigned long __fls(unsigned long word)
|
||||
#undef ADDR
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/**
|
||||
* ffs - find first set bit in word
|
||||
* @x: the word to search
|
||||
*
|
||||
* This is defined the same way as the libc and compiler builtin ffs
|
||||
* routines, therefore differs in spirit from the other bitops.
|
||||
*
|
||||
* ffs(value) returns 0 if value is 0 or the position of the first
|
||||
* set bit if value is nonzero. The first (least significant) bit
|
||||
* is at position 1.
|
||||
*/
|
||||
static __always_inline int ffs(int x)
|
||||
static __always_inline int variable_ffs(int x)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -333,6 +332,19 @@ static __always_inline int ffs(int x)
|
||||
return r + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ffs - find first set bit in word
|
||||
* @x: the word to search
|
||||
*
|
||||
* This is defined the same way as the libc and compiler builtin ffs
|
||||
* routines, therefore differs in spirit from the other bitops.
|
||||
*
|
||||
* ffs(value) returns 0 if value is 0 or the position of the first
|
||||
* set bit if value is nonzero. The first (least significant) bit
|
||||
* is at position 1.
|
||||
*/
|
||||
#define ffs(x) (__builtin_constant_p(x) ? __builtin_ffs(x) : variable_ffs(x))
|
||||
|
||||
/**
|
||||
* fls - find last set bit in word
|
||||
* @x: the word to search
|
||||
|
||||
Reference in New Issue
Block a user