aboutsummaryrefslogtreecommitdiff
path: root/riscv/arith.h
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/arith.h')
-rw-r--r--riscv/arith.h21
1 files changed, 21 insertions, 0 deletions
diff --git a/riscv/arith.h b/riscv/arith.h
index 3b807e9..20b1504 100644
--- a/riscv/arith.h
+++ b/riscv/arith.h
@@ -7,6 +7,7 @@
#include <cstdint>
#include <climits>
#include <cstddef>
+#include <type_traits>
inline uint64_t mulhu(uint64_t a, uint64_t b)
{
@@ -221,4 +222,24 @@ static inline uint64_t xperm(uint64_t rs1, uint64_t rs2, size_t sz_log2, size_t
return r;
}
+// Rotates right an unsigned integer by the given number of bits.
+template <typename T>
+static inline T rotate_right(T x, std::size_t shiftamt) {
+ static_assert(std::is_unsigned<T>::value);
+ static constexpr T mask = (8 * sizeof(T)) - 1;
+ const std::size_t rshift = shiftamt & mask;
+ const std::size_t lshift = (-rshift) & mask;
+ return (x << lshift) | (x >> rshift);
+}
+
+// Rotates right an unsigned integer by the given number of bits.
+template <typename T>
+static inline T rotate_left(T x, std::size_t shiftamt) {
+ static_assert(std::is_unsigned<T>::value);
+ static constexpr T mask = (8 * sizeof(T)) - 1;
+ const std::size_t lshift = shiftamt & mask;
+ const std::size_t rshift = (-lshift) & mask;
+ return (x << lshift) | (x >> rshift);
+}
+
#endif