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

david at codespeak.net david at codespeak.net
Thu Oct 14 17:37:19 CEST 2010


Author: david
Date: Thu Oct 14 17:37:17 2010
New Revision: 77946

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/gen.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py
Log:
Encode register based data processing and generate functions for them.


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	Thu Oct 14 17:37:17 2010
@@ -1,4 +1,5 @@
 import conditions as cond
+import registers as reg
 from pypy.rlib.rmmap import alloc
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.jit.backend.arm.instruction_builder import define_instructions
@@ -26,14 +27,6 @@
                         | (rd & 0xF) << 12
                         | (imm & 0xFFF))
 
-
-    def MOV_rr(self, rd, rm, cond=cond.AL, s=0):
-        self.write32(cond << 28
-                    | 0xD << 21
-                    | (s & 0x1) << 20
-                    | (rd & 0xFF) << 12
-                    | (rm & 0xFF))
-
     def MOV_ri(self, rt, imm=0, cond=cond.AL):
         # XXX Check the actual allowed size for imm
         # XXX S bit
@@ -44,27 +37,8 @@
                     | (rt & 0xF) << 12
                     | (imm & 0xFFF))
 
-    def ASR_ri(self, rd, rm, imm=0, cond=cond.AL, s=0):
-        self.write32(cond << 28
-                    | 0xD << 21
-                    | (s & 0x1) << 20
-                    | (rd & 0xF) << 12
-                    | (imm & 0x1F) << 7
-                    | 0x4 << 4
-                    | (rm & 0xF))
-
-    #XXX encode shifttype correctly
-    def ORR_rr(self, rd, rn, rm, imm=0, cond=cond.AL, s=0, shifttype=0):
-        self.write32(cond << 28
-                    | 0x3 << 23
-                    | (s & 0x1) << 20
-                    | (rn & 0xFF) << 16
-                    | (rd & 0xFF) << 12
-                    | (imm & 0x1F) << 7
-                    | (shifttype & 0x3) << 5
-                    | (rm & 0xFF))
-
     def PUSH(self, regs, cond=cond.AL):
+        assert reg.sp not in regs
         instr = self._encode_reg_list(cond << 28 | 0x92D << 16, regs)
         self.write32(instr)
 

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	Thu Oct 14 17:37:17 2010
@@ -1,7 +1,7 @@
 from pypy.jit.backend.arm import conditions as cond
 from pypy.jit.backend.arm import instructions
 
-def define_load_store_func(target, name, table):
+def define_load_store_func(name, table):
     #  XXX W and P bits are not encoded yet
     n = (0x1 << 26
         | (table['A'] & 0x1) << 25
@@ -30,14 +30,60 @@
                         | (p & 0x1) <<  24
                         | (u & 0x1) << 23
                         | (w & 0x1) << 21
-                        | (rn & 0xFF) << 16
-                        | (rt & 0xFF) << 12
+                        | reg_operation(rt, rn, rm, imm, s, shifttype))
+    return f
+
+def define_data_proc(name, table):
+    n = ((table['op1'] & 0x1F) << 20
+        | (table['op2'] & 0x1F) << 7
+        | (table['op3'] & 0x3) << 5)
+    if name[-2:] == 'ri':
+        def f(self, rd, rm, imm=0, cond=cond.AL, s=0):
+            if table['op2cond'] == '!0':
+                assert imm != 0
+            elif table['op2cond'] == '0':
+                assert imm == 0
+            self.write32(n
+                        | cond << 28
+                        | (s & 0x1) << 20
+                        | (rd & 0xFF) << 12
                         | (imm & 0x1F) << 7
-                        | (shifttype & 0x3) << 5
                         | (rm & 0xFF))
 
-    setattr(target, name, f)
+    elif not table['result']:
+        # ops without result
+        def f(self, rn, rm, imm=0, cond=cond.AL, s=0, shifttype=0):
+            self.write32(n
+                        | cond << 28
+                        | reg_operation(0, rn, rm, imm, s, shifttype))
+    elif not table['base']:
+        # ops without base register
+        def f(self, rd, rm, imm=0, cond=cond.AL, s=0, shifttype=0):
+            self.write32(n
+                        | cond << 28
+                        | reg_operation(rd, 0, rm, imm, s, shifttype))
+    else:
+        def f(self, rd, rn, rm, imm=0, cond=cond.AL, s=0, shifttype=0):
+            self.write32(n
+                        | cond << 28
+                        | reg_operation(rd, rn, rm, imm, s, shifttype))
+    return f
+
+
+def reg_operation(rt, rn, rm, imm, s, shifttype):
+    # XXX encode shiftype correctly
+    return ((s & 0x1 << 20)
+            | (rn & 0xFF) << 16
+            | (rt & 0xFF) << 12
+            | (imm & 0x1F) << 7
+            | (shifttype & 0x3) << 5
+            | (rm & 0xFF))
 
 def define_instructions(target):
     for key, val in instructions.load_store.iteritems():
