diff python/codegenarm.py @ 279:2ccd57b1d78c

Fix register allocator to do burn2 OK
author Windel Bouwman
date Sat, 12 Oct 2013 09:56:23 +0200
parents 046017431c6a
children 02385f62f250
line wrap: on
line diff
--- a/python/codegenarm.py	Sun Sep 29 14:08:15 2013 +0200
+++ b/python/codegenarm.py	Sat Oct 12 09:56:23 2013 +0200
@@ -70,11 +70,15 @@
         """
         self.instructions.insert(0, makeIns('{}:'.format(self.name)))
         self.instructions.insert(1, makeIns('push {lr, r7}'))
-        self.instructions.insert(2, makeIns('mov r7, sp'))
-        self.instructions.insert(3, makeIns('add sp, sp, {}'.format(self.stacksize)))
-        self.instructions.append(makeIns('sub sp, sp, {}'.format(self.stacksize)))
+        # Reserve stack space for locals:
+        self.instructions.insert(2, makeIns('sub sp, sp, {}'.format(self.stacksize)))
+        # Setup frame pointer:
+        self.instructions.insert(3, makeIns('mov r7, sp'))
+        # Stack grows downwards
+        self.instructions.append(makeIns('add sp, sp, {}'.format(self.stacksize)))
         self.instructions.append(makeIns('pop {pc,r7}'))
         # Add constant literals:
+        self.instructions.append(makeIns('align 4')) # Align at 4 bytes
         for ln, v in self.constants:
             self.instructions.append(makeIns('{}:'.format(ln)))
             self.instructions.append(makeIns('dcd {}'.format(v)))
@@ -86,7 +90,8 @@
     def munchExpr(self, e):
         if isinstance(e, ir.Alloc):
             return 0
-        elif isinstance(e, ir.Binop) and e.operation == '+' and isinstance(e.b, ir.Const) and e.b.value < 8:
+        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()
             self.emit('add %d0, %s0, {}'.format(e.b.value), dst=[d], src=[a])
@@ -97,7 +102,8 @@
             d = self.newTmp()
             self.emit('add %d0, %s0, %s1', 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:
+        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()
             self.emit('sub %d0, %s0, {}'.format(e.b.value), dst=[d], src=[a])
@@ -112,22 +118,23 @@
             a = self.munchExpr(e.a)
             b = self.munchExpr(e.b)
             d = self.newTmp()
-            self.emit('mov %d0, %s0', src=[a], dst=[d])
-            self.emit('orr %d0, %s0', dst=[d], src=[b, d])
+            self.move(d, a)
+            self.emit('orr %s1, %s0', dst=[], src=[b, d])
             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('mov %d0, %s0', src=[a], dst=[d])
-            self.emit('lsl %d0, %s0', dst=[d], src=[b, d]) # TODO: is d a source variable?
+            self.move(d, a)
+            self.emit('lsl %s1, %s0', dst=[], src=[b, d]) # 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.emit('mov %d0, %s0', src=[a], dst=[d])
-            self.emit('mul %d0, %s0', dst=[d], src=[b, d])
+            self.move(d, a)
+            # this mul instruction has operands swapped:
+            self.emit('mul %s0, %d0', dst=[d], src=[b, d])
             return d
         elif isinstance(e, ir.Const) and e.value < 256:
             d = self.newTmp()
@@ -142,7 +149,8 @@
                 e.e.operation == '+' and isinstance(e.e.b, ir.Const):
             base = self.munchExpr(e.e.a)
             d = self.newTmp()
-            self.emit('ldr %d0, [%s0 + {}]'.format(e.e.b.value), src=[base], dst=[d])
+            c = e.e.b.value
+            self.emit('ldr %d0, [%s0 + {}]'.format(c), src=[base], dst=[d])
             return d
         elif isinstance(e, ir.Mem):
             # Load from memory
@@ -171,9 +179,13 @@
     def munchStm(self, s):
         if isinstance(s, ir.Terminator):
             pass
-        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and isinstance(s.dst.e.a, ir.Temp) and isinstance(s.dst.e.b, ir.Const):
+        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \
+            isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \
+            isinstance(s.dst.e.b, ir.Const):
+            a = self.munchExpr(s.dst.e.a)
             val = self.munchExpr(s.src)
-            self.emit('str %s1, [%s0 + {}]'.format(s.dst.e.b.value), src=[s.dst.e.a, val])
+            c = s.dst.e.b.value
+            self.emit('str %s1, [%s0 + {}]'.format(c), src=[a, val])
         elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
             memloc = self.munchExpr(s.dst.e)
             val = self.munchExpr(s.src)
@@ -185,7 +197,7 @@
         elif isinstance(s, ir.Exp):
             # Generate expression code and discard the result.
             x = self.munchExpr(s.e)
-            self.emit('mov r0, r0', src=[x])
+            self.emit('nop', src=[x])
         elif isinstance(s, ir.Jump):
             tgt = self.targets[s.target]
             self.emit('b {}'.format(s.target.name), jumps=[tgt])
@@ -248,6 +260,10 @@
         # another interface?
         assembler = asm.Assembler(target=arm.armtarget, stream=self.outs)
         self.outs.selectSection('code')
+        # assembly glue to make it work:
+        self.outs.emit(arm.dcd_ins(Imm32(0x20000678))) # initial SP
+        self.outs.emit(arm.dcd_ins(Imm32(0x08000009))) # reset vector
+        self.outs.emit(arm.b_ins(LabelRef('main')))
         for frame in self.frames:
             for i in frame.instructions:
                 assembler.assemble_line(str(i))