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