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

david at codespeak.net david at codespeak.net
Tue Nov 9 19:43:11 CET 2010


Author: david
Date: Tue Nov  9 19:43:09 2010
New Revision: 78937

Modified:
   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/instructions.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/test/support.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py
Log:
Generate block data transfer instruction encoding and refactor machine code generation tests


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	Tue Nov  9 19:43:09 2010
@@ -49,11 +49,6 @@
         instr = self._encode_reg_list(cond << 28 | 0x8BD << 16, regs)
         self.write32(instr)
 
-    def LDM(self, rn, regs, w=0, cond=cond.AL):
-        instr = cond << 28 | 0x89 << 20 | w << 21 | (rn & 0xFF) << 16
-        instr = self._encode_reg_list(instr, regs)
-        self.write32(instr)
-
     def BKPT(self, cond=cond.AL):
         self.write32(cond << 28 | 0x1200070)
 

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	Tue Nov  9 19:43:09 2010
@@ -255,8 +255,20 @@
 
     return f
 
-def define_long_mult_div_instructions(name, table):
-    pass
+def define_block_data_func(name, table):
+    n = (table['op'] & 0x3F) << 20
+    def f(self, rn, regs, w=0, cond=cond.AL):
+        # no R bit for now at bit 15
+        instr = (n
+                | cond << 28
+                | 0x1 << 27
+                | (w & 0x1) << 21
+                | (rn & 0xF) << 16)
+        instr = self._encode_reg_list(instr, regs)
+        self.write32(instr)
+
+    return f
+
 def imm_operation(rt, rn, imm):
     return ((rn & 0xFF) << 16
     | (rt & 0xFF) << 12
@@ -282,7 +294,8 @@
                 (instructions.data_proc_imm, define_data_proc_imm),
                 (instructions.supervisor_and_coproc, define_supervisor_and_coproc),
                 (instructions.multiply, define_multiply_instructions),
-                (instructions.data_proc_reg_shift_reg, define_data_proc_register_shifted)]
+                (instructions.data_proc_reg_shift_reg, define_data_proc_register_shifted),
+                (instructions.block_data, define_block_data_func)]
 
     for inss, gen in i_g_map:
         for key, val in inss.iteritems():

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	Tue Nov  9 19:43:09 2010
@@ -104,8 +104,8 @@
     'LDMDB': {'op': 0x11},
     'STMIB': {'op': 0x18},
     'LDMIB': {'op': 0x19},
-    'STM':   {'op': 0x4},
-    'LDM':   {'op': 0x5},
+    #'STM':   {'op': 0x4},
+    #'LDM':   {'op': 0x5},
 }
 branch = {
     'B':     {'op': 0x20},

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/test/support.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/test/support.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/test/support.py	Tue Nov  9 19:43:09 2010
@@ -32,3 +32,46 @@
     finally:
         if skip:
             py.test.skip(msg)
+
+# generators for asm tests
+
+def gen_test_function(name, asm, args, kwargs=None, asm_ext=None):
+    if kwargs is None:
+        kwargs = {}
+    if asm_ext is None:
+        asm_ext = ''
+    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('%s%s %s' % (f_name, asm_ext, asm))
+    return f
+
+def define_test(cls, name, test_case, base_name=None):
+    import types
+    if base_name is None:
+        base_name = ''
+    templ = 'test_generated_%s_%s'
+    test_name = templ % (base_name, name)
+    if hasattr(cls, test_name):
+        i = 1
+        new_test_name = test_name
+        while hasattr(cls, new_test_name):
+            new_test_name = '%s_%d' % (test_name, i)
+            i += 1
+        test_name = new_test_name
+    if not isinstance(test_case, types.FunctionType):
+        asm, sig = test_case[0:2]
+        kw_args = None
+        asm_ext = None
+        if len(test_case) > 2:
+            kw_args = test_case[2]
+        if len(test_case) > 3:
+            asm_ext = test_case[3]
+        f = gen_test_function(name, asm, sig, kw_args, asm_ext)
+    else:
+        f = test_case
+    setattr(cls, test_name, f)

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	Tue Nov  9 19:43:09 2010
@@ -2,7 +2,7 @@
 from pypy.jit.backend.arm import codebuilder
 from pypy.jit.backend.arm import conditions
 from pypy.jit.backend.arm import instructions
-from pypy.jit.backend.arm.test.support import requires_arm_as
+from pypy.jit.backend.arm.test.support import (requires_arm_as, define_test, gen_test_function)
 from gen import assemble
 import py
 
@@ -91,18 +91,6 @@
         self.cb.PUSH([reg.value for reg in [r.fp, r.ip, r.lr, r.pc]])
         self.assert_equal('PUSH {fp, ip, lr, pc}')
 
-    def test_ldm_one_reg(self):
-        self.cb.LDM(r.sp.value, [r.fp.value])
-        self.assert_equal('LDM sp, {fp}')
-
-    def test_ldm_multiple_reg(self):
-        self.cb.LDM(r.sp.value, [reg.value for reg in [r.fp, r.ip, r.lr]])
-        self.assert_equal('LDM sp, {fp, ip, lr}')
-
-    def test_ldm_multiple_reg2(self):
-        self.cb.LDM(r.sp.value, [reg.value for reg in [r.fp, r.sp, r.pc]])
-        self.assert_equal("LDM sp, {fp, sp, pc}")
-
     def test_sub_ri(self):
         self.cb.SUB_ri(r.r2.value, r.r4.value, 123)
         self.assert_equal('SUB r2, r4, #123')
@@ -149,24 +137,6 @@
     def setup_method(self, ffuu_method):
         self.cb = CodeBuilder()
 
-# XXX refactor this functions
-
-def build_test(builder, key, value, test_name):
-    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']:
@@ -175,112 +145,97 @@
             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)')
