[pypy-svn] pypy arm-backend-2: import some tests from the x86 backend

bivab commits-noreply at bitbucket.org
Wed Feb 2 13:50:38 CET 2011


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r41558:65b41cb0797a
Date: 2011-02-01 02:11 +0100
http://bitbucket.org/pypy/pypy/changeset/65b41cb0797a/

Log:	import some tests from the x86 backend

diff --git a/pypy/jit/backend/arm/test/test_regalloc2.py b/pypy/jit/backend/arm/test/test_regalloc2.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/arm/test/test_regalloc2.py
@@ -0,0 +1,294 @@
+import py
+from pypy.jit.metainterp.history import ResOperation, BoxInt, ConstInt,\
+     BoxPtr, ConstPtr, BasicFailDescr, LoopToken
+from pypy.jit.metainterp.resoperation import rop
+from pypy.jit.backend.detect_cpu import getcpuclass
+from pypy.jit.backend.arm.arch import WORD
+CPU = getcpuclass()
+
+def test_bug_rshift():
+    v1 = BoxInt()
+    v2 = BoxInt()
+    v3 = BoxInt()
+    v4 = BoxInt()
+    inputargs = [v1]
+    operations = [
+        ResOperation(rop.INT_ADD, [v1, v1], v2),
+        ResOperation(rop.INT_INVERT, [v2], v3),
+        ResOperation(rop.UINT_RSHIFT, [v1, ConstInt(3)], v4),
+        ResOperation(rop.FINISH, [v4, v3], None, descr=BasicFailDescr()),
+        ]
+    cpu = CPU(None, None)
+    cpu.setup_once()
+    looptoken = LoopToken()
+    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.set_future_value_int(0, 9)
+    cpu.execute_token(looptoken)
+    assert cpu.get_latest_value_int(0) == (9 >> 3)
+    assert cpu.get_latest_value_int(1) == (~18)
+
+def test_bug_int_is_true_1():
+    v1 = BoxInt()
+    v2 = BoxInt()
+    v3 = BoxInt()
+    v4 = BoxInt()
+    tmp5 = BoxInt()
+    inputargs = [v1]
+    operations = [
+        ResOperation(rop.INT_MUL, [v1, v1], v2),
+        ResOperation(rop.INT_MUL, [v2, v1], v3),
+        ResOperation(rop.INT_IS_TRUE, [v2], tmp5),
+        ResOperation(rop.INT_IS_ZERO, [tmp5], v4),
+        ResOperation(rop.FINISH, [v4, v3, tmp5], None, descr=BasicFailDescr()),
+            ]
+    cpu = CPU(None, None)
+    cpu.setup_once()
+    looptoken = LoopToken()
+    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.set_future_value_int(0, -10)
+    cpu.execute_token(looptoken)
+    assert cpu.get_latest_value_int(0) == 0
+    assert cpu.get_latest_value_int(1) == -1000
+    assert cpu.get_latest_value_int(2) == 1
+
+def test_bug_0():
+    v1 = BoxInt()
+    v2 = BoxInt()
+    v3 = BoxInt()
+    v4 = BoxInt()
+    v5 = BoxInt()
+    v6 = BoxInt()
+    v7 = BoxInt()
+    v8 = BoxInt()
+    v9 = BoxInt()
+    v10 = BoxInt()
+    v11 = BoxInt()
+    v12 = BoxInt()
+    v13 = BoxInt()
+    v14 = BoxInt()
+    v15 = BoxInt()
+    v16 = BoxInt()
+    v17 = BoxInt()
+    v18 = BoxInt()
+    v19 = BoxInt()
+    v20 = BoxInt()
+    v21 = BoxInt()
+    v22 = BoxInt()
+    v23 = BoxInt()
+    v24 = BoxInt()
+    v25 = BoxInt()
+    v26 = BoxInt()
+    v27 = BoxInt()
+    v28 = BoxInt()
+    v29 = BoxInt()
+    v30 = BoxInt()
+    v31 = BoxInt()
+    v32 = BoxInt()
+    v33 = BoxInt()
+    v34 = BoxInt()
+    v35 = BoxInt()
+    v36 = BoxInt()
+    v37 = BoxInt()
+    v38 = BoxInt()
+    v39 = BoxInt()
+    v40 = BoxInt()
+    tmp41 = BoxInt()
+    tmp42 = BoxInt()
+    tmp43 = BoxInt()
+    tmp44 = BoxInt()
+    tmp45 = BoxInt()
+    tmp46 = BoxInt()
+    inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
+    operations = [
+        ResOperation(rop.UINT_GT, [v3, ConstInt(-48)], v11),
+        ResOperation(rop.INT_XOR, [v8, v1], v12),
+        ResOperation(rop.INT_GT, [v6, ConstInt(-9)], v13),
+        ResOperation(rop.INT_LE, [v13, v2], v14),
+        ResOperation(rop.INT_LE, [v11, v5], v15),
+        ResOperation(rop.UINT_GE, [v13, v13], v16),
+        ResOperation(rop.INT_OR, [v9, ConstInt(-23)], v17),
+        ResOperation(rop.INT_LT, [v10, v13], v18),
+        ResOperation(rop.INT_OR, [v15, v5], v19),
+        ResOperation(rop.INT_XOR, [v17, ConstInt(54)], v20),
+        ResOperation(rop.INT_MUL, [v8, v10], v21),
+        ResOperation(rop.INT_OR, [v3, v9], v22),
+        ResOperation(rop.INT_AND, [v11, ConstInt(-4)], tmp41),
+        ResOperation(rop.INT_OR, [tmp41, ConstInt(1)], tmp42),
+        ResOperation(rop.INT_MOD, [v12, tmp42], v23),
+        ResOperation(rop.INT_IS_TRUE, [v6], v24),
+        ResOperation(rop.UINT_RSHIFT, [v15, ConstInt(6)], v25),
+        ResOperation(rop.INT_OR, [ConstInt(-4), v25], v26),
+        ResOperation(rop.INT_INVERT, [v8], v27),
+        ResOperation(rop.INT_SUB, [ConstInt(-113), v11], v28),
+        ResOperation(rop.INT_NEG, [v7], v29),
+        ResOperation(rop.INT_NEG, [v24], v30),
+        ResOperation(rop.INT_FLOORDIV, [v3, ConstInt(53)], v31),
+        ResOperation(rop.INT_MUL, [v28, v27], v32),
+        ResOperation(rop.INT_AND, [v18, ConstInt(-4)], tmp43),
+        ResOperation(rop.INT_OR, [tmp43, ConstInt(1)], tmp44),
+        ResOperation(rop.INT_MOD, [v26, tmp44], v33),
+        ResOperation(rop.INT_OR, [v27, v19], v34),
+        ResOperation(rop.UINT_LT, [v13, ConstInt(1)], v35),
+        ResOperation(rop.INT_AND, [v21, ConstInt(31)], tmp45),
+        ResOperation(rop.INT_RSHIFT, [v21, tmp45], v36),
+        ResOperation(rop.INT_AND, [v20, ConstInt(31)], tmp46),
+        ResOperation(rop.UINT_RSHIFT, [v4, tmp46], v37),
+        ResOperation(rop.UINT_GT, [v33, ConstInt(-11)], v38),
+        ResOperation(rop.INT_NEG, [v7], v39),
+        ResOperation(rop.INT_GT, [v24, v32], v40),
+        ResOperation(rop.FINISH, [v40, v36, v37, v31, v16, v34, v35, v23, v22, v29, v14, v39, v30, v38], None, descr=BasicFailDescr()),
+            ]
+    cpu = CPU(None, None)
+    cpu.setup_once()
+    looptoken = LoopToken()
+    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.set_future_value_int(0, -13)
+    cpu.set_future_value_int(1, 10)
+    cpu.set_future_value_int(2, 10)
+    cpu.set_future_value_int(3, 8)
+    cpu.set_future_value_int(4, -8)
+    cpu.set_future_value_int(5, -16)
+    cpu.set_future_value_int(6, -18)
+    cpu.set_future_value_int(7, 46)
+    cpu.set_future_value_int(8, -12)
+    cpu.set_future_value_int(9, 26)
+    cpu.execute_token(looptoken)
+    assert cpu.get_latest_value_int(0) == 0
+    assert cpu.get_latest_value_int(1) == 0
+    assert cpu.get_latest_value_int(2) == 0
+    assert cpu.get_latest_value_int(3) == 0
+    assert cpu.get_latest_value_int(4) == 1
+    assert cpu.get_latest_value_int(5) == -7
+    assert cpu.get_latest_value_int(6) == 1
+    assert cpu.get_latest_value_int(7) == 0
+    assert cpu.get_latest_value_int(8) == -2
+    assert cpu.get_latest_value_int(9) == 18
+    assert cpu.get_latest_value_int(10) == 1
+    assert cpu.get_latest_value_int(11) == 18
+    assert cpu.get_latest_value_int(12) == -1
+    assert cpu.get_latest_value_int(13) == 0
+
+def test_bug_1():
+    v1 = BoxInt()
+    v2 = BoxInt()
+    v3 = BoxInt()
+    v4 = BoxInt()
+    v5 = BoxInt()
+    v6 = BoxInt()
+    v7 = BoxInt()
+    v8 = BoxInt()
+    v9 = BoxInt()
+    v10 = BoxInt()
+    v11 = BoxInt()
+    v12 = BoxInt()
+    v13 = BoxInt()
+    v14 = BoxInt()
+    v15 = BoxInt()
+    v16 = BoxInt()
+    v17 = BoxInt()
+    v18 = BoxInt()
+    v19 = BoxInt()
+    v20 = BoxInt()
+    v21 = BoxInt()
+    v22 = BoxInt()
+    v23 = BoxInt()
+    v24 = BoxInt()
+    v25 = BoxInt()
+    v26 = BoxInt()
+    v27 = BoxInt()
+    v28 = BoxInt()
+    v29 = BoxInt()
+    v30 = BoxInt()
+    v31 = BoxInt()
+    v32 = BoxInt()
+    v33 = BoxInt()
+    v34 = BoxInt()
+    v35 = BoxInt()
+    v36 = BoxInt()
+    v37 = BoxInt()
+    v38 = BoxInt()
+    v39 = BoxInt()
+    v40 = BoxInt()
+    tmp41 = BoxInt()
+    tmp42 = BoxInt()
+    tmp43 = BoxInt()
+    tmp44 = BoxInt()
+    tmp45 = BoxInt()
+    inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
+    operations = [
+        ResOperation(rop.UINT_LT, [v6, ConstInt(0)], v11),
+        ResOperation(rop.INT_AND, [v3, ConstInt(31)], tmp41),
+        ResOperation(rop.INT_RSHIFT, [v3, tmp41], v12),
+        ResOperation(rop.INT_NEG, [v2], v13),
+        ResOperation(rop.INT_ADD, [v11, v7], v14),
+        ResOperation(rop.INT_OR, [v3, v2], v15),
+        ResOperation(rop.INT_OR, [v12, v12], v16),
+        ResOperation(rop.INT_NE, [v2, v5], v17),
+        ResOperation(rop.INT_AND, [v5, ConstInt(31)], tmp42),
+        ResOperation(rop.UINT_RSHIFT, [v14, tmp42], v18),
+        ResOperation(rop.INT_AND, [v14, ConstInt(31)], tmp43),
+        ResOperation(rop.INT_LSHIFT, [ConstInt(7), tmp43], v19),
+        ResOperation(rop.INT_NEG, [v19], v20),
+        ResOperation(rop.INT_MOD, [v3, ConstInt(1)], v21),
+        ResOperation(rop.UINT_GE, [v15, v1], v22),
+        ResOperation(rop.INT_AND, [v16, ConstInt(31)], tmp44),
+        ResOperation(rop.INT_LSHIFT, [v8, tmp44], v23),
+        ResOperation(rop.INT_IS_TRUE, [v17], v24),
+        ResOperation(rop.INT_AND, [v5, ConstInt(31)], tmp45),
+        ResOperation(rop.INT_LSHIFT, [v14, tmp45], v25),
+        ResOperation(rop.INT_LSHIFT, [v5, ConstInt(17)], v26),
+        ResOperation(rop.INT_EQ, [v9, v15], v27),
+        ResOperation(rop.INT_GE, [ConstInt(0), v6], v28),
+        ResOperation(rop.INT_NEG, [v15], v29),
+        ResOperation(rop.INT_NEG, [v22], v30),
+        ResOperation(rop.INT_ADD, [v7, v16], v31),
+        ResOperation(rop.UINT_LT, [v19, v19], v32),
+        ResOperation(rop.INT_ADD, [v2, ConstInt(1)], v33),
+        ResOperation(rop.INT_NEG, [v5], v34),
+        ResOperation(rop.INT_ADD, [v17, v24], v35),
+        ResOperation(rop.UINT_LT, [ConstInt(2), v16], v36),
+        ResOperation(rop.INT_NEG, [v9], v37),
+        ResOperation(rop.INT_GT, [v4, v11], v38),
+        ResOperation(rop.INT_LT, [v27, v22], v39),
+        ResOperation(rop.INT_NEG, [v27], v40),
+        ResOperation(rop.FINISH, [v40, v10, v36, v26, v13, v30, v21, v33, v18, v25, v31, v32, v28, v29, v35, v38, v20, v39, v34, v23, v37], None, descr=BasicFailDescr()),
+            ]
+    cpu = CPU(None, None)
+    cpu.setup_once()
+    looptoken = LoopToken()
+    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.set_future_value_int(0, 17)
+    cpu.set_future_value_int(1, -20)
+    cpu.set_future_value_int(2, -6)
+    cpu.set_future_value_int(3, 6)
+    cpu.set_future_value_int(4, 1)
+    cpu.set_future_value_int(5, 13)
+    cpu.set_future_value_int(6, 13)
+    cpu.set_future_value_int(7, 9)
+    cpu.set_future_value_int(8, 49)
+    cpu.set_future_value_int(9, 8)
+    cpu.execute_token(looptoken)
+    assert cpu.get_latest_value_int(0) == 0
+    assert cpu.get_latest_value_int(1) == 8
+    assert cpu.get_latest_value_int(2) == 1
+    assert cpu.get_latest_value_int(3) == 131072
+    assert cpu.get_latest_value_int(4) == 20
+    assert cpu.get_latest_value_int(5) == -1
+    assert cpu.get_latest_value_int(6) == 0
+    assert cpu.get_latest_value_int(7) == -19
+    assert cpu.get_latest_value_int(8) == 6
+    assert cpu.get_latest_value_int(9) == 26
+    assert cpu.get_latest_value_int(10) == 12
+    assert cpu.get_latest_value_int(11) == 0
+    assert cpu.get_latest_value_int(12) == 0
+    assert cpu.get_latest_value_int(13) == 2
+    assert cpu.get_latest_value_int(14) == 2
+    assert cpu.get_latest_value_int(15) == 1
+    assert cpu.get_latest_value_int(16) == -57344
+    assert cpu.get_latest_value_int(17) == 1
+    assert cpu.get_latest_value_int(18) == -1
+    if WORD == 4:
+        assert cpu.get_latest_value_int(19) == -2147483648
+    elif WORD == 8:
+        assert cpu.get_latest_value_int(19) == 19327352832
+    assert cpu.get_latest_value_int(20) == -49

