Mercurial > lcfOS
changeset 316:56e6ff84f646
Fixed burn led demo
author | Windel Bouwman |
---|---|
date | Sat, 21 Dec 2013 13:13:26 +0100 |
parents | 084cccaa5deb |
children | e30a77ae359b |
files | python/outstream.py python/ppci/c3/astnodes.py python/ppci/c3/codegenerator.py python/ppci/codegen/codegen.py python/ppci/transform.py python/target/arminstructionselector.py python/zcc.py |
diffstat | 7 files changed, 95 insertions(+), 60 deletions(-) [+] |
line wrap: on
line diff
--- a/python/outstream.py Sat Dec 21 10:03:01 2013 +0100 +++ b/python/outstream.py Sat Dec 21 13:13:26 2013 +0100 @@ -33,6 +33,7 @@ di = [i for i in self.instructions if isinstance(i, DebugInfo)] return di + class OutputStream: def __init__(self): self.sections = {} @@ -69,15 +70,19 @@ bts = i.encode() address += len(bts) - def dump(self): - self.backpatch() - self.backpatch() - for s in sorted(self.sections.keys()): - self.dumpSection(s) +class OutputStreamWriter: + def __init__(self, extra_indent=''): + self.extra_indent = extra_indent - def dumpSection(self, s): - print('.section '+ s) - for i in self.sections[s].instructions: + def dump(self, stream, f): + stream.backpatch() + stream.backpatch() + for s in sorted(stream.sections.keys()): + # print('.section '+ s) + self.dumpSection(stream.sections[s], f) + + def dumpSection(self, s, f): + for i in s.instructions: if type(i) is DebugInfo: continue addr = i.address @@ -86,9 +91,9 @@ insword = binascii.hexlify(bytes(reversed(insword))).decode('ascii') asm = str(i) if len(insword) == 0: - print(' {}'.format(asm)) + print(' {}'.format(asm), file=f) else: - print(' 0x{0:08x} 0x{1} {2}'.format(addr, insword, asm)) + print(' 0x{0:08x} 0x{1} {2}'.format(addr, insword, asm), file=f) class TextOutputStream(OutputStream):
--- a/python/ppci/c3/astnodes.py Sat Dec 21 10:03:01 2013 +0100 +++ b/python/ppci/c3/astnodes.py Sat Dec 21 13:13:26 2013 +0100 @@ -85,11 +85,11 @@ class StructField: + """ Field of a struct type """ def __init__(self, name, typ): assert type(name) is str self.name = name self.typ = typ - self.offset = 0 class StructureType(Type): @@ -133,6 +133,7 @@ class Constant(Symbol): + """ Constant definition """ def __init__(self, name, typ, value): super().__init__(name) self.typ = typ @@ -147,7 +148,6 @@ super().__init__(name) self.typ = typ self.isLocal = False - self.isReadOnly = False self.isParameter = False def __repr__(self):
--- a/python/ppci/c3/codegenerator.py Sat Dec 21 10:03:01 2013 +0100 +++ b/python/ppci/c3/codegenerator.py Sat Dec 21 13:13:26 2013 +0100 @@ -55,10 +55,6 @@ self.pkg.ok = False self.diag.error(msg, loc) - def checkType(self, t): - """ Verify the type is correct """ - t = self.theType(t) - def gen_function(self, fn): # TODO: handle arguments f = self.funcMap[fn] @@ -70,11 +66,14 @@ # generate room for locals: for sym in fn.innerScope: - # TODO: handle parameters different - self.checkType(sym.typ) + self.the_type(sym.typ) if sym.isParameter: - variable = ir.Parameter(sym.name) - f.addParameter(variable) + p = ir.Parameter(sym.name) + variable = ir.LocalVariable(sym.name + '_copy') + f.addParameter(p) + f.addLocal(variable) + # Move parameter into local copy: + self.emit(ir.Move(ir.Mem(variable), p)) elif sym.isLocal: variable = ir.LocalVariable(sym.name) f.addLocal(variable) @@ -248,7 +247,7 @@ elif type(expr) is ast.Deref: # dereference pointer type: addr = self.genExprCode(expr.ptr) - ptr_typ = self.theType(expr.ptr.typ) + ptr_typ = self.the_type(expr.ptr.typ) expr.lvalue = True if type(ptr_typ) is ast.PointerType: expr.typ = ptr_typ.ptype @@ -258,7 +257,7 @@ elif type(expr) is ast.Member: base = self.genExprCode(expr.base) expr.lvalue = expr.base.lvalue - basetype = self.theType(expr.base.typ) + basetype = self.the_type(expr.base.typ) if type(basetype) is ast.StructureType: if basetype.hasField(expr.field): expr.typ = basetype.fieldType(expr.field) @@ -270,7 +269,7 @@ .format(expr.field, basetype), expr.loc) assert type(base) is ir.Mem, type(base) - bt = self.theType(expr.base.typ) + bt = self.the_type(expr.base.typ) offset = ir.Const(bt.fieldOffset(expr.field)) return ir.Mem(ir.Add(base.e, offset)) elif type(expr) is ast.Literal: @@ -291,8 +290,8 @@ def gen_type_cast(self, expr): """ Generate code for type casting """ ar = self.genExprCode(expr.a) - from_type = self.theType(expr.a.typ) - to_type = self.theType(expr.to_type) + from_type = self.the_type(expr.a.typ) + to_type = self.the_type(expr.to_type) if isinstance(from_type, ast.PointerType) and isinstance(to_type, ast.PointerType): expr.typ = expr.to_type return ar @@ -351,12 +350,28 @@ assert isinstance(s, ast.Symbol) return s - def theType(self, t): + def size_of(self, t): + """ Determine the byte size of a type """ + t = self.the_type(t) + if type(t) is ast.BaseType: + return t.bytesize + elif type(t) is ast.StructureType: + return sum(self.size_of(mem.typ) for mem in t.mems) + else: + raise NotImplementedError(str(t)) + + def the_type(self, t): """ Recurse until a 'real' type is found """ if type(t) is ast.DefinedType: - t = self.theType(t.typ) + t = self.the_type(t.typ) elif type(t) in [ast.Identifier, ast.Member]: - t = self.theType(self.resolveSymbol(t)) + t = self.the_type(self.resolveSymbol(t)) + elif type(t) is ast.StructureType: + # Setup offsets of fields. Is this the right place?: + offset = 0 + for mem in t.mems: + mem.offset = offset + offset = offset + self.size_of(mem.typ) elif isinstance(t, ast.Type): pass else: @@ -367,10 +382,8 @@ def equalTypes(self, a, b): """ Compare types a and b for structural equavalence. """ # Recurse into named types: - a = self.theType(a) - b = self.theType(b) - assert isinstance(a, ast.Type) - assert isinstance(b, ast.Type) + a = self.the_type(a) + b = self.the_type(b) if type(a) is type(b): if type(a) is ast.BaseType:
--- a/python/ppci/codegen/codegen.py Sat Dec 21 10:03:01 2013 +0100 +++ b/python/ppci/codegen/codegen.py Sat Dec 21 13:13:26 2013 +0100 @@ -27,10 +27,10 @@ # Canonicalize the intermediate language: canonicalize(irfunc, frame) - self.logger.info('after canonicalize', extra={'irfunc':irfunc}) + self.logger.info('after canonicalize', extra={'irfunc': irfunc}) self.verifier.verify_function(irfunc) self.ins_sel.munchFunction(irfunc, frame) - self.logger.info('Selected instructions', extra={'ppci_frame':frame}) + self.logger.info('Selected instructions', extra={'ppci_frame': frame}) # Do register allocation: self.ra.allocFrame(frame)
--- a/python/ppci/transform.py Sat Dec 21 10:03:01 2013 +0100 +++ b/python/ppci/transform.py Sat Dec 21 13:13:26 2013 +0100 @@ -8,7 +8,7 @@ class FunctionPass: def __init__(self): - self.logger = logging.getLogger('optimize') + self.logger = logging.getLogger(str(self.__class__.__name__)) def run(self, ir): """ Main entry point for the pass """ @@ -116,27 +116,26 @@ else: constMap[k] = i.result for i in to_remove: - logging.debug('removing {}'.format(i)) + self.logger.debug('removing {}'.format(i)) bb.removeInstruction(i) class CleanPass(FunctionPass): def onFunction(self, f): - removeEmptyBasicBlocks(f) - + self.remove_empty_blocks(f) -def removeEmptyBlocks(f): - """ Remove empty basic blocks from function. """ - # If a block only contains a branch, it can be removed: - empty = lambda b: type(b.FirstInstruction) is ir.Jump - empty_blocks = list(filter(empty, f.Blocks)) - for b in empty_blocks: - # Update predecessors - preds = b.Predecessors - if b not in preds + [f.entry]: - # Do not remove if preceeded by itself - tgt = b.LastInstruction.target - for pred in preds: - pred.LastInstruction.changeTarget(b, tgt) - logging.debug('Removing empty block: {}'.format(b)) - f.removeBlock(b) + def remove_empty_blocks(self, f): + """ Remove empty basic blocks from function. """ + # If a block only contains a branch, it can be removed: + empty = lambda b: type(b.FirstInstruction) is ir.Jump + empty_blocks = list(filter(empty, f.Blocks)) + for b in empty_blocks: + # Update predecessors + preds = b.Predecessors + if b not in preds + [f.entry]: + # Do not remove if preceeded by itself + tgt = b.LastInstruction.target + for pred in preds: + pred.LastInstruction.changeTarget(b, tgt) + self.logger.debug('Removing empty block: {}'.format(b)) + f.removeBlock(b)
--- a/python/target/arminstructionselector.py Sat Dec 21 10:03:01 2013 +0100 +++ b/python/target/arminstructionselector.py Sat Dec 21 13:13:26 2013 +0100 @@ -45,14 +45,14 @@ b = self.munchExpr(e.b) d = self.newTmp() self.move(d, a) - self.emit(Orr, dst=[], src=[b, d]) + self.emit(Orr, dst=[], src=[d, b]) return d elif isinstance(e, ir.Binop) and e.operation == '<<': a = self.munchExpr(e.a) b = self.munchExpr(e.b) d = self.newTmp() self.move(d, a) - self.emit(Lsl, dst=[], src=[b, d]) # TODO: is d a source variable? + self.emit(Lsl, dst=[], src=[d, b]) # TODO: is d a source variable? return d elif isinstance(e, ir.Binop) and e.operation == '*': a = self.munchExpr(e.a)
--- a/python/zcc.py Sat Dec 21 10:03:01 2013 +0100 +++ b/python/zcc.py Sat Dec 21 13:13:26 2013 +0100 @@ -13,6 +13,7 @@ import target from ppci import irutils import io +from ppci.transform import CleanPass logformat='%(asctime)s|%(levelname)s|%(name)s|%(message)s' @@ -79,6 +80,7 @@ print('.. graphviz::', file=f) print('', file=f) print(' digraph G {', file=f) + print(' size="8,80";', file=f) cfg = record.ra_cfg cfg.to_dot(f) print(' }', file=f) @@ -91,11 +93,22 @@ print('.. graphviz::', file=f) print('', file=f) print(' digraph G {', file=f) + print(' ratio="compress";', file=f) + print(' size="8,80";', file=f) ig = record.ra_ig ig.to_dot(f) print(' }', file=f) print('', file=f) s += '\n' + f.getvalue() + if hasattr(record, 'zcc_outs'): + f = io.StringIO() + print('', file=f) + print('', file=f) + print('.. code::', file=f) + print('', file=f) + outstream.OutputStreamWriter(' ').dump(record.zcc_outs, f) + print('', file=f) + s += '\n' + f.getvalue() return s @@ -119,7 +132,8 @@ type=argparse.FileType('w')) parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])', type=logLevel, default='WARN') -parser.add_argument('--report', help='Specify a file to write the compile report to', +parser.add_argument('--report', + help='Specify a file to write the compile report to', type=argparse.FileType('w')) @@ -129,7 +143,8 @@ Compile sources into output stream. Sources is an iterable of open files. """ - logging.info('Zcc started {}'.format(srcs)) + logger = logging.getLogger('zcc') + logger.info('Zcc started {}'.format(srcs)) # Front end: c3b = Builder(diag, tg) cg = CodeGenerator(tg) @@ -145,13 +160,16 @@ return d = {'ircode':ircode} - logging.info('Verifying code {}'.format(ircode), extra=d) - # Optimization passes, TODO + logger.info('Verifying code {}'.format(ircode), extra=d) + Verifier().verify(ircode) + + # Optimization passes: + CleanPass().run(ircode) Verifier().verify(ircode) # Code generation: d = {'ircode':ircode} - logging.info('Starting code generation for {}'.format(ircode), extra=d) + logger.info('Starting code generation for {}'.format(ircode), extra=d) cg.generate(ircode, outs) # TODO: fixup references, do this in another way? outs.backpatch()