+        return [f]
     else:
-        f = gen_test_function(name, '%s r3, #23', [r.r3.value, 23])
-    return f
+        return [('r3, #23', [r.r3.value, 23])]
 
-def gen_test_imm_func(name, table):
-    return gen_test_function(name, '%s r3, [r7, #23]', [r.r3.value, r.r7.value, 23])
-
-def gen_test_reg_func(name, table):
-    return gen_test_function(name, '%s r3, [r7, r12]', [r.r3.value, r.r7.value, r.r12.value])
+def gen_test_load_store_func(name, table):
+    if table['imm']:
+        return [('r3, [r7, #23]', [r.r3.value, r.r7.value, 23]),
+            ('r3, [r7, #-23]', [r.r3.value, r.r7.value, -23])
+            ]
+    else:
+        return [('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])
+            return [('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])
+            return [('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])
+            return [('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 [('r4, [r5, #223]', [r.r4.value, r.r5.value, 223])]
     return f
-def gen_test_mul_func(name, table):
+
+def gen_test_multiply_func(name, table):
     if 'acc' in table and table['acc']:
         if 'update_flags' in table and table['update_flags']:
-            def f(self):
-                func = getattr(self.cb, name)
-                func(r.r3.value, r.r7.value, r.r12.value, r.r13.value)
-                func(r.r3.value, r.r7.value, r.r12.value, r.r13.value, s=1)
-                self.assert_equal("""
-    %(name)s r3, r7, r12, r13
-    %(name)sS r3, r7, r12, r13
-    """ % {'name':name})
+            return [
+            ('r3, r7, r12, r13', (r.r3.value, r.r7.value, r.r12.value, r.r13.value)),
+            ('r3, r7, r12, r13', (r.r3.value, r.r7.value, r.r12.value, r.r13.value), {'s':1}, 'S')
+            ]
         else:
-            def f(self):
-                func = getattr(self.cb, name)
-                func(r.r3.value, r.r7.value, r.r12.value, r.r13.value)
-                self.assert_equal("""%(name)s r3, r7, r12, r13 """ % {'name':name})
+            return [('r3, r7, r12, r13', (r.r3.value, r.r7.value, r.r12.value,
+            r.r13.value))]
     elif 'long' in table and table['long']:
-        def f(self):
-            func = getattr(self.cb, name)
-            func(r.r3.value, r.r13.value, r.r7.value, r.r12.value)
-            self.assert_equal("""%(name)s r3, r13, r7, r12 """ % {'name':name})
+        return [('r3, r13, r7, r12', (r.r3.value, r.r13.value, r.r7.value, r.r12.value))]
     else:
-        f = gen_test_function(name, '%s r3, r7, r12 ', [r.r3.value, r.r7.value, r.r12.value])
-    return f
+        return [('r3, r7, r12', (r.r3.value, r.r7.value, r.r12.value))]
 
-def gen_test_data_reg_shift_reg_func(name, table):
+def gen_test_data_proc_reg_shift_reg_func(name, table):
     if name[-2:] == 'rr':
-        f = gen_test_function(name, '%s r3, r7, r12', [r.r3.value, r.r7.value, r.r12.value])
+        return [('r3, r7, r12', [r.r3.value, r.r7.value, r.r12.value])]
     else:
         result = 'result' not in table or table['result']
         if result:
-            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})
+            return [('r3, r7, r8, ASR r11', [r.r3.value, r.r7.value,
+                            r.r8.value, r.r11.value], {'shifttype':0x2})]
         else:
-            f = gen_test_function(name, '%s r3, r7, ASR r11',
-                                    [r.r3.value, r.r7.value, r.r11.value], {'shifttype':0x2})
-    return f
+            return [('r3, r7, ASR r11', [r.r3.value, r.r7.value,
+                            r.r11.value], {'shifttype':0x2})]
 
-def gen_test_data_reg_func(name, table):
+def gen_test_data_proc_func(name, table):
     op_name = name[:name.index('_')]
     if name[-2:] == 'ri':
-        def f(self):
-            func = getattr(self.cb, name)
-            func(r.r3.value, r.r7.value, 12)
-            func(r.r3.value, r.r7.value, 12, s=1)
-            self.assert_equal("""
-%(name)s r3, r7, #12
-%(name)sS r3, r7, #12""" % {'name': op_name})
-
+        return [('r3, r7, #12', (r.r3.value, r.r7.value, 12)),
+                ('r3, r7, #12', (r.r3.value, r.r7.value, 12), {'s':1}, 'S')]
     elif table['base'] and table['result']:
-        def f(self):
-            func = getattr(self.cb, name)
-            func(r.r3.value, r.r7.value, r.r12.value)
-            func(r.r3.value, r.r7.value, r.r12.value, s=1)
-            self.assert_equal("""%(name)s r3, r7, r12
-%(name)sS r3, r7, r12
-""" % {'name':op_name})
+        return [('r3, r7, r12', (r.r3.value, r.r7.value, r.r12.value)),
+                ('r3, r7, r12', (r.r3.value, r.r7.value, r.r12.value), {'s':1}, 'S')]
     else:
-        f = gen_test_function(name, '%s r3, r7', [r.r3.value, r.r7.value])
+        return [('r3, r7', [r.r3.value, r.r7.value])]
 
-    return f
+def gen_test_supervisor_and_coproc_func(name, table):
+    def f(self):
+        py.test.skip('not used at the moment')
+    return [f]
+
+def gen_test_branch_func(name, table):
+    def f(self):
+        py.test.skip('not used at the moment')
+    return [f]
 
+def gen_test_block_data_func(name, table):
+    tests = []
+    for c,v in [('EQ', conditions.EQ), ('LE', conditions.LE), ('AL', conditions.AL)]:
+        for regs in range(16):
+            asm = 'r3, {%s}' % ','.join(['r%d' % i for i in range(regs+1)])
+            tests.append((asm, (r.r3.value, range(regs+1))))
+    return tests
 def build_tests():
+    cls = TestInstrCodeBuilderForGeneratedInstr
     test_name = 'test_generated_%s'
-    for key, value in instructions.load_store.iteritems():
-        if value['imm']:
-            f = gen_test_imm_func
-        else:
-            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)
-
-    for key, value, in instructions.data_proc_reg_shift_reg.iteritems():
-        build_test(gen_test_data_reg_shift_reg_func, key, value, test_name)
-
-    for key, value, in instructions.data_proc_imm.iteritems():
-        build_test(gen_test_data_proc_imm_func, key, value, test_name)
-
-    for key, value, in instructions.multiply.iteritems():
-        build_test(gen_test_mul_func, key, value, test_name)
-
+    ins = [k for k in instructions.__dict__.keys() if not k.startswith('__')]
+    for name in ins:
+        try:
+            func = globals()['gen_test_%s_func' % name]
+        except KeyError:
+            print 'No test generator for %s instructions' % name
+            continue
+        for key, value in getattr(instructions, name).iteritems():
+            for test_case in func(key, value):
+                define_test(cls, key, test_case, name)
 build_tests()



More information about the Pypy-commit mailing list