Mercurial > lcfOS
diff python/codegenarm.py @ 268:5ec7580976d9
Op naar tree-IR
author | Windel Bouwman |
---|---|
date | Wed, 14 Aug 2013 20:12:40 +0200 |
parents | ed14e077124c |
children | 5f8c04a8d26b |
line wrap: on
line diff
--- a/python/codegenarm.py Mon Aug 12 20:14:47 2013 +0200 +++ b/python/codegenarm.py Wed Aug 14 20:12:40 2013 +0200 @@ -7,14 +7,113 @@ class InstructionSelector: - pass + def newTmp(self): + return 't999' + + def munchProgram(self, p): + assert isinstance(p, ir.Module) + self.result = [] + for f in p.Functions: + for bb in f.BasicBlocks: + for i in bb.Instructions: + self.munchStm(i) + return self.result + + def emit(self, *args, **kwargs): + """ Abstract instruction emitter """ + i = irmach.AbstractInstruction(*args, **kwargs) + self.result.append(i) + + def munchStm(self, s): + raise NotImplementedError() + + def munchExpr(self, e): + raise NotImplementedError() class RegisterAllocator: + """ Target independent register allocator """ pass +class ArmInstructionSelector(InstructionSelector): + def munchExpr(self, e): + if isinstance(e, ir.Alloc): + return 0 + elif isinstance(e, ir.Binop) and e.operation == '+': + a = self.munchExpr(e.value1) + b = self.munchExpr(e.value2) + d = self.newTmp() + self.emit('add %d0, %s0, %s1', dst=[d], src=[a, b]) + return d + elif isinstance(e, ir.Binop) and e.operation == '|': + a = self.munchExpr(e.value1) + b = self.munchExpr(e.value2) + d = self.newTmp() + self.emit('orrrr %d0, %s0, %s1', dst=[d], src=[a, b]) + return d + elif isinstance(e, ir.Binop) and e.operation == '<<': + a = self.munchExpr(e.value1) + b = self.munchExpr(e.value2) + d = self.newTmp() + self.emit('lsl %d0, %s0, %s1', dst=[d], src=[a, b]) + return d + elif isinstance(e, ir.Binop) and e.operation == '*': + a = self.munchExpr(e.value1) + b = self.munchExpr(e.value2) + d = self.newTmp() + self.emit('mylll %d0, %s0, %s1', dst=[d], src=[a, b]) + return d + elif isinstance(e, ir.Const): + d = self.newTmp() + if e.value < 256: + self.emit('ldr %d0, {}'.format(e.value), dst=[d]) + else: + self.emit('ldrpcrel TODO') + return d + elif isinstance(e, ir.Mem): + # Load from memory + loc = self.munchExpr(e.e) + d = self.newTmp() + self.emit('ldr %d0, [%s0]', src=[loc], dst=[d]) + return d + elif isinstance(e, ir.Temp): + return e + else: + raise NotImplementedError('--> {}'.format(e)) + + def munchStm(self, s): + if isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem): + memloc = self.munchExpr(s.dst.e) + val = self.munchExpr(s.src) + self.emit('str [%s0], %s1') + elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp): + val = self.munchExpr(s.src) + self.emit('str %d0, %s0', dst=[s.dst], src=[val]) + elif isinstance(s, ir.Return): + self.emit('ret') + elif isinstance(s, ir.Jump): + self.emit('jmp {}'.format(s)) + elif isinstance(s, ir.CJump): + self.munchExpr(s.a) + self.munchExpr(s.b) + self.emit('jmp {}'.format(s)) + else: + raise NotImplementedError('--> {}'.format(s)) + + class ArmCodeGenerator: + def __init__(self, outs): + self.ins_sel = ArmInstructionSelector() + self.outs = outs + self.outs.getSection('code').address = 0x08000000 + self.outs.getSection('data').address = 0x20000000 + + def generate(self, ircode): + self.ins_sel.munchProgram(ircode) + + +class ArmCodeGenerator_old: """ Simple code generator Ad hoc implementation