1 #pragma once
2
3 #include "Platform.h"
4
5 #include <vector>
6
7 //-----------------------------------------------------------------------------
8
9 void printbits ( const void * blob, int len );
10 void printhex32 ( const void * blob, int len );
11 void printbytes ( const void * blob, int len );
12 void printbytes2 ( const void * blob, int len );
13
14 uint32_t popcount ( uint32_t v );
15 uint32_t parity ( uint32_t v );
16
17 uint32_t getbit ( const void * blob, int len, uint32_t bit );
18 uint32_t getbit_wrap ( const void * blob, int len, uint32_t bit );
19
20 void setbit ( void * blob, int len, uint32_t bit );
21 void setbit ( void * blob, int len, uint32_t bit, uint32_t val );
22
23 void clearbit ( void * blob, int len, uint32_t bit );
24
25 void flipbit ( void * blob, int len, uint32_t bit );
26
27 int countbits ( uint32_t v );
28 int countbits ( std::vector<uint32_t> & v );
29
30 int countbits ( const void * blob, int len );
31
32 void invert ( std::vector<uint32_t> & v );
33
34 //----------
35
36 template< typename T >
getbit(T & blob,uint32_t bit)37 inline uint32_t getbit ( T & blob, uint32_t bit )
38 {
39 return getbit(&blob,sizeof(blob),bit);
40 }
41
getbit(uint32_t & blob,uint32_t bit)42 template<> inline uint32_t getbit ( uint32_t & blob, uint32_t bit ) { return (blob >> (bit & 31)) & 1; }
getbit(uint64_t & blob,uint32_t bit)43 template<> inline uint32_t getbit ( uint64_t & blob, uint32_t bit ) { return (blob >> (bit & 63)) & 1; }
44
45 //----------
46
47 template< typename T >
setbit(T & blob,uint32_t bit)48 inline void setbit ( T & blob, uint32_t bit )
49 {
50 return setbit(&blob,sizeof(blob),bit);
51 }
52
setbit(uint32_t & blob,uint32_t bit)53 template<> inline void setbit ( uint32_t & blob, uint32_t bit ) { blob |= uint32_t(1) << (bit & 31); }
setbit(uint64_t & blob,uint32_t bit)54 template<> inline void setbit ( uint64_t & blob, uint32_t bit ) { blob |= uint64_t(1) << (bit & 63); }
55
56 //----------
57
58 template< typename T >
flipbit(T & blob,uint32_t bit)59 inline void flipbit ( T & blob, uint32_t bit )
60 {
61 flipbit(&blob,sizeof(blob),bit);
62 }
63
flipbit(uint32_t & blob,uint32_t bit)64 template<> inline void flipbit ( uint32_t & blob, uint32_t bit ) { bit &= 31; blob ^= (uint32_t(1) << bit); }
flipbit(uint64_t & blob,uint32_t bit)65 template<> inline void flipbit ( uint64_t & blob, uint32_t bit ) { bit &= 63; blob ^= (uint64_t(1) << bit); }
66
67 //-----------------------------------------------------------------------------
68 // Left and right shift of blobs. The shift(N) versions work on chunks of N
69 // bits at a time (faster)
70
71 void lshift1 ( void * blob, int len, int c );
72 void lshift8 ( void * blob, int len, int c );
73 void lshift32 ( void * blob, int len, int c );
74
75 void rshift1 ( void * blob, int len, int c );
76 void rshift8 ( void * blob, int len, int c );
77 void rshift32 ( void * blob, int len, int c );
78
lshift(void * blob,int len,int c)79 inline void lshift ( void * blob, int len, int c )
80 {
81 if((len & 3) == 0)
82 {
83 lshift32(blob,len,c);
84 }
85 else
86 {
87 lshift8(blob,len,c);
88 }
89 }
90
rshift(void * blob,int len,int c)91 inline void rshift ( void * blob, int len, int c )
92 {
93 if((len & 3) == 0)
94 {
95 rshift32(blob,len,c);
96 }
97 else
98 {
99 rshift8(blob,len,c);
100 }
101 }
102
103 template < typename T >
lshift(T & blob,int c)104 inline void lshift ( T & blob, int c )
105 {
106 if((sizeof(T) & 3) == 0)
107 {
108 lshift32(&blob,sizeof(T),c);
109 }
110 else
111 {
112 lshift8(&blob,sizeof(T),c);
113 }
114 }
115
116 template < typename T >
rshift(T & blob,int c)117 inline void rshift ( T & blob, int c )
118 {
119 if((sizeof(T) & 3) == 0)
120 {
121 lshift32(&blob,sizeof(T),c);
122 }
123 else
124 {
125 lshift8(&blob,sizeof(T),c);
126 }
127 }
128
lshift(uint32_t & blob,int c)129 template<> inline void lshift ( uint32_t & blob, int c ) { blob <<= c; }
lshift(uint64_t & blob,int c)130 template<> inline void lshift ( uint64_t & blob, int c ) { blob <<= c; }
rshift(uint32_t & blob,int c)131 template<> inline void rshift ( uint32_t & blob, int c ) { blob >>= c; }
rshift(uint64_t & blob,int c)132 template<> inline void rshift ( uint64_t & blob, int c ) { blob >>= c; }
133
134 //-----------------------------------------------------------------------------
135 // Left and right rotate of blobs. The rot(N) versions work on chunks of N
136 // bits at a time (faster)
137
138 void lrot1 ( void * blob, int len, int c );
139 void lrot8 ( void * blob, int len, int c );
140 void lrot32 ( void * blob, int len, int c );
141
142 void rrot1 ( void * blob, int len, int c );
143 void rrot8 ( void * blob, int len, int c );
144 void rrot32 ( void * blob, int len, int c );
145
lrot(void * blob,int len,int c)146 inline void lrot ( void * blob, int len, int c )
147 {
148 if((len & 3) == 0)
149 {
150 return lrot32(blob,len,c);
151 }
152 else
153 {
154 return lrot8(blob,len,c);
155 }
156 }
157
rrot(void * blob,int len,int c)158 inline void rrot ( void * blob, int len, int c )
159 {
160 if((len & 3) == 0)
161 {
162 return rrot32(blob,len,c);
163 }
164 else
165 {
166 return rrot8(blob,len,c);
167 }
168 }
169
170 template < typename T >
lrot(T & blob,int c)171 inline void lrot ( T & blob, int c )
172 {
173 if((sizeof(T) & 3) == 0)
174 {
175 return lrot32(&blob,sizeof(T),c);
176 }
177 else
178 {
179 return lrot8(&blob,sizeof(T),c);
180 }
181 }
182
183 template < typename T >
rrot(T & blob,int c)184 inline void rrot ( T & blob, int c )
185 {
186 if((sizeof(T) & 3) == 0)
187 {
188 return rrot32(&blob,sizeof(T),c);
189 }
190 else
191 {
192 return rrot8(&blob,sizeof(T),c);
193 }
194 }
195
lrot(uint32_t & blob,int c)196 template<> inline void lrot ( uint32_t & blob, int c ) { blob = ROTL32(blob,c); }
lrot(uint64_t & blob,int c)197 template<> inline void lrot ( uint64_t & blob, int c ) { blob = ROTL64(blob,c); }
rrot(uint32_t & blob,int c)198 template<> inline void rrot ( uint32_t & blob, int c ) { blob = ROTR32(blob,c); }
rrot(uint64_t & blob,int c)199 template<> inline void rrot ( uint64_t & blob, int c ) { blob = ROTR64(blob,c); }
200
201 //-----------------------------------------------------------------------------
202 // Bit-windowing functions - select some N-bit subset of the input blob
203
204 uint32_t window1 ( void * blob, int len, int start, int count );
205 uint32_t window8 ( void * blob, int len, int start, int count );
206 uint32_t window32 ( void * blob, int len, int start, int count );
207
window(void * blob,int len,int start,int count)208 inline uint32_t window ( void * blob, int len, int start, int count )
209 {
210 if(len & 3)
211 {
212 return window8(blob,len,start,count);
213 }
214 else
215 {
216 return window32(blob,len,start,count);
217 }
218 }
219
220 template < typename T >
window(T & blob,int start,int count)221 inline uint32_t window ( T & blob, int start, int count )
222 {
223 if((sizeof(T) & 3) == 0)
224 {
225 return window32(&blob,sizeof(T),start,count);
226 }
227 else
228 {
229 return window8(&blob,sizeof(T),start,count);
230 }
231 }
232
233 template<>
window(uint32_t & blob,int start,int count)234 inline uint32_t window ( uint32_t & blob, int start, int count )
235 {
236 return ROTR32(blob,start) & ((1<<count)-1);
237 }
238
239 template<>
window(uint64_t & blob,int start,int count)240 inline uint32_t window ( uint64_t & blob, int start, int count )
241 {
242 return (uint32_t)ROTR64(blob,start) & ((1<<count)-1);
243 }
244
245 //-----------------------------------------------------------------------------
246