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

david at codespeak.net david at codespeak.net
Mon Nov 1 16:00:26 CET 2010


Author: david
Date: Mon Nov  1 16:00:24 2010
New Revision: 78636

Modified:
   pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/codebuilder.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py
Log:
Refactor branch and branch with link patters to methods

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  1 16:00:24 2010
@@ -101,9 +101,7 @@
                                     # parameter to next procedure call
         self.mc.MOV_rr(r.r1.value, r.sp.value)  # pass the current stack pointer as second param
 
-        self.mc.ADD_ri(r.lr.value, r.pc.value, 4)
-        self.mc.LDR_ri(r.pc.value, r.pc.value, -4)
-        self.mc.write32(rffi.cast(lltype.Signed, decode_registers_addr))
+        self.mc.BL(rffi.cast(lltype.Signed, decode_registers_addr))
         self.mc.MOV_rr(r.ip.value, r.r0.value)
         self.mc.LDM(r.sp.value, range(12), w=1) # XXX Replace with POP instr. someday
 
@@ -139,9 +137,8 @@
 
         n = self.cpu.get_fail_descr_number(op.getdescr())
         self.encode32(mem, j+1, n)
-        self.mc.gen_load_int(r.lr.value, memaddr, cond=fcond)
-        self.mc.gen_load_int(reg.value, self._exit_code_addr, cond=fcond)
-        self.mc.MOV_rr(r.pc.value, reg.value, cond=fcond)
+        self.mc.gen_load_int(r.lr.value, memaddr, cond=fcond) # use lr to pass an argument
+        self.mc.B(self._exit_code_addr, fcond, reg)
 
         # This register is used for patching when assembling a bridge
         # guards going to be patched are allways conditional
@@ -183,6 +180,7 @@
         looptoken._arm_bootstrap_code = loop_start
         looptoken._arm_loop_code = loop_head
         fcond=c.AL
+        #print inputargs, operations
         for op in operations:
             # XXX consider merging ops with next one if it is an adecuate guard
             opnum = op.getopnum()
@@ -222,10 +220,8 @@
     def patch_trace(self, faildescr, bridge_addr):
         # XXX make sure there is enough space at patch target
         fcond = faildescr._arm_guard_cond
-        b = ARMv7InMemoryBuilder(faildescr._arm_guard_code, faildescr._arm_guard_code+100)
-        reg = faildescr._arm_guard_reg
-        b.gen_load_int(reg.value, bridge_addr, fcond)
-        b.MOV_rr(r.pc.value, reg.value, cond=fcond)
+        b = ARMv7InMemoryBuilder(faildescr._arm_guard_code, faildescr._arm_guard_size)
+        b.B(bridge_addr, fcond, some_reg=faildescr._arm_guard_reg)
 
     # regalloc support
     def regalloc_mov(self, prev_loc, loc):

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/codebuilder.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/codebuilder.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/codebuilder.py	Mon Nov  1 16:00:24 2010
@@ -12,16 +12,16 @@
 def binary_helper_call(name):
     signature = getattr(arch, 'arm_%s_sign' % name)
     function = getattr(arch, 'arm_%s' % name)
-    def f(self, cond=cond.AL):
+    def f(self, c=cond.AL):
         """Generates a call to a helper function, takes its
         arguments in r0 and r1, result is placed in r0"""
-        self.ensure_can_fit(self.size_of_gen_load_int*2+3*WORD)
-        self.PUSH(range(2, 4), cond=cond)
         addr = rffi.cast(lltype.Signed, llhelper(signature, function))
-        self.gen_load_int(reg.r2.value, addr, cond=cond)
-        self.gen_load_int(reg.lr.value, self.curraddr()+self.size_of_gen_load_int+WORD, cond=cond)
-        self.MOV_rr(reg.pc.value, reg.r2.value, cond=cond)
-        self.LDM(reg.sp.value, range(2, 4), w=1, cond=cond) # XXX Replace with POP instr. someday
+        if c == cond.AL:
+            self.BL(addr)
+        else:
+            self.PUSH(range(2, 4), cond=c)
+            self.BL(addr, cond=c, some_reg=reg.r2)
+            self.LDM(reg.sp.value, range(2, 4), w=1, cond=c) # XXX Replace with POP instr. someday
     return f
 
 class AbstractARMv7Builder(object):
@@ -52,6 +52,30 @@
     def BKPT(self, cond=cond.AL):
         self.write32(cond << 28 | 0x1200070)
 
+    def B(self, target, c=cond.AL, some_reg=None):
+        if c == cond.AL:
+            self.ensure_can_fit(2*WORD)
+            self.LDR_ri(reg.pc.value, reg.pc.value, -4)
+            self.write32(target)
+        else:
+            assert some_reg is not None
+            self.ensure_can_fit(self.size_of_gen_load_int+WORD)
+            self.gen_load_int(some_reg.value, target, cond=c)
+            self.MOV_rr(reg.pc.value, some_reg.value, cond=c)
+
+    def BL(self, target, c=cond.AL, some_reg=None):
+        if c == cond.AL:
+            self.ensure_can_fit(3*WORD)
+            self.ADD_ri(reg.lr.value, reg.pc.value, 4)
+            self.LDR_ri(reg.pc.value, reg.pc.value, imm=-4)
+            self.write32(target)
+        else:
+            assert some_reg is not None
+            self.ensure_can_fit(self.size_of_gen_load_int*2+WORD)
+            self.gen_load_int(some_reg.value, target, cond=c)
+            self.gen_load_int(reg.lr.value, self.curraddr()+self.size_of_gen_load_int+WORD, cond=c)
+            self.MOV_rr(reg.pc.value, some_reg.value, cond=c)
+
     DIV = binary_helper_call('int_div')
     MOD = binary_helper_call('int_mod')
     UDIV = binary_helper_call('uint_div')