diff --git a/pypy/jit/backend/arm/test/test_recompilation.py b/pypy/jit/backend/arm/test/test_recompilation.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/arm/test/test_recompilation.py
@@ -0,0 +1,142 @@
+from pypy.jit.backend.arm.test.test_regalloc import BaseTestRegalloc
+
+class TestRecompilation(BaseTestRegalloc):
+    def test_compile_bridge_not_deeper(self):
+        ops = '''
+        [i0]
+        i1 = int_add(i0, 1)
+        i2 = int_lt(i1, 20)
+        guard_true(i2, descr=fdescr1) [i1]
+        jump(i1)
+        '''
+        loop = self.interpret(ops, [0])
+        assert self.getint(0) == 20
+        ops = '''
+        [i1]
+        i3 = int_add(i1, 1)
+        finish(i3, descr=fdescr2)
+        '''
+        bridge = self.attach_bridge(ops, loop, -2)
+        self.cpu.set_future_value_int(0, 0)
+        fail = self.run(loop)
+        assert fail.identifier == 2
+        assert self.getint(0) == 21
+    
+    def test_compile_bridge_deeper(self):
+        ops = '''
+        [i0]
+        i1 = int_add(i0, 1)
+        i2 = int_lt(i1, 20)
+        guard_true(i2, descr=fdescr1) [i1]
+        jump(i1)
+        '''
+        loop = self.interpret(ops, [0])
+        assert self.getint(0) == 20
+        ops = '''
+        [i1]
+        i3 = int_add(i1, 1)
+        i4 = int_add(i3, 1)
+        i5 = int_add(i4, 1)
+        i6 = int_add(i5, 1)
+        i7 = int_add(i5, i4)
+        i8 = int_add(i7, 1)
+        i9 = int_add(i8, 1)
+        finish(i3, i4, i5, i6, i7, i8, i9, descr=fdescr2)
+        '''
+        bridge = self.attach_bridge(ops, loop, -2)
+        descr = loop.operations[2].getdescr()
+        self.cpu.set_future_value_int(0, 0)
+        fail = self.run(loop)
+        assert fail.identifier == 2
+        assert self.getint(0) == 21
+        assert self.getint(1) == 22
+        assert self.getint(2) == 23
+        assert self.getint(3) == 24
+
+    def test_bridge_jump_to_other_loop(self):
+        loop = self.interpret('''
+        [i0, i10, i11, i12, i13, i14, i15, i16]
+        i1 = int_add(i0, 1)
+        i2 = int_lt(i1, 20)
+        guard_true(i2, descr=fdescr1) [i1]
+        jump(i1, i10, i11, i12, i13, i14, i15, i16)
+        ''', [0])
+        other_loop = self.interpret('''
+        [i3]
+        guard_false(i3, descr=fdescr2) [i3]
+        jump(i3)
+        ''', [1])
+        ops = '''
+        [i3]
+        jump(i3, 1, 2, 3, 4, 5, 6, 7, descr=looptoken)
+        '''
+        bridge = self.attach_bridge(ops, other_loop, 0, looptoken=loop.token)
+        self.cpu.set_future_value_int(0, 1)
+        fail = self.run(other_loop)
+        assert fail.identifier == 1
+
+    def test_bridge_jumps_to_self_deeper(self):
+        loop = self.interpret('''
+        [i0, i1, i2, i31, i32, i33]
+        i98 = same_as(0)
+        i99 = same_as(1)
+        i30 = int_add(i1, i2)
+        i3 = int_add(i0, 1)
+        i4 = int_and(i3, 1)
+        guard_false(i4) [i98, i3]
+        i5 = int_lt(i3, 20)
+        guard_true(i5) [i99, i3]
+        jump(i3, i30, 1, i30, i30, i30)
+        ''', [0])
+        assert self.getint(0) == 0
+        assert self.getint(1) == 1
+        ops = '''
+        [i97, i3]
+        i10 = int_mul(i3, 2)
+        i8 = int_add(i3, 1)
+        i6 = int_add(i8, i10)
+        i7 = int_add(i3, i6)
+        i12 = int_add(i7, i8)
+        i11 = int_add(i12, i6)
+        jump(i3, i12, i11, i10, i6, i7, descr=looptoken)
+        '''
+        bridge = self.attach_bridge(ops, loop, 5, looptoken=loop.token)
+        guard_op = loop.operations[5]
+        #loop_frame_depth = loop.token._x86_frame_depth
+        #assert loop.token._x86_param_depth == 0
+        ## XXX: Maybe add enough ops to force stack on 64-bit as well?
+        #    assert guard_op.getdescr()._arm_bridge_frame_depth > loop_frame_depth
+        #assert guard_op.getdescr()._x86_bridge_param_depth == 0
+        self.cpu.set_future_value_int(0, 0)
+        self.cpu.set_future_value_int(1, 0)
+        self.cpu.set_future_value_int(2, 0)
+        self.run(loop)
+        assert self.getint(0) == 1
+        assert self.getint(1) == 20
+
+    def test_bridge_jumps_to_self_shallower(self):
+        loop = self.interpret('''
+        [i0, i1, i2]
+        i98 = same_as(0)
+        i99 = same_as(1)
+        i3 = int_add(i0, 1)
+        i4 = int_and(i3, 1)
+        guard_false(i4) [i98, i3]
+        i5 = int_lt(i3, 20)
+        guard_true(i5) [i99, i3]
+        jump(i3, i1, i2)
+        ''', [0])
+        assert self.getint(0) == 0
+        assert self.getint(1) == 1
+        ops = '''
+        [i97, i3]
+        jump(i3, 0, 1, descr=looptoken)
+        '''
+        bridge = self.attach_bridge(ops, loop, 4, looptoken=loop.token)
+        self.cpu.set_future_value_int(0, 0)
+        self.cpu.set_future_value_int(1, 0)
+        self.cpu.set_future_value_int(2, 0)
+        self.run(loop)
+        assert self.getint(0) == 1
+        assert self.getint(1) == 20
+        

