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

david at codespeak.net david at codespeak.net
Sat Nov 6 15:27:57 CET 2010


Author: david
Date: Sat Nov  6 15:27:56 2010
New Revision: 78794

Modified:
   pypy/branch/arm-backend/pypy/jit/backend/arm/instruction_builder.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/instructions.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py
Log:
Implement extra load store instructions for half word and byte access and refactor tests a bit

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 Nov  6 15:27:56 2010
@@ -30,6 +30,77 @@
                         | (w & 0x1) << 21
                         | reg_operation(rt, rn, rm, imm, s, shifttype))
     return f
+
+def define_extra_load_store_func(name, table):
+    def check_registers(r1, r2):
+        assert r1 % 2 == 0
+        assert r1 + 1 == r2
+        assert r1 != 14
+
+    n = ((table['op1'] & 0x1F) << 20
+        | 0x1 << 7
+        | (table['op2'] & 0x3) << 5
+        | 0x1 << 4)
+    p = 1
+    w = 0
+    rncond = ('rn' in table and table['rn'] == '!0xF')
+    dual =  (name[-4] == 'D')
+
+    if dual:
+        if name[-2:] == 'rr':
+            def f(self, rt, rt2, rn, rm, cond=cond.AL):
+                check_registers(rt, rt2)
+                assert not (rncond and rn == 0xF)
+                self.write32(n
+                        | cond << 28
+                        | (p & 0x1) << 24
+                        | (1 & 0x1) << 23
+                        | (w & 0x1) << 21
+                        | (rn & 0xF) << 16
+                        | (rt & 0xF) << 12
+                        | (rm & 0xF))
+        else:
+            def f(self, rt, rt2, rn, imm=0, cond=cond.AL):
+                check_registers(rt, rt2)
+                assert not (rncond and rn == 0xF)
+                u, imm = self._encode_imm(imm)
+                self.write32(n
+                        | cond << 28
+                        | (p & 0x1) << 24
+                        | (u & 0x1) << 23
+                        | (w & 0x1) << 21
+                        | (rn & 0xF) << 16
+                        | (rt & 0xF) << 12
+                        | ((imm >> 0x4) & 0xF) << 8
+                        | (imm & 0xF))
+
+    else:
+        if name[-2:] == 'rr':
+            def f(self, rt, rn, rm, cond=cond.AL):
+                assert not (rncond and rn == 0xF)
+                self.write32(n
+                        | cond << 28
+                        | (p & 0x1) << 24
+                        | (1 & 0x1) << 23
+                        | (w & 0x1) << 21
+                        | (rn & 0xF) << 16
+                        | (rt & 0xF) << 12
+                        | (rm & 0xF))
+        else:
+            def f(self, rt, rn, imm=0, cond=cond.AL):
+                assert not (rncond and rn == 0xF)
+                u, imm = self._encode_imm(imm)
+                self.write32(n
+                        | cond << 28
+                        | (p & 0x1) << 24
+                        | (u & 0x1) << 23
+                        | (w & 0x1) << 21
+                        | (rn & 0xF) << 16
+                        | (rt & 0xF) << 12
+                        | ((imm >> 0x4) & 0xF) << 8
+                        | (imm & 0xF))
+    return f
+
 def define_data_proc_imm(name, table):
     n = (0x1 << 25
         | (table['op'] & 0x1F) << 20)
@@ -194,11 +265,11 @@
 def reg_operation(rt, rn, rm, imm, s, shifttype):
     # XXX encode shiftype correctly
     return ((s & 0x1) << 20
-            | (rn & 0xFF) << 16
-            | (rt & 0xFF) << 12
+            | (rn & 0xF) << 16
+            | (rt & 0xF) << 12
             | (imm & 0x1F) << 7
             | (shifttype & 0x3) << 5
-            | (rm & 0xFF))
+            | (rm & 0xF))
 
 def define_instruction(builder, key, val, target):
         f = builder(key, val)
@@ -206,6 +277,7 @@
 
 def define_instructions(target):
     i_g_map = [(instructions.load_store, define_load_store_func),
+                (instructions.extra_load_store, define_extra_load_store_func),
                 (instructions.data_proc, define_data_proc),
                 (instructions.data_proc_imm, define_data_proc_imm),
                 (instructions.supervisor_and_coproc, define_supervisor_and_coproc),

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/instructions.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/instructions.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/instructions.py	Sat Nov  6 15:27:56 2010
@@ -10,6 +10,21 @@
     'LDRB_ri': {'A':0, 'op1': 0x5, 'B': 0, 'imm': True},
     'LDRB_rr': {'A':1, 'op1': 0x5, 'B': 0, 'imm': False},
 }
