view python/outstream.py @ 219:1fa3e0050b49

Expanded ad hoc code generator
author Windel Bouwman
date Sat, 06 Jul 2013 12:38:09 +0200
parents 4cb47d80fd1f
children 1c7364bd74c7
line wrap: on
line source

import binascii
from asmnodes import ALabel
"""
 The output stream is a stream of instructions that can be output
 to a file or binary or hexfile.
"""

class Alignment:
    def __init__(self, a):
        self.align = a

class OutputStream:
    def __init__(self):
        self.sections = {}
        self.currentSection = None
    def emit(self, item):
        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 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
                if type(i) is ALabel:
                    continue
                if type(i) is Alignment:
                    while (address % i.align) != 0:
                        address += 1
                    continue
                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]:
            if type(i) is ALabel:
                print(i)
            elif type(i) is Alignment:
                pass
            else:
                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