diff --git a/pypy/jit/backend/arm/test/test_gc_integration.py b/pypy/jit/backend/arm/test/test_gc_integration.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/arm/test/test_gc_integration.py
@@ -0,0 +1,259 @@
+
+""" Tests for register allocation for common constructs
+"""
+
+import py
+from pypy.jit.metainterp.history import BoxInt, ConstInt,\
+     BoxPtr, ConstPtr, TreeLoop
+from pypy.jit.metainterp.resoperation import rop, ResOperation
+from pypy.jit.codewriter import heaptracker
+from pypy.jit.backend.llsupport.descr import GcCache
+from pypy.jit.backend.llsupport.gc import GcLLDescription
+from pypy.jit.backend.detect_cpu import getcpuclass
+from pypy.jit.backend.arm.regalloc import ARMRegisterManager
+from pypy.jit.backend.arm.arch import WORD
+from pypy.jit.tool.oparser import parse
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+from pypy.rpython.annlowlevel import llhelper
+from pypy.rpython.lltypesystem import rclass, rstr
+from pypy.jit.backend.llsupport.gc import GcLLDescr_framework, GcRefList, GcPtrFieldDescr
+
+from pypy.jit.backend.arm.test.test_regalloc import MockAssembler
+from pypy.jit.backend.arm.test.test_regalloc import BaseTestRegalloc
+
+CPU = getcpuclass()
+
+class MockGcRootMap(object):
+    def get_basic_shape(self, is_64_bit):
+        return ['shape']
+    def add_ebp_offset(self, shape, offset):
+        shape.append(offset)
+    def add_callee_save_reg(self, shape, reg_index):
+        index_to_name = { 1: 'ebx', 2: 'esi', 3: 'edi' }
+        shape.append(index_to_name[reg_index])
+    def compress_callshape(self, shape, datablockwrapper):
+        assert datablockwrapper == 'fakedatablockwrapper'
+        assert shape[0] == 'shape'
+        return ['compressed'] + shape[1:]
+
+class MockGcDescr(GcCache):
+    def get_funcptr_for_new(self):
+        return 123
+    get_funcptr_for_newarray = get_funcptr_for_new
+    get_funcptr_for_newstr = get_funcptr_for_new
+    get_funcptr_for_newunicode = get_funcptr_for_new
+    
+    moving_gc = True
+    gcrootmap = MockGcRootMap()
+
+    def initialize(self):
+        self.gcrefs = GcRefList()
+        self.gcrefs.initialize()
+        self.single_gcref_descr = GcPtrFieldDescr('', 0)
+        
+    rewrite_assembler = GcLLDescr_framework.rewrite_assembler.im_func
+
+
+class TestRegallocGcIntegration(BaseTestRegalloc):
+    
+    cpu = CPU(None, None)
+    cpu.gc_ll_descr = MockGcDescr(False)
+    cpu.setup_once()
+    
+    S = lltype.GcForwardReference()
+    S.become(lltype.GcStruct('S', ('field', lltype.Ptr(S)),
+                             ('int', lltype.Signed)))
+
+    fielddescr = cpu.fielddescrof(S, 'field')
+
+    struct_ptr = lltype.malloc(S)
+    struct_ref = lltype.cast_opaque_ptr(llmemory.GCREF, struct_ptr)
+    child_ptr = lltype.nullptr(S)
+    struct_ptr.field = child_ptr
+
+
+    descr0 = cpu.fielddescrof(S, 'int')
+    ptr0 = struct_ref
+
+    namespace = locals().copy()
+
+    def test_basic(self):
+        ops = '''
+        [p0]
+        p1 = getfield_gc(p0, descr=fielddescr)
+        finish(p1)
+        '''
+        self.interpret(ops, [self.struct_ptr])
+        assert not self.getptr(0, lltype.Ptr(self.S))
+
+    def test_rewrite_constptr(self):
+        ops = '''
+        []
+        p1 = getfield_gc(ConstPtr(struct_ref), descr=fielddescr)
+        finish(p1)
+        '''
+        self.interpret(ops, [])
+        assert not self.getptr(0, lltype.Ptr(self.S))
+
+    def test_bug_0(self):
+        ops = '''
+        [i0, i1, i2, i3, i4, i5, i6, i7, i8]
+        guard_value(i2, 1) [i2, i3, i4, i5, i6, i7, i0, i1, i8]
+        guard_class(i4, 138998336) [i4, i5, i6, i7, i0, i1, i8]
+        i11 = getfield_gc(i4, descr=descr0)
+        guard_nonnull(i11) [i4, i5, i6, i7, i0, i1, i11, i8]
+        i13 = getfield_gc(i11, descr=descr0)
+        guard_isnull(i13) [i4, i5, i6, i7, i0, i1, i11, i8]
+        i15 = getfield_gc(i4, descr=descr0)
+        i17 = int_lt(i15, 0)
+        guard_false(i17) [i4, i5, i6, i7, i0, i1, i11, i15, i8]
+        i18 = getfield_gc(i11, descr=descr0)
+        i19 = int_ge(i15, i18)
+        guard_false(i19) [i4, i5, i6, i7, i0, i1, i11, i15, i8]
+        i20 = int_lt(i15, 0)
+        guard_false(i20) [i4, i5, i6, i7, i0, i1, i11, i15, i8]
+        i21 = getfield_gc(i11, descr=descr0)
+        i22 = getfield_gc(i11, descr=descr0)
+        i23 = int_mul(i15, i22)
+        i24 = int_add(i21, i23)
+        i25 = getfield_gc(i4, descr=descr0)
+        i27 = int_add(i25, 1)
+        setfield_gc(i4, i27, descr=descr0)
+        i29 = getfield_raw(144839744, descr=descr0)
+        i31 = int_and(i29, -2141192192)
+        i32 = int_is_true(i31)
+        guard_false(i32) [i4, i6, i7, i0, i1, i24]
+        i33 = getfield_gc(i0, descr=descr0)
+        guard_value(i33, ConstPtr(ptr0)) [i4, i6, i7, i0, i1, i33, i24]
+        jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24)
+        '''
+        self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0, 0], run=False)
+
+class GCDescrFastpathMalloc(GcLLDescription):
+    gcrootmap = None
+    
+    def __init__(self):
+        GcCache.__init__(self, False)
+        # create a nursery
+        NTP = rffi.CArray(lltype.Signed)
+        self.nursery = lltype.malloc(NTP, 16, flavor='raw')
+        self.addrs = lltype.malloc(rffi.CArray(lltype.Signed), 2,
+                                   flavor='raw')
+        self.addrs[0] = rffi.cast(lltype.Signed, self.nursery)
+        self.addrs[1] = self.addrs[0] + 64
+        # 64 bytes
+        def malloc_slowpath(size):
+            assert size == WORD*2
+            nadr = rffi.cast(lltype.Signed, self.nursery)
+            self.addrs[0] = nadr + size
+            return nadr
+        self.malloc_slowpath = malloc_slowpath
+        self.MALLOC_SLOWPATH = lltype.FuncType([lltype.Signed],
+                                               lltype.Signed)
+        self._counter = 123
+
+    def can_inline_malloc(self, descr):
+        return True
+
+    def get_funcptr_for_new(self):
+        return 42
+#        return llhelper(lltype.Ptr(self.NEW_TP), self.new)
+
+    def init_size_descr(self, S, descr):
+        descr.tid = self._counter
+        self._counter += 1
+
+    def get_nursery_free_addr(self):
+        return rffi.cast(lltype.Signed, self.addrs)
+
+    def get_nursery_top_addr(self):
+        return rffi.cast(lltype.Signed, self.addrs) + WORD
+
+    def get_malloc_fixedsize_slowpath_addr(self):
+        fptr = llhelper(lltype.Ptr(self.MALLOC_SLOWPATH), self.malloc_slowpath)
+        return rffi.cast(lltype.Signed, fptr)
+
+    get_funcptr_for_newarray = None
+    get_funcptr_for_newstr = None
+    get_funcptr_for_newunicode = None
+
+class TestMallocFastpath(BaseTestRegalloc):
+
+    def setup_method(self, method):
+        cpu = CPU(None, None)
+        cpu.vtable_offset = WORD
+        cpu.gc_ll_descr = GCDescrFastpathMalloc()
+        cpu.setup_once()
+
+        NODE = lltype.Struct('node', ('tid', lltype.Signed),
+                                     ('value', lltype.Signed))
+        nodedescr = cpu.sizeof(NODE)     # xxx hack: NODE is not a GcStruct
+        valuedescr = cpu.fielddescrof(NODE, 'value')
+
+        self.cpu = cpu
+        self.nodedescr = nodedescr
+        vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
+        vtable_int = cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(vtable))
+        NODE2 = lltype.GcStruct('node2',
+                                  ('parent', rclass.OBJECT),
+                                  ('tid', lltype.Signed),
+                                  ('vtable', lltype.Ptr(rclass.OBJECT_VTABLE)))
+        descrsize = cpu.sizeof(NODE2)
+        heaptracker.register_known_gctype(cpu, vtable, NODE2)
+        self.descrsize = descrsize
+        self.vtable_int = vtable_int
+
+        self.namespace = locals().copy()
+        
+    def test_malloc_fastpath(self):
+        py.test.skip()
+        ops = '''
+        [i0]
+        p0 = new(descr=nodedescr)
+        setfield_gc(p0, i0, descr=valuedescr)
+        finish(p0)
+        '''
+        self.interpret(ops, [42])
+        # check the nursery
+        gc_ll_descr = self.cpu.gc_ll_descr
+        assert gc_ll_descr.nursery[0] == self.nodedescr.tid
+        assert gc_ll_descr.nursery[1] == 42
+        nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery)
+        assert gc_ll_descr.addrs[0] == nurs_adr + (WORD*2)
+
+    def test_malloc_slowpath(self):
+        py.test.skip()
+        ops = '''
+        []
+        p0 = new(descr=nodedescr)
+        p1 = new(descr=nodedescr)
+        p2 = new(descr=nodedescr)
+        p3 = new(descr=nodedescr)
+        p4 = new(descr=nodedescr)
+        p5 = new(descr=nodedescr)
+        p6 = new(descr=nodedescr)
+        p7 = new(descr=nodedescr)
+        p8 = new(descr=nodedescr)
+        finish(p0, p1, p2, p3, p4, p5, p6, p7, p8)
+        '''
+        self.interpret(ops, [])
+        # this should call slow path once
+        gc_ll_descr = self.cpu.gc_ll_descr
+        nadr = rffi.cast(lltype.Signed, gc_ll_descr.nursery)
+        assert gc_ll_descr.addrs[0] == nadr + (WORD*2)
+
+    def test_new_with_vtable(self):
+        py.test.skip()
+        ops = '''
+        [i0, i1]
+        p0 = new_with_vtable(ConstClass(vtable))
+        guard_class(p0, ConstClass(vtable)) [i0]
+        finish(i1)
+        '''
+        self.interpret(ops, [0, 1])
+        assert self.getint(0) == 1
+        gc_ll_descr = self.cpu.gc_ll_descr
+        assert gc_ll_descr.nursery[0] == self.descrsize.tid
+        assert gc_ll_descr.nursery[1] == self.vtable_int
+        nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery)
+        assert gc_ll_descr.addrs[0] == nurs_adr + (WORD*3)

