diff python/codegenarm.py @ 274:ea93e0a7a31e

Move docs
author Windel Bouwman
date Wed, 04 Sep 2013 17:35:06 +0200
parents e64bae57cda8
children 6f2423df0675
line wrap: on
line diff
--- a/python/codegenarm.py	Mon Sep 02 17:40:21 2013 +0200
+++ b/python/codegenarm.py	Wed Sep 04 17:35:06 2013 +0200
@@ -8,8 +8,19 @@
 from instructionselector import InstructionSelector
 import irmach
 
+
+class ArmFrame(irmach.Frame):
+    """
+      Arm specific frame for functions.
+    """
+    pass
+
+
 class ArmInstructionSelector(InstructionSelector):
     """ Instruction selector for the arm architecture """
+    def newFrame(self, name):
+        return ArmFrame(name)
+
     def munchExpr(self, e):
         if isinstance(e, ir.Alloc):
             return 0
@@ -58,9 +69,15 @@
             return d
         elif isinstance(e, ir.Temp):
             return self.getTempReg(e)
+        elif isinstance(e, ir.Parameter):
+            offset = 1337 # TODO: determine offset in frame??
+            d = self.newTmp()
+            self.emit('ldr %d0, [sp + {}]'.format(offset), dst=[d])
+            return d
         elif isinstance(e, ir.Call):
             args = [self.munchExpr(a) for a in e.arguments]
-            self.emit('add sp, sp, 22')
+            frame_size = 222 # TODO: determine frame size?
+            self.emit('add sp, sp, {}'.format(frame_size))
             # TODO: save frame
             for a in args:
                 self.emit('push %s0', src=[a])
@@ -73,28 +90,31 @@
         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')
+            self.emit('str [%s0], %s1', src=[memloc, val])
         elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
             val = self.munchExpr(s.src)
             dreg = self.getTempReg(s.dst)
             self.emit('mov %d0, %s0', dst=[dreg], src=[val])
         elif isinstance(s, ir.Jump):
             tgt = self.targets[s.target]
-            self.emit('jmp {}'.format(s), jumps=[tgt])
+            self.emit('jmp %l0', jumps=[tgt])
         elif isinstance(s, ir.CJump):
             a = self.munchExpr(s.a)
             b = self.munchExpr(s.b)
             self.emit('cmp %s0, %s1', src=[a, b])
             ntgt = self.targets[s.lab_no]
             ytgt = self.targets[s.lab_yes]
-            jmp_ins = self.makeIns('jmp {}'.format(s.lab_no), jumps=[ntgt])
+            jmp_ins = self.makeIns('jmp %l0', jumps=[ntgt])
             # Explicitely add fallthrough:
-            self.emit('jeq {}'.format(s.lab_yes), jumps=[ytgt, jmp_ins])
+            self.emit('jeq %l0', jumps=[ytgt, jmp_ins])
             self.emit2(jmp_ins)
+        elif isinstance(s, ir.Terminator):
+            pass
         else:
-            raise NotImplementedError('--> {}'.format(s))
+            raise NotImplementedError('Stmt --> {}'.format(s))
 
 
+# TODO: this class could be target independent:
 class ArmCodeGenerator:
     def __init__(self, outs):
         # TODO: schedule traces in better order.
@@ -116,31 +136,42 @@
         defTemps = set(defTemps)
         useTemps = set(useTemps)
         unUsed = defTemps - useTemps
-        #print('Unused:', unUsed)
+        print('Unused:', unUsed)
         for uu in unUsed:
             inslist.append(irmach.AbstractInstruction('use %s0', src=[uu]))
         #print(useTemps)
 
-    def generate(self, ircode, cfg_file=None, ig_file=None):
-        ir2 = self.ins_sel.munchProgram(ircode)
-        self.useUnused(ir2)
-        cfg = flowgraph.FlowGraph(ir2)
-        if cfg_file:
-            cfg.to_dot(cfg_file)
+    def allocFrame(self, f):
+        """
+            Do register allocation for a single stack frame.
+        """
+        ilist = f.instructions
+        self.useUnused(ilist)
+        cfg = flowgraph.FlowGraph(ilist)
+        f.cfg = cfg
         ig = registerallocator.InterferenceGraph(cfg)
-        if ig_file:
-            ig.to_dot(ig_file)
+        f.ig = ig
 
         regs = ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7']
         ra = registerallocator.RegisterAllocator()
         regMap = ra.registerAllocate(ig, regs)
         #print(regMap)
         # Use allocated registers:
-        for i in ir2:
+        for i in ilist:
             i.src = tuple(regMap[t] for t in i.src)
             i.dst = tuple(regMap[t] for t in i.dst)
             #print(i)
-        return ir2
+
+    def generate(self, ircode):
+        # Munch program into a bunch of frames. One frame per function.
+        # Each frame has a flat list of abstract instructions.
+        frames = self.ins_sel.munchProgram(ircode)
+        self.frames = frames
+        for f in frames:
+            self.allocFrame(f)
+
+        # TODO: Peep-hole here
+        # TODO: Materialize assembly
+        return frames
 
 
-