xenium
Loading...
Searching...
No Matches
utils.hpp
1//
2// Copyright (c) 2018-2020 Manuel Pöter.
3// Licensed under the MIT License. See LICENSE file in the project root for full license information.
4//
5
6#ifndef XENIUM_UTILS_HPP
7#define XENIUM_UTILS_HPP
8
9#include <cstdint>
10#ifdef _M_AMD64
11#include <intrin.h>
12#endif
13
14namespace xenium { namespace utils {
15 template <typename T>
16 constexpr bool is_power_of_two(T val) {
17 return (val & (val - 1)) == 0;
18 }
19
20 template <typename T>
21 constexpr unsigned find_last_bit_set(T val) {
22 unsigned result = 0;
23 for (; val != 0; val >>= 1)
24 ++result;
25 return result;
26 }
27
28 template <typename T>
29 constexpr T next_power_of_two(T val)
30 {
31 if (is_power_of_two(val))
32 return val;
33
34 return static_cast<T>(1) << find_last_bit_set(val);
35 }
36
37 template <typename T>
38 struct modulo {
39 T operator()(T a, T b) { return a % b; }
40 };
41
42 // TODO - use intrinsics for rotate operation (if available)
43 template <uintptr_t C>
44 struct rotate {
45 static uintptr_t left(uintptr_t v) {
46 static_assert(C > 0, "should never happen!");
47 return (v >> (64 - C)) | (v << C);
48 }
49
50 static uintptr_t right(uintptr_t v) {
51 static_assert(C > 0, "should never happen!");
52 return (v >> C) | (v << (64 - C));
53 }
54 };
55
56 template <>
57 struct rotate<0> {
58 static uintptr_t left(uintptr_t v) { return v; }
59 static uintptr_t right(uintptr_t v) { return v; }
60 };
61
62#if defined(__sparc__)
63 static inline std::uint64_t getticks(void) {
64 std::uint64_t ret;
65 __asm__("rd %%tick, %0" : "=r" (ret));
66 return ret;
67 }
68#elif defined(__x86_64__)
69 static inline std::uint64_t getticks(void) {
70 std::uint32_t hi, lo;
71 __asm__ ("rdtsc" : "=a"(lo), "=d"(hi));
72 return (static_cast<std::uint64_t>(hi) << 32) | static_cast<std::uint64_t>(lo);
73 }
74#elif defined(_M_AMD64)
75 static inline std::uint64_t getticks(void) {
76 return __rdtsc();
77 }
78#else
79 // TODO - add support for more compilers!
80 #error "Unsupported compiler"
81#endif
82
83 inline std::uint64_t random() {
84 return getticks() >> 4;
85 }
86}}
87#endif