diff --git a/pypy/jit/backend/arm/test/support.py b/pypy/jit/backend/arm/test/support.py
--- a/pypy/jit/backend/arm/test/support.py
+++ b/pypy/jit/backend/arm/test/support.py
@@ -2,6 +2,16 @@
 import py
 
 from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.jit.backend.detect_cpu import getcpuclass
+from pypy.jit.metainterp.test import test_basic
+from pypy.rlib.jit import JitDriver
+
+class JitARMMixin(test_basic.LLJitMixin):
+    type_system = 'lltype'
+    CPUClass = getcpuclass()
+
+    def check_jumps(self, maxcount):
+        pass
 
 if os.uname()[1] == 'llaima.local':
     AS = '~/Code/arm-jit/android/android-ndk-r4b//build/prebuilt/darwin-x86/arm-eabi-4.4.0/arm-eabi/bin/as'

diff --git a/pypy/jit/backend/arm/test/test_loop_unroll.py b/pypy/jit/backend/arm/test/test_loop_unroll.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/arm/test/test_loop_unroll.py
@@ -0,0 +1,8 @@
+import py
+from pypy.jit.backend.x86.test.test_basic import Jit386Mixin
+from pypy.jit.metainterp.test import test_loop_unroll
+
+class TestLoopSpec(Jit386Mixin, test_loop_unroll.LoopUnrollTest):
+    # for the individual tests see
+    # ====> ../../../metainterp/test/test_loop.py
+    pass

