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