summaryrefslogtreecommitdiffstats
path: root/arch/riscv
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2023-11-22 18:29:39 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2023-11-23 15:50:35 +0100
commitdde1c3e59b88a74a2eb85e9874384936ae20cb57 (patch)
tree06fc76c2535ddae56085ef42b8888d7adb14eef7 /arch/riscv
parent2376924e24c003def53712d91524f8ffaa6903e7 (diff)
downloadbarebox-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.h49
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 */