+extra_load_store = { #Section 5.2.8
+    'STRH_rr':  {'op2': 0x1, 'op1': 0x0},
+    'LDRH_rr':  {'op2': 0x1, 'op1': 0x1},
+    'STRH_ri':  {'op2': 0x1, 'op1': 0x4},
+    'LDRH_ri':  {'op2': 0x1, 'op1': 0x5, 'rn':'!0xF'},
+    'LDRD_rr':  {'op2': 0x2, 'op1': 0x0},
+    'LDRSB_rr': {'op2': 0x2, 'op1': 0x1},
+    'LDRD_ri':  {'op2': 0x2, 'op1': 0x4},
+    'LDRSB_ri': {'op2': 0x2, 'op1': 0x5, 'rn':'!0xF'},
+    'STRD_rr':  {'op2': 0x3, 'op1': 0x0},
+    'LDRSH_rr': {'op2': 0x3, 'op1': 0x1},
+    'STRD_ri':  {'op2': 0x3, 'op1': 0x4},
+    'LDRSH_ri': {'op2': 0x3, 'op1': 0x5, 'rn':'!0xF'},
+}
+
 
 data_proc = {
     'AND_rr': {'op1':0x0, 'op2':0, 'op3':0, 'result':True, 'base':True},

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py	Sat Nov  6 15:27:56 2010
@@ -52,9 +52,8 @@
         self.assert_equal('MOV r9, #255')
 
     def test_mov_ri_max(self):
-        py.test.skip('Check the actual largest thing')
-        self.cb.MOV_ri(r.r9.value, 0xFFF)
-        self.assert_equal('MOV r9, #4095')
+        self.cb.MOV_ri(r.r9.value, 0xFF)
+        self.assert_equal('MOV r9, #255')
 
     def test_str_ri(self):
         self.cb.STR_ri(r.r9.value, r.r14.value)
@@ -109,9 +108,8 @@
         self.assert_equal('SUB r2, r4, #123')
 
     def test_sub_ri2(self):
-        py.test.skip('XXX check the actual largest value')
-        self.cb.SUB_ri(r.r3.value, r.r7.value, 0xFFF)
-        self.assert_equal('SUB r3, r7, #4095')
+        self.cb.SUB_ri(r.r3.value, r.r7.value, 0xFF)
+        self.assert_equal('SUB r3, r7, #255')
 
     def test_cmp_ri(self):
         self.cb.CMP_ri(r.r3.value, 123)
@@ -157,6 +155,19 @@
     test = builder(key, value)
     setattr(TestInstrCodeBuilderForGeneratedInstr, test_name % key, test)
 
+def gen_test_function(name, asm, args, kwargs=None):
+    if kwargs is None:
+        kwargs = {}
+    def f(self):
+        func = getattr(self.cb, name)
+        func(*args, **kwargs)
+        try:
+            f_name = name[:name.index('_')]
+        except ValueError, e:
+            f_name = name
+        self.assert_equal(asm % f_name)
+    return f
+
 def gen_test_data_proc_imm_func(name, table):
     if table['result'] and table['base']:
         def f(self):
@@ -164,32 +175,28 @@
             func(r.r3.value, r.r7.value, 23)
             self.assert_equal('%s r3, r7, #23' % name[:name.index('_')])
             py.test.raises(ValueError, 'func(r.r3.value, r.r7.value, -12)')
-    elif not table['base']:
-        def f(self):
-            func = getattr(self.cb, name)
-            func(r.r3.value, 23)
-            self.assert_equal('%s r3, #23' % name[:name.index('_')])
     else:
-        def f(self):
-            func = getattr(self.cb, name)
-            func(r.r3.value, 23)
-            self.assert_equal('%s r3, #23' % name[:name.index('_')])
+        f = gen_test_function(name, '%s r3, #23', [r.r3.value, 23])
     return f
 
 def gen_test_imm_func(name, table):
-    def f(self):
-        func = getattr(self.cb, name)
-        func(r.r3.value, r.r7.value, 23)
-        self.assert_equal('%s r3, [r7, #23]' % name[:name.index('_')])
-    return f
+    return gen_test_function(name, '%s r3, [r7, #23]', [r.r3.value, r.r7.value, 23])
 
 def gen_test_reg_func(name, table):
-    def f(self):
-        func = getattr(self.cb, name)
-        func(r.r3.value, r.r7.value, r.r12.value)
-        self.assert_equal('%s r3, [r7, r12]' % name[:name.index('_')])
-    return f
+    return gen_test_function(name, '%s r3, [r7, r12]', [r.r3.value, r.r7.value, r.r12.value])
 
+def gen_test_extra_load_store_func(name, table):
+    if name[-4] == 'D':
+        if name[-2:] == 'rr':
+            f = gen_test_function(name, '%s r4, [r8, r12]', [r.r4.value, r.r5.value, r.r8.value, r.r12.value])
+        else:
+            f = gen_test_function(name, '%s r4, [r8, #223]', [r.r4.value, r.r5.value, r.r8.value, 223])
+    else:
+        if name[-2:] == 'rr':
+            f = gen_test_function(name, '%s r4, [r5, r12]', [r.r4.value, r.r5.value, r.r12.value])
+        else:
+            f = gen_test_function(name, '%s r4, [r5, #223]', [r.r4.value, r.r5.value, 223])
+    return f
 def gen_test_mul_func(name, table):
     if 'acc' in table and table['acc']:
         if 'update_flags' in table and table['update_flags']:
@@ -212,35 +219,20 @@
             func(r.r3.value, r.r13.value, r.r7.value, r.r12.value)
             self.assert_equal("""%(name)s r3, r13, r7, r12 """ % {'name':name})
     else:
-        def f(self):
-            func = getattr(self.cb, name)
-            func(r.r3.value, r.r7.value, r.r12.value)
-            self.assert_equal("""%(name)s r3, r7, r12 """ % {'name':name})
+        f = gen_test_function(name, '%s r3, r7, r12 ', [r.r3.value, r.r7.value, r.r12.value])
     return f
 
 def gen_test_data_reg_shift_reg_func(name, table):
     if name[-2:] == 'rr':
-        def f(self):
-            func = getattr(self.cb, name)
-            func(r.r3.value, r.r7.value, r.r12.value)
-            self.assert_equal('%s r3, r7, r12' % name[:name.index('_')])
-
+        f = gen_test_function(name, '%s r3, r7, r12', [r.r3.value, r.r7.value, r.r12.value])
     else:
-        if 'result' in table and not table['result']:
-            result = False
-        else:
-            result = True
+        result = 'result' not in table or table['result']
         if result:
-            def f(self):
-                func = getattr(self.cb, name)
-                func(r.r3.value, r.r7.value, r.r8.value, r.r11.value, shifttype=0x2)
-                self.assert_equal('%s r3, r7, r8, ASR r11' % name[:name.index('_')])
+            f = gen_test_function(name, '%s r3, r7, r8, ASR r11',
+                                    [r.r3.value, r.r7.value, r.r8.value, r.r11.value], {'shifttype':0x2})
         else:
-            def f(self):
-                func = getattr(self.cb, name)
-                func(r.r3.value, r.r7.value, r.r11.value, shifttype=0x2)
-                self.assert_equal('%s r3, r7, ASR r11' % name[:name.index('_')])
-
+            f = gen_test_function(name, '%s r3, r7, ASR r11',
+                                    [r.r3.value, r.r7.value, r.r11.value], {'shifttype':0x2})
     return f
 
 def gen_test_data_reg_func(name, table):
@@ -263,10 +255,7 @@
 %(name)sS r3, r7, r12
 """ % {'name':op_name})
     else:
-        def f(self):
-            func = getattr(self.cb, name)
-            func(r.r3.value, r.r7.value)
-            self.assert_equal("""%(name)s r3, r7""" % {'name':op_name})
+        f = gen_test_function(name, '%s r3, r7', [r.r3.value, r.r7.value])
 
     return f
 
@@ -279,6 +268,9 @@
             f = gen_test_reg_func
         build_test(f, key, value, test_name)
 
+    for key, value in instructions.extra_load_store.iteritems():
+        build_test(gen_test_extra_load_store_func, key, value, 'test_extra_load_store_%s' % test_name)
+
     for key, value, in instructions.data_proc.iteritems():
         build_test(gen_test_data_reg_func, key, value, test_name)
 



More information about the Pypy-commit mailing list