comparison python/outstream.py @ 234:83781bd10fdb

wip
author Windel Bouwman
date Sun, 14 Jul 2013 19:29:21 +0200
parents 1c7364bd74c7
children ff40407c0240
comparison
equal deleted inserted replaced
233:d3dccf12ca88 234:83781bd10fdb
1 import binascii 1 import binascii
2 from asmnodes import ALabel, AComment 2 from target import Instruction, Label
3
3 """ 4 """
4 The output stream is a stream of instructions that can be output 5 The output stream is a stream of instructions that can be output
5 to a file or binary or hexfile. 6 to a file or binary or hexfile.
6 """ 7 """
7 8
8 class Alignment:
9 def __init__(self, a):
10 self.align = a
11 9
12 class OutputStream: 10 class OutputStream:
13 def __init__(self): 11 def __init__(self):
14 self.sections = {} 12 self.sections = {}
15 self.currentSection = None 13 self.currentSection = None
16 14
17 def emit(self, item): 15 def emit(self, item):
16 assert isinstance(item, Instruction)
18 self.sections[self.currentSection].append(item) 17 self.sections[self.currentSection].append(item)
19 18
20 def align(self, alignment): 19 def align(self, alignment):
21 self.emit(Alignment(alignment)) 20 self.emit(Alignment(alignment))
22 21
23 def selectSection(self, s): 22 def selectSection(self, s):
24 self.currentSection = s 23 self.currentSection = s
25 if not s in self.sections: 24 if not s in self.sections:
26 self.sections[s] = [] 25 self.sections[s] = []
26
27 def getLabelAddress(self, l):
28 assert isinstance(l, Label)
29 for s in self.sections.values():
30 for i in s:
31 if type(i) is Label:
32 if i.name == l.name:
33 return i.address
34 return 0
27 35
28 def backpatch(self): 36 def backpatch(self):
29 """ Fixup references to other parts in the assembler """ 37 """ Fixup references to other parts in the assembler """
30 for s in self.sections: 38 for s in self.sections:
31 # TODO parameterize this: 39 # TODO parameterize this:
35 address = 0x02000000 43 address = 0x02000000
36 else: 44 else:
37 address = 0x0 45 address = 0x0
38 for i in self.sections[s]: 46 for i in self.sections[s]:
39 i.address = address 47 i.address = address
40 if type(i) in [ALabel, AComment]: 48 i.resolve(self.getLabelAddress)
41 continue
42 if type(i) is Alignment:
43 while (address % i.align) != 0:
44 address += 1
45 continue
46 bts = i.encode() 49 bts = i.encode()
47 address += len(bts) 50 address += len(bts)
48 51
49 def dump(self): 52 def dump(self):
50 self.backpatch() 53 self.backpatch()
52 self.dumpSection(s) 55 self.dumpSection(s)
53 56
54 def dumpSection(self, s): 57 def dumpSection(self, s):
55 print('.section '+s) 58 print('.section '+s)
56 for i in self.sections[s]: 59 for i in self.sections[s]:
57 if type(i) in [ALabel, AComment]: 60 addr = i.address
58 print(i) 61 insword = i.encode()
59 elif type(i) is Alignment: 62 assert type(insword) is bytes
60 pass 63 insword = binascii.hexlify(bytes(reversed(insword))).decode('ascii')
61 else: 64 asm = str(i)
62 addr = i.address 65 print(' 0x{0:08x} 0x{1} {2}'.format(addr, insword, asm))
63 insword = i.encode()
64 assert type(insword) is bytes
65 insword = binascii.hexlify(bytes(reversed(insword))).decode('ascii')
66 asm = str(i)
67 print(' 0x{0:08x} 0x{1} {2}'.format(addr, insword, asm))
68 66
69 class TextOutputStream(OutputStream): 67 class TextOutputStream(OutputStream):
70 pass 68 pass
71 69
72 class BinOutputStream(OutputStream): 70 class BinOutputStream(OutputStream):