[pypy-svn] r78861 - in pypy/branch/arm-backend/pypy/jit/backend/arm: . helper test

david at codespeak.net david at codespeak.net
Mon Nov 8 11:06:20 CET 2010


Author: david
Date: Mon Nov  8 11:06:18 2010
New Revision: 78861

Modified:
   pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_runner.py
Log:
Fixed decoding of spilled values on stack

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py	Mon Nov  8 11:06:18 2010
@@ -55,7 +55,8 @@
         the failboxes.
         Registers are saved on the stack
         XXX Rest to follow"""
-        i = -1
+        frame_depth = self.decode32(enc, 0)
+        i = 3
         fail_index = -1
         while(True):
             i += 1
@@ -77,7 +78,8 @@
             elif res == '\xFC': # stack location
                 stack_loc = self.decode32(enc, i+1)
                 #XXX ffuu use propper calculation here
-                value = self.decode32(stack, len(r.all_regs)*WORD+40-stack_loc*WORD)
+                value = self.decode32(stack,
+                                    (len(r.all_regs)+frame_depth-stack_loc)*WORD)
                 i += 4
             else: # an int for now
                 reg = ord(enc[i])
@@ -142,8 +144,9 @@
         # XXX free this memory
         # XXX allocate correct amount of memory
         mem = lltype.malloc(rffi.CArray(lltype.Char), (len(args)+5)*4, flavor='raw')
+        self.encode32(mem, 0, regalloc.frame_manager.frame_depth-1)
         i = 0
-        j = 0
+        j = 4
         while(i < len(args)):
             if args[i]:
                 loc = regalloc.loc(args[i])
@@ -217,6 +220,7 @@
             self.mc.gen_load_int(reg.value, addr)
             self.mc.LDR_ri(reg.value, reg.value)
             regs.append(reg)
+            regalloc.possibly_free_var(reg)
         looptoken._arm_arglocs = regs
 
     # cpu interface
@@ -258,7 +262,7 @@
         cb = ARMv7InMemoryBuilder(addr, ARMv7InMemoryBuilder.size_of_gen_load_int)
         if regalloc.frame_manager.frame_depth == 1:
             return
-        n = regalloc.frame_manager.frame_depth*WORD
+        n = (regalloc.frame_manager.frame_depth - 1)*WORD
         self._adjust_sp(n, cb)
 
     def _adjust_sp(self, n, cb=None, fcond=c.AL):

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py	Mon Nov  8 11:06:18 2010
@@ -4,8 +4,9 @@
 
 def gen_emit_op_unary_cmp(true_cond, false_cond):
     def f(self, op, regalloc, fcond):
-        reg = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
-        res = regalloc.force_allocate_reg(op.result)
+        a0 = op.getarg(0)
+        reg = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
+        res = regalloc.force_allocate_reg(op.result, [a0])
         self.mc.CMP_ri(reg.value, 0)
         self.mc.MOV_ri(res.value, 1, true_cond)
         self.mc.MOV_ri(res.value, 0, false_cond)
@@ -24,18 +25,18 @@
         imm_a1 = self._check_imm_arg(arg1, imm_size, allow_zero=allow_zero)
         if commutative and imm_a0:
             l0 = regalloc.make_sure_var_in_reg(arg0, imm_fine=imm_a0)
-            l1 = regalloc.make_sure_var_in_reg(arg1)
-            res = regalloc.force_allocate_reg(op.result)
+            l1 = regalloc.make_sure_var_in_reg(arg1, [arg0])
+            res = regalloc.force_allocate_reg(op.result, [arg0, arg1])
             ri_op(res.value, l1.value, imm=l0.getint(), cond=fcond)
         elif imm_a1:
             l0 = regalloc.make_sure_var_in_reg(arg0, imm_fine=False)
-            l1 = regalloc.make_sure_var_in_reg(arg1, imm_fine=True)
-            res = regalloc.force_allocate_reg(op.result)
+            l1 = regalloc.make_sure_var_in_reg(arg1, [arg0], imm_fine=True)
+            res = regalloc.force_allocate_reg(op.result, [arg0, arg1])
             ri_op(res.value, l0.value, imm=l1.getint(), cond=fcond)
         else:
             l0 = regalloc.make_sure_var_in_reg(arg0, imm_fine=False)
-            l1 = regalloc.make_sure_var_in_reg(arg1, imm_fine=False)
-            res = regalloc.force_allocate_reg(op.result)
+            l1 = regalloc.make_sure_var_in_reg(arg1, [arg0], imm_fine=False)
+            res = regalloc.force_allocate_reg(op.result, [arg0, arg1])
             rr_op(res.value, l0.value, l1.value)
         regalloc.possibly_free_vars_for_op(op)
         return fcond
@@ -43,8 +44,10 @@
 
 def gen_emit_op_by_helper_call(opname):
     def f(self, op, regalloc, fcond):
-        arg1 = regalloc.make_sure_var_in_reg(op.getarg(0), selected_reg=r.r0, imm_fine=False)
-        arg2 = regalloc.make_sure_var_in_reg(op.getarg(1), selected_reg=r.r1, imm_fine=False)
+        a0 = op.getarg(0)
+        a1 = op.getarg(1)
+        arg1 = regalloc.make_sure_var_in_reg(a0, selected_reg=r.r0, imm_fine=False)
+        arg2 = regalloc.make_sure_var_in_reg(a1, [a0], selected_reg=r.r1, imm_fine=False)
         assert arg1 == r.r0
         assert arg2 == r.r1
         res = regalloc.force_allocate_reg(op.result, selected_reg=r.r0)

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py	Mon Nov  8 11:06:18 2010
@@ -32,16 +32,16 @@
             a0, a1 = a1, a0
         if imm_a1:
             l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
-            l1 = regalloc.make_sure_var_in_reg(a1, imm_fine=True)
-            res = regalloc.force_allocate_reg(op.result)
+            l1 = regalloc.make_sure_var_in_reg(a1, [a0], imm_fine=True)
+            res = regalloc.force_allocate_reg(op.result, [a0, a1])
             if l1.getint() < 0:
                 self.mc.SUB_ri(res.value, l0.value, -1 * l1.getint(), s=1)
             else:
                 self.mc.ADD_ri(res.value, l0.value, l1.getint(), s=1)
         else:
             l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
-            l1 = regalloc.make_sure_var_in_reg(a1, imm_fine=False)
-            res = regalloc.force_allocate_reg(op.result)
+            l1 = regalloc.make_sure_var_in_reg(a1, forbidden_vars=[a0], imm_fine=False)
+            res = regalloc.force_allocate_reg(op.result, forbidden_vars=[a0, a1])
             self.mc.ADD_rr(res.value, l0.value, l1.value, s=1)
 
         regalloc.possibly_free_vars_for_op(op)
@@ -54,8 +54,8 @@
         imm_a0 = isinstance(a0, ConstInt) and (a0.getint() <= 0xFF or -1 * a0.getint() <= 0xFF)
         imm_a1 = isinstance(a1, ConstInt) and (a1.getint() <= 0xFF or -1 * a1.getint() <= 0xFF)
         l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=imm_a0)
-        l1 = regalloc.make_sure_var_in_reg(a1, imm_fine=imm_a1)
-        res = regalloc.force_allocate_reg(op.result)
+        l1 = regalloc.make_sure_var_in_reg(a1, [a0], imm_fine=imm_a1)
+        res = regalloc.force_allocate_reg(op.result, [a0, a1])
         if imm_a0:
             value = l0.getint()
             if value < 0:
@@ -78,18 +78,22 @@
         return fcond
 
     def emit_op_int_mul(self, op, regalloc, fcond):
-        reg1 = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
-        reg2 = regalloc.make_sure_var_in_reg(op.getarg(1), imm_fine=False)
-        res = regalloc.force_allocate_reg(op.result)
+        a0 = op.getarg(0)
+        a1 = op.getarg(1)
+        reg1 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
+        reg2 = regalloc.make_sure_var_in_reg(a1, [a0], imm_fine=False)
+        res = regalloc.force_allocate_reg(op.result, [a0, a1])
         self.mc.MUL(res.value, reg1.value, reg2.value)
         regalloc.possibly_free_vars_for_op(op)
         return fcond
 
     #ref: http://blogs.arm.com/software-enablement/detecting-overflow-from-mul/
     def emit_op_int_mul_ovf(self, op, regalloc, fcond):
-        reg1 = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
-        reg2 = regalloc.make_sure_var_in_reg(op.getarg(1), imm_fine=False)
-        res = regalloc.force_allocate_reg(op.result)
+        a0 = op.getarg(0)
+        a1 = op.getarg(1)
+        reg1 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
+        reg2 = regalloc.make_sure_var_in_reg(a1, [a0], imm_fine=False)
+        res = regalloc.force_allocate_reg(op.result, [a0, a1])
         self.mc.SMULL(res.value, r.ip.value, reg1.value, reg2.value, cond=fcond)
         self.mc.CMP_rr(r.ip.value, res.value, shifttype=shift.ASR, s=31, cond=fcond)
         regalloc.possibly_free_vars_for_op(op)
@@ -129,8 +133,9 @@
     emit_op_int_is_zero = gen_emit_op_unary_cmp(c.EQ, c.NE)
 
     def emit_op_int_invert(self, op, regalloc, fcond):
-        reg = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
-        res = regalloc.force_allocate_reg(op.result)
+        a0 = op.getarg(0)
+        reg = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
+        res = regalloc.force_allocate_reg(op.result, [a0])
 
         self.mc.MVN_rr(res.value, reg.value)
         regalloc.possibly_free_vars_for_op(op)
@@ -139,9 +144,9 @@
     #XXX check for a better way of doing this
     def emit_op_int_neg(self, op, regalloc, fcond):
             arg = op.getarg(0)
-            l0 = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
-            l1 = regalloc.make_sure_var_in_reg(ConstInt(-1), imm_fine=False)
-            res = regalloc.force_allocate_reg(op.result)
+            l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
+            l1 = regalloc.make_sure_var_in_reg(ConstInt(-1), [arg], imm_fine=False)
+            res = regalloc.force_allocate_reg(op.result, [a0])
             self.mc.MUL(res.value, l0.value, l1.value)
             regalloc.possibly_free_vars([l0, l1, res])
             return fcond
@@ -225,11 +230,13 @@
 class FieldOpAssembler(object):
 
     def emit_op_setfield_gc(self, op, regalloc, fcond):
+        a0 = op.getarg(0)
+        a1 = op.getarg(1)
         ofs, size, ptr = self._unpack_fielddescr(op.getdescr())
         #ofs_loc = regalloc.make_sure_var_in_reg(ConstInt(ofs))
         #size_loc = regalloc.make_sure_var_in_reg(ofs)
-        base_loc = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
-        value_loc = regalloc.make_sure_var_in_reg(op.getarg(1), imm_fine=False)
+        base_loc = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
+        value_loc = regalloc.make_sure_var_in_reg(a1, [a0], imm_fine=False)
         if size == 4:
             f = self.mc.STR_ri
         elif size == 2:
@@ -242,10 +249,11 @@
         return fcond
 
     def emit_op_getfield_gc(self, op, regalloc, fcond):
+        a0 = op.getarg(0)
         ofs, size, ptr = self._unpack_fielddescr(op.getdescr())
         # ofs_loc = regalloc.make_sure_var_in_reg(ConstInt(ofs))
-        base_loc = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
-        res = regalloc.force_allocate_reg(op.result)
+        base_loc = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
+        res = regalloc.force_allocate_reg(op.result, [a0])
         if size == 4:
             f = self.mc.LDR_ri
         elif size == 2:

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py	Mon Nov  8 11:06:18 2010
@@ -15,7 +15,8 @@
         RegisterManager.__init__(self, longevity, frame_manager, assembler)
 
     def update_bindings(self, enc, inputargs):
-        j = 0
+        # first word contains frame depth
+        j = 4
         for i in range(len(inputargs)):
             # XXX decode imm and and stack locs and REFs
             while enc[j] == '\xFE':

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_runner.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_runner.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_runner.py	Mon Nov  8 11:06:18 2010
@@ -1,6 +1,15 @@
 from pypy.jit.backend.arm.runner import ArmCPU
 from pypy.jit.backend.test.runner_test import LLtypeBackendTest
 from pypy.jit.backend.arm.test.support import skip_unless_arm
+from pypy.jit.metainterp.history import (AbstractFailDescr,
+                                         AbstractDescr,
+                                         BasicFailDescr,
+                                         BoxInt, Box, BoxPtr,
+                                         LoopToken,
+                                         ConstInt, ConstPtr,
+                                         BoxObj, Const,
+                                         ConstObj, BoxFloat, ConstFloat)
+from pypy.jit.metainterp.resoperation import ResOperation, rop
 
 skip_unless_arm()
 
@@ -14,3 +23,27 @@
 
     def setup_method(self, meth):
         self.cpu = ArmCPU(rtyper=None, stats=FakeStats())
+
+    def test_result_is_spilled(self):
+        cpu = self.cpu
+        inp = [BoxInt(i) for i in range(1, 15)]
+        out = list(inp)
+        out.reverse()
+        looptoken = LoopToken()
+        operations = [
+            ResOperation(rop.INT_ADD, [inp[0], inp[1]], inp[2]),
+            ResOperation(rop.INT_SUB, [inp[1], ConstInt(1)], inp[4]),
+            ResOperation(rop.INT_ADD, [inp[4], ConstInt(0)], inp[3]),
+            ResOperation(rop.INT_ADD, [inp[5], inp[6]], inp[7]),
+            ResOperation(rop.INT_SUB, [inp[8], ConstInt(1)], inp[9]),
+            ResOperation(rop.INT_ADD, [inp[10], ConstInt(1)], inp[3]),
+            ResOperation(rop.INT_ADD, [inp[11], inp[12]], inp[13]),
+            ResOperation(rop.FINISH, out, None, descr=BasicFailDescr(1)),
+            ]
+        cpu.compile_loop(inp, operations, looptoken)
+        for i in range(1, 15):
+            self.cpu.set_future_value_int(i-1, i)
+        res = self.cpu.execute_token(looptoken)
+        output = [self.cpu.get_latest_value_int(i-1) for i in range(1, 15)]
+        expected = [25,13,12,11,8,9,13,7,6,1,12,3,2,1]
+        assert output == expected



More information about the Pypy-commit mailing list