diff python/target/arminstructionselector.py @ 323:e9fe6988497c

Used burg for generating expressions
author Windel Bouwman
date Thu, 30 Jan 2014 19:03:24 +0100
parents 44f336460c2a
children d1ecc493384e
line wrap: on
line diff
--- a/python/target/arminstructionselector.py	Mon Jan 27 19:58:07 2014 +0100
+++ b/python/target/arminstructionselector.py	Thu Jan 30 19:03:24 2014 +0100
@@ -15,116 +15,41 @@
 spec_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'arm.brg')
 arm_matcher = pyburg.load_as_module(spec_file)
 
+
 class ArmMatcher(arm_matcher.Matcher):
-    def __init__(self):
+    """ Matcher that derives from a burg spec generated matcher """
+    def __init__(self, selector):
         super().__init__()
-
-    def newTmp(self):
-        pass
-
-    def emit(self, *args, **kwargs):
-        pass
+        self.newTmp = selector.newTmp
+        self.emit = selector.emit
+        self.selector = selector
 
 
 class ArmInstructionSelector(InstructionSelector):
     """ Instruction selector for the arm architecture """
     def __init__(self):
         super().__init__()
-        self.matcher = ArmMatcher()
+        self.matcher = ArmMatcher(self)
 
     def munchExpr(self, e):
-        #t = makeTree(e)
-        #print(t)
-        #return self.matcher.gen(t)
+        # Use BURG system here:
+        t = makeTree(e)
+        return self.matcher.gen(t)
 
-        # TODO: below is obsolete:
-        if isinstance(e, ir.Binop) and e.operation == '+' and \
-            isinstance(e.b, ir.Const) and e.b.value < 8:
-            a = self.munchExpr(e.a)
-            d = self.newTmp()
-            c = Imm3(e.b.value)
-            self.emit(Add2, others=[c], dst=[d], src=[a])
-            return d
-        elif isinstance(e, ir.Binop) and e.operation == '+':
-            a = self.munchExpr(e.a)
-            b = self.munchExpr(e.b)
-            d = self.newTmp()
-            self.emit(Add, dst=[d], src=[a, b])
-            return d
-        elif isinstance(e, ir.Binop) and e.operation == '-' and \
-            isinstance(e.b, ir.Const) and e.b.value < 8:
-            a = self.munchExpr(e.a)
-            d = self.newTmp()
-            c = Imm3(e.b.value)
-            self.emit(Sub2, others=[c], dst=[d], src=[a])
-            return d
-        elif isinstance(e, ir.Binop) and e.operation == '-':
-            a = self.munchExpr(e.a)
-            b = self.munchExpr(e.b)
-            d = self.newTmp()
-            self.emit(Sub, dst=[d], src=[a, 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(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=[d, b]) # TODO: is d a source variable?
-            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)
-            # this mul instruction has operands swapped:
-            self.emit(Mul, dst=[d], src=[b, d])
-            return d
-        elif isinstance(e, ir.Const) and e.value < 256:
-            d = self.newTmp()
-            self.emit(Mov3, others=[Imm8(e.value)], dst=[d])
-            return d
-        elif isinstance(e, ir.Const) and e.value < (2**31):
-            d = self.newTmp()
-            ln = LabelRef(self.frame.addConstant(e.value))
-            self.emit(Ldr3, others=[ln], dst=[d])
-            return d
-        elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \
-                e.e.operation == '+' and isinstance(e.e.b, ir.Const):
-            base = self.munchExpr(e.e.a)
-            d = self.newTmp()
-            c = e.e.b.value
-            self.emit(Ldr2, others=[c], src=[base], dst=[d])
-            return d
-        elif isinstance(e, ir.Mem):
-            # Load from memory
-            base = self.munchExpr(e.e)
-            d = self.newTmp()
-            self.emit(Ldr2, others=[0], src=[base], dst=[d])
-            return d
-        elif isinstance(e, ir.Temp):
-            return e
-        elif isinstance(e, ir.Call):
-            # Move arguments into proper locations:
-            reguses = []
-            for i, a in enumerate(e.arguments):
-                loc = self.frame.argLoc(i)
-                m = ir.Move(loc, a)
-                self.munchStm(m)
-                if isinstance(loc, ir.Temp):
-                    reguses.append(loc)
-            self.emit(Bl(LabelRef(e.f)), src=reguses, dst=[self.frame.rv])
-            d = self.newTmp()
-            self.move(d, self.frame.rv)
-            return d
-        else:
-            raise NotImplementedError('Expr --> {}'.format(e))
+    def munchCall(self, e):
+        """ Generate code for call sequence """
+        # Move arguments into proper locations:
+        reguses = []
+        for i, a in enumerate(e.arguments):
+            loc = self.frame.argLoc(i)
+            m = ir.Move(loc, a)
+            self.munchStm(m)
+            if isinstance(loc, ir.Temp):
+                reguses.append(loc)
+        self.emit(Bl(LabelRef(e.f)), src=reguses, dst=[self.frame.rv])
+        d = self.newTmp()
+        self.move(d, self.frame.rv)
+        return d
 
     def munchStm(self, s):
         if isinstance(s, ir.Terminator):