summaryrefslogtreecommitdiff
path: root/core/bit_access.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/bit_access.hpp')
-rw-r--r--core/bit_access.hpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/core/bit_access.hpp b/core/bit_access.hpp
new file mode 100644
index 0000000..566254e
--- /dev/null
+++ b/core/bit_access.hpp
@@ -0,0 +1,38 @@
+#ifndef vjxaugYoBtZu5XZVahcafy1l5XU
+#define vjxaugYoBtZu5XZVahcafy1l5XU
+
+#include <inttypes.h>
+#include <assert.h>
+
+#include "template_helpers.hpp"
+
+inline uint8_t bit_extract(void *base, uint8_t width, uint64_t id) {
+ assert(width < 8);
+
+ uint8_t off, mask, block, result, *addr;
+
+ addr = ((uint8_t*) base) + (id * width / 8);
+ off = (id % (8 / width)) * width;
+ mask = (~((~0) << width)) << off;
+ block = * addr;
+ result = (block & mask) >> off;
+
+ return result;
+}
+
+template<class T>
+inline void bit_insert(void *base, uint8_t width, uint64_t id, T rawValue) {
+ assert(width < 8);
+
+ uint8_t off, mask, block, result, *addr;
+ uint8_t value(FORCE_CONV(uint8_t, rawValue));
+
+ addr = ((uint8_t*) base) + (id * width / 8);
+ off = (id % (8 / width)) * width;
+ mask = (~((~0) << width)) << off;
+ block = * addr;
+ result = (block & (~mask)) | ((value << off) & mask); // mask also value, in case it is larger than allowed
+ *addr = result;
+}
+
+#endif // vjxaugYoBtZu5XZVahcafy1l5XU
contact: Jan Huwald // Impressum