view python/outstream.py @ 235:ff40407c0240

Fix ALabel to Label
author Windel Bouwman
date Mon, 15 Jul 2013 17:20:37 +0200
parents 83781bd10fdb
children 8786811a5a59
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 selectSection(self, s):
        self.currentSection = s
        if not s in self.sections:
            self.sections[s] = []

    def getLabelAddress(self, lname):
        assert isinstance(lname, str)
        for s in self.sections.values():
            for i in s:
                if type(i) is Label:
                    if i.name == lname:
                        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)
            if len(insword) == 0:
                print('    {}'.format(asm))
            else:
                print('    0x{0:08x} 0x{1} {2}'.format(addr, insword, asm))

class TextOutputStream(OutputStream):
    pass

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