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

david at codespeak.net david at codespeak.net
Sat Oct 30 16:02:18 CEST 2010


Author: david
Date: Sat Oct 30 16:02:16 2010
New Revision: 78526

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/opassembler.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py
Log:
Implement shift operations int_lshift, int_rshift, uint_rshift

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 16:02:16 2010
@@ -94,6 +94,42 @@
                         | reg_operation(rd, rn, rm, imm, s, shifttype))
     return f
 
+def define_data_proc_register_shifted(name, table):
+    n = ((0x1 << 4) | (table['op1'] & 0x1F) << 20 | (table['op2'] & 0x3) << 5)
+    if 'result' in table and not table['result']:
+        result = False
+    else:
+        result = True
+    if name[-2:] == 'sr':
+        if result:
+            def f(self, rd, rn, rm, rs, cond=cond.AL, s=0, shifttype=0):
+                self.write32(n
+                            | cond << 28
+                            | (s & 0x1) << 20
+                            | (rn & 0xF) << 16
+                            | (rd & 0xF) << 12
+                            | (rs & 0xF) << 8
+                            | (shifttype & 0x3) << 5
+                            | (rm & 0xF))
+        else:
+            def f(self, rn, rm, rs, cond=cond.AL, s=0, shifttype=0):
+                self.write32(n
+                            | cond << 28
+                            | (s & 0x1) << 20
+                            | (rn & 0xF) << 16
+                            | (rs & 0xF) << 8
+                            | (shifttype & 0x3) << 5
+                            | (rm & 0xF))
+    else:
+        def f(self, rd, rn, rm, cond=cond.AL, s=0):
+            self.write32(n
+                        | cond << 28
+                        | (s & 0x1) << 20
+                        | (rd & 0xF) << 12
+                        | (rm & 0xF) << 8
+                        | (rn & 0xF))
+    return f
+
 def define_supervisor_and_coproc(name, table):
     n = (0x3 << 26 | (table['op1'] & 0x3F) << 20 | (table['op'] & 0x1) << 4)
     def f(self, coproc, opc1, rt, crn, crm, opc2=0, cond=cond.AL):
@@ -162,7 +198,8 @@
                 (instructions.data_proc, define_data_proc),
                 (instructions.data_proc_imm, define_data_proc_imm),
                 (instructions.supervisor_and_coproc, define_supervisor_and_coproc),
-                (instructions.multiply, define_multiply_instructions)]
+                (instructions.multiply, define_multiply_instructions),
+                (instructions.data_proc_reg_shift_reg, define_data_proc_register_shifted)]
 
     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	Sat Oct 30 16:02:16 2010
@@ -31,6 +31,30 @@
     'ASR_ri': {'op1':0x1A, 'op2':0, 'op3':0x2, 'op2cond':'', 'result':False, 'base':True},
     #'RRX_ri': {'op1':0x1A, 'op2':0, 'op3':0x3, 'op2cond':'0', 'result':False, 'base':True},
     'ROR_ri': {'op1':0x1A, 'op2':0x0, 'op3':0x3, 'op2cond':'!0', 'result':True, 'base':False},
