diff options
Diffstat (limited to 'core/bit_access.hpp')
-rw-r--r-- | core/bit_access.hpp | 38 |
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 |