summaryrefslogtreecommitdiff
path: root/core/bit_access.hpp
blob: 566254e4edf8ab43666af69646afba95eaaa29ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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