diff --git a/pypy/jit/backend/arm/test/test_regalloc.py b/pypy/jit/backend/arm/test/test_regalloc.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/arm/test/test_regalloc.py
@@ -0,0 +1,633 @@
+
+""" Tests for register allocation for common constructs
+"""
+
+import py
+from pypy.jit.metainterp.history import BoxInt, ConstInt,\
+     BoxPtr, ConstPtr, LoopToken, BasicFailDescr
+from pypy.jit.metainterp.resoperation import rop, ResOperation
+from pypy.jit.backend.llsupport.descr import GcCache
+from pypy.jit.backend.detect_cpu import getcpuclass
+from pypy.jit.backend.arm.regalloc import ARMRegisterManager
+from pypy.jit.tool.oparser import parse
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+from pypy.rpython.annlowlevel import llhelper
+from pypy.rpython.lltypesystem import rclass, rstr
+
+
+CPU = getcpuclass()
+class MockGcDescr(GcCache):
+    def get_funcptr_for_new(self):
+        return 123
+    get_funcptr_for_newarray = get_funcptr_for_new
+    get_funcptr_for_newstr = get_funcptr_for_new
+    get_funcptr_for_newunicode = get_funcptr_for_new
+ 
+    def rewrite_assembler(self, cpu, operations):
+        pass
+
+class MockAssembler(object):
+    gcrefs = None
+    _float_constants = None
+
+    def __init__(self, cpu=None, gc_ll_descr=None):
+        self.movs = []
+        self.performs = []
+        self.lea = []
+        if cpu is None:
+            cpu = CPU(None, None)
+            cpu.setup_once()
+        self.cpu = cpu
+        if gc_ll_descr is None:
+            gc_ll_descr = MockGcDescr(False)
+        self.cpu.gc_ll_descr = gc_ll_descr
+
+    def dump(self, *args):
+        pass
+
+    def regalloc_mov(self, from_loc, to_loc):
+        self.movs.append((from_loc, to_loc))
+
+    def regalloc_perform(self, op, arglocs, resloc):
+        self.performs.append((op, arglocs, resloc))
+
+    def regalloc_perform_discard(self, op, arglocs):
+        self.performs.append((op, arglocs))
+
+    def load_effective_addr(self, *args):
+        self.lea.append(args)
+
+class RegAllocForTests(ARMRegisterManager):
+    position = 0
+    def _compute_next_usage(self, v, _):
+        return -1
+
+class BaseTestRegalloc(object):
+    cpu = CPU(None, None)
+    cpu.setup_once()
+
+    def raising_func(i):
+        if i:
+            raise LLException(zero_division_error,
+                              zero_division_value)
+    FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
+    raising_fptr = llhelper(FPTR, raising_func)
+    zero_division_tp, zero_division_value = cpu.get_zero_division_error()
+    zd_addr = cpu.cast_int_to_adr(zero_division_tp)
+    zero_division_error = llmemory.cast_adr_to_ptr(zd_addr,
+                                            lltype.Ptr(rclass.OBJECT_VTABLE))
+    raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT)
+
+    fdescr1 = BasicFailDescr(1)
+    fdescr2 = BasicFailDescr(2)
+    fdescr3 = BasicFailDescr(3)
+
+    def f1(x):
+        return x+1
+
+    def f2(x, y):
+        return x*y
+
+    def f10(*args):
+        assert len(args) == 10
+        return sum(args)
+
+    F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
+    F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*2, lltype.Signed))
+    F10PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*10, lltype.Signed))
+    f1ptr = llhelper(F1PTR, f1)
+    f2ptr = llhelper(F2PTR, f2)
+    f10ptr = llhelper(F10PTR, f10)
+
+    f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT)
+    f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT)
+    f10_calldescr = cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT)
+
+    namespace = locals().copy()
+    type_system = 'lltype'
+
+    def parse(self, s, boxkinds=None):
+        return parse(s, self.cpu, self.namespace,
+                     type_system=self.type_system,
+                     boxkinds=boxkinds)
+
+    def interpret(self, ops, args, run=True):
+        loop = self.parse(ops)
+        self.cpu.compile_loop(loop.inputargs, loop.operations, loop.token)
+        for i, arg in enumerate(args):
+            if isinstance(arg, int):
+                self.cpu.set_future_value_int(i, arg)
+            elif isinstance(arg, float):
+                self.cpu.set_future_value_float(i, arg)
+            else:
+                assert isinstance(lltype.typeOf(arg), lltype.Ptr)
+                llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg)
+                self.cpu.set_future_value_ref(i, llgcref)
+        if run:
+            self.cpu.execute_token(loop.token)
+        return loop
+
+    def getint(self, index):
+        return self.cpu.get_latest_value_int(index)
+
+    def getfloat(self, index):
+        return self.cpu.get_latest_value_float(index)
+
+    def getints(self, end):
+        return [self.cpu.get_latest_value_int(index) for
+                index in range(0, end)]
+
+    def getfloats(self, end):
+        return [self.cpu.get_latest_value_float(index) for
+                index in range(0, end)]
+
+    def getptr(self, index, T):
+        gcref = self.cpu.get_latest_value_ref(index)
+        return lltype.cast_opaque_ptr(T, gcref)
+
+    def attach_bridge(self, ops, loop, guard_op_index, looptoken=None, **kwds):
+        if looptoken is not None:
+            self.namespace = self.namespace.copy()
+            self.namespace['looptoken'] = looptoken
+        guard_op = loop.operations[guard_op_index]
+        assert guard_op.is_guard()
+        bridge = self.parse(ops, **kwds)
+        assert ([box.type for box in bridge.inputargs] ==
+                [box.type for box in guard_op.getfailargs()])
+        faildescr = guard_op.getdescr()
+        self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations,
+                                loop.token)
+        return bridge
+
+    def run(self, loop):
+        return self.cpu.execute_token(loop.token)
+
+class TestRegallocSimple(BaseTestRegalloc):
+    def test_simple_loop(self):
+        ops = '''
+        [i0]
+        i1 = int_add(i0, 1)
+        i2 = int_lt(i1, 20)
+        guard_true(i2) [i1]
+        jump(i1)
+        '''
+        self.interpret(ops, [0])
+        assert self.getint(0) == 20
+
+    def test_two_loops_and_a_bridge(self):
+        ops = '''
+        [i0, i1, i2, i3]
+        i4 = int_add(i0, 1)
+        i5 = int_lt(i4, 20)
+        guard_true(i5) [i4, i1, i2, i3]
+        jump(i4, i1, i2, i3)
+        '''
+        loop = self.interpret(ops, [0, 0, 0, 0])
+        ops2 = '''
+        [i5]
+        i1 = int_add(i5, 1)
+        i3 = int_add(i1, 1)
+        i4 = int_add(i3, 1)
+        i2 = int_lt(i4, 30)
+        guard_true(i2) [i4]
+        jump(i4)
+        '''
+        loop2 = self.interpret(ops2, [0])
+        bridge_ops = '''
+        [i4]
+        jump(i4, i4, i4, i4, descr=looptoken)
+        '''
+        bridge = self.attach_bridge(bridge_ops, loop2, 4, looptoken=loop.token)
+        self.cpu.set_future_value_int(0, 0)
+        self.run(loop2)
+        assert self.getint(0) == 31
+        assert self.getint(1) == 30
+        assert self.getint(2) == 30
+        assert self.getint(3) == 30
+
+    def test_pointer_arg(self):
+        ops = '''
+        [i0, p0]
+        i1 = int_add(i0, 1)
+        i2 = int_lt(i1, 10)
+        guard_true(i2) [p0]
+        jump(i1, p0)
+        '''
+        S = lltype.GcStruct('S')
+        ptr = lltype.malloc(S)
+        self.cpu.clear_latest_values(2)
+        self.interpret(ops, [0, ptr])
+        assert self.getptr(0, lltype.Ptr(S)) == ptr
+
+    def test_exception_bridge_no_exception(self):
+        ops = '''
+        [i0]
+        i1 = same_as(1)
+        call(ConstClass(raising_fptr), i0, descr=raising_calldescr)
+        guard_exception(ConstClass(zero_division_error)) [i1]
+        finish(0)
+        '''
+        bridge_ops = '''
+        [i3]
+        i2 = same_as(2)
+        guard_no_exception() [i2]
+        finish(1)
+        '''
+        loop = self.interpret(ops, [0])
+        assert self.getint(0) == 1
+        bridge = self.attach_bridge(bridge_ops, loop, 2)
+        self.cpu.set_future_value_int(0, 0)
+        self.run(loop)
+        assert self.getint(0) == 1
+
+    def test_inputarg_unused(self):
+        ops = '''
+        [i0]
+        finish(1)
+        '''
+        self.interpret(ops, [0])
+        # assert did not explode
+
+    def test_nested_guards(self):
+        ops = '''
+        [i0, i1]
+        guard_true(i0) [i0, i1]
+        finish(4)
+        '''
+        bridge_ops = '''
+        [i0, i1]
+        guard_true(i0) [i0, i1]
+        finish(3)
+        '''
+        loop = self.interpret(ops, [0, 10])
+        assert self.getint(0) == 0
+        assert self.getint(1) == 10
+        bridge = self.attach_bridge(bridge_ops, loop, 0)
+        self.cpu.set_future_value_int(0, 0)
+        self.cpu.set_future_value_int(1, 10)
+        self.run(loop)
+        assert self.getint(0) == 0
+        assert self.getint(1) == 10
+
+    def test_nested_unused_arg(self):
+        ops = '''
+        [i0, i1]
+        guard_true(i0) [i0, i1]
+        finish(1)
+        '''
+        loop = self.interpret(ops, [0, 1])
+        assert self.getint(0) == 0
+        bridge_ops = '''
+        [i0, i1]
+        finish(1, 2)
+        '''
+        self.attach_bridge(bridge_ops, loop, 0)
+        self.cpu.set_future_value_int(0, 0)
+        self.cpu.set_future_value_int(1, 1)
+        self.run(loop)
+
+    def test_spill_for_constant(self):
+        ops = '''
+        [i0, i1, i2, i3]
+        i4 = int_add(3, i1)
+        i5 = int_lt(i4, 30)
+        guard_true(i5) [i0, i4, i2, i3]
+        jump(1, i4, 3, 4)
+        '''
+        self.interpret(ops, [0, 0, 0, 0])
+        assert self.getints(4) == [1, 30, 3, 4]
+
+    def test_spill_for_constant_lshift(self):
+        ops = '''
+        [i0, i2, i1, i3]
+        i4 = int_lshift(1, i1)
+        i5 = int_add(1, i1)
+        i6 = int_lt(i5, 30)
+        guard_true(i6) [i4, i5, i2, i3]
+        jump(i4, 3, i5, 4)
+        '''
+        self.interpret(ops, [0, 0, 0, 0])
+        assert self.getints(4) == [1<<29, 30, 3, 4]
+        ops = '''
+        [i0, i1, i2, i3]
+        i4 = int_lshift(1, i1)
+        i5 = int_add(1, i1)
+        i6 = int_lt(i5, 30)
+        guard_true(i6) [i4, i5, i2, i3]
+        jump(i4, i5, 3, 4)
+        '''
+        self.interpret(ops, [0, 0, 0, 0])
+        assert self.getints(4) == [1<<29, 30, 3, 4]
+        ops = '''
+        [i0, i3, i1, i2]
+        i4 = int_lshift(1, i1)
+        i5 = int_add(1, i1)
+        i6 = int_lt(i5, 30)
+        guard_true(i6) [i4, i5, i2, i3]
+        jump(i4, 4, i5, 3)
+        '''
+        self.interpret(ops, [0, 0, 0, 0])
+        assert self.getints(4) == [1<<29, 30, 3, 4]
+
+    def test_result_selected_reg_via_neg(self):
+        ops = '''
+        [i0, i1, i2, i3]
+        i6 = int_neg(i2)
+        i7 = int_add(1, i1)
+        i4 = int_lt(i7, 10)
+        guard_true(i4) [i0, i6, i7]
+        jump(1, i7, i2, i6)
+        '''
+        self.interpret(ops, [0, 0, 3, 0])
+        assert self.getints(3) == [1, -3, 10]
+        
+    def test_compare_memory_result_survives(self):
+        ops = '''
+        [i0, i1, i2, i3]
+        i4 = int_lt(i0, i1)
+        i5 = int_add(i3, 1)
+        i6 = int_lt(i5, 30)
+        guard_true(i6) [i4]
+        jump(i0, i1, i4, i5)
+        '''
+        self.interpret(ops, [0, 10, 0, 0])
+        assert self.getint(0) == 1
+
+    def test_jump_different_args(self):
+        ops = '''
+        [i0, i15, i16, i18, i1, i2, i3]
+        i4 = int_add(i3, 1)
+        i5 = int_lt(i4, 20)
+        guard_true(i5) [i2, i1]
+        jump(i0, i18, i15, i16, i2, i1, i4)
+        '''
+        self.interpret(ops, [0, 1, 2, 3])
+
+    def test_op_result_unused(self):
+        ops = '''
+        [i0, i1]
+        i2 = int_add(i0, i1)
+        finish(0)
+        '''
+        self.interpret(ops, [0, 0])
+
+    def test_guard_value_two_boxes(self):
+        ops = '''
+        [i0, i1, i2, i3, i4, i5, i6, i7]
+        guard_value(i6, i1) [i0, i2, i3, i4, i5, i6]
+        finish(i0, i2, i3, i4, i5, i6)
+        '''
+        self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0])
+        assert self.getint(0) == 0
+
+    def test_bug_wrong_stack_adj(self):
+        ops = '''
+        [i0, i1, i2, i3, i4, i5, i6, i7, i8]
+        i9 = same_as(0)
+        guard_true(i0) [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8]
+        finish(1, i0, i1, i2, i3, i4, i5, i6, i7, i8)
+        '''
+        loop = self.interpret(ops, [0, 1, 2, 3, 4, 5, 6, 7, 8])
+        assert self.getint(0) == 0
+        bridge_ops = '''
+        [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8]
+        call(ConstClass(raising_fptr), 0, descr=raising_calldescr)
+        finish(i0, i1, i2, i3, i4, i5, i6, i7, i8)
+        '''
+        self.attach_bridge(bridge_ops, loop, 1)
+        for i in range(9):
+            self.cpu.set_future_value_int(i, i)
+        self.run(loop)
+        assert self.getints(9) == range(9)
+
+class TestRegallocCompOps(BaseTestRegalloc):
+    
+    def test_cmp_op_0(self):
+        ops = '''
+        [i0, i3]
+        i1 = same_as(1)
+        i2 = int_lt(i0, 100)
+        guard_true(i3) [i1, i2]
+        finish(0, i2)
+        '''
+        self.interpret(ops, [0, 1])
+        assert self.getint(0) == 0
+
+class TestRegallocMoreRegisters(BaseTestRegalloc):
+
+    cpu = BaseTestRegalloc.cpu
+
+    S = lltype.GcStruct('S', ('field', lltype.Char))
+    fielddescr = cpu.fielddescrof(S, 'field')
+
+    A = lltype.GcArray(lltype.Char)
+    arraydescr = cpu.arraydescrof(A)
+
+    namespace = locals().copy()
+
+    def test_int_is_true(self):
+        ops = '''
+        [i0, i1, i2, i3, i4, i5, i6, i7]
+        i10 = int_is_true(i0)
+        i11 = int_is_true(i1)
+        i12 = int_is_true(i2)
+        i13 = int_is_true(i3)
+        i14 = int_is_true(i4)
+        i15 = int_is_true(i5)
+        i16 = int_is_true(i6)
+        i17 = int_is_true(i7)
+        finish(i10, i11, i12, i13, i14, i15, i16, i17)
+        '''
+        self.interpret(ops, [0, 42, 12, 0, 13, 0, 0, 3333])
+        assert self.getints(8) == [0, 1, 1, 0, 1, 0, 0, 1]
+
+    def test_comparison_ops(self):
+        ops = '''
+        [i0, i1, i2, i3, i4, i5, i6]
+        i10 = int_lt(i0, i1)
+        i11 = int_le(i2, i3)
+        i12 = int_ge(i4, i5)
+        i13 = int_eq(i5, i6)
+        i14 = int_gt(i6, i2)
+        i15 = int_ne(i2, i6)
+        finish(i10, i11, i12, i13, i14, i15)
+        '''
+        self.interpret(ops, [0, 1, 2, 3, 4, 5, 6])
+        assert self.getints(6) == [1, 1, 0, 0, 1, 1]
+
+    def test_strsetitem(self):
+        ops = '''
+        [p0, i]
+        strsetitem(p0, 1, i)
+        finish()
+        '''
+        llstr  = rstr.mallocstr(10)
+        self.interpret(ops, [llstr, ord('a')])
+        assert llstr.chars[1] == 'a'
+
+    def test_setfield_char(self):
+        ops = '''
+        [p0, i]
+        setfield_gc(p0, i, descr=fielddescr)
+        finish()
+        '''
+        s = lltype.malloc(self.S)
+        self.interpret(ops, [s, ord('a')])
+        assert s.field == 'a'
+
+    def test_setarrayitem_gc(self):
+        ops = '''
+        [p0, i]
+        setarrayitem_gc(p0, 1, i, descr=arraydescr)
+        finish()
+        '''
+        s = lltype.malloc(self.A, 3)
+        self.interpret(ops, [s, ord('a')])
+        assert s[1] == 'a'
+
+    def test_division_optimized(self):
+        ops = '''
+        [i7, i6]
+        i18 = int_floordiv(i7, i6)
+        i19 = int_xor(i7, i6)
+        i21 = int_lt(i19, 0)
+        i22 = int_mod(i7, i6)
+        i23 = int_is_true(i22)
+        i24 = int_eq(i6, 4)
+        guard_false(i24) [i18]
+        jump(i18, i6)
+        '''
+        self.interpret(ops, [10, 4])
+        assert self.getint(0) == 2
+        # FIXME: Verify that i19 - i23 are removed
+
+class TestRegallocFloats(BaseTestRegalloc):
+    def test_float_add(self):
+        py.test.skip('need floats')
+        ops = '''
+        [f0, f1]
+        f2 = float_add(f0, f1)
+        finish(f2, f0, f1)
+        '''
+        self.interpret(ops, [3.0, 1.5])
+        assert self.getfloats(3) == [4.5, 3.0, 1.5]
+
+    def test_float_adds_stack(self):
+        py.test.skip('need floats')
+        ops = '''
+        [f0, f1, f2, f3, f4, f5, f6, f7, f8]
+        f9 = float_add(f0, f1)
+        f10 = float_add(f8, 3.5)
+        finish(f9, f10, f2, f3, f4, f5, f6, f7, f8)
+        '''
+        self.interpret(ops, [0.1, .2, .3, .4, .5, .6, .7, .8, .9])
+        assert self.getfloats(9) == [.1+.2, .9+3.5, .3, .4, .5, .6, .7, .8, .9]
+
+    def test_lt_const(self):
+        py.test.skip('need floats')
+        ops = '''
+        [f0]
+        i1 = float_lt(3.5, f0)
+        finish(i1)
+        '''
+        self.interpret(ops, [0.1])
+        assert self.getint(0) == 0
+
+    def test_bug_float_is_true_stack(self):
+        py.test.skip('need floats')
+        # NB. float_is_true no longer exists.  Unsure if keeping this test
+        # makes sense any more.
+        ops = '''
+        [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9]
+        i0 = float_ne(f0, 0.0)
+        i1 = float_ne(f1, 0.0)
+        i2 = float_ne(f2, 0.0)
+        i3 = float_ne(f3, 0.0)
+        i4 = float_ne(f4, 0.0)
+        i5 = float_ne(f5, 0.0)
+        i6 = float_ne(f6, 0.0)
+        i7 = float_ne(f7, 0.0)
+        i8 = float_ne(f8, 0.0)
+        i9 = float_ne(f9, 0.0)
+        finish(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+        '''
+        loop = self.interpret(ops, [0.0, .1, .2, .3, .4, .5, .6, .7, .8, .9])
+        assert self.getints(9) == [0, 1, 1, 1, 1, 1, 1, 1, 1]
+
+class TestRegAllocCallAndStackDepth(BaseTestRegalloc):
+    def expected_param_depth(self, num_args):
+        # Assumes the arguments are all non-float
+        return num_args
+
+    def test_one_call(self):
+        ops = '''
+        [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+        i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+        finish(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+        '''
+        loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9, 9])
+        assert self.getints(11) == [5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9]
+
+    def test_two_calls(self):
+        ops = '''
+        [i0, i1,  i2, i3, i4, i5, i6, i7, i8, i9]
+        i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+        i11 = call(ConstClass(f2ptr), i10, i1, descr=f2_calldescr)        
+        finish(i11, i1,  i2, i3, i4, i5, i6, i7, i8, i9)
+        '''
+        loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9, 9])
+        assert self.getints(11) == [5*7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9]
+
+    def test_call_many_arguments(self):
+        ops = '''
+        [i0, i1, i2, i3, i4, i5, i6, i7]
+        i8 = call(ConstClass(f10ptr), 1, i0, i1, i2, i3, i4, i5, i6, i7, 10, descr=f10_calldescr)
+        finish(i8)
+        '''
+        loop = self.interpret(ops, [2, 3, 4, 5, 6, 7, 8, 9])
+        assert self.getint(0) == 55
+
+    def test_bridge_calls_1(self):
+        ops = '''
+        [i0, i1]
+        i2 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+        guard_value(i2, 0, descr=fdescr1) [i2, i1]
+        finish(i1)
+        '''
+        loop = self.interpret(ops, [4, 7])
+        assert self.getint(0) == 5
+        ops = '''
+        [i2, i1]
+        i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)        
+        finish(i3, descr=fdescr2)        
+        '''
+        bridge = self.attach_bridge(ops, loop, -2)
+
+
+        self.cpu.set_future_value_int(0, 4)
+        self.cpu.set_future_value_int(1, 7)        
+        self.run(loop)
+        assert self.getint(0) == 5*7
+
+    def test_bridge_calls_2(self):
+        ops = '''
+        [i0, i1]
+        i2 = call(ConstClass(f2ptr), i0, i1, descr=f2_calldescr)
+        guard_value(i2, 0, descr=fdescr1) [i2]
+        finish(i1)
+        '''
+        loop = self.interpret(ops, [4, 7])
+        assert self.getint(0) == 4*7
+        ops = '''
+        [i2]
+        i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr)        
+        finish(i3, descr=fdescr2)        
+        '''
+        bridge = self.attach_bridge(ops, loop, -2)
+
+
+        self.cpu.set_future_value_int(0, 4)
+        self.cpu.set_future_value_int(1, 7)        
+        self.run(loop)
+        assert self.getint(0) == 29
+