+    #BIC
+    #MVN
+}
+
+data_proc_reg_shift_reg = {
+    'AND_rr_sr': {'op1':0x0,  'op2':0},
+    'EOR_rr_sr': {'op1':0x2,  'op2':0},
+    'SUB_rr_sr': {'op1':0x4,  'op2':0},
+    'RSB_rr_sr': {'op1':0x6,  'op2':0},
+    'ADD_rr_sr': {'op1':0x8,  'op2':0},
+    'ADC_rr_sr': {'op1':0xA,  'op2':0},
+    'SBC_rr_sr': {'op1':0xC,  'op2':0},
+    'RSC_rr_sr': {'op1':0xE,  'op2':0},
+    'TST_rr_sr': {'op1':0x11, 'op2':0, 'result': False},
+    'TEQ_rr_sr': {'op1':0x13, 'op2':0, 'result': False},
+    'CMP_rr_sr': {'op1':0x15, 'op2':0, 'result': False},
+    'CMN_rr_sr': {'op1':0x17, 'op2':0, 'result': False},
+    'ORR_rr_sr': {'op1':0x18, 'op2':0},
+    'LSL_rr': {'op1':0x1A, 'op2':0, },
+    'LSR_rr': {'op1':0x1A, 'op2':0x1},
+    'ASR_rr': {'op1':0x1A, 'op2':0x2},
+    #'RRX_rr': {'op1':0x1A, 'op2':0,},
+    'ROR_rr': {'op1':0x1A, 'op2':0x3},
+    # BIC, MVN
 }
 
 data_proc_imm = {

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 16:02:16 2010
@@ -12,7 +12,7 @@
 from pypy.rpython.annlowlevel import llhelper
 from pypy.rpython.lltypesystem import lltype, rffi, llmemory
 
-def gen_emit_op_ri(opname):
+def gen_emit_op_ri(opname, imm_size=0xFF, commutative=True):
     def f(self, op, regalloc, fcond):
         ri_op = getattr(self.mc, '%s_ri' % opname)
         rr_op = getattr(self.mc, '%s_rr' % opname)
@@ -20,17 +20,15 @@
         arg0 = op.getarg(0)
         arg1 = op.getarg(1)
         res = regalloc.try_allocate_reg(op.result)
-        if self._check_imm_arg(arg0, 0xFF) and not isinstance(arg1, ConstInt):
-            print 'arg0 is imm'
+        if (commutative
+                and self._check_imm_arg(arg0, imm_size)
+                and not isinstance(arg1, ConstInt)):
             reg = regalloc.try_allocate_reg(arg1)
             ri_op(res.value, reg.value, imm=arg0.getint(), cond=fcond)
-        elif self._check_imm_arg(arg1, 0xFF) and not isinstance(arg0, ConstInt):
-            print 'arg1 is imm'
-            box = Box()
+        elif self._check_imm_arg(arg1, imm_size) and not isinstance(arg0, ConstInt):
             reg = regalloc.try_allocate_reg(arg0)
             ri_op(res.value, reg.value, imm=arg1.getint(), cond=fcond)
         else:
-            print 'generating rr'
             reg = self._put_in_reg(arg0, regalloc)
             reg2 = self._put_in_reg(arg1, regalloc)
             rr_op(res.value, reg.value, reg2.value)
@@ -140,9 +138,14 @@
     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')
+    emit_op_int_lshift = gen_emit_op_ri('LSL', imm_size=0x1F, commutative=False)
+    emit_op_int_rshift = gen_emit_op_ri('ASR', imm_size=0x1F, commutative=False)
+    emit_op_uint_rshift = gen_emit_op_ri('LSR', imm_size=0x1F, commutative=False)
+
 
     def _check_imm_arg(self, arg, size):
-        return isinstance(arg, ConstInt) and arg.getint() <= size and arg.getint() >= 0
+        #XXX check ranges for different operations
+        return isinstance(arg, ConstInt) and arg.getint() <= size and arg.getint() > 0
 
 
 class GuardOpAssembler(object):

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 Oct 30 16:02:16 2010
@@ -126,23 +126,6 @@
     def setup_method(self, ffuu_method):
         self.cb = CodeBuilder()
 
-def build_tests():
-    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.data_proc.iteritems():
-        build_test(gen_test_data_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)
 # XXX refactor this functions
 
 def build_test(builder, key, value, test_name):
@@ -200,6 +183,31 @@
             self.assert_equal('%s r3, r7, r12' % name)
     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('_')])
+
+    else:
+        if 'result' in table and not table['result']:
+            result = False
+        else:
+            result = True
+        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('_')])
+        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('_')])
+
+    return f
+
 def gen_test_data_reg_func(name, table):
     if name[-2:] == 'ri':
         def f(self):
@@ -220,4 +228,25 @@
 
     return f
 
+def build_tests():
+    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.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)
+
 build_tests()



More information about the Pypy-commit mailing list