diff python/codegenarm.py @ 219:1fa3e0050b49

Expanded ad hoc code generator
author Windel Bouwman
date Sat, 06 Jul 2013 12:38:09 +0200
parents 494828a7adf1
children c3f1ce8b638f
line wrap: on
line diff
--- a/python/codegenarm.py	Fri Jul 05 15:30:22 2013 +0200
+++ b/python/codegenarm.py	Sat Jul 06 12:38:09 2013 +0200
@@ -4,7 +4,10 @@
 from ppci import CompilerError
 
 class ArmCodeGenerator:
-    """ Simple code generator """
+    """
+        Simple code generator
+        Ad hoc implementation
+    """
     def __init__(self, out):
         self.outs = out
 
@@ -21,8 +24,14 @@
             # TODO: use initial value:
             self.emit(arm.dcd_ins(0))
 
+        self.imms = [] # list with immediates relative to PC.
         self.outs.selectSection('code')
         for f in ircode.Functions:
+            # Add global variable addresses to immediate list:
+            for gvar in ircode.Variables:
+                pass  #self.imms.append((
+
+            self.stack_frame = []
             self.emit(ALabel(f.name))
             # Save some registers:
             self.emit(arm.push_ins(arm.RegisterSet({arm.r4, arm.r5, arm.r6,arm.r7,arm.lr})))
@@ -31,27 +40,67 @@
                 for ins in bb.Instructions:
                     self.generateInstruction(ins)
 
+            self.outs.align(4)
+            while self.imms:
+                l, v = self.imms.pop()
+                self.emit(ALabel(l))
+                self.emit(arm.dcd_ins(v))
+            self.outs.align(4)
+
+    def getStack(self, v):
+        off = self.stack_frame.index(v)
+        return off * 4
+    def addStack(self, v):
+        self.stack_frame.append(v)
+        return self.getStack(v)
+    def getGlobal(self, r, g):
+        _global_address = g.name + '__global'
+        self.emit(arm.ldr_pcrel(r, ALabel(_global_address)))
+
     def generateInstruction(self, ins):
         if type(ins) is ir.Branch:
-            self.emit(arm.jmp_ins(ins.target))
-        elif type(ins) is ir.ImmLoad and ins.value < 255:
-            self.emit(arm.mov_ins(arm.r0, arm.Imm8(ins.value)))
-            # determine stack frame..
-            self.emit(arm.mov_ins(arm.r1, arm.Imm8(9)))
-            #self.emit(arm.
-        elif type(ins) is ir.ImmLoad and ins.value < (2**32):
-            print(ins)
+            tgt = ALabel(ins.target.name)
+            self.emit(arm.jmp_ins(tgt))
+        elif type(ins) is ir.ImmLoad:
+            lname = ins.target.name + '_ivalue'
+            self.emit(arm.ldr_pcrel(arm.r0, ALabel(lname)))
+            self.imms.append((lname, ins.value))
+            self.emit(arm.str_sprel(arm.r0, self.addStack(ins.target)))
         elif type(ins) is ir.Store:
-            print(ins)
-        elif type(ins) is ir.Return:
-            self.emit(arm.pop_ins(arm.RegisterSet({arm.r5, arm.r6, arm.pc})))
+            # Load value in r0:
+            self.emit(arm.ldr_sprel(arm.r0, self.getStack(ins.value)))
+            # store in memory:
+            self.getGlobal(arm.r1, ins.location)
+            self.emit(arm.storeimm5_ins(arm.r0, arm.MemoryOp(arm.r1, 0)))
         elif type(ins) is ir.Load:
-            print(ins)
+            self.getGlobal(arm.r0, ins.location)
+            self.emit(arm.loadimm5_ins(arm.r0, arm.MemoryOp(arm.r0, 0)))
+            # Store value on stack:
+            self.emit(arm.str_sprel(arm.r0, self.addStack(ins.value)))
         elif type(ins) is ir.BinaryOperator:
-            print(ins)
+            # Load operands:
+            self.emit(arm.ldr_sprel(arm.r0, self.getStack(ins.value1)))
+            self.emit(arm.ldr_sprel(arm.r1, self.getStack(ins.value2)))
+            # do operation:
+            if ins.operation == '+':
+                self.emit(arm.addregs_ins(arm.r0, arm.r0, arm.r1))
+            else:
+                print('operation not implemented', ins.operation)
+            # Store value back:
+            self.emit(arm.str_sprel(arm.r0, self.addStack(ins.result)))
+        elif type(ins) is ir.Return:
+            self.emit(arm.pop_ins(arm.RegisterSet({arm.r4, arm.r5, arm.r6, arm.r7, arm.pc})))
         elif type(ins) is ir.ConditionalBranch:
-            print(ins)
+            self.emit(arm.ldr_sprel(arm.r0, self.getStack(ins.a)))
+            self.emit(arm.ldr_sprel(arm.r1, self.getStack(ins.b)))
             self.emit(arm.cmp_ins(arm.r1, arm.r0))
+            tgt_yes = ALabel(ins.lab1.name)
+            if ins.cond == '==':
+                self.emit(arm.beq_ins(tgt_yes))
+            else:
+                print('TODO', ins.cond)
+            tgt_no = ALabel(ins.lab2.name)
+            self.emit(arm.jmp_ins(tgt_no))
         else:
             raise CompilerError('IR "{}" not covered'.format(ins))