1 """
2 A file full of bit twidling helpers
3 """
4
5 import struct
6
7 MAX_WORD = 8
8
9
10 u_maxes = [ (2 ** (8*i)) - 1 for i in range(MAX_WORD+1) ]
11 u_maxes[0] = 0
12
13
14 sign_bits = [ (2 ** (8*i)) >> 1 for i in range(MAX_WORD+1) ]
15 sign_bits[0] = 0
16
17
18 s_maxes = [ u_maxes[i] ^ sign_bits[i] for i in range(len(u_maxes))]
19 s_maxes[0] = 0
20
21
22 b_masks = [ (2**i)-1 for i in range(MAX_WORD*8) ]
23 b_masks[0] = 0
24
26 """
27 Make a value unsigned based on it's size.
28 """
29
30 return value & u_maxes[size]
31
40
44
46 """
47 Take a value and extend it's size filling
48 in the space with the value of the high
49 order bit.
50 """
51 x = unsigned(value, cursize)
52 if cursize != newsize:
53
54 if x & sign_bits[cursize]:
55 delta = newsize - cursize
56 highbits = u_maxes[delta]
57 x |= highbits << (8*cursize)
58 return x
59
61 s = 0
62 while val:
63 s ^= val & 1
64 val = val >> 1
65 return (not s)
66
67 parity_table = []
68 for i in range(256):
69 parity_table.append(is_parity(i))
70
72 """
73 An "optimized" parity checker that looks up the index.
74 """
75 return parity_table[bval & 0xff]
76
79
80 -def msb(value, size):
84
86 max = s_maxes[size]
87 if value > max:
88 return True
89 if value < -max:
90 return True
91 return False
92
94 umax = u_maxes[size]
95 if value > umax:
96 return True
97 elif value < 0:
98 return True
99 return False
100
102
103 dst = dst & 0xf
104 src = src & 0xf
105 if (dst + src) > 15:
106 return True
107 return False
108
109 le_fmt_chars = (None,"B","<H",None,"<L",None,None,None,"<Q")
110 be_fmt_chars = (None,"B",">H",None,">L",None,None,None,">Q")
111 -def parsebytes(bytes, offset, size, sign=False, bigend=False):
112 """
113 Mostly for pulling immediates out of strings...
114 """
115 if size > 8:
116 return slowparsebytes(bytes, offset, size, sign=sign, bigend=bigend)
117 if bigend:
118 f = be_fmt_chars[size]
119 else:
120 f = le_fmt_chars[size]
121 if f == None:
122 return slowparsebytes(bytes, offset, size, sign=sign, bigend=bigend)
123 d = bytes[offset:offset+size]
124 x = struct.unpack(f, d)[0]
125 if sign:
126 x = signed(x, size)
127 return x
128
130 if bigend:
131 begin = offset
132 inc = 1
133 else:
134 begin = offset + (size-1)
135 inc = -1
136
137 ret = 0
138 ioff = 0
139 for x in range(size):
140 ret = ret << 8
141 ret |= ord(bytes[begin+ioff])
142 ioff += inc
143 if sign:
144 ret = signed(ret, size)
145 return ret
146
148 if bigend:
149 f = be_fmt_chars[size]
150 else:
151 f = le_fmt_chars[size]
152 if f == None:
153 raise Exception("envi.bits.buildbytes needs slowbuildbytes")
154 return struct.pack(f, value)
155
157 ret = 0
158 for i in range(size):
159 ret |= (value >> (8*i)) & 0xff
160 ret = ret << 8
161 return ret
162
163 hex_fmt = {
164 1:"0x%.2x",
165 2:"0x%.4x",
166 4:"0x%.8x",
167 8:"0x%.16x",
168 }
169
171 if val < 0:
172 val = abs(val)
173 ret = 0
174 while val:
175 ret += 1
176 val = val >> 8
177 return ret
178
179 -def hex(value, size=None):
196
197 -def binrepr(intval, bitwidth=None):
198 '''
199 Return a string of one's and zero's for the given value.
200 '''
201 ret = []
202 while intval:
203 ret.append(str(intval & 0x1))
204 intval >>= 1
205 ret.reverse()
206 binstr = ''.join(ret)
207 if bitwidth != None:
208 binstr = binstr.rjust(bitwidth, '0')
209 return binstr
210
212 '''
213 Decode a binary string of 1/0's into a python number
214 '''
215 x = 0
216 for c in binstr:
217 x = (x << 1) + int(c)
218 return x
219
221 '''
222 Decode a binary string of 1/0's into a python binary
223 string.
224 '''
225 if len(binstr) % 8 != 0:
226 raise Exception('Byte padded binary strings only for now!')
227 bytes = ''
228 while binstr:
229 bytes += chr( binary(binstr[:8]) )
230 binstr = binstr[8:]
231 return bytes
232
233 -def parsebits(bytes, offset, bitoff, bitsize):
234 '''
235 Parse bitsize bits from the bit offset bitoff beginning
236 at offset bytes.
237
238 Example:
239 '''
240 val = 0
241 cnt = 0
242 while cnt < bitsize:
243
244 addbit = bitoff + cnt
245 addoff = offset + (addbit / 8)
246
247 modoff = addbit % 8
248
249 o = ord(bytes[addoff])
250 val = (val << 1) + ((o >> (7 - modoff)) & 1)
251
252 cnt += 1
253
254 return val
255
256
257
258
259
260