@@ -104,6 +128,11 @@
         data = rffi.cast(PTR, start)
         self._init(data, map_size)
 
+    def ensure_can_fit(self, n):
+        """ensure after this call there is enough space for n instructions
+        in a contiguous memory chunk or raise an exception"""
+        if not self._pos + n < self._size:
+            raise ValueError
 
 class ARMv7Builder(AbstractARMv7Builder):
 

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  1 16:00:24 2010
@@ -128,7 +128,7 @@
             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)
-            self.mc.MUL(res.value, reg.value, reg2.value)
+            self.mc.MUL(res.value, l0.value, l1.value)
             regalloc.possibly_free_vars([l0, l1, res])
             return fcond
 
@@ -142,6 +142,7 @@
         memaddr = self._gen_path_to_exit_path(op, op.getfailargs(), regalloc, fcond)
         descr._failure_recovery_code = memaddr
         descr._arm_guard_cond = fcond
+        descr._arm_guard_size = self.mc.curraddr() - descr._arm_guard_code
 
     def emit_op_guard_true(self, op, regalloc, fcond):
         assert fcond == c.LE
@@ -166,8 +167,7 @@
             inpreg = registers[i]
             self.mc.MOV_rr(inpreg.value, reg.value)
         loop_code = op.getdescr()._arm_loop_code
-        self.mc.LDR_ri(r.pc.value, r.pc.value, -4)
-        self.mc.write32(loop_code)
+        self.mc.B(loop_code, fcond)
         return fcond
 
     def emit_op_finish(self, op, regalloc, fcond):

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py	Mon Nov  1 16:00:24 2010
@@ -91,8 +91,7 @@
         self.a.mc.CMP_ri(r.r1.value, 0) # z=0, z=1
         self.a.mc.MOV_ri(r.r1.value, 0, cond=c.NE)
         self.a.mc.MOV_ri(r.r1.value, 7, cond=c.EQ)
-        self.a.mc.gen_load_int(r.r4.value, loop_head, cond=c.NE)
-        self.a.mc.MOV_rr(r.pc.value, r.r4.value, cond=c.NE)
+        self.a.mc.B(loop_head, c.NE, some_reg = r.r4)
         self.a.mc.MOV_rr(r.r0.value, r.r1.value)
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 7
@@ -103,8 +102,7 @@
         loop_head = self.a.mc.curraddr()
         self.a.mc.ADD_ri(r.r1.value, r.r1.value, 1)
         self.a.mc.CMP_ri(r.r1.value, 9)
-        self.a.mc.gen_load_int(r.r4.value, loop_head, cond=c.NE)
-        self.a.mc.MOV_rr(r.pc.value, r.r4.value, cond=c.NE)
+        self.a.mc.B(loop_head, c.NE, some_reg = r.r4)
         self.a.mc.MOV_rr(r.r0.value, r.r1.value)
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 9
@@ -127,9 +125,7 @@
         call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
         self.a.gen_func_prolog()
         self.a.mc.MOV_ri(r.r0.value, 123)
-        self.a.mc.gen_load_int(r.r1.value, call_addr)
-        self.a.mc.gen_load_int(r.lr.value, self.a.mc.curraddr()+self.a.mc.size_of_gen_load_int+WORD)
-        self.a.mc.MOV_rr(r.pc.value, r.r1.value)
+        self.a.mc.BL(call_addr)
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 133
 
@@ -141,9 +137,7 @@
         # call to div
         self.a.mc.PUSH(range(2, 12))
         div_addr = rffi.cast(lltype.Signed, llhelper(arm_int_div_sign, arm_int_div))
-        self.a.mc.gen_load_int(r.r10.value, div_addr)
-        self.a.mc.gen_load_int(r.lr.value, self.a.mc.curraddr()+self.a.mc.size_of_gen_load_int+WORD)
-        self.a.mc.MOV_rr(r.pc.value, r.r10.value)
+        self.a.mc.BL(div_addr, some_reg=r.r2)
         self.a.mc.LDM(r.sp.value, range(2, 12), w=1) # XXX Replace with POP instr. someday
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 61
@@ -174,6 +168,17 @@
         self.a.gen_func_epilog()
         assert run_asm(self.a) == -36
 
+
+    def test_bl_with_conditional_exec(self):
+        functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
+        call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
+        self.a.gen_func_prolog()
+        self.a.mc.MOV_ri(r.r0.value, 123)
+        self.a.mc.CMP_ri(r.r0.value, 1)
+        self.a.mc.BL(call_addr, c.NE, some_reg=r.r1)
+        self.a.gen_func_epilog()
+        assert run_asm(self.a) == 133
+
 def callme(inp):
     i = inp + 10
     return i



More information about the Pypy-commit mailing list