diff --git a/pypy/jit/backend/arm/test/test_list.py b/pypy/jit/backend/arm/test/test_list.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/arm/test/test_list.py
@@ -0,0 +1,8 @@
+
+from pypy.jit.metainterp.test.test_list import ListTests
+from pypy.jit.backend.arm.test.support import JitARMMixin
+
+class TestList(JitARMMixin, ListTests):
+    # for individual tests see
+    # ====> ../../../metainterp/test/test_list.py
+    pass

diff --git a/pypy/jit/backend/arm/test/test_recursive.py b/pypy/jit/backend/arm/test/test_recursive.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/arm/test/test_recursive.py
@@ -0,0 +1,8 @@
+
+from pypy.jit.metainterp.test.test_recursive import RecursiveTests
+from pypy.jit.backend.arm.test.support import JitARMMixin
+
+class TestRecursive(JitARMMixin, RecursiveTests):
+    # for the individual tests see
+    # ====> ../../../metainterp/test/test_recursive.py
+    pass

diff --git a/pypy/jit/backend/arm/test/test_string.py b/pypy/jit/backend/arm/test/test_string.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/arm/test/test_string.py
@@ -0,0 +1,13 @@
+import py
+from pypy.jit.metainterp.test import test_string
+from pypy.jit.backend.arm.test.support import JitARMMixin
+
+class TestString(JitARMMixin, test_string.TestLLtype):
+    # for the individual tests see
+    # ====> ../../../metainterp/test/test_string.py
+    pass
+
+class TestUnicode(JitARMMixin, test_string.TestLLtypeUnicode):
+    # for the individual tests see
+    # ====> ../../../metainterp/test/test_string.py
+    pass


More information about the Pypy-commit mailing list