diff options
author | 2023-10-06 15:42:41 +0200 | |
---|---|---|
committer | 2023-10-16 13:04:09 +0200 | |
commit | 76292d7243f809486ec26dd6cd3436dbcb9e5319 (patch) | |
tree | ed94521d81a64c9e2e17d68da82a0b800516d1cb | |
parent | s390/extable: reduce number of extable macros (diff) | |
download | linux-76292d7243f809486ec26dd6cd3436dbcb9e5319.tar.gz linux-76292d7243f809486ec26dd6cd3436dbcb9e5319.tar.bz2 linux-76292d7243f809486ec26dd6cd3436dbcb9e5319.zip |
s390: provide word-at-a-time implementation
Provide an s390 specific word-at-a-time implementation. Compared to the
generic variant the generated code for has_zero() is slightly
better. However find_zero() is much simpler since it reuses the result
of __fls() aka flogr() and now comes without any conditional branches,
while the generic variant has three of them.
Reviewed-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
-rw-r--r-- | arch/s390/include/asm/word-at-a-time.h | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/arch/s390/include/asm/word-at-a-time.h b/arch/s390/include/asm/word-at-a-time.h new file mode 100644 index 000000000000..09b37541a175 --- /dev/null +++ b/arch/s390/include/asm/word-at-a-time.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_WORD_AT_A_TIME_H +#define _ASM_WORD_AT_A_TIME_H + +#include <linux/kernel.h> +#include <asm/bitsperlong.h> + +struct word_at_a_time { + const unsigned long bits; +}; + +#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x7f) } + +static inline unsigned long prep_zero_mask(unsigned long val, unsigned long data, const struct word_at_a_time *c) +{ + return data; +} + +static inline unsigned long create_zero_mask(unsigned long data) +{ + return __fls(data); +} + +static inline unsigned long find_zero(unsigned long data) +{ + return (data ^ (BITS_PER_LONG - 1)) >> 3; +} + +static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) +{ + unsigned long mask = (val & c->bits) + c->bits; + + *data = ~(mask | val | c->bits); + return *data; +} + +static inline unsigned long zero_bytemask(unsigned long data) +{ + return ~1UL << data; +} + +#endif /* _ASM_WORD_AT_A_TIME_H */ |