Mercurial > lcfOS
comparison python/ir/bitreader.py @ 147:4e79484a9d47
Moved core to ir folder
author | Windel Bouwman |
---|---|
date | Fri, 22 Feb 2013 10:33:48 +0100 |
parents | python/ppci/core/bitreader.py@6a303f835c6d |
children |
comparison
equal
deleted
inserted
replaced
146:91af0e40f868 | 147:4e79484a9d47 |
---|---|
1 from .errors import CompilerException | |
2 from .module import Module | |
3 import struct | |
4 | |
5 def enum(**enums): | |
6 return type('Enum', (), enums) | |
7 | |
8 BitCodes = enum(END_BLOCK=0, ENTER_SUBBLOCK=1) | |
9 | |
10 class BitstreamReader: | |
11 def __init__(self, f): | |
12 self.f = f | |
13 # Initialize the bitreader: | |
14 self.bitsInCurrent = 32 | |
15 self.curWord = self.getWord() | |
16 self.curCodeSize = 2 | |
17 def getWord(self): | |
18 bts = self.f.read(4) | |
19 return struct.unpack('<I', bts)[0] | |
20 def Read(self, numbits): | |
21 if numbits > 32: | |
22 raise CompilerException("Cannot read more than 32 bits") | |
23 if self.bitsInCurrent >= numbits: | |
24 # numbits inside the current word: | |
25 R = self.curWord & ((1 << numbits) - 1) | |
26 self.curWord = self.curWord >> numbits | |
27 self.bitsInCurrent -= numbits | |
28 return R | |
29 R = self.curWord | |
30 self.curWord = self.getWord() | |
31 bitsLeft = numbits - self.bitsInCurrent | |
32 | |
33 # Add remaining bits: | |
34 R |= (self.curWord & (0xFFFFFFFF >> (32 - bitsLeft))) << self.bitsInCurrent | |
35 | |
36 # Update curword and bits in current: | |
37 self.curWord = self.curWord >> bitsLeft | |
38 self.bitsInCurrent = 32 - bitsLeft | |
39 return R | |
40 def ReadVBR(self, numbits): | |
41 """ Read variable bits, checking for the last bit is zero. """ | |
42 piece = self.Read(numbits) | |
43 if (piece & (1 << (numbits - 1))) == 0: | |
44 return piece | |
45 result = 0 | |
46 nextbit = 0 | |
47 while True: | |
48 mask = (1 << (numbits - 1)) - 1 | |
49 result |= ( piece & mask ) << nextbit | |
50 if (piece & (1 << (numbits - 1))) == 0: | |
51 return result | |
52 nextbit += numbits - 1 | |
53 piece = self.Read(numbits) | |
54 def ReadCode(self): | |
55 """ Read the code depending on the current code size """ | |
56 return self.Read(self.curCodeSize) | |
57 def ReadSubBlockId(self): | |
58 return self.ReadVBR(8) | |
59 def EnterSubBlock(self, blockId): | |
60 pass | |
61 | |
62 BLOCKINFO_BLOCKID = 0 | |
63 FIRST_APPLICATION_BLOCKID = 8 | |
64 MODULE_BLOCKID = FIRST_APPLICATION_BLOCKID | |
65 | |
66 class BitcodeReader: | |
67 def __init__(self, f): | |
68 self.stream = BitstreamReader(f) | |
69 def parseModule(self): | |
70 for bitsig in [ord('B'), ord('C')]: | |
71 if self.stream.Read(8) != bitsig: | |
72 raise CompilerException('Invalid bitcode signature') | |
73 for bitsig in [0x0, 0xC, 0xE, 0xD]: | |
74 if self.stream.Read(4) != bitsig: | |
75 raise CompilerException('Invalid bitcode signature') | |
76 while True: | |
77 code = self.stream.ReadCode() | |
78 if code != BitCodes.ENTER_SUBBLOCK: | |
79 raise CompilerException('Invalid record at toplevel') | |
80 blockId = self.stream.ReadSubBlockId() | |
81 if blockId == MODULE_BLOCKID: | |
82 print('module block') | |
83 pass | |
84 else: | |
85 print('Block id:', blockId) | |
86 raise | |
87 return Module() | |
88 | |
89 class BitstreamWriter: | |
90 def __init__(self, f): | |
91 self.f = f | |
92 self.u32 = 0 | |
93 self.curpos = 0 | |
94 def Emit1(self, val): | |
95 self.Emit(val, 1) | |
96 def Emit(self, val, numbits): | |
97 """ Emits value using numbits bits """ | |
98 if numbits == 1: | |
99 if val != 0: | |
100 self.u32 |= (0x1 << self.curpos) | |
101 self.curpos += 1 | |
102 if self.curpos == 32: | |
103 self.writeWord() | |
104 elif numbits > 1: | |
105 for i in range(numbits): | |
106 if val & (1 << i) != 0: | |
107 self.Emit1(1) | |
108 else: | |
109 self.Emit1(0) | |
110 def writeWord(self): | |
111 bts = struct.pack('<I', self.u32) | |
112 self.f.write(bts) | |
113 self.u32 = 0 | |
114 self.curpos = 0 | |
115 def flush(self): | |
116 if self.curpos != 0: | |
117 self.writeWord() | |
118 | |
119 class BitcodeWriter: | |
120 def __init__(self): | |
121 pass | |
122 def WriteModule(self, module): | |
123 pass | |
124 def WriteModuleToFile(self, module, f): | |
125 s = BitstreamWriter(f) | |
126 s.Emit(ord('B'), 8) | |
127 s.Emit(ord('C'), 8) | |
128 s.Emit(0x0, 4) | |
129 s.Emit(0xC, 4) | |
130 s.Emit(0xE, 4) | |
131 s.Emit(0xD, 4) | |
132 self.WriteModule(module) | |
133 s.flush() | |
134 |