-        define_load_store_func(target, key, val)
+        f = define_load_store_func(key, val)
+        setattr(target, key, f)
+
+    for key, val in instructions.data_proc.iteritems():
+        f = define_data_proc(key, val)
+        setattr(target, key, f)

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	Thu Oct 14 17:37:17 2010
@@ -10,3 +10,25 @@
     'LDRB_ri': {'A':0, 'op1': 0x5, 'B': 0, 'imm': True},
     'LDRB_rr': {'A':1, 'op1': 0x5, 'B': 0, 'imm': False},
 }
+
+data_proc = {
+    'AND_rr': {'op1':0x0, 'op2':0, 'op3':0, 'result':True, 'base':True},
+    'EOR_rr': {'op1':0x2, 'op2':0, 'op3':0, 'result':True, 'base':True},
+    'SUB_rr': {'op1':0x4, 'op2':0, 'op3':0, 'result':True, 'base':True},
+    'RSB_rr': {'op1':0x6, 'op2':0, 'op3':0, 'result':True, 'base':True},
+    'ADD_rr': {'op1':0x8, 'op2':0, 'op3':0, 'result':True, 'base':True},
+    'ADC_rr': {'op1':0xA, 'op2':0, 'op3':0, 'result':True, 'base':True},
+    'SBC_rr': {'op1':0xC, 'op2':0, 'op3':0, 'result':True, 'base':True},
+    'RSC_rr': {'op1':0xE, 'op2':0, 'op3':0, 'result':True, 'base':True},
+    'TST_rr': {'op1':0x11, 'op2':0, 'op3':0, 'result':False, 'base':True},
+    'TEQ_rr': {'op1':0x13, 'op2':0, 'op3':0, 'result':False, 'base':True},
+    'CMP_rr': {'op1':0x15, 'op2':0, 'op3':0, 'result':False, 'base':True},
+    'CMN_rr': {'op1':0x17, 'op2':0, 'op3':0, 'result':False, 'base':True},
+    'ORR_rr': {'op1':0x18, 'op2':0, 'op3':0, 'result':True, 'base':True},
+    'MOV_rr': {'op1':0x1A, 'op2':0, 'op3':0, 'result':True, 'base':False},
+    'LSL_ri': {'op1':0x1A, 'op2':0x0, 'op3':0, 'op2cond':'!0', 'result':False, 'base':True},
+    'LSR_ri': {'op1':0x1A, 'op2':0, 'op3':0x1, 'op2cond':'', 'result':False, 'base':True},
+    '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},
+}

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/test/gen.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/test/gen.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/test/gen.py	Thu Oct 14 17:37:17 2010
@@ -38,7 +38,7 @@
         res = self.body % (self.instr)
         self.file.write(res)
         self.file.flush()
-        os.system("%s %s %s -o %s/a.out" % (AS, self.asm_opts, self.name, self.tmpdir))
+        os.system("%s --fatal-warnings %s %s -o %s/a.out" % (AS, self.asm_opts, self.name, self.tmpdir))
 
     def __del__(self):
         self.file.close()

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	Thu Oct 14 17:37:17 2010
@@ -82,8 +82,8 @@
         self.assert_equal('PUSH {r1}')
 
     def test_push_multiple(self):
-        self.cb.PUSH([r.r3, r.r1, r.r6, r.r8, r.sp, r.pc])
-        self.assert_equal('PUSH {r3, r1, r6, r8, sp, pc}')
+        self.cb.PUSH([r.r1, r.r3, r.r6, r.r8, r.pc])
+        self.assert_equal('PUSH {r1, r3, r6, r8, pc}')
 
     def test_push_multiple2(self):
         self.cb.PUSH([r.fp, r.ip, r.lr, r.pc])
@@ -126,7 +126,11 @@
         else:
             f = gen_test_reg_func
         test = f(key, value)
-    setattr(TestInstrCodeBuilderForGeneratedInstr, 'test_%s' % key, test)
+        setattr(TestInstrCodeBuilderForGeneratedInstr, 'test_%s' % key, test)
+
+    for key, value, in instructions.data_proc.iteritems():
+        test = gen_test_data_reg_func(key, value)
+        setattr(TestInstrCodeBuilderForGeneratedInstr, 'test_%s' % key, test)
 
 def gen_test_imm_func(name, table):
     def f(self):
@@ -141,4 +145,25 @@
         func(r.r3, r.r7, r.r12)
         self.assert_equal('%s r3, [r7, r12]' % name[:name.index('_')])
     return f
+
+def gen_test_data_reg_func(name, table):
+    if name[-2:] == 'ri':
+        def f(self):
+            func = getattr(self.cb, name)
+            func(r.r3, r.r7, 12)
+            self.assert_equal('%s r3, r7, #12' % name[:name.index('_')])
+
+    elif table['base'] and table['result']:
+        def f(self):
+            func = getattr(self.cb, name)
+            func(r.r3, r.r7, r.r12)
+            self.assert_equal('%s r3, r7, r12' % name[:name.index('_')])
+    else:
+        def f(self):
+            func = getattr(self.cb, name)
+            func(r.r3, r.r7)
+            self.assert_equal('%s r3, r7' % name[:name.index('_')])
+
+    return f
+
 build_tests()



More information about the Pypy-commit mailing list