[pypy-commit] pypy s390x-backend: assembler recursion: testing if it the assembler can correctly invoke a recursive function. added helper functions to label positions (in the test suite)

plan_rich noreply at buildbot.pypy.org
Wed Oct 21 20:07:55 EDT 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80377:aa2a464734d2
Date: 2015-10-21 13:58 +0200
http://bitbucket.org/pypy/pypy/changeset/aa2a464734d2/

Log:	assembler recursion: testing if it the assembler can correctly
	invoke a recursive function. added helper functions to label
	positions (in the test suite)

diff --git a/rpython/jit/backend/zarch/assembler.py b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -50,14 +50,17 @@
         return clt.asmmemmgr_blocks
 
     def gen_func_prolog(self):
-        self.mc.STMG(reg.r11, reg.r15, loc.addr(-96, reg.sp))
-        self.mc.AHI(reg.sp, loc.imm(-96))
+        STACK_FRAME_SIZE = 40
+        self.mc.STMG(reg.r11, reg.r15, loc.addr(-STACK_FRAME_SIZE, reg.sp))
+        self.mc.AHI(reg.sp, loc.imm(-STACK_FRAME_SIZE))
 
     def gen_func_epilog(self):
         self.mc.LMG(reg.r11, reg.r15, loc.addr(0, reg.sp))
         self.jmpto(reg.r14)
 
     def jmpto(self, register):
+        # TODO, manual says this is a performance killer, there
+        # might be another operation for unconditional JMP?
         self.mc.BCR_rr(0xf, register.value)
 
     def _build_failure_recovery(self, exc, withfloats=False):
diff --git a/rpython/jit/backend/zarch/instruction_builder.py b/rpython/jit/backend/zarch/instruction_builder.py
--- a/rpython/jit/backend/zarch/instruction_builder.py
+++ b/rpython/jit/backend/zarch/instruction_builder.py
@@ -76,9 +76,9 @@
         | ... | base | length[0:11] | length[12:20] | ... |
         +-------------------------------------------------+
     """
-    displace = basedisp.displace & 0xfffff
+    displace = basedisp.displace & BIT_MASK_20
     base = basedisp.base & 0xf
-    byte = displace >> 8 & 0xf | base << 4
+    byte = (displace >> 8) & 0xf | base << 4
     mc.writechar(chr(byte))
     mc.writechar(chr(displace & 0xff))
     byte = displace >> 12 & 0xff
diff --git a/rpython/jit/backend/zarch/instructions.py b/rpython/jit/backend/zarch/instructions.py
--- a/rpython/jit/backend/zarch/instructions.py
+++ b/rpython/jit/backend/zarch/instructions.py
@@ -29,7 +29,7 @@
     # and one byte and store it back at the op2 position
     'NI':         ('si',       ['\x94']),
     'NIY':        ('siy',      ['\xEB','\x54']),
-    'NC':         ('ssa',   ['\xD4']),
+    'NC':         ('ssa',      ['\xD4']),
 
     # AND immediate
     'NIHH':       ('ri_u',     ['\xA5', '\x04']),
diff --git a/rpython/jit/backend/zarch/test/test_assembler.py b/rpython/jit/backend/zarch/test/test_assembler.py
--- a/rpython/jit/backend/zarch/test/test_assembler.py
+++ b/rpython/jit/backend/zarch/test/test_assembler.py
@@ -110,4 +110,65 @@
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 0x0807060504030201
 
+    def label(self, name, func=False):
+        self.mc.mark_op(name)
+        class ctxmgr(object):
+            def __enter__(_self):
+                if func:
+                    self.a.gen_func_prolog()
+            def __exit__(_self, a, b, c):
+                if func:
+                    self.a.gen_func_epilog()
+                self.mc.mark_op(name + '.end')
+        return ctxmgr()
 
+    def patch_branch_imm16(self, base, imm):
+        print "branch to", imm, "base", base, self.cur(), self.pos('lit.end'), self.pos('lit')
+        imm = (imm & 0xffff) >> 1
+        self.mc.overwrite(base, chr((imm >> 8) & 0xFF))
+        self.mc.overwrite(base+1, chr(imm & 0xFF))
+
+    def pos(self, name):
+        return self.mc.ops_offset[name]
+    def cur(self):
+        return self.mc.get_relative_pos()
+
+    def jump_here(self, func, name):
+        if func.__name__ == 'BRAS':
+            self.patch_branch_imm16(self.pos(name)+2, self.cur() - self.pos(name))
+        else:
+            raise NotImplementedError
+
+    def jump_to(self, reg, label):
+        val = (self.pos(label) - self.cur())
+        print "val", val
+        self.mc.BRAS(reg, loc.imm(val))
+
+    def test_stmg(self):
+        self.mc.LGR(reg.r2, reg.r15)
+        self.a.jmpto(reg.r14)
+        print hex(run_asm(self.a))
+
+    def test_recursion(self):
+        with self.label('func', func=True):
+            with self.label('lit'):
+                self.mc.BRAS(reg.r13, loc.imm(0))
+            self.mc.write('\x00\x00\x00\x00\x00\x00\x00\x00')
+            self.jump_here(self.mc.BRAS, 'lit')
+            # recurse X times
+            self.mc.XGR(reg.r2, reg.r2)
+            self.mc.LGHI(reg.r9, loc.imm(15))
+            with self.label('L1'):
+                self.mc.BRAS(reg.r14, loc.imm(0))
+            with self.label('rec', func=True):
+                self.mc.AGR(reg.r2, reg.r9)
+                self.mc.AHI(reg.r9, loc.imm(-1))
+                # if not entered recursion, return from activation record
+                # implicitly generated here by with statement
+                self.mc.BRC(con.GT, loc.imm(self.pos('rec') - self.cur()))
+            self.jump_here(self.mc.BRAS, 'L1')
+            # call rec... recursivly
+            self.jump_to(reg.r14, 'rec')
+        self.a.jmpto(reg.r14)
+        assert run_asm(self.a) == 120
+


More information about the pypy-commit mailing list