Mercurial > lcfOS
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): |