diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2023-11-22 18:29:39 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2023-11-23 15:50:35 +0100 |
commit | dde1c3e59b88a74a2eb85e9874384936ae20cb57 (patch) | |
tree | 06fc76c2535ddae56085ef42b8888d7adb14eef7 /arch/riscv | |
parent | 2376924e24c003def53712d91524f8ffaa6903e7 (diff) | |
download | barebox-dde1c3e59b88a74a2eb85e9874384936ae20cb57.tar.gz barebox-dde1c3e59b88a74a2eb85e9874384936ae20cb57.tar.xz |
include: import Linux word-at-a-time.h
The Linux <linux/word-at-a-time.h> interface is used to optimize
searching for bytes in strings by doing word-size comparisons. This will
be used in the implementation of strscpy in a follow-up commit, so
import the generic version here.
A good overview on the interface is available at LWN[1]. Note that
it discuss Linux v3.5. The asm-generic version imported here works
also on little-endian and not only big-endian[2].
[1]: https://lwn.net/Articles/501492/
[2]: Linux kernel commit a6e2f029ae34 ("Make asm/word-at-a-time.h
available on all architectures").
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Link: https://lore.barebox.org/20231122172951.376531-9-a.fatoum@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/riscv')
-rw-r--r-- | arch/riscv/include/asm/word-at-a-time.h | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/arch/riscv/include/asm/word-at-a-time.h b/arch/riscv/include/asm/word-at-a-time.h new file mode 100644 index 0000000000..74f077d38f --- /dev/null +++ b/arch/riscv/include/asm/word-at-a-time.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2012 Regents of the University of California + * + * Derived from arch/x86/include/asm/word-at-a-time.h + */ + +#ifndef _ASM_RISCV_WORD_AT_A_TIME_H +#define _ASM_RISCV_WORD_AT_A_TIME_H + + +#include <linux/kernel.h> +#include <linux/bitops.h> + +struct word_at_a_time { + const unsigned long one_bits, high_bits; +}; + +#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) } + +static inline unsigned long has_zero(unsigned long val, + unsigned long *bits, const struct word_at_a_time *c) +{ + unsigned long mask = ((val - c->one_bits) & ~val) & c->high_bits; + *bits = mask; + return mask; +} + +static inline unsigned long prep_zero_mask(unsigned long val, + unsigned long bits, const struct word_at_a_time *c) +{ + return bits; +} + +static inline unsigned long create_zero_mask(unsigned long bits) +{ + bits = (bits - 1) & ~bits; + return bits >> 7; +} + +static inline unsigned long find_zero(unsigned long mask) +{ + return fls64(mask) >> 3; +} + +/* The mask we created is directly usable as a bytemask */ +#define zero_bytemask(mask) (mask) + +#endif /* _ASM_RISCV_WORD_AT_A_TIME_H */ |