diff options
Diffstat (limited to 'riscv/arith.h')
-rw-r--r-- | riscv/arith.h | 21 |
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 |