view python/outstream.py @ 234:83781bd10fdb

wip
author Windel Bouwman
date Sun, 14 Jul 2013 19:29:21 +0200
parents 1c7364bd74c7
children ff40407c0240
line wrap: on
line source

import binascii
from target import Instruction, Label

"""
 The output stream is a stream of instructions that can be output
 to a file or binary or hexfile.
"""


class OutputStream:
    def __init__(self):
        self.sections = {}
        self.currentSection = None

    def emit(self, item):
        assert isinstance(item, Instruction)
        self.sections[self.currentSection].append(item)

    def align(self, alignment):
        self.emit(Alignment(alignment))

    def selectSection(self, s):
        self.currentSection = s
        if not s in self.sections:
            self.sections[s] = []

    def getLabelAddress(self, l):
        assert isinstance(l, Label)
        for s in self.sections.values():
            for i in s:
                if type(i) is Label:
                    if i.name == l.name:
                        return i.address
        return 0

    def backpatch(self):
        """ Fixup references to other parts in the assembler """
        for s in self.sections:
            # TODO parameterize this:
            if s == 'code':
                address = 0x08000000
            elif s == 'data':
                address = 0x02000000
            else:
                address = 0x0
            for i in self.sections[s]:
                i.address = address
                i.resolve(self.getLabelAddress)
                bts = i.encode()
                address += len(bts)

    def dump(self):
        self.backpatch()
        for s in sorted(self.sections.keys()):
            self.dumpSection(s)

    def dumpSection(self, s):
        print('.section '+s)
        for i in self.sections[s]:
            addr = i.address
            insword = i.encode()
            assert type(insword) is bytes
            insword = binascii.hexlify(bytes(reversed(insword))).decode('ascii')
            asm = str(i)
            print('    0x{0:08x} 0x{1} {2}'.format(addr, insword, asm))

class TextOutputStream(OutputStream):
    pass

class BinOutputStream(OutputStream):
    def dump(self):
        pass