diff python/codegenarm.py @ 276:56d37ed4b4d2

phaa
author Windel Bouwman
date Mon, 16 Sep 2013 21:51:17 +0200
parents 6f2423df0675
children 046017431c6a
line wrap: on
line diff
--- a/python/codegenarm.py	Sat Sep 14 17:29:10 2013 +0200
+++ b/python/codegenarm.py	Mon Sep 16 21:51:17 2013 +0200
@@ -35,6 +35,8 @@
         self.tempMap[self.fp] = 'r7'
         self.locVars = {}
         self.parMap = {}
+        # Literal pool:
+        self.constants = []
 
     def argLoc(self, pos):
         """
@@ -57,6 +59,11 @@
             self.stacksize = self.stacksize + 4
         return self.locVars[lvar]
 
+    def addConstant(self, value):
+        lab_name = '{}_literal_{}'.format(self.name, len(self.constants))
+        self.constants.append((lab_name, value))
+        return lab_name
+
     def EntryExitGlue3(self):
         """
             Add code for the prologue and the epilogue. Add a label, the
@@ -68,9 +75,14 @@
         self.instructions.insert(3, makeIns('add sp, sp, {}'.format(self.stacksize)))
         self.instructions.append(makeIns('sub sp, sp, {}'.format(self.stacksize)))
         self.instructions.append(makeIns('pop {pc,r7}'))
+        # Add constant literals:
+        for ln, v in self.constants:
+            self.instructions.append(makeIns('{}:'.format(ln)))
+            self.instructions.append(makeIns('dcd {}'.format(v)))
 
 
 class ArmInstructionSelector(InstructionSelector):
+
     """ Instruction selector for the arm architecture """
     def munchExpr(self, e):
         if isinstance(e, ir.Alloc):
@@ -101,24 +113,32 @@
             a = self.munchExpr(e.a)
             b = self.munchExpr(e.b)
             d = self.newTmp()
-            self.emit('or %d0, %s0, %s1', dst=[d], src=[a, b])
+            self.emit('mov %d0, %s0', src=[a], dst=[d])
+            self.emit('orr %d0, %s0', dst=[d], 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('lsl %d0, %s0, %s1', dst=[d], src=[a, b])
+            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?
             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('mul %d0, %s0, %s1', dst=[d], src=[a, b])
+            self.emit('mov %d0, %s0', src=[a], dst=[d])
+            self.emit('mul %d0, %s0', dst=[d], src=[b, d])
             return d
         elif isinstance(e, ir.Const) and e.value < 256:
             d = self.newTmp()
             self.emit('mov %d0, {}'.format(e.value), dst=[d])
             return d
+        elif isinstance(e, ir.Const) and e.value < (2**31):
+            d = self.newTmp()
+            ln = self.frame.addConstant(e.value)
+            self.emit('ldr %d0, {}'.format(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)
@@ -176,9 +196,9 @@
             self.emit('cmp %s0, %s1', src=[a, b])
             ntgt = self.targets[s.lab_no]
             ytgt = self.targets[s.lab_yes]
-            jmp_ins = makeIns('jmp {}'.format(s.lab_no.name), jumps=[ntgt])
+            jmp_ins = makeIns('b {}'.format(s.lab_no.name), jumps=[ntgt])
             # Explicitely add fallthrough:
-            self.emit('jeq %l0', jumps=[ytgt, jmp_ins])
+            self.emit('beq {}'.format(s.lab_yes.name), jumps=[ytgt, jmp_ins])
             self.emit2(jmp_ins)
         else:
             raise NotImplementedError('Stmt --> {}'.format(s))
@@ -266,5 +286,8 @@
             for i in frame.instructions:
                 assembler.assemble_line(str(i))
 
+        # TODO: fixup references, do this in another way?
+        self.outs.backpatch()
+        self.outs.backpatch()
         return self.frames