[pypy-svn] r78538 - pypy/branch/arm-backend/pypy/jit/backend/arm

david at codespeak.net david at codespeak.net
Sat Oct 30 17:53:49 CEST 2010


Author: david
Date: Sat Oct 30 17:53:48 2010
New Revision: 78538

Modified:
   pypy/branch/arm-backend/pypy/jit/backend/arm/arch.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/codebuilder.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/instruction_builder.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
Log:
Implement uint_floordiv and some helper functions to generate operations

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/arch.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/arch.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/arch.py	Sat Oct 30 17:53:48 2010
@@ -1,14 +1,18 @@
+from pypy.rlib.rarithmetic import r_uint
 from pypy.rpython.lltypesystem import lltype
 
 FUNC_ALIGN=8
 WORD=4
 
 arm_int_div_sign = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
-arm_int_mod_sign = arm_int_div_sign
-
 def arm_int_div(a, b):
     return int(a/float(b))
 
+arm_uint_div_sign = lltype.Ptr(lltype.FuncType([lltype.Unsigned, lltype.Unsigned], lltype.Unsigned))
+def arm_uint_div(a, b):
+    return r_uint(a)/r_uint(b)
+
+arm_int_mod_sign = arm_int_div_sign
 def arm_int_mod(a, b):
     sign = 1
     if a < 0:
@@ -18,3 +22,4 @@
         b = -1 * b
     res = a % b
     return sign * res
+

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	Sat Oct 30 17:53:48 2010
@@ -1,7 +1,7 @@
+from pypy.jit.backend.arm import arch
 from pypy.jit.backend.arm import conditions as cond
 from pypy.jit.backend.arm import registers as reg
-from pypy.jit.backend.arm.arch import (WORD, FUNC_ALIGN, arm_int_div,
-                                        arm_int_div_sign, arm_int_mod_sign, arm_int_mod)
+from pypy.jit.backend.arm.arch import (WORD, FUNC_ALIGN)
 from pypy.jit.backend.arm.instruction_builder import define_instructions
 
 from pypy.rlib.rmmap import alloc, PTR
@@ -9,6 +9,20 @@
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.jit.metainterp.history import ConstInt, BoxInt, Box, BasicFailDescr
 
+def binary_helper_call(name):
+    signature = getattr(arch, 'arm_%s_sign' % name)
+    function = getattr(arch, 'arm_%s' % name)
+    def f(self, cond=cond.AL):
+        """Generates a call to a helper function, takes its
+        arguments in r0 and r1, result is placed in r0"""
+        self.PUSH(range(2, 12), 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, 12), w=1, cond=cond) # XXX Replace with POP instr. someday
+    return f
+
 class AbstractARMv7Builder(object):
     def _init(self, data, map_size):
         self._data = data
@@ -43,25 +57,9 @@
     def BKPT(self, cond=cond.AL):
         self.write32(cond << 28 | 0x1200070)
 
-    def DIV(self, cond=cond.AL):
-        """Generates a call to a helper function used for division, takes its
-        arguments in r0 and r1, result is placed in r0"""
-        self.PUSH(range(2, 12), cond=cond)
-        div_addr = rffi.cast(lltype.Signed, llhelper(arm_int_div_sign, arm_int_div))
-        self.gen_load_int(reg.r2.value, div_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, 12), w=1, cond=cond) # XXX Replace with POP instr. someday
-
-    def MOD(self, cond=cond.AL):
-        """Generate a call to a helper function used for modulo, takes its
-        arguments in r0 and r1, result is placed in r0"""
-        self.PUSH(range(2, 12), cond=cond)
-        mod_addr = rffi.cast(lltype.Signed, llhelper(arm_int_mod_sign, arm_int_mod))
-        self.gen_load_int(reg.r2.value, mod_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, 12), w=1, cond=cond) # XXX Replace with POP instr. someday
+    DIV = binary_helper_call('int_div')
+    MOD = binary_helper_call('int_mod')
+    UDIV = binary_helper_call('uint_div')
 
     def _encode_reg_list(self, instr, regs):
         for reg in regs:
@@ -121,7 +119,7 @@
         self.checks = True
         self.n_data=0
 
-    _space_for_jump = 10 * WORD
+    _space_for_jump = 9 * WORD
     def writechar(self, char):
         if self.checks and not self._pos < self._size - self._space_for_jump:
             self.checks = False
@@ -133,13 +131,13 @@
     def _add_more_mem(self):
         new_mem = alloc(self._size)
         new_mem_addr = rffi.cast(lltype.Signed, new_mem)
-        self.PUSH([reg.r0.value, reg.ip.value])
-        self.gen_load_int(reg.r0.value, new_mem_addr)
-        self.MOV_rr(reg.pc.value, reg.r0.value)
+        self.PUSH([reg.ip.value, reg.lr.value])
+        self.gen_load_int(reg.lr.value, new_mem_addr)
+        self.MOV_rr(reg.pc.value, reg.lr.value)
         self._dump_trace('data%d.asm' % self.n_data)
-        self.n_data+=1
+        self.n_data += 1
         self._data = new_mem
         self._pos = 0
-        self.LDM(reg.sp.value, [reg.r0.value, reg.ip.value], w=1) # XXX Replace with POP instr. someday
+        self.LDM(reg.sp.value, [reg.ip.value, reg.lr.value], w=1) # XXX Replace with POP instr. someday
 
 define_instructions(AbstractARMv7Builder)

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/instruction_builder.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/instruction_builder.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/instruction_builder.py	Sat Oct 30 17:53:48 2010
@@ -175,6 +175,8 @@
 
     return f
 
+def define_long_mult_div_instructions(name, table):
+    pass
 def imm_operation(rt, rn, imm):
     return ((rn & 0xFF) << 16
     | (rt & 0xFF) << 12

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	Sat Oct 30 17:53:48 2010
@@ -39,6 +39,19 @@
         return fcond
     return f
 
+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)
+        arg2 = regalloc.make_sure_var_in_reg(op.getarg(1), selected_reg=r.r1)
+        assert arg1 == r.r0
+        assert arg2 == r.r1
+        res = regalloc.try_allocate_reg(op.result)
+        getattr(self.mc, opname)(fcond)
+        self.mc.MOV_rr(res.value, r.r0.value, cond=fcond)
+        regalloc.possibly_free_vars_for_op(op)
+        return fcond
+    return f
+
 class IntOpAsslember(object):
     _mixin_ = True
 
@@ -104,28 +117,6 @@
         regalloc.possibly_free_var(reg2)
         return fcond
 
-    def emit_op_int_floordiv(self, op, regalloc, fcond):
-        arg1 = regalloc.make_sure_var_in_reg(op.getarg(0), selected_reg=r.r0)
-        arg2 = regalloc.make_sure_var_in_reg(op.getarg(1), selected_reg=r.r1)
-        assert arg1 == r.r0
-        assert arg2 == r.r1
-        res = regalloc.try_allocate_reg(op.result)
-        self.mc.DIV(fcond)
-        self.mc.MOV_rr(res.value, r.r0.value, cond=fcond)
-        regalloc.possibly_free_vars_for_op(op)
-        return fcond
-
-    def emit_op_int_mod(self, op, regalloc, fcond):
-        res = regalloc.force_allocate_reg(op.result)
-        arg1 = regalloc.make_sure_var_in_reg(op.getarg(0), selected_reg=r.r0)
-        arg2 = regalloc.make_sure_var_in_reg(op.getarg(1), selected_reg=r.r1)
-        assert arg1 == r.r0
-        assert arg2 == r.r1
-        self.mc.MOD(fcond)
-        self.mc.MOV_rr(res.value, r.r0.value, cond=fcond)
-        regalloc.possibly_free_vars_for_op(op)
-        return fcond
-
     def _put_in_reg(self, box, regalloc):
         if isinstance(box, ConstInt):
             t = Box()
@@ -135,6 +126,10 @@
             reg = regalloc.try_allocate_reg(box)
         return reg
 
+    emit_op_int_floordiv = gen_emit_op_by_helper_call('DIV')
+    emit_op_int_mod = gen_emit_op_by_helper_call('MOD')
+    emit_op_uint_floordiv = gen_emit_op_by_helper_call('UDIV')
+
     emit_op_int_and = gen_emit_op_ri('AND')
     emit_op_int_or = gen_emit_op_ri('ORR')
     emit_op_int_xor = gen_emit_op_ri('EOR')



More information about the Pypy-commit mailing list