diff options
author | Jan Huwald <jh@sotun.de> | 2012-05-07 20:01:51 (GMT) |
---|---|---|
committer | Jan Huwald <jh@sotun.de> | 2012-05-07 20:01:51 (GMT) |
commit | 420d2ef464d4a741028e132e662d5626806a41f5 (patch) | |
tree | 1aca6eb512e4ed0fb5f3c10c528cb998b6ffd695 /core/bit_access.hpp |
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 |