-
Notifications
You must be signed in to change notification settings - Fork 1
/
bit_tools.h
96 lines (84 loc) · 3.57 KB
/
bit_tools.h
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#ifndef BIT_TOOLS_H
#define BIT_TOOLS_H
#include <cstdint>
template<typename T>
constexpr T GenMask(int size, int shift) {
T mask = 0;
for (int i = 0; i < size; ++i) {
mask = (mask << 1) | 1;
}
return mask << shift;
}
template<typename T>
T SetBit(T data, int value, int pos) {
if (value) {
return data | ((T)1 << pos);
} else {
return data & ~((T)1 << pos);
}
}
namespace {
uint64_t mask[] = {0x0, 0x01, 0x03, 0x07, 0x0F,
0x01F, 0x03F, 0x07F, 0x0FF, 0x01FF,
0x03FF, 0x07FF, 0x0FFF, 0x01FFF, 0x03FFF,
0x07FFF, 0x0FFFF, 0x01FFFF, 0x03FFFF, 0x07FFFF,
0x0FFFFF, 0x01FFFFF, 0x03FFFFF, 0x07FFFFF, 0x0FFFFFF,
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
0x01FFFFFFF, 0x03FFFFFFF, 0x07FFFFFFF, 0x0FFFFFFFF,
0x01FFFFFFFF, 0x03FFFFFFFF, 0x07FFFFFFFF, 0x0FFFFFFFFF,
0x01FFFFFFFFF, 0x03FFFFFFFFF, 0x07FFFFFFFFF, 0x0FFFFFFFFFF,
0x01FFFFFFFFFF, 0x03FFFFFFFFFF, 0x07FFFFFFFFFF, 0x0FFFFFFFFFFF,
0x01FFFFFFFFFFF, 0x03FFFFFFFFFFF, 0x07FFFFFFFFFFF, 0x0FFFFFFFFFFFF,
0x01FFFFFFFFFFFF, 0x03FFFFFFFFFFFF, 0x07FFFFFFFFFFFF, 0x0FFFFFFFFFFFFF,
0x01FFFFFFFFFFFFF, 0x03FFFFFFFFFFFFF, 0x07FFFFFFFFFFFFF, 0x0FFFFFFFFFFFFFF,
0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF, 0x0FFFFFFFFFFFFFFF,
0x01FFFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
};
uint64_t sign_mask[] = {
0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFF8, 0xFFFFFFFFFFFFFFF0,
0xFFFFFFFFFFFFFFE0, 0xFFFFFFFFFFFFFFC0, 0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFF00,
0xFFFFFFFFFFFFFE00, 0xFFFFFFFFFFFFFC00, 0xFFFFFFFFFFFFF800, 0xFFFFFFFFFFFFF000,
0xFFFFFFFFFFFFE000, 0xFFFFFFFFFFFFC000, 0xFFFFFFFFFFFF8000, 0xFFFFFFFFFFFF0000,
0xFFFFFFFFFFFE0000, 0xFFFFFFFFFFFC0000, 0xFFFFFFFFFFF80000, 0xFFFFFFFFFFF00000,
0xFFFFFFFFFFE00000, 0xFFFFFFFFFFC00000, 0xFFFFFFFFFF800000, 0xFFFFFFFFFF000000,
0xFFFFFFFFFE000000, 0xFFFFFFFFFC000000, 0xFFFFFFFFF8000000, 0xFFFFFFFFF0000000,
0xFFFFFFFFE0000000, 0xFFFFFFFFC0000000, 0xFFFFFFFF80000000, 0xFFFFFFFF00000000,
0xFFFFFFFE00000000, 0xFFFFFFFC00000000, 0xFFFFFFF800000000, 0xFFFFFFF000000000,
0xFFFFFFE000000000, 0xFFFFFFC000000000, 0xFFFFFF8000000000, 0xFFFFFF0000000000,
0xFFFFFE0000000000, 0xFFFFFC0000000000, 0xFFFFF80000000000, 0xFFFFF00000000000,
0xFFFFE00000000000, 0xFFFFC00000000000, 0xFFFF800000000000, 0xFFFF000000000000,
0xFFFE000000000000, 0xFFFC000000000000, 0xFFF8000000000000, 0xFFF0000000000000,
0xFFE0000000000000, 0xFFC0000000000000, 0xFF80000000000000, 0xFF00000000000000,
0xFE00000000000000, 0xFC00000000000000, 0xF800000000000000, 0xF000000000000000,
0xE000000000000000, 0xC000000000000000, 0x8000000000000000, 0x0000000000000000,
};
}
template<class T>
T BitShift(T val, int width, int offset, int distpos){
val >>= offset;
val &= mask[width];
val <<= distpos;
return val;
}
template<class T>
T bitcrop(const T& val, const int width, const int offset) {
T target_bits = val >> offset;
target_bits &= mask[width];
return target_bits;
}
template<class T>
T SignExtend(T value, int width){
if ((value >> (width - 1)) & 1) {
value |= sign_mask[width - 1];
} else {
value &= ~sign_mask[width - 1];
}
return value;
}
template<class T>
T bitset(const T& reg, const int width, const int offset, const T& val) {
T new_reg = reg & (~mask[width + offset] | mask[offset]);
new_reg |= (val & mask[width]) << offset;
return new_reg;
}
#endif // BIT